diff options
author | Clément Bœsch <clement@stupeflix.com> | 2013-10-30 15:50:36 +0100 |
---|---|---|
committer | Clément Bœsch <clement@stupeflix.com> | 2013-11-04 12:53:06 +0100 |
commit | d10b1a200dc3676f014f7e2c020800a15c7cab8a (patch) | |
tree | 3a4b2d6d250c84be9487433d6903d61c42181ff6 /doc | |
parent | 405ceb181236b0c7b4558dbefac8869c93df5965 (diff) | |
download | ffmpeg-d10b1a200dc3676f014f7e2c020800a15c7cab8a.tar.gz |
doc/examples/demuxing: show how to use the reference counting system.
Diffstat (limited to 'doc')
-rw-r--r-- | doc/examples/demuxing.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c index 7ae3654faa..b13246e2a4 100644 --- a/doc/examples/demuxing.c +++ b/doc/examples/demuxing.c @@ -53,6 +53,18 @@ static AVPacket pkt; static int video_frame_count = 0; static int audio_frame_count = 0; +/* The different ways of decoding and managing data memory. You are not + * supposed to support all the modes in your application but pick the one most + * appropriate to your needs. Look for the use of api_mode in this example to + * see what are the differences of API usage between them */ +enum { + API_MODE_OLD = 0, /* old method, deprecated */ + API_MODE_NEW_API_REF_COUNT = 1, /* new method, using the frame reference counting */ + API_MODE_NEW_API_NO_REF_COUNT = 2, /* new method, without reference counting */ +}; + +static int api_mode = API_MODE_OLD; + static int decode_packet(int *got_frame, int cached) { int ret = 0; @@ -115,6 +127,11 @@ static int decode_packet(int *got_frame, int cached) } } + /* If we use the new API with reference counting, we own the data and need + * to de-reference it when we don't use it anymore */ + if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT) + av_frame_unref(frame); + return decoded; } @@ -125,6 +142,7 @@ static int open_codec_context(int *stream_idx, AVStream *st; AVCodecContext *dec_ctx = NULL; AVCodec *dec = NULL; + AVDictionary *opts = NULL; ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0); if (ret < 0) { @@ -144,7 +162,10 @@ static int open_codec_context(int *stream_idx, return ret; } - if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { + /* Init the decoders, with or without reference counting */ + if (api_mode == API_MODE_NEW_API_REF_COUNT) + av_dict_set(&opts, "refcounted_frames", "1", 0); + if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) { fprintf(stderr, "Failed to open %s codec\n", av_get_media_type_string(type)); return ret; @@ -187,15 +208,31 @@ int main (int argc, char **argv) { int ret = 0, got_frame; - if (argc != 4) { - fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n" + if (argc != 4 && argc != 5) { + fprintf(stderr, "usage: %s [-refcount=<old|new_norefcount|new_refcount>] " + "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" + "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. If unset, it's using\n" + "the classic old method.\n" "\n", argv[0]); exit(1); } + if (argc == 5) { + const char *mode = argv[1] + strlen("-refcount="); + if (!strcmp(mode, "old")) api_mode = API_MODE_OLD; + else if (!strcmp(mode, "new_norefcount")) api_mode = API_MODE_NEW_API_NO_REF_COUNT; + else if (!strcmp(mode, "new_refcount")) api_mode = API_MODE_NEW_API_REF_COUNT; + else { + fprintf(stderr, "unknow mode '%s'\n", mode); + exit(1); + } + argv++; + } src_filename = argv[1]; video_dst_filename = argv[2]; audio_dst_filename = argv[3]; @@ -257,7 +294,12 @@ int main (int argc, char **argv) goto end; } - frame = avcodec_alloc_frame(); + /* When using the new API, you need to use the libavutil/frame.h API, while + * the classic frame management is available in libavcodec */ + if (api_mode == API_MODE_OLD) + frame = avcodec_alloc_frame(); + else + frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate frame\n"); ret = AVERROR(ENOMEM); @@ -336,7 +378,10 @@ end: fclose(video_dst_file); if (audio_dst_file) fclose(audio_dst_file); - av_free(frame); + if (api_mode == API_MODE_OLD) + avcodec_free_frame(&frame); + else + av_frame_free(&frame); av_free(video_dst_data[0]); return ret < 0; |