2017-08-29 329 views
0

我正在開發一個應用程序,它需要將NV12幀從h264_cuvid解碼器轉換爲RGB以修改這些幀。我檢查了this question,但我並不是'超越'的價值。使用libswscale從NV12轉換爲RGB/YUV420P

我的代碼如下:

uint8_t *inData[2] = { videoFrame->data[0], videoFrame->data[0] + videoFrame->width * videoFrame->height }; 
int inLinesize[2] = { videoFrame->width, videoFrame->width }; 

sws_scale(convert_yuv_to_rgb, inData, inLinesize, 0, videoFrame->height, aux_frame->data, aux_frame->linesize); 

但它不工作。雖然問題出在顏色上,因爲我可以正確地看到亮度平面。

+1

色度數據應存儲在videoFrame-> data [1]而不是videoFrame-> data [0] + videoFrame-> width * videoFrame-> height中。 – OldC

+0

@OldC事情是以前的RGB - > YUV420P轉換工作,但如果原始幀是NV12第二次轉換不起作用。我檢查了RGB幀是否正確,將每一個都保存爲PNG文件。 –

回答

0

我最終使用了基於this example的視頻濾鏡。

char args[512]; 
int ret; 
AVFilter *buffersrc = avfilter_get_by_name("buffer"); 
AVFilter *buffersink = avfilter_get_by_name("buffersink"); 
AVFilterInOut *outputs = avfilter_inout_alloc(); 
AVFilterInOut *inputs = avfilter_inout_alloc(); 
AVFilterGraph *filter_graph = avfilter_graph_alloc(); 
AVBufferSinkParams *buffersink_params; 
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE }; 

/* buffer video source: the decoded frames from the decoder will be inserted here. */ 
snprintf(args, sizeof(args), 
     "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", 
     inStream.width, inStream.height, inStream.pix_fmt, 
     inStream.time_base.num, inStream.time_base.den, 
     inStream.sample_aspect_ratio.num, inStream.sample_aspect_ratio.den); 
ret = avfilter_graph_create_filter(&buffersrc_ctx_to_rgb_, buffersrc, "in", args, NULL, filter_graph); 

if (ret < 0) { 
    throw SVSException(QString("Could not create filter graph, error: %1").arg(svsAvErrorToFormattedString(ret))); 
} 

/* buffer video sink: to terminate the filter chain. */ 
buffersink_params = av_buffersink_params_alloc(); 
buffersink_params->pixel_fmts = pix_fmts; 
ret = avfilter_graph_create_filter(&buffersink_ctx_to_rgb_, buffersink, "out", NULL, buffersink_params, filter_graph); 

if (ret < 0) { 
    throw SVSException(QString("Cannot create buffer sink, error: %1").arg(svsAvErrorToFormattedString(ret))); 
} 

/* Endpoints for the filter graph. */ 
outputs -> name = av_strdup("in"); 
outputs -> filter_ctx = buffersrc_ctx_to_rgb_; 
outputs -> pad_idx = 0; 
outputs -> next = NULL; 
/* Endpoints for the filter graph. */ 
inputs -> name = av_strdup("out"); 
inputs -> filter_ctx = buffersink_ctx_to_rgb_; 
inputs -> pad_idx = 0; 
inputs -> next = NULL; 

QString filter_description = "format=pix_fmts=rgb32"; 
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_description.toStdString().c_str(), &inputs, &outputs, NULL)) < 0) { 
    svsCritical("", QString("Could not add the filter to graph, error: %1").arg(svsAvErrorToFormattedString(ret))) 
} 

if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) { 
    svsCritical("", QString("Could not configure the graph, error: %1").arg(svsAvErrorToFormattedString(ret))) 
} 

return; 

我創造了一個又一個從RGB轉換爲YUV420P編碼之前以類似的方式。