[FFmpeg-devel] [PATCH] libavformat: Add H264 API test

Vittorio Giovara vittorio.giovara at gmail.com
Mon Jun 22 14:32:11 CEST 2015


On Mon, Jun 22, 2015 at 10:50 AM, Ludmila Glinskih <lglinskih at gmail.com> wrote:
> +static int video_decode_example(const char *input_filename)
> +{
> +    AVCodec *codec = NULL;
> +    AVCodecContext *origin_ctx = NULL, *ctx= NULL;
> +    AVFrame *fr = NULL;
> +    uint8_t *byte_buffer = NULL;
> +    AVPacket pkt;
> +    AVFormatContext *fmt_ctx = NULL;
> +    int number_of_written_bytes;
> +    int video_stream;
> +    int get_frame = 0;
> +    int byte_buffer_size;
> +    int i = 0;
> +
> +
> +    if (avformat_open_input(&fmt_ctx, input_filename, NULL, NULL) < 0) {
> +        fprintf(stderr, "Could not open source file %s\n", input_filename);
> +        exit(1);
> +    }
> +
> +    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
> +        fprintf(stderr, "Could not find stream information\n");
> +        exit(1);
> +    }
> +
> +    video_stream = -1;
> +    for (i = 0; i < fmt_ctx->nb_streams; i++) {
> +        if (fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
> +            video_stream = i;
> +            break;
> +        }
> +    }
> +
> +    origin_ctx = fmt_ctx->streams[video_stream]->codec;
> +
> +    codec = avcodec_find_decoder(origin_ctx->codec_id);
> +    if (codec == NULL) {
> +        return -1;
> +    }
> +    ctx = avcodec_alloc_context3(codec);
> +    if (ctx == NULL) {
> +        return -1;
> +    }
> +
> +    if (avcodec_copy_context(ctx, origin_ctx)) {
> +        return -1;
> +    }
> +
> +    if (avcodec_open2(ctx, codec, NULL) < 0) {
> +        return -1;
> +    }
> +
> +    fr = av_frame_alloc();
> +    if (fr == NULL) {
> +        return -1;
> +    }
> +
> +    byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16);
> +    byte_buffer = av_malloc(byte_buffer_size);
> +
> +    printf("#tb %d: %d/%d\n", video_stream, fmt_ctx->streams[video_stream]->time_base.num, fmt_ctx->streams[video_stream]->time_base.den);
> +    i = 0;
> +    av_init_packet(&pkt);
> +    while (av_read_frame(fmt_ctx, &pkt) >= 0) {
> +        if (pkt.stream_index == video_stream) {
> +            get_frame = 0;
> +            if (pkt.pts == AV_NOPTS_VALUE)
> +                pkt.pts = pkt.dts = i;
> +            avcodec_decode_video2(ctx, fr, &get_frame, &pkt);
> +            if (get_frame) {
> +                number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
> +                                        (const uint8_t* const *)fr->data, (const int*) fr->linesize,
> +                                        ctx->pix_fmt, ctx->width, ctx->height, 1);
> +                printf("%d, %10"PRId64", %10"PRId64", %8d, %8d, 0x%08"PRIx32"\n", video_stream,
> +                        fr->pkt_pts, fr->pkt_dts, fr->pkt_duration,
> +                        number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes));
> +            }
> +            av_free_packet(&pkt);
> +            av_init_packet(&pkt);
> +        }
> +        i++;
> +    }
> +    pkt.data = NULL;
> +    pkt.size = 0;
> +    if (pkt.pts == AV_NOPTS_VALUE)
> +        pkt.pts = pkt.dts = i;
> +    int flag = 0;
> +    while (!flag) {
> +        if (pkt.stream_index != video_stream)
> +            break;
> +        get_frame = 0;
> +        if (avcodec_decode_video2(ctx, fr, &get_frame, &pkt) < 0 || get_frame == 0)
> +            flag = 1;
> +        if (get_frame) {
> +            number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
> +                                    (const uint8_t* const *)fr->data, (const int*) fr->linesize,
> +                                    ctx->pix_fmt, ctx->width, ctx->height, 1);
> +            printf("%d, %10"PRId64", %10"PRId64", %8d, %8d, 0x%08"PRIx32"\n", video_stream,
> +                    fr->pkt_pts, fr->pkt_dts, fr->pkt_duration,
> +                    number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes));
> +        }
> +        i++;
> +    }
> +    av_free_packet(&pkt);
> +    av_frame_free(&fr);
> +    avcodec_close(ctx);
> +    avformat_close_input(&fmt_ctx);
> +    avcodec_free_context(&ctx);
> +    av_freep(&byte_buffer);
> +    return 0;
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    av_register_all();
> +    video_decode_example(argv[1]);
> +    return 0;
> +}

video_decode_example can return -1 on error, and this is lost, so
you'd better do "return video_decode_example(argv[1]);" to return the
value to the caller. Also sometimes you exit(1) and sometimes you
return -1, maybe you could go with only one of them.
-- 
Vittorio


More information about the ffmpeg-devel mailing list