views:

287

answers:

2

Hi

I'm trying to learn to use the different ffmpeg libs with Cocoa, and I'm trying to get frames to display with help of Core Video. It seems I have gotten the CV callbacks to work, and it gets frames which I try to put in a CVImageBufferRef that I later draw with Core Image.

The problem is I'm trying to get PIX_FMT_YUYV422 to work with libswscale, but as soon as I change the pixel format to anything other than PIX_FMT_YUV420P it crashes with EXC_BAD_ACCESS.

As long as I use YUV420P the program runs, allthough it doesn't display properly. I suspected that the pixel format isn't supported, so I wanted to try PIX_FMT_YUYV422.

I have had it running before and successfully wrote PPM files with PIX_FMT_RGB24. For some reason it just crashes on me now, and I don't see what might be wrong.

I'm a bit in over my head here, but that is how I prefer to learn. :)

Here's how I allocate the AVFrames:

inFrame = avcodec_alloc_frame();
outFrame = avcodec_alloc_frame();
int frameBytes = avpicture_get_size(PIX_FMT_YUYV422, cdcCtx->width, cdcCtx->height);


uint8_t *frameBuffer = malloc(frameBytes);
avpicture_fill((AVPicture *)outFrame, frameBuffer, PIX_FMT_YUYV422, cdcCtx->width, cdcCtx->height);

Then I try to run it through swscale like so:

static struct SwsContext *convertContext;


 if (convertContext == NULL) {
  int w = cdcCtx->width;
  int h = cdcCtx->height;
  convertContext = sws_getContext(w, h, cdcCtx->pix_fmt, outWidth, outHeight, PIX_FMT_YUYV422, SWS_BICUBIC, NULL, NULL, NULL);
  if (convertContext == NULL) {
   NSLog(@"Cannot initialize the conversion context!");
   return NO;
  }
 }

 sws_scale(convertContext, inFrame->data, inFrame->linesize, 0, outHeight, outFrame->data, outFrame->linesize);

And finally I try to write it to a pixel buffer for use with Core Image:

int ret = CVPixelBufferCreateWithBytes(0, outWidth, outHeight, kYUVSPixelFormat, outFrame->data[0], outFrame->linesize[0], 0, 0, 0, &currentFrame);

With 420P it runs, but it doesnt match up with the kYUVSPixelformat for the pixel buffer, and as I understand it doesnt accept YUV420.

I would really appreciate any help, no matter how small, as it might help me struggle on. :)

+1  A: 

This certainly isn't a complete code sample, since you never decode anything into the input frame. If you were to do that, it looks correct.

You also don't need to fill the output picture, or even allocate an AVFrame for it, really.

alex strange
A: 

YUV420P is a planar format. Therefore, AVFrame.data[0] is not the whole story. I see a mistake in

int ret = CVPixelBufferCreateWithBytes(0, outWidth, outHeight, kYUVSPixelFormat, outFrame->data[0], outFrame->linesize[0], 0, 0, 0, &currentFrame);

For planar formats, you will have to read data blocks from AVFrame.data[0] up to AVFrame.data[3]

pierrelucbacon