mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 04:26:37 +08:00 
			
		
		
		
	fftools/ffmpeg_mux_init: postpone matching -disposition to streams
Do it in set_dispositions() rather than during stream creation. Since at this point all other stream information is known, this allows setting disposition based on metadata, which implements #10015. This also avoids an extra allocated string in OutputStream that was unused after of_open().
This commit is contained in:
		| @@ -585,7 +585,6 @@ typedef struct OutputStream { | |||||||
|     int streamcopy_started; |     int streamcopy_started; | ||||||
|     int copy_initial_nonkeyframes; |     int copy_initial_nonkeyframes; | ||||||
|     int copy_prior_start; |     int copy_prior_start; | ||||||
|     char *disposition; |  | ||||||
|  |  | ||||||
|     int keep_pix_fmt; |     int keep_pix_fmt; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -673,7 +673,6 @@ static void ost_free(OutputStream **post) | |||||||
|     av_freep(&ost->logfile_prefix); |     av_freep(&ost->logfile_prefix); | ||||||
|     av_freep(&ost->forced_kf_pts); |     av_freep(&ost->forced_kf_pts); | ||||||
|     av_freep(&ost->apad); |     av_freep(&ost->apad); | ||||||
|     av_freep(&ost->disposition); |  | ||||||
|  |  | ||||||
| #if FFMPEG_OPT_MAP_CHANNEL | #if FFMPEG_OPT_MAP_CHANNEL | ||||||
|     av_freep(&ost->audio_channels_map); |     av_freep(&ost->audio_channels_map); | ||||||
|   | |||||||
| @@ -333,9 +333,6 @@ static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o, | |||||||
|         ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale; |         ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     MATCH_PER_STREAM_OPT(disposition, str, ost->disposition, oc, st); |  | ||||||
|     ost->disposition = av_strdup(ost->disposition); |  | ||||||
|  |  | ||||||
|     ms->max_muxing_queue_size = 128; |     ms->max_muxing_queue_size = 128; | ||||||
|     MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ms->max_muxing_queue_size, oc, st); |     MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ms->max_muxing_queue_size, oc, st); | ||||||
|  |  | ||||||
| @@ -1667,11 +1664,21 @@ static void copy_meta(Muxer *mux, const OptionsContext *o) | |||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
| static int set_dispositions(OutputFile *of, AVFormatContext *ctx) | static int set_dispositions(Muxer *mux, const OptionsContext *o) | ||||||
| { | { | ||||||
|  |     OutputFile                    *of = &mux->of; | ||||||
|  |     AVFormatContext              *ctx = mux->fc; | ||||||
|  |  | ||||||
|     int nb_streams[AVMEDIA_TYPE_NB]   = { 0 }; |     int nb_streams[AVMEDIA_TYPE_NB]   = { 0 }; | ||||||
|     int have_default[AVMEDIA_TYPE_NB] = { 0 }; |     int have_default[AVMEDIA_TYPE_NB] = { 0 }; | ||||||
|     int have_manual = 0; |     int have_manual = 0; | ||||||
|  |     int ret = 0; | ||||||
|  |  | ||||||
|  |     const char **dispositions; | ||||||
|  |  | ||||||
|  |     dispositions = av_calloc(ctx->nb_streams, sizeof(*dispositions)); | ||||||
|  |     if (!dispositions) | ||||||
|  |         return AVERROR(ENOMEM); | ||||||
|  |  | ||||||
|     // first, copy the input dispositions |     // first, copy the input dispositions | ||||||
|     for (int i = 0; i < ctx->nb_streams; i++) { |     for (int i = 0; i < ctx->nb_streams; i++) { | ||||||
| @@ -1679,7 +1686,9 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) | |||||||
|  |  | ||||||
|         nb_streams[ost->st->codecpar->codec_type]++; |         nb_streams[ost->st->codecpar->codec_type]++; | ||||||
|  |  | ||||||
|         have_manual |= !!ost->disposition; |         MATCH_PER_STREAM_OPT(disposition, str, dispositions[i], ctx, ost->st); | ||||||
|  |  | ||||||
|  |         have_manual |= !!dispositions[i]; | ||||||
|  |  | ||||||
|         if (ost->ist) { |         if (ost->ist) { | ||||||
|             ost->st->disposition = ost->ist->st->disposition; |             ost->st->disposition = ost->ist->st->disposition; | ||||||
| @@ -1693,25 +1702,25 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) | |||||||
|         // process manually set dispositions - they override the above copy |         // process manually set dispositions - they override the above copy | ||||||
|         for (int i = 0; i < ctx->nb_streams; i++) { |         for (int i = 0; i < ctx->nb_streams; i++) { | ||||||
|             OutputStream *ost = of->streams[i]; |             OutputStream *ost = of->streams[i]; | ||||||
|             int ret; |             const char  *disp = dispositions[i]; | ||||||
|  |  | ||||||
|             if (!ost->disposition) |             if (!disp) | ||||||
|                 continue; |                 continue; | ||||||
|  |  | ||||||
| #if LIBAVFORMAT_VERSION_MAJOR >= 60 | #if LIBAVFORMAT_VERSION_MAJOR >= 60 | ||||||
|             ret = av_opt_set(ost->st, "disposition", ost->disposition, 0); |             ret = av_opt_set(ost->st, "disposition", disp, 0); | ||||||
| #else | #else | ||||||
|             { |             { | ||||||
|                 const AVClass *class = av_stream_get_class(); |                 const AVClass *class = av_stream_get_class(); | ||||||
|                 const AVOption    *o = av_opt_find(&class, "disposition", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ); |                 const AVOption    *o = av_opt_find(&class, "disposition", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ); | ||||||
|  |  | ||||||
|                 av_assert0(o); |                 av_assert0(o); | ||||||
|                 ret = av_opt_eval_flags(&class, o, ost->disposition, &ost->st->disposition); |                 ret = av_opt_eval_flags(&class, o, disp, &ost->st->disposition); | ||||||
|             } |             } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|             if (ret < 0) |             if (ret < 0) | ||||||
|                 return ret; |                 goto finish; | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|         // For each media type with more than one stream, find a suitable stream to |         // For each media type with more than one stream, find a suitable stream to | ||||||
| @@ -1730,7 +1739,10 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; | finish: | ||||||
|  |     av_freep(&dispositions); | ||||||
|  |  | ||||||
|  |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void validate_enc_avopt(const Muxer *mux, const AVDictionary *codec_avopt) | static void validate_enc_avopt(const Muxer *mux, const AVDictionary *codec_avopt) | ||||||
| @@ -1943,7 +1955,7 @@ int of_open(const OptionsContext *o, const char *filename) | |||||||
|     of_add_programs(oc, o); |     of_add_programs(oc, o); | ||||||
|     of_add_metadata(of, oc, o); |     of_add_metadata(of, oc, o); | ||||||
|  |  | ||||||
|     err = set_dispositions(of, oc); |     err = set_dispositions(mux, o); | ||||||
|     if (err < 0) { |     if (err < 0) { | ||||||
|         av_log(NULL, AV_LOG_FATAL, "Error setting output stream dispositions\n"); |         av_log(NULL, AV_LOG_FATAL, "Error setting output stream dispositions\n"); | ||||||
|         exit_program(1); |         exit_program(1); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Anton Khirnov
					Anton Khirnov