| 2730 | } |
| 2731 | |
| 2732 | static int of_add_programs(Muxer *mux, const OptionsContext *o) |
| 2733 | { |
| 2734 | AVFormatContext *oc = mux->fc; |
| 2735 | /* process manually set programs */ |
| 2736 | for (int i = 0; i < o->program.nb_opt; i++) { |
| 2737 | AVDictionary *dict = NULL; |
| 2738 | const AVDictionaryEntry *e; |
| 2739 | AVProgram *program; |
| 2740 | int ret, progid = i + 1; |
| 2741 | |
| 2742 | ret = av_dict_parse_string(&dict, o->program.opt[i].u.str, "=", ":", |
| 2743 | AV_DICT_MULTIKEY); |
| 2744 | if (ret < 0) { |
| 2745 | av_log(mux, AV_LOG_ERROR, "Error parsing program specification %s\n", |
| 2746 | o->program.opt[i].u.str); |
| 2747 | return ret; |
| 2748 | } |
| 2749 | |
| 2750 | e = av_dict_get(dict, "program_num", NULL, 0); |
| 2751 | if (e) { |
| 2752 | progid = strtol(e->value, NULL, 0); |
| 2753 | av_dict_set(&dict, e->key, NULL, 0); |
| 2754 | } |
| 2755 | |
| 2756 | program = av_new_program(oc, progid); |
| 2757 | if (!program) { |
| 2758 | ret = AVERROR(ENOMEM); |
| 2759 | goto fail; |
| 2760 | } |
| 2761 | |
| 2762 | e = av_dict_get(dict, "title", NULL, 0); |
| 2763 | if (e) { |
| 2764 | av_dict_set(&program->metadata, e->key, e->value, 0); |
| 2765 | av_dict_set(&dict, e->key, NULL, 0); |
| 2766 | } |
| 2767 | |
| 2768 | e = NULL; |
| 2769 | while (e = av_dict_get(dict, "st", e, 0)) { |
| 2770 | int st_num = strtol(e->value, NULL, 0); |
| 2771 | av_program_add_stream_index(oc, progid, st_num); |
| 2772 | } |
| 2773 | |
| 2774 | // make sure that nothing but "st" entries are left in the dict |
| 2775 | e = NULL; |
| 2776 | while (e = av_dict_iterate(dict, e)) { |
| 2777 | if (!strcmp(e->key, "st")) |
| 2778 | continue; |
| 2779 | |
| 2780 | av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", e->key); |
| 2781 | ret = AVERROR(EINVAL); |
| 2782 | goto fail; |
| 2783 | } |
| 2784 | |
| 2785 | fail: |
| 2786 | av_dict_free(&dict); |
| 2787 | if (ret < 0) |
| 2788 | return ret; |
| 2789 | } |
no test coverage detected