[Libav-user] Mapping / converting QTCapture's to FFmpeg's pixel format

Brad O'Hearne brado at bighillsoftware.com
Tue Feb 5 00:44:49 CET 2013


Quick summary of my use case: I am capturing video on Mac OS X using QTKit, and then using FFmpeg to stream FLV video. I am presently successfully capturing from my internal MacBook Pro camera, using FFmpeg to encode, using FFmpeg to stream (publish) to a server (Wowza), and then am able to successfully play this video in a client from the server. So in other words, the capture / publish / play pipeline is in tact and video is moving across it as expected. 

The problem is that the video quality (specifically color and artifacts) isn't what I'm capturing. The color is off -- desaturated with a slightly green hue, with colored lines consistently across the the video image. In addition, the left border of the image appears cut off/repeated. 

I suspect that the problem is due to a mismatch between pixel formats of the captured video frames, vs. the expected pixel format in the filled frame. Because my AVCodec is outputting FLV, it only supports one pixel format: PIX_FMT_YUV420P. Choosing any other pixel format results in an error, and that would seem to be supported in the source code I read in flvenc.c. So the codec is set to that pixel format. 

The data coming in from the QTCapture on the OSX / Cocoa side is set as kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,one of only two pixel formats that work in this case. The doc for this format reads as follows: 

"Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255] chroma=[1,255]). baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct."

My code (heavily abridged for brevity) hits these high points: 

NOTE: frameBufferAddress is a CVImageBufferRef received from the QT capture callback: 

    int returnVal = avpicture_fill((AVPicture*)avFrame, frameBufferBaseAddress, PIX_FMT_YUV420P, width, height);
    returnVal = avcodec_encode_video2(_videoStream->codec, &avPacket, avFrame, &gotPacket);
    returnVal = av_interleaved_write_frame(_avOutputFormatContext, &avPacket);

My suspicion is that kCVPPixelFormatType_420YpCBCrBBiPlanarFullRange isn't matching properly to PIX_FMT_YUV420P, and so the avpicture_fill call isn't properly filling the frame with data. I've spent the day poring over the pixel format descriptions in pixfmt.h, and doing trial and error in that first line of code with a number of other formats that have come close in description, to no avail. In fact, most of them crash the app with no log message at all. 

If anyone has any idea on how to fix this video quality, I would greatly appreciate your help. Any ideas are welcome. Thanks so much in advance.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20130204/ceac9362/attachment.html>

More information about the Libav-user mailing list