I want to use FFmpeg to convert the input NV12 format to YUV420P.
I tried to use sws_scale conversion, but the colors are all green.
I have successfully converted YUYV422 to 420P using sws, but FAILED to convert NV12 to YUV420.
What should I change?
Here is my code:
QStringList inList = int_put_res.split("x");
m_in_width = inList[0].toInt();
m_in_hieght = inList[1].toInt();
QStringList outList = out_put_res.split("x");
m_out_width = outList[0].toInt();
m_out_hieght = outList[1].toInt();
int VSize = m_in_width * m_in_hieght;
AVPacket *packet;
AVCodecContext *enc_ctx = NULL;
AVFrame *image_inFrame= nullptr;
packet = av_packet_alloc();
int ret = 0;
int base = 0;
image_inFrame = av_frame_alloc();
open_encoder(m_out_width,m_out_hieght, &enc_ctx);
switch (AVPixelFormat(m_fmt_ctx->streams[m_videoindex]->codecpar->format))
{
case AV_PIX_FMT_YUV420P:
m_yuv420p_convert_ctx = initSWS(image_inFrame,NULL,m_in_width,m_in_hieght,AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV420P);
break;
case AV_PIX_FMT_YUYV422:
m_yuv420p_convert_ctx = initSWS(image_inFrame,NULL,m_in_width,m_in_hieght,AV_PIX_FMT_YUYV422,AV_PIX_FMT_YUV420P);
break;
case AV_PIX_FMT_NV12:
m_yuv420p_convert_ctx = initSWS(image_inFrame,NULL,m_in_width,m_in_hieght,AV_PIX_FMT_NV12,AV_PIX_FMT_YUV420P);
break;
}
m_frame = create_frame(m_out_width, m_out_hieght);
AVPacket *newpkt = av_packet_alloc();
if (!newpkt)
{
spdlog::error("failed to alloc avpacket!");
goto __ERROR;
}
if (!m_fmt_ctx)
{
goto __ERROR;
}
while (m_isStop != true)
{
if(av_read_frame(m_fmt_ctx, packet) != 0) {
goto __ERROR;
}
getSWS(m_yuv420p_convert_ctx,packet,image_inFrame,m_frame);
av_packet_unref(packet);
m_frame->pts = base++;
}
SwsContext *FFSDK::initSWS(AVFrame *scrFrame, AVFrame *dstFrame, int
image_width, int image_height,enum AVPixelFormat scrFmt, enum
AVPixelFormat dstFmt)
if(scrFrame != NULL){
av_image_alloc(scrFrame->data, scrFrame->linesize,image_width, image_height, scrFmt, 1);
}
if(dstFrame != NULL){
av_image_alloc(dstFrame->data, dstFrame->linesize, m_out_width, m_out_hieght, dstFmt, 1);
}
return sws_getContext(image_width,image_height,
scrFmt,
m_out_width, m_out_hieght, dstFmt,
SWS_BICUBIC,
nullptr,
nullptr,
nullptr);
}
void FFSDK::getSWS(SwsContext *context,AVPacket *packet,AVFrame *scrFrame, AVFrame *dstFrame)
{
scrFrame->data[0] = packet->data;
sws_scale(context,
scrFrame->data,
scrFrame->linesize, 0, m_in_hieght, dstFrame->data,
dstFrame->linesize);
}