Replaced deprecated api avcodec_decode_{audio4,video2}() with avcodec_send_packet()/avcodec_receive_frame(). Also made some clean up according to this change.
Signed-off-by: Zhao, Gang <gang.zhao...@gmail.com> --- Tested that the new code generated the same files as before by running ./doc/examples/demuxing_decoding_g my_samples/demuxing_decoding.mp4 my_samples/demuxing_decoding.video my_samples/demuxing_decoding.audio doc/examples/demuxing_decoding.c | 102 ++++++++++++------------------- 1 file changed, 38 insertions(+), 64 deletions(-) diff --git doc/examples/demuxing_decoding.c doc/examples/demuxing_decoding.c index 69a31a8935..b2db3f1afa 100644 --- doc/examples/demuxing_decoding.c +++ doc/examples/demuxing_decoding.c @@ -55,29 +55,34 @@ static AVPacket pkt; static int video_frame_count = 0; static int audio_frame_count = 0; -/* Enable or disable frame reference counting. You are not supposed to support - * both paths in your application but pick the one most appropriate to your - * needs. Look for the use of refcount in this example to see what are the - * differences of API usage between them. */ -static int refcount = 0; - -static int decode_packet(int *got_frame, int cached) +static int decode_packet(int cached) { - int ret = 0; - int decoded = pkt.size; + int ret; + AVCodecContext *ctx; - *got_frame = 0; + if (pkt.stream_index == video_stream_idx) + ctx = video_dec_ctx; + else if (pkt.stream_index == audio_stream_idx) + ctx = audio_dec_ctx; - if (pkt.stream_index == video_stream_idx) { - /* decode video frame */ - ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt); - if (ret < 0) { - fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret)); - return ret; - } + /* send the packet with the compressed data to the decoder */ + ret = avcodec_send_packet(ctx, &pkt); + if (ret < 0) { + fprintf(stderr, "Error submitting the packet to the decoder\n"); + exit(1); + } - if (*got_frame) { + /* read all the output frames (in general there may be any number of them */ + while (ret >= 0) { + ret = avcodec_receive_frame(ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return 0; + else if (ret < 0) { + fprintf(stderr, "Error during decoding\n"); + exit(1); + } + if (pkt.stream_index == video_stream_idx) { if (frame->width != width || frame->height != height || frame->format != pix_fmt) { /* To handle this change, one could call av_image_alloc again and @@ -105,21 +110,7 @@ static int decode_packet(int *got_frame, int cached) /* write to rawvideo file */ fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file); - } - } else if (pkt.stream_index == audio_stream_idx) { - /* decode audio frame */ - ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt); - if (ret < 0) { - fprintf(stderr, "Error decoding audio frame (%s)\n", av_err2str(ret)); - return ret; - } - /* Some audio decoders decode only part of the packet, and have to be - * called again with the remainder of the packet data. - * Sample: fate-suite/lossless-audio/luckynight-partial.shn - * Also, some decoders might over-read the packet. */ - decoded = FFMIN(ret, pkt.size); - - if (*got_frame) { + } else if (pkt.stream_index == audio_stream_idx) { size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format); printf("audio_frame%s n:%d nb_samples:%d pts:%s\n", cached ? "(cached)" : "", @@ -138,12 +129,7 @@ static int decode_packet(int *got_frame, int cached) } } - /* If we use frame reference counting, we own the data and need - * to de-reference it when we don't use it anymore */ - if (*got_frame && refcount) - av_frame_unref(frame); - - return decoded; + return ret; } static int open_codec_context(int *stream_idx, @@ -186,8 +172,6 @@ static int open_codec_context(int *stream_idx, return ret; } - /* Init the decoders, with or without reference counting */ - av_dict_set(&opts, "refcounted_frames", refcount ? "1" : "0", 0); if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) { fprintf(stderr, "Failed to open %s codec\n", av_get_media_type_string(type)); @@ -230,24 +214,18 @@ static int get_format_from_sample_fmt(const char **fmt, int main (int argc, char **argv) { - int ret = 0, got_frame; + int ret = 0; if (argc != 4 && argc != 5) { - fprintf(stderr, "usage: %s [-refcount] input_file video_output_file audio_output_file\n" + fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n" "API example program to show how to read frames from an input file.\n" "This program reads frames from a file, decodes them, and writes decoded\n" "video frames to a rawvideo file named video_output_file, and decoded\n" - "audio frames to a rawaudio file named audio_output_file.\n\n" - "If the -refcount option is specified, the program use the\n" - "reference counting frame system which allows keeping a copy of\n" - "the data for longer than one decode call.\n" - "\n", argv[0]); + "audio frames to a rawaudio file named audio_output_file.\n", + argv[0]); exit(1); } - if (argc == 5 && !strcmp(argv[1], "-refcount")) { - refcount = 1; - argv++; - } + src_filename = argv[1]; video_dst_filename = argv[2]; audio_dst_filename = argv[3]; @@ -325,23 +303,19 @@ int main (int argc, char **argv) /* read frames from the file */ while (av_read_frame(fmt_ctx, &pkt) >= 0) { - AVPacket orig_pkt = pkt; - do { - ret = decode_packet(&got_frame, 0); - if (ret < 0) - break; - pkt.data += ret; - pkt.size -= ret; - } while (pkt.size > 0); - av_packet_unref(&orig_pkt); + ret = decode_packet(0); + if (ret < 0) + break; } /* flush cached frames */ pkt.data = NULL; pkt.size = 0; - do { - decode_packet(&got_frame, 1); - } while (got_frame); + ret = decode_packet(1); + if (ret < 0) { + printf("Flushing cached frames failed\n"); + goto end; + } printf("Demuxing succeeded.\n"); -- 2.17.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".