2014-04-21 52 views
0

我与MPEG-4,H264工作流如何从AVFrame获取亮度图片?

首先我tryed转换为RGB24和使用imagemagic使灰度,它亘古不变的工作

while(av_read_frame(pFormatCtx, &packet)>=0) 
    { 
     // Is this a packet from the video stream? 
     if(packet.stream_index==videoStream) 
     { 
      // Decode video frame 
      avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, 
            &packet); 

      // Did we get a video frame? 
      if(frameFinished) 
      { 
       f++; 
       //this->fram->Clear(); 
       // if (pFrame->pict_type == AV_PICTURE_TYPE_I) wxMessageBox("I cadr"); 
       // if (pFrame->pict_type != AV_PICTURE_TYPE_I) 
       // printMVMatrix(f, pFrame, pCodecCtx); 
       pFrameRGB->linesize[0]= pCodecCtx->width*3; // in case of rgb4 one plane 

       sws_scale(swsContext, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); 


       Magick::Blob* m_blob = new Magick::Blob(pFrameRGB->data,pCodecCtx->width*pCodecCtx->height*3); 
       Magick::Image* image =new Magick::Image(*m_blob); // this doesnotwork 

       image->quantizeColorSpace(Magick::GRAYColorspace); 
       image->quantizeColors(256); 
       image->quantize(); 

但是ffmpeg的给我YUV图片?所以只需要Y组件,如何得到它?得到Ypicture [x] [y]

回答

4

我假设你已经配置swscale到YUV420p色彩空间。 420P意味着4:2:0平面。平面意味着颜色通道是分开的。将亮度数据(Y)存储在pFrame-> data [0]的缓冲点(Cb和Cr分别在pFrame-> data [1]和pFrame-> data [2]中)。在YUV420中,Y平面是每个像素1个字节。

因此:

uint8_t getY(int x, int y, AVFrame *f) 
{ 
    return f->data[0][(y*f->linesize)+x]; 
} 
+0

谢谢!在什么颜色空间下ffmpeg avcodec_decode_video2默认打包未编码的视频帧? – user3177342

+1

无论视频编码的颜色空间是多少,并且可以从编解码器到编解码器/文件到文件有所不同。由于历史原因,大多数编解码器使用YUV420或YUV422。但我相信未来会有更多的人开始使用YUV444。您随时可以查看AVCodecCtx.pix_fmt以了解您所得到的结果。 – szatmary

+0

此外,如果这有助于您请upvote并添加接受答案。 – szatmary