fftools/ffmpeg_mux_init: improve of_add_programs()
Replace duplicated(!) and broken* custom string parsing with av_dict_parse_string(). Return error codes instead of aborting. * e.g. it treats NULL returned from av_get_token() as "separator not found", when in fact av_get_token() only returns NULL on memory allocation failure
This commit is contained in:
		
							parent
							
								
									fd40197170
								
							
						
					
					
						commit
						dd44871eb9
					
				| @ -1782,76 +1782,66 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void of_add_programs(Muxer *mux, const OptionsContext *o) | static int of_add_programs(Muxer *mux, const OptionsContext *o) | ||||||
| { | { | ||||||
|     AVFormatContext *oc = mux->fc; |     AVFormatContext *oc = mux->fc; | ||||||
|     /* process manually set programs */ |     /* process manually set programs */ | ||||||
|     for (int i = 0; i < o->nb_program; i++) { |     for (int i = 0; i < o->nb_program; i++) { | ||||||
|         const char *p = o->program[i].u.str; |         AVDictionary *dict = NULL; | ||||||
|         int progid = i+1; |         const AVDictionaryEntry *e; | ||||||
|         AVProgram *program; |         AVProgram *program; | ||||||
|  |         int ret, progid = i + 1; | ||||||
| 
 | 
 | ||||||
|         while(*p) { |         ret = av_dict_parse_string(&dict, o->program[i].u.str, "=", ":", | ||||||
|             const char *p2 = av_get_token(&p, ":"); |                                    AV_DICT_MULTIKEY); | ||||||
|             const char *to_dealloc = p2; |         if (ret < 0) { | ||||||
|             char *key; |             av_log(mux, AV_LOG_ERROR, "Error parsing program specification %s\n", | ||||||
|             if (!p2) |                    o->program[i].u.str); | ||||||
|                 break; |             return ret; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|             if(*p) p++; |         e = av_dict_get(dict, "program_num", NULL, 0); | ||||||
| 
 |         if (e) { | ||||||
|             key = av_get_token(&p2, "="); |             progid = strtol(e->value, NULL, 0); | ||||||
|             if (!key || !*p2) { |             av_dict_set(&dict, e->key, NULL, 0); | ||||||
|                 av_freep(&to_dealloc); |  | ||||||
|                 av_freep(&key); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|             p2++; |  | ||||||
| 
 |  | ||||||
|             if (!strcmp(key, "program_num")) |  | ||||||
|                 progid = strtol(p2, NULL, 0); |  | ||||||
|             av_freep(&to_dealloc); |  | ||||||
|             av_freep(&key); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         program = av_new_program(oc, progid); |         program = av_new_program(oc, progid); | ||||||
|         if (!program) |         if (!program) { | ||||||
|             report_and_exit(AVERROR(ENOMEM)); |             ret = AVERROR(ENOMEM); | ||||||
| 
 |             goto fail; | ||||||
|         p = o->program[i].u.str; |  | ||||||
|         while(*p) { |  | ||||||
|             const char *p2 = av_get_token(&p, ":"); |  | ||||||
|             const char *to_dealloc = p2; |  | ||||||
|             char *key; |  | ||||||
|             if (!p2) |  | ||||||
|                 break; |  | ||||||
|             if(*p) p++; |  | ||||||
| 
 |  | ||||||
|             key = av_get_token(&p2, "="); |  | ||||||
|             if (!key) { |  | ||||||
|                 av_log(mux, AV_LOG_FATAL, |  | ||||||
|                        "No '=' character in program string %s.\n", |  | ||||||
|                        p2); |  | ||||||
|                 exit_program(1); |  | ||||||
|             } |  | ||||||
|             if (!*p2) |  | ||||||
|                 exit_program(1); |  | ||||||
|             p2++; |  | ||||||
| 
 |  | ||||||
|             if (!strcmp(key, "title")) { |  | ||||||
|                 av_dict_set(&program->metadata, "title", p2, 0); |  | ||||||
|             } else if (!strcmp(key, "program_num")) { |  | ||||||
|             } else if (!strcmp(key, "st")) { |  | ||||||
|                 int st_num = strtol(p2, NULL, 0); |  | ||||||
|                 av_program_add_stream_index(oc, progid, st_num); |  | ||||||
|             } else { |  | ||||||
|                 av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", key); |  | ||||||
|                 exit_program(1); |  | ||||||
|             } |  | ||||||
|             av_freep(&to_dealloc); |  | ||||||
|             av_freep(&key); |  | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         e = av_dict_get(dict, "title", NULL, 0); | ||||||
|  |         if (e) { | ||||||
|  |             av_dict_set(&program->metadata, e->key, e->value, 0); | ||||||
|  |             av_dict_set(&dict, e->key, NULL, 0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         e = NULL; | ||||||
|  |         while (e = av_dict_get(dict, "st", e, 0)) { | ||||||
|  |             int st_num = strtol(e->value, NULL, 0); | ||||||
|  |             av_program_add_stream_index(oc, progid, st_num); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // make sure that nothing but "st" entries are left in the dict
 | ||||||
|  |         e = NULL; | ||||||
|  |         while (e = av_dict_iterate(dict, e)) { | ||||||
|  |             if (!strcmp(e->key, "st")) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", e->key); | ||||||
|  |             ret = AVERROR(EINVAL); | ||||||
|  |             goto fail; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | fail: | ||||||
|  |         av_dict_free(&dict); | ||||||
|  |         if (ret < 0) | ||||||
|  |             return ret; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -2547,7 +2537,10 @@ int of_open(const OptionsContext *o, const char *filename) | |||||||
|     if (err < 0) |     if (err < 0) | ||||||
|         return err; |         return err; | ||||||
| 
 | 
 | ||||||
|     of_add_programs(mux, o); |     err = of_add_programs(mux, o); | ||||||
|  |     if (err < 0) | ||||||
|  |         return err; | ||||||
|  | 
 | ||||||
|     of_add_metadata(of, oc, o); |     of_add_metadata(of, oc, o); | ||||||
| 
 | 
 | ||||||
|     err = set_dispositions(mux, o); |     err = set_dispositions(mux, o); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user