我一直在嘗試使用Visual C++使用FFmpeg對幀進行編碼。這是我如何做到的。 我首先有一個平面RGB24圖像緩衝區。FFmpeg avcodec_encode_video2訪問衝突
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;
我實現這樣的:我使用以下規則將其轉換爲YUV平面
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);
}
但是,這導致Access violation writing location 0x00000000
avcodec_encode_video2
。我檢查了每個FFmpeg函數返回的錯誤,看起來它們都工作,除了av_image_fill_arrays
,它返回一個奇怪的1382400
錯誤,但根據調試器的RAM查看工具,所有東西都被正確填充。
看起來好像avcodec_encode_video2
試圖訪問一個不應該是的NULL對象,但是我找不到它可能是什麼,因爲我遵循很多源示例,並且我不知道我做錯了什麼。
在此先感謝!
編輯:應用由埃德加Rokyan(這是設置第四個參數爲int指針)建議的修復程序後,我現在0x00000024
與avformat_alloc_output_context2
得到一個訪問衝突,仍。我相信問題是相似的,但我仍然找不到任何東西。