1

I had an h264 video stream encoded from yuv444p frames, it was played well using vlc or mpv player.

But when I tried to decode it using libavcodec, it just looked like this.

wrong result;

The source frame is an upsize down vlc-player logo.

Here is the intialization of the decoder:

AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_H264);
AVCodecContext *codecCtx = avcodec_alloc_context3(codec);
avcodec_open2(codecCtx, codec, NULL);

The decoder worked well when decoding packets encoded from yuv420p. Did I miss anything when decoding those packets encoded from yuv444p frames?

Update:I converted the yuv444p output into BGRA with sws_scale(), then I make a transforment with the follow codes;

int offset_out = 0, offset_tmp = 0;
uint32_t *tmp = (uint32_t *)malloc(width * height * 4);
for (int i = 0; i < width * height; i++) { 
    if ((i + width + 9) % (width + 9) > width) {
        out[offset_out++] = in[i];
    } else {
        tmp[offset_tmp++] = in[i];
    }
}
memcpy(out + offset_out, tmp, offset_tmp);
free(tmp);

Then the picture looked all right.

There is a number 9 in i + width + 9. I guessed that cause I knew the width and height of the source picture. But what if the width or height was changed to some value else, 9 didn't work.

I want to know what's wrong with the decoder.

  • edit your question, and put that in a code-block (four leading spaces, not back-ticks), because it's not very readable. Or post your solution as an answer. Also, libavcodec has functions for format-conversion. Its implementation will take advantage of vector instructions and other stuff like that on platforms where they're available. – Peter Cordes Oct 21 '15 at 11:58
  • 1
    How did you convert to BGRA? Because is definitely an issues with your line_stride. – szatmary Oct 21 '15 at 15:22
  • ffmpeg converts it ok? (command line) – rogerdpack Oct 22 '15 at 16:40
  • H264-->decode-->YUV444P-->convert-->BGRA; The problem exists in decoding. Conversion is OK. –  Oct 23 '15 at 01:52

1 Answers1

1

What pixel format does the video have? If you encoded with ffmpeg, it doesn't downscale the chroma to yuv420 unless you tell it to. By default, it would make a yuv444 h.264 stream, which libavcodec would decode to yuv444 frames. If you interpreted those bytes as yuv420, it won't look right. Judging from the image, that's probably what happened.

libavcodec could even give you planar RGB (gbrp) output if you're decoding an RGB h.264 stream.

So you have to check what pixel format you get from the decoder, and treat it accordingly.

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731