繁体   English   中英

FFmpeg avcodec_encode_video2访问冲突

[英]FFmpeg avcodec_encode_video2 access violation

我一直在尝试使用FFmpeg和Visual C ++对帧进行编码。 这是我的方法。 我首先有一个平面RGB24图像缓冲区。 我使用以下规则将其转换为平面YUV:

Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

我是这样实现的:

void rgb8toYuv(uchar* rgb, uchar* yuv, uint pixelAmount) {
    uchar r, g, b;
    for (uint i = 0; i < pixelAmount; i++) {
        r = rgb[3 * i];
        g = rgb[3 * i + 1];
        b = rgb[3 * i + 2];
        yuv[3 * i] = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
        yuv[3 * i + 1] = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
        yuv[3 * i + 2] = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
    }
}

我打开所有类似的东西(我正在使用malloc,因为我在C中已经习惯了它,这是我的第一个C ++程序,我想它应该不会引起任何问题?):

AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
AVFormatContext* outContext;
avformat_alloc_output_context2(&outContext, NULL, "mp4", filepath);

AVStream* video = avformat_new_stream(outContext, codec);
video->codec->bit_rate = VIDEOBITRATE;
video->codec->width = VIDEOWIDTH;
video->codec->height = VIDEOHEIGHT;
video->time_base = fps;
video->codec->gop_size = 10;
video->codec->max_b_frames = 1;
video->codec->pix_fmt = AV_PIX_FMT_YUV420P;
video->codec->codec_id = AV_CODEC_ID_H264;
video->codec->codec_type = AVMEDIA_TYPE_VIDEO;

avio_open(&outContext->pb, filepath, AVIO_FLAG_READ_WRITE);
avformat_write_header(outContext, NULL);

AVFrame* frame = av_frame_alloc();
frame->width = VIDEOWIDTH;
frame->height = VIDEOHEIGHT;
frame->format = AV_PIX_FMT_YUV420P;

然后,这是我用来编码帧的函数:

void encodeFrame(uint currentFrame, uchar* data) { // RGB data
    uchar* yuvData = (uchar*) malloc(videoWidth * videoHeight * 3);
    rgb8toYuv(data, yuvData, videoWidth * videoHeight);
    av_image_fill_arrays(frame->data, frame->linesize, yuvData, AV_PIX_FMT_YUV420P, videoWidth, videoHeight, 3); // I'm not sure about that 3, I couldn't find any documentation about it

    AVPacket* packet = (AVPacket*) malloc(sizeof(AVPacket));
    memset(packet, 0, sizeof(AVPacket));
    av_init_packet(packet);
    packet->data = NULL;
    packet->size = 0;

    frame->pts = currentFrame; // I don't know if this is corrrect too
    avcodec_encode_video2(video->codec, packet, frame, NULL);
    av_interleaved_write_frame(outContext, packet);
    av_packet_unref(packet);

    free(yuvData);
    free(packet);
}

但是,这会导致avcodec_encode_video2上的Access violation writing location 0x00000000 我检查了FFmpeg的每个函数返回的错误,似乎它们都可以工作,但av_image_fill_arrays返回一个奇怪的1382400错误,尽管根据调试器的RAM查看工具,所有内容都可以正确填充。

似乎avcodec_encode_video2尝试访问不应该访问的NULL对象,但是由于我遵循了许多源代码示例,因此我找不到它可能是什么,而且我不知道自己做错了什么。

提前致谢!

编辑:应用Edgar Rokyan建议的修复程序(将第4个参数设置为int指针)后,我现在在0x00000024仍然avformat_alloc_output_context2的访问冲突。 我相信问题是相似的,但是我仍然找不到任何东西。

您需要在avcodec_encode_video2之前调用avcodec_encode_video2 建议您不要在avformat_new_stream返回的流中使用编解码器上下文,而是先使用avcodec_alloc_context3avcodec_copy_context将其副本复制到新变量中。

并且,别忘了在完成后免费关闭( avcodec_close )( avcodec_free_context )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM