-
I’m using ffmpeg API in C++ to convert h264 video stream to yuv420p, then I construct a MediaStreamSource and play it with MediaPlayer. Everything looks fine. However, recently I found that the video picture is a bit whitish, and I can’t distinguish between light gray and white areas. After searching a lot of information online, I suspect it has something to do with color_range, color_space. But I’m not familiar with ffmpeg, and I tried various parameters related to these two options, but they had no effect. MediaPlayer seems to have no settings related to colorspace either. Can anyone help me? Thank you very much! Code in C#: var videoProperties = VideoEncodingProperties.CreateUncompressed(MediaEncodingSubtypes.Iyuv, width, height);
var videoDescriptor = new VideoStreamDescriptor(videoProperties);
var mediaStreamSource = new MediaStreamSource(videoDescriptor);
mediaStreamSource.BufferTime = TimeSpan.Zero;
mediaStreamSource.CanSeek = false;
mediaStreamSource.IsLive = true;
mediaStreamSource.SampleRequested += MediaStreamSource_SampleRequested;
mediaSource = MediaSource.CreateFromMediaStreamSource(mediaStreamSource); Code in C++ // Initialize
m_pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
m_pCodecCtx = avcodec_alloc_context3(m_pCodec);
m_pCodecCtx->extradata = (uint8_t*)av_malloc(privatedatalen);
m_pCodecCtx->extradata_size = privatedatalen;
memcpy(m_pCodecCtx->extradata, privatedata, privatedatalen);
m_pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
//m_pCodecCtx->color_range = AVCOL_RANGE_JPEG;
//m_pCodecCtx->colorspace = AVCOL_SPC_BT2020_CL;
// Remove padding
for (int i = 0; i < pFrame->height; i++) {
memcpy(data + pFrame->width * i, pFrame->data[0] + pFrame->linesize[0] * i, pFrame->width);
if (i < pFrame->height / 2)
{
memcpy(data + pFrame->width * pFrame->height + pFrame->width * i / 2, pFrame->data[1] + pFrame->linesize[1] * i, pFrame->width / 2);
memcpy(data + pFrame->width * pFrame->height * 5 / 4 + pFrame->width * i / 2, pFrame->data[2] + pFrame->linesize[2] * i, pFrame->width / 2);
}
} The first decoded AVFrame:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
It looks like that MediaPlayer can only work with YUV420P which has limited color range. If I can convert full range color to limited range color it works well with MediaPlayer. Does anyone know how to make MediaPlayer work with full color range? |
Beta Was this translation helpful? Give feedback.
-
Your frames have pix format AV_PIX_FMT_YUVJ420P, which means that it has full color range (0-255). Normal mpeg color range is 16-235. The MediaPlayer will assume that your frames have normal mpeg color range, so it will expand the 16-235 range to 0-255, which causes the loss of all details very bright and very dark areas. You must set the MF_MT_VIDEO_NOMINAL_RANGE attribute to make MediaPlayer aware of the actual color range. This is how we do it in our UncompressedVideoSampleProvider:
|
Beta Was this translation helpful? Give feedback.
Your frames have pix format AV_PIX_FMT_YUVJ420P, which means that it has full color range (0-255). Normal mpeg color range is 16-235. The MediaPlayer will assume that your frames have normal mpeg color range, so it will expand the 16-235 range to 0-255, which causes the loss of all details very bright and very dark areas.
You must set the MF_MT_VIDEO_NOMINAL_RANGE attribute to make MediaPlayer aware of the actual color range.
This is how we do it in our UncompressedVideoSampleProvider: