Log in

View Full Version : x264, problems about high444 encodes 16bits gray image into Y and U channels


l35633
20th November 2014, 14:42
Using x264 as encoder for 16bits depth gray image, high 8bits into Y , low 8bits into U, zeros into V. The configuration is below:
x264_param_default_preset(pX264Param, "medium", "zerolatency");
pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO;
pX264Param->i_keyint_max = 1; //IDR
pX264Param->rc.f_rf_constant = 0; //crf
pX264Param->i_fps_den = 1;
pX264Param->i_fps_num = 30;
pX264Param->i_timebase_den = pX264Param->i_fps_num;
pX264Param->i_timebase_num = pX264Param->i_fps_den;
//high444
x264_param_apply_profile(pX264Param, x264_profile_names[5]);

The debugging information:
profile High 4:4:4 Intra, level 3.0, 4:2:0 8-bit,

x264 encoding and ffmpeg decoding are both OK. Seperately show Y, it is right! If add the low 8bits data from U channel, the image result is obviously wrong, i.e, the U channel data is changed too much. what and where is wrong? NEED YOU HELP, MY FRIEND.

MasterNobody
20th November 2014, 19:09
You encoding in 4:2:0 colorspace where U plane is 4 times smaller then Y plane. So make sure that this not the cause of you problem.
You have to use pX264Param->i_csp = X264_CSP_I444; for 4:4:4 colorspace encoding which you probably want.

l35633
20th November 2014, 21:45
I added pX264Param->i_csp = X264_CSP_I444, but still error below:
x264 [info]: profile High 4:4:4 Intra, level 3.0, 4:4:4 8-bit
x264 [error]: Invalid input colorspace

would you please give more advices?
Thank you very much!

MasterNobody
20th November 2014, 22:28
I added pX264Param->i_csp = X264_CSP_I444, but still error below:
x264 [info]: profile High 4:4:4 Intra, level 3.0, 4:4:4 8-bit
x264 [error]: Invalid input colorspace
This mean that while you changed encoder to encode 4:4:4 colorspace you are still trying to send it 4:2:0 colorspace image in x264_encoder_encode (x264_picture_t *pic_in argument). If you are using x264_picture_alloc to allocate pic_in then you should use correct colorspace there also.

l35633
20th November 2014, 23:03
Yes, you are right! I really forgot modifying x264_picture_alloc.
Now encoding with x264 is no problem. But after decoding with ffmpeg, the Y channel data is right! But U channel data changed so much! so many data changed to value 205. I am not sure something is wrong with encoder or decoder?

Would you please give me more nice advices?
Thank you very much!

MasterNobody
20th November 2014, 23:09
I am out of ideas without code snippets. But are you sure that you correctly fill pic_in planes?

l35633
21st November 2014, 10:57
Thank you so much for your warm reply!
Now I think it is the problem of ffmpeg decoding, but I am not totally sure, I just show the result I test.
First I use ffmpeg command line to decode yuv444 encoded file test444.264:
./ffmpeg -f h264 -i test444.264 output.yuv
some errors happened:
[h264 @ 0x252ff40] top block unavailable for requested intra mode at 0 0
[h264 @ 0x252ff40] error while decoding MB 0 0, bytestream (58749)
[h264 @ 0x252ff40] number of reference frames exceeds max (probably corrupt input), discarding one
[h264 @ 0x252ff40] concealing 1200 DC, 1200 AC, 1200 MV errors

But if I use ffmpeg lib and function to decode test444.264, though no error printed, the result of U is not right. How do I use ffmpeg lib to decode,I show below:
AVCodec* pCodec = NULL;

avcodec_register_all();
av_register_all();

pCodec = avcodec_find_decoder(CODEC_ID_H264);

if(pCodec != NULL)
{

pCodecCtx = avcodec_alloc_context3(NULL);

pCodecCtx->time_base.num = 1;

pCodecCtx->time_base.den = 30;

pCodecCtx->bit_rate = 0;

pCodecCtx->frame_number = 1;

pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;

pCodecCtx->width = width;

pCodecCtx->height = height;

if(avcodec_open2(pCodecCtx, pCodec,NULL) >= 0)
{

pAvfFrame = avcodec_alloc_frame();// Allocate video frame

}
}

AVPacket pkt;
av_init_packet(&pkt);

pkt.data = (unsigned char*)pSrcData;

pkt.size = dwDataLen;

avcodec_decode_video2(pCodecCtx,pAvfFrame,(int*)(&get),&pkt);


if(get != 0)
{
for(int i=0,nDatalen=0; i<3; i++)
{
int nShift = (i==0)?0:1;
uint8_t* pYUVData = (uint8_t*)pAvfFrame->data[i];
for(int j=0; j<(pCodecCtx->height>>nShift); j++)
{
memcpy(&pDeData[nDatalen],pYUVData,(pCodecCtx->width>>nShift));
pYUVData += pAvfFrame->linesize[i];
nDatalen += (pCodecCtx->width>>nShift);
}
}

return true;
}
else
return false;

That is what I did. Would you please give me more advices?
Thank you very much!

MasterNobody
21st November 2014, 19:07
I am dunno about ffmpeg decoding but ffmpeg warnings sounds like your output stream is broken. I was more interested in you libx264 use code snippet and also muxing (writing to file) code. Small output sample can be useful for analyzing what you done wrong. Also you can try to create your yuv sample file and feed it to x264 CLI (instead of your libx264 code) to encode to see if it would output it correctly and would ffmpeg be able to decode it.

l35633
24th November 2014, 12:55
Thank you very much!
Now I have a high444 yuv file, I encoded by x264 command below,no error happend, but I cannot open the 264 file by vlc player, and decoded by ffmpeg is wrong! Would you please tell me where is wrong with my command?

./x264 vga_640x480.yuv --preset medium --tune zerolatency --input-csp i444 --keyint 1 --crf 0 --fps 30 --profile high444 --output-csp i444 -o test.264

Thank you very much!

MasterNobody
24th November 2014, 18:24
l35633
What do you mean by "decoded by ffmpeg is wrong"? Wrong output or errors during decoding? Can you upload encoded sample to any file sharing service so I can look at it.

l35633
24th November 2014, 18:52
hello,dear friend.
What I mean, when I use command below:
./ffmpeg -f h264 -i test.264 output.yuv
errors below:
[h264 @ 0x1e55f60] concealing 99 DC, 99 AC, 99 MV errors
[h264 @ 0x1e55f60] top block unavailable for requested intra mode at 0 0
[h264 @ 0x1e55f60] error while decoding MB 0 0, bytestream (41380)
[h264 @ 0x1e55f60] number of reference frames exceeds max (probably corrupt input), discarding one
[h264 @ 0x1e55f60] concealing 99 DC, 99 AC, 99 MV errors


Now links below is repectivly a yuv444 test file, and encoded result by my command:

https://www.dropbox.com/s/bgt80xnswirb40z/qcif_176x144.yuv?dl=0

https://www.dropbox.com/s/7j9vh0ovye4t3xn/test.264?dl=0

Thank you very much! I now don't make clear it is encoder command has problem or decoder command has problem.

MasterNobody
24th November 2014, 19:35
l35633
Update your ffmpeg or try avconv (libav). It decodes correctly (and bit exact to input) here with both JM (ldecod) and with your ffmpeg command line.

l35633
24th November 2014, 20:22
Dear MasterNobody, thank you so much!
I think you are Master of me!
Would you please tell me your ffmpeg version and JM version? I will try in my machine later!

Thank you for your warm help!

MasterNobody
24th November 2014, 20:46
I tested with JM 18.4 and with Latest Zeranoe FFmpeg Build Version: git-5182a2a (2014-11-24) (http://ffmpeg.zeranoe.com/builds/)

l35633
24th November 2014, 20:55
Thank you very much!