avcodec_encode_video2()访问冲突

时间:2016-03-22 01:02:07

标签: c++ ffmpeg

我试图通过以下在线示例来了解FFmpeg API,但似乎FFmpeg API随着时间的推移而发生了变化,使得大部分示例都已过时;我希望你们中的一些人可以帮助我更好地理解FFmpeg API的例子。

我目前正在尝试了解FFmpeg中的encoding-example,但我在此行收到了访问冲突错误:

out_size = avcodec_encode_video2(codecCtx, &avpkt, picture, &got_packet);

我在test01_encode.exe中的0x77c29e42处获得“未处理的异常:0xC0000005:访问冲突读取位置0xccccccc8。”来自Visual Studio。

我了解 avcodec_encode_video()已弃用,而使用AVPacket的 avcodec_encode_video2()。我已经为AVPacket的数据成员分配了一个缓冲区并设置了它的大小,但仍然是相同的。我错过了什么?

我正在使用的库是 ffmpeg-20160219-git-98a0053-win32-dev 。如果你能帮我解决这个困惑,我真的很感激。

(侧面:“获取延迟帧”是什么意思,为什么我们通过将AVFrame *参数指定为NULL进行编码?)

/*
 * Video encoding example
 */
char filename[] = "test.mpg";
int main(int argc, char** argv)
{
    AVCodec *codec;
    AVCodecContext *codecCtx= NULL;
    int i, out_size, size, x, y, outbuf_size;
    FILE *f;
    AVFrame *picture;
    uint8_t *outbuf, *picture_buf;

    printf("Video encoding\n");

    // Register all formats and codecs
    av_register_all();

    /* find the mpeg1 video encoder */
    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    codecCtx= avcodec_alloc_context3(codec);
    picture= av_frame_alloc();

    /* put sample parameters */
    codecCtx->bit_rate = 400000;
    /* resolution must be a multiple of two */
    codecCtx->width = 352;
    codecCtx->height = 288;
    /* frames per second */
    //codecCtx->time_base= (AVRational){1,25};
    codecCtx->time_base.num = 1;
    codecCtx->time_base.den = 25;

    codecCtx->gop_size = 10; /* emit one intra frame every ten frames */
    codecCtx->max_b_frames=1;
    codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;

    /* open it */
    if (avcodec_open2(codecCtx, codec, NULL) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    fopen_s(&f,filename, "wb");
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }

    /* alloc image and output buffer */
    outbuf_size = 100000;
    outbuf = (uint8_t*) malloc(outbuf_size);
    size = codecCtx->width * codecCtx->height;
    picture_buf = (uint8_t*) malloc((size * 3) / 2); /* size for YUV 420 */

    picture->data[0] = picture_buf;
    picture->data[1] = picture->data[0] + size;
    picture->data[2] = picture->data[1] + size / 4;
    picture->linesize[0] = codecCtx->width;
    picture->linesize[1] = codecCtx->width / 2;
    picture->linesize[2] = codecCtx->width / 2;

    picture->width = codecCtx->width;
    picture->height = codecCtx->height;
    picture->format = codecCtx->pix_fmt;

    AVPacket avpkt;
    int got_packet;

    avpkt.size=av_image_get_buffer_size(codecCtx->pix_fmt, codecCtx->width,
                    codecCtx->height,1);    
    avpkt.data = (uint8_t *)av_malloc(avpkt.size*sizeof(uint8_t));

    /* encode 1 second of video */
    for(i=0;i<25;i++) {
        fflush(stdout);
        /* prepare a dummy image */
        /* Y */
        for(y=0;y<codecCtx->height;y++) {
            for(x=0;x<codecCtx->width;x++) {
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
            }
        }

        /* Cb and Cr */
        for(y=0;y<codecCtx->height/2;y++) {
            for(x=0;x<codecCtx->width/2;x++) {
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
            }
        }

        /* encode the image */
        //out_size = avcodec_encode_video(codecCtx, outbuf, outbuf_size, picture);
        // <Access violation> 
        out_size = avcodec_encode_video2(codecCtx, &avpkt, picture, &got_packet); 
        printf("encoding frame %3d (size=%5d)\n", i, out_size);
        //fwrite(outbuf, 1, out_size, f);
        fwrite(avpkt.data, 1, avpkt.size, f);
    }

    /* get the delayed frames */
    for(; out_size; i++) {
        fflush(stdout);

        //out_size = avcodec_encode_video(codecCtx, outbuf, outbuf_size, NULL);
        out_size = avcodec_encode_video2(codecCtx, &avpkt, NULL, &got_packet); 
        printf("write frame %3d (size=%5d)\n", i, out_size);
        //fwrite(outbuf, 1, out_size, f);
        fwrite(avpkt.data, 1, avpkt.size, f);
    }

    /* add sequence end code to have a real mpeg file */
    outbuf[0] = 0x00;
    outbuf[1] = 0x00;
    outbuf[2] = 0x01;
    outbuf[3] = 0xb7;
    fwrite(outbuf, 1, 4, f);
    fclose(f);
    free(picture_buf);
    free(outbuf);

    avcodec_close(codecCtx);
    av_free(codecCtx);
    av_free(picture);
    printf("\n");
}

0 个答案:

没有答案