doc/examples/demuxing: show how to use the reference counting system.
This commit is contained in:
		
							parent
							
								
									405ceb1812
								
							
						
					
					
						commit
						d10b1a200d
					
				@ -53,6 +53,18 @@ static AVPacket pkt;
 | 
				
			|||||||
static int video_frame_count = 0;
 | 
					static int video_frame_count = 0;
 | 
				
			||||||
static int audio_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)
 | 
					static int decode_packet(int *got_frame, int cached)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = 0;
 | 
					    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;
 | 
					    return decoded;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -125,6 +142,7 @@ static int open_codec_context(int *stream_idx,
 | 
				
			|||||||
    AVStream *st;
 | 
					    AVStream *st;
 | 
				
			||||||
    AVCodecContext *dec_ctx = NULL;
 | 
					    AVCodecContext *dec_ctx = NULL;
 | 
				
			||||||
    AVCodec *dec = NULL;
 | 
					    AVCodec *dec = NULL;
 | 
				
			||||||
 | 
					    AVDictionary *opts = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
 | 
					    ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
@ -144,7 +162,10 @@ static int open_codec_context(int *stream_idx,
 | 
				
			|||||||
            return ret;
 | 
					            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",
 | 
					            fprintf(stderr, "Failed to open %s codec\n",
 | 
				
			||||||
                    av_get_media_type_string(type));
 | 
					                    av_get_media_type_string(type));
 | 
				
			||||||
            return ret;
 | 
					            return ret;
 | 
				
			||||||
@ -187,15 +208,31 @@ int main (int argc, char **argv)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    int ret = 0, got_frame;
 | 
					    int ret = 0, got_frame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (argc != 4) {
 | 
					    if (argc != 4 && argc != 5) {
 | 
				
			||||||
        fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
 | 
					        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"
 | 
					                "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"
 | 
					                "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"
 | 
					                "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]);
 | 
					                "\n", argv[0]);
 | 
				
			||||||
        exit(1);
 | 
					        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];
 | 
					    src_filename = argv[1];
 | 
				
			||||||
    video_dst_filename = argv[2];
 | 
					    video_dst_filename = argv[2];
 | 
				
			||||||
    audio_dst_filename = argv[3];
 | 
					    audio_dst_filename = argv[3];
 | 
				
			||||||
@ -257,7 +294,12 @@ int main (int argc, char **argv)
 | 
				
			|||||||
        goto end;
 | 
					        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) {
 | 
					    if (!frame) {
 | 
				
			||||||
        fprintf(stderr, "Could not allocate frame\n");
 | 
					        fprintf(stderr, "Could not allocate frame\n");
 | 
				
			||||||
        ret = AVERROR(ENOMEM);
 | 
					        ret = AVERROR(ENOMEM);
 | 
				
			||||||
@ -336,7 +378,10 @@ end:
 | 
				
			|||||||
        fclose(video_dst_file);
 | 
					        fclose(video_dst_file);
 | 
				
			||||||
    if (audio_dst_file)
 | 
					    if (audio_dst_file)
 | 
				
			||||||
        fclose(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]);
 | 
					    av_free(video_dst_data[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret < 0;
 | 
					    return ret < 0;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user