我有彩色OpenCV::Mat
類型的JPEG圖像和我從他們的視頻使用avcodec
創建。我得到的視頻是顛倒的,黑色&白色,每幀的每一行都移動了,我得到了對角線。什麼可能是這種輸出的原因? 按照this鏈接觀看,我開始使用avcodec中的視頻。 我使用acpicture_fill
函數來創建avFrame
從cv::Mat
幀!如何使用avcodec從OpenCV :: Mat類型的jpeg圖像創建視頻?
P.S.我注意到avFrame(由acpicture_fill填充)有linesize[0]=2430
我試着手動設置avFrame->linesizep0]=2432
而不是2430,但它仍然沒有幫助。
======== CODE ==================================== =====================
AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
AVStream *outStream = avformat_new_stream(outContainer, encoder);
avcodec_get_context_defaults3(outStream->codec, encoder);
outStream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
outStream->codec->width = 810;
outStream->codec->height = 610;
//...
SwsContext *swsCtx = sws_getContext(outStream->codec->width, outStream->codec->height, PIX_FMT_RGB24,
outStream->codec->width, outStream->codec->height, outStream->codec->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
for (uint i=0; i < frameNums; i++)
{
// get frame at location I using OpenCV
cv::Mat cvFrame;
myReader.getFrame(cvFrame, i);
cv::Size frameSize = cvFrame.size();
//Each cv::Mat cvFrame has width=810, height=610, step=2432
1. // create AVPicture from cv::Mat frame
2. avpicture_fill((AVPicture*)avFrame, cvFrame.data, PIX_FMT_RGB24, outStream->codec->width, outStream->codec->height);
3avFrame->width = frameSize.width;
4. avFrame->height = frameSize.height;
// rescale to outStream format
sws_scale(swsCtx, avFrame->data, avFrame->linesize, 0, outStream->codec->height, avFrameRescaledFrame->data, avFrameRescaledFrame ->linesize);
encoderRescaledFrame->pts=i;
avFrameRescaledFrame->width = frameSize.width;
avFrameRescaledFrame->height = frameSize.height;
av_init_packet(&avEncodedPacket);
avEncodedPacket.data = NULL;
avEncodedPacket.size = 0;
// encode rescaled frame
if(avcodec_encode_video2(outStream->codec, &avEncodedPacket, avFrameRescaledFrame, &got_frame) < 0) exit(1);
if(got_frame)
{
if (avEncodedPacket.pts != AV_NOPTS_VALUE)
avEncodedPacket.pts = av_rescale_q(avEncodedPacket.pts, outStream->codec->time_base, outStream->time_base);
if (avEncodedPacket.dts != AV_NOPTS_VALUE)
avEncodedPacket.dts = av_rescale_q(avEncodedPacket.dts, outStream->codec->time_base, outStream->time_base);
// outContainer is "mp4"
av_write_frame(outContainer, & avEncodedPacket);
av_free_packet(&encodedPacket);
}
}
修訂
作爲@Alex建議我更改的行1-4的代碼低於
int width = frameSize.width, height = frameSize.height;
avpicture_alloc((AVPicture*)avFrame, AV_PIX_FMT_RGB24, outStream->codec->width, outStream->codec->height);
for (int h = 0; h < height; h++)
{
memcpy(&(avFrame->data[0][h*avFrame->linesize[0]]), &(cvFrame.data[h*cvFrame.step]), width*3);
}
我現在得到的視頻(here)幾乎是pe rfect。它不是倒置的,不是黑色的&白色,但似乎有一個RGB組件丟失。每個棕色/紅色變成藍色(在原始圖像中應該是副詩)。 可能是什麼問題?可以重新換算(sws_scale
)到AV_PIX_FMT_YUV420P
格式的原因造成的?
據我所知,我需要爲'pic-> data [0]'和'pic-> data [1]'和'pic-> data [2]'分配緩衝區多少? 'pic-> linesize [0]'也是0,我應該在那裏放2430嗎? – theateist
我其實不太確定當格式是BGR24時avpicture_fill()如何填充圖片。請參閱上面的編輯。 –
你不需要分配pic-> data [0]或設置linesize,avpicture_alloc()應該這樣做。無論如何,這都是第二種方法。請先嚐試第一種方法(將數據複製到沒有填充的buf並調用avpicture_fill)。 –