You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avconv: switch to the new BSF API
This commit is contained in:
		
							
								
								
									
										147
									
								
								avconv.c
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								avconv.c
									
									
									
									
									
								
							| @@ -175,13 +175,12 @@ static void avconv_cleanup(int ret) | ||||
|     } | ||||
|     for (i = 0; i < nb_output_streams; i++) { | ||||
|         OutputStream *ost = output_streams[i]; | ||||
|         AVBitStreamFilterContext *bsfc = ost->bitstream_filters; | ||||
|         while (bsfc) { | ||||
|             AVBitStreamFilterContext *next = bsfc->next; | ||||
|             av_bitstream_filter_close(bsfc); | ||||
|             bsfc = next; | ||||
|         } | ||||
|         ost->bitstream_filters = NULL; | ||||
|  | ||||
|         for (j = 0; j < ost->nb_bitstream_filters; j++) | ||||
|             av_bsf_free(&ost->bsf_ctx[j]); | ||||
|         av_freep(&ost->bsf_ctx); | ||||
|         av_freep(&ost->bitstream_filters); | ||||
|  | ||||
|         av_frame_free(&ost->filtered_frame); | ||||
|  | ||||
|         av_parser_close(ost->parser); | ||||
| @@ -255,10 +254,9 @@ static void abort_codec_experimental(AVCodec *c, int encoder) | ||||
|     exit_program(1); | ||||
| } | ||||
|  | ||||
| static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) | ||||
| static void write_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) | ||||
| { | ||||
|     AVStream *st = ost->st; | ||||
|     AVBitStreamFilterContext *bsfc = ost->bitstream_filters; | ||||
|     int ret; | ||||
|  | ||||
|     /* | ||||
| @@ -286,32 +284,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     while (bsfc) { | ||||
|         AVCodecContext *avctx = ost->encoding_needed ? ost->enc_ctx : ost->st->codec; | ||||
|         AVPacket new_pkt = *pkt; | ||||
|         int a = av_bitstream_filter_filter(bsfc, avctx, NULL, | ||||
|                                            &new_pkt.data, &new_pkt.size, | ||||
|                                            pkt->data, pkt->size, | ||||
|                                            pkt->flags & AV_PKT_FLAG_KEY); | ||||
|         if (a > 0) { | ||||
|             av_packet_unref(pkt); | ||||
|             new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, | ||||
|                                            av_buffer_default_free, NULL, 0); | ||||
|             if (!new_pkt.buf) | ||||
|                 exit_program(1); | ||||
|         } else if (a < 0) { | ||||
|             av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s", | ||||
|                    bsfc->filter->name, pkt->stream_index, | ||||
|                    avctx->codec ? avctx->codec->name : "copy"); | ||||
|             print_error("", a); | ||||
|             if (exit_on_error) | ||||
|                 exit_program(1); | ||||
|         } | ||||
|         *pkt = new_pkt; | ||||
|  | ||||
|         bsfc = bsfc->next; | ||||
|     } | ||||
|  | ||||
|     if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) && | ||||
|         ost->last_mux_dts != AV_NOPTS_VALUE && | ||||
|         pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) { | ||||
| @@ -342,6 +314,49 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void output_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) | ||||
| { | ||||
|     int ret = 0; | ||||
|  | ||||
|     /* apply the output bitstream filters, if any */ | ||||
|     if (ost->nb_bitstream_filters) { | ||||
|         int idx; | ||||
|  | ||||
|         ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt); | ||||
|         if (ret < 0) | ||||
|             goto finish; | ||||
|  | ||||
|         idx = 1; | ||||
|         while (idx) { | ||||
|             /* get a packet from the previous filter up the chain */ | ||||
|             ret = av_bsf_receive_packet(ost->bsf_ctx[idx - 1], pkt); | ||||
|             if (ret == AVERROR(EAGAIN)) { | ||||
|                 ret = 0; | ||||
|                 idx--; | ||||
|                 continue; | ||||
|             } else if (ret < 0) | ||||
|                 goto finish; | ||||
|  | ||||
|             /* send it to the next filter down the chain or to the muxer */ | ||||
|             if (idx < ost->nb_bitstream_filters) { | ||||
|                 ret = av_bsf_send_packet(ost->bsf_ctx[idx], pkt); | ||||
|                 if (ret < 0) | ||||
|                     goto finish; | ||||
|                 idx++; | ||||
|             } else | ||||
|                 write_packet(s, pkt, ost); | ||||
|         } | ||||
|     } else | ||||
|         write_packet(s, pkt, ost); | ||||
|  | ||||
| finish: | ||||
|     if (ret < 0 && ret != AVERROR_EOF) { | ||||
|         av_log(NULL, AV_LOG_FATAL, "Error applying bitstream filters to an output " | ||||
|                "packet for stream #%d:%d.\n", ost->file_index, ost->index); | ||||
|         exit_program(1); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int check_recording_time(OutputStream *ost) | ||||
| { | ||||
|     OutputFile *of = output_files[ost->file_index]; | ||||
| @@ -380,7 +395,7 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, | ||||
|  | ||||
|     if (got_packet) { | ||||
|         av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); | ||||
|         write_frame(s, &pkt, ost); | ||||
|         output_packet(s, &pkt, ost); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -449,7 +464,7 @@ static void do_subtitle_out(AVFormatContext *s, | ||||
|             else | ||||
|                 pkt.pts += 90 * sub->end_display_time; | ||||
|         } | ||||
|         write_frame(s, &pkt, ost); | ||||
|         output_packet(s, &pkt, ost); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -516,7 +531,7 @@ static void do_video_out(AVFormatContext *s, | ||||
|  | ||||
|     if (got_packet) { | ||||
|         av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); | ||||
|         write_frame(s, &pkt, ost); | ||||
|         output_packet(s, &pkt, ost); | ||||
|         *frame_size = pkt.size; | ||||
|  | ||||
|         /* if two pass, output log */ | ||||
| @@ -983,7 +998,7 @@ static void flush_encoders(void) | ||||
|                     break; | ||||
|                 } | ||||
|                 av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); | ||||
|                 write_frame(os, &pkt, ost); | ||||
|                 output_packet(os, &pkt, ost); | ||||
|             } | ||||
|  | ||||
|             if (stop_encoding) | ||||
| @@ -1076,7 +1091,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p | ||||
|         opkt.size = pkt->size; | ||||
|     } | ||||
|  | ||||
|     write_frame(of->ctx, &opkt, ost); | ||||
|     output_packet(of->ctx, &opkt, ost); | ||||
| } | ||||
|  | ||||
| int guess_input_channel_layout(InputStream *ist) | ||||
| @@ -1554,6 +1569,51 @@ static InputStream *get_input_stream(OutputStream *ost) | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| static int init_output_bsfs(OutputStream *ost) | ||||
| { | ||||
|     AVBSFContext *ctx; | ||||
|     int i, ret; | ||||
|  | ||||
|     if (!ost->nb_bitstream_filters) | ||||
|         return 0; | ||||
|  | ||||
|     ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx)); | ||||
|     if (!ost->bsf_ctx) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (i = 0; i < ost->nb_bitstream_filters; i++) { | ||||
|         ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx); | ||||
|         if (ret < 0) { | ||||
|             av_log(NULL, AV_LOG_ERROR, "Error allocating a bistream filter context\n"); | ||||
|             return ret; | ||||
|         } | ||||
|         ost->bsf_ctx[i] = ctx; | ||||
|  | ||||
|         ret = avcodec_parameters_copy(ctx->par_in, | ||||
|                                       i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|  | ||||
|         ctx->time_base_in = i ? ost->bsf_ctx[i - 1]->time_base_out : ost->st->time_base; | ||||
|  | ||||
|         ret = av_bsf_init(ctx); | ||||
|         if (ret < 0) { | ||||
|             av_log(NULL, AV_LOG_ERROR, "Error initializing bistream filter: %s\n", | ||||
|                    ost->bitstream_filters[i]->name); | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1]; | ||||
|     ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     ost->st->time_base = ctx->time_base_out; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int init_output_stream(OutputStream *ost, char *error, int error_len) | ||||
| { | ||||
|     int ret = 0; | ||||
| @@ -1648,6 +1708,13 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) | ||||
|             return ret; | ||||
|     } | ||||
|  | ||||
|     /* initialize bitstream filters for the output stream | ||||
|      * needs to be done here, because the codec id for streamcopy is not | ||||
|      * known until now */ | ||||
|     ret = init_output_bsfs(ost); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								avconv.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								avconv.h
									
									
									
									
									
								
							| @@ -325,7 +325,11 @@ typedef struct OutputStream { | ||||
|     int64_t first_pts; | ||||
|     /* dts of the last packet sent to the muxer */ | ||||
|     int64_t last_mux_dts; | ||||
|     AVBitStreamFilterContext *bitstream_filters; | ||||
|  | ||||
|     int                    nb_bitstream_filters; | ||||
|     const AVBitStreamFilter **bitstream_filters; | ||||
|     AVBSFContext            **bsf_ctx; | ||||
|  | ||||
|     AVCodecContext *enc_ctx; | ||||
|     AVCodec *enc; | ||||
|     int64_t max_frames; | ||||
|   | ||||
							
								
								
									
										22
									
								
								avconv_opt.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								avconv_opt.c
									
									
									
									
									
								
							| @@ -912,7 +912,6 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | ||||
|     AVStream *st = avformat_new_stream(oc, NULL); | ||||
|     int idx      = oc->nb_streams - 1, ret = 0; | ||||
|     char *bsf = NULL, *next, *codec_tag = NULL; | ||||
|     AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | ||||
|     double qscale = -1; | ||||
|  | ||||
|     if (!st) { | ||||
| @@ -980,19 +979,26 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | ||||
|  | ||||
|     MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st); | ||||
|     while (bsf) { | ||||
|         const AVBitStreamFilter *filter; | ||||
|  | ||||
|         if (next = strchr(bsf, ',')) | ||||
|             *next++ = 0; | ||||
|         if (!(bsfc = av_bitstream_filter_init(bsf))) { | ||||
|  | ||||
|         filter = av_bsf_get_by_name(bsf); | ||||
|         if (!bsf) { | ||||
|             av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); | ||||
|             exit_program(1); | ||||
|         } | ||||
|         if (bsfc_prev) | ||||
|             bsfc_prev->next = bsfc; | ||||
|         else | ||||
|             ost->bitstream_filters = bsfc; | ||||
|  | ||||
|         bsfc_prev = bsfc; | ||||
|         bsf       = next; | ||||
|         ost->bitstream_filters = av_realloc_array(ost->bitstream_filters, | ||||
|                                                   ost->nb_bitstream_filters + 1, | ||||
|                                                   sizeof(*ost->bitstream_filters)); | ||||
|         if (!ost->bitstream_filters) | ||||
|             exit_program(1); | ||||
|  | ||||
|         ost->bitstream_filters[ost->nb_bitstream_filters++] = filter; | ||||
|  | ||||
|         bsf = next; | ||||
|     } | ||||
|  | ||||
|     MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st); | ||||
|   | ||||
| @@ -1173,10 +1173,11 @@ int show_encoders(void *optctx, const char *opt, const char *arg) | ||||
|  | ||||
| int show_bsfs(void *optctx, const char *opt, const char *arg) | ||||
| { | ||||
|     AVBitStreamFilter *bsf = NULL; | ||||
|     const AVBitStreamFilter *bsf = NULL; | ||||
|     void *opaque = NULL; | ||||
|  | ||||
|     printf("Bitstream filters:\n"); | ||||
|     while ((bsf = av_bitstream_filter_next(bsf))) | ||||
|     while ((bsf = av_bsf_next(&opaque))) | ||||
|         printf("%s\n", bsf->name); | ||||
|     printf("\n"); | ||||
|     return 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user