mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 12:36:41 +08:00 
			
		
		
		
	ffmpeg: only copy bits_per_sample from decoder when it remains valid
I.e. when the only filters that are applied do not modify the frame data.
This commit is contained in:
		| @@ -3335,7 +3335,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) | |||||||
|  |  | ||||||
|         if (ost->bits_per_raw_sample) |         if (ost->bits_per_raw_sample) | ||||||
|             enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; |             enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; | ||||||
|         else if (dec_ctx) |         else if (dec_ctx && ost->filter->graph->is_meta) | ||||||
|             enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, |             enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, | ||||||
|                                                  av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3); |                                                  av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3); | ||||||
|  |  | ||||||
| @@ -3361,7 +3361,10 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) | |||||||
|             av_buffersink_get_sample_aspect_ratio(ost->filter->filter); |             av_buffersink_get_sample_aspect_ratio(ost->filter->filter); | ||||||
|  |  | ||||||
|         enc_ctx->pix_fmt = av_buffersink_get_format(ost->filter->filter); |         enc_ctx->pix_fmt = av_buffersink_get_format(ost->filter->filter); | ||||||
|         if (dec_ctx) |  | ||||||
|  |         if (ost->bits_per_raw_sample) | ||||||
|  |             enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; | ||||||
|  |         else if (dec_ctx && ost->filter->graph->is_meta) | ||||||
|             enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, |             enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, | ||||||
|                                                  av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth); |                                                  av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth); | ||||||
|  |  | ||||||
| @@ -3377,13 +3380,6 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) | |||||||
|  |  | ||||||
|         ost->st->avg_frame_rate = ost->frame_rate; |         ost->st->avg_frame_rate = ost->frame_rate; | ||||||
|  |  | ||||||
|         if (!dec_ctx || |  | ||||||
|             enc_ctx->width   != dec_ctx->width  || |  | ||||||
|             enc_ctx->height  != dec_ctx->height || |  | ||||||
|             enc_ctx->pix_fmt != dec_ctx->pix_fmt) { |  | ||||||
|             enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Field order: autodetection |         // Field order: autodetection | ||||||
|         if (frame) { |         if (frame) { | ||||||
|             if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) && |             if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) && | ||||||
|   | |||||||
| @@ -287,6 +287,9 @@ typedef struct FilterGraph { | |||||||
|  |  | ||||||
|     AVFilterGraph *graph; |     AVFilterGraph *graph; | ||||||
|     int reconfiguration; |     int reconfiguration; | ||||||
|  |     // true when the filtergraph contains only meta filters | ||||||
|  |     // that do not modify the frame data | ||||||
|  |     int is_meta; | ||||||
|  |  | ||||||
|     InputFilter   **inputs; |     InputFilter   **inputs; | ||||||
|     int          nb_inputs; |     int          nb_inputs; | ||||||
|   | |||||||
| @@ -960,6 +960,30 @@ static void cleanup_filtergraph(FilterGraph *fg) | |||||||
|     avfilter_graph_free(&fg->graph); |     avfilter_graph_free(&fg->graph); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int filter_is_buffersrc(const AVFilterContext *f) | ||||||
|  | { | ||||||
|  |     return f->nb_inputs == 0 && | ||||||
|  |            (!strcmp(f->filter->name, "buffersrc") || | ||||||
|  |             !strcmp(f->filter->name, "abuffersrc")); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int graph_is_meta(AVFilterGraph *graph) | ||||||
|  | { | ||||||
|  |     for (unsigned i = 0; i < graph->nb_filters; i++) { | ||||||
|  |         const AVFilterContext *f = graph->filters[i]; | ||||||
|  |  | ||||||
|  |         /* in addition to filters flagged as meta, also | ||||||
|  |          * disregard sinks and buffersources (but not other sources, | ||||||
|  |          * since they introduce data we are not aware of) | ||||||
|  |          */ | ||||||
|  |         if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) || | ||||||
|  |               f->nb_outputs == 0                               || | ||||||
|  |               filter_is_buffersrc(f))) | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| int configure_filtergraph(FilterGraph *fg) | int configure_filtergraph(FilterGraph *fg) | ||||||
| { | { | ||||||
|     AVFilterInOut *inputs, *outputs, *cur; |     AVFilterInOut *inputs, *outputs, *cur; | ||||||
| @@ -1060,6 +1084,8 @@ int configure_filtergraph(FilterGraph *fg) | |||||||
|     if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) |     if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) | ||||||
|         goto fail; |         goto fail; | ||||||
|  |  | ||||||
|  |     fg->is_meta = graph_is_meta(fg->graph); | ||||||
|  |  | ||||||
|     /* limit the lists of allowed formats to the ones selected, to |     /* limit the lists of allowed formats to the ones selected, to | ||||||
|      * make sure they stay the same if the filtergraph is reconfigured later */ |      * make sure they stay the same if the filtergraph is reconfigured later */ | ||||||
|     for (i = 0; i < fg->nb_outputs; i++) { |     for (i = 0; i < fg->nb_outputs; i++) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Anton Khirnov
					Anton Khirnov