[Libav-user] get RGB values from ffmpeg frame

Navin nkipe at tatapowersed.com
Wed Nov 21 06:34:41 CET 2012


@Everyone: I had seen the doc/examples code and every other possible 
source of information but there seems to be some problem causing the 
crashes when I use RGB. Even for the below Tutorial01 code of ffmpeg for 
example.
Am using the latest ffmpeg-win32-dev and I've tried with a wmv, many mp4 
(from youtube, h264 (high) (avc1/0x31637661), yuv420p 1280x720, 
1139kb/s, 24fps) files and avi too, but they're all crashing with 
Unhandled exception, Access violation writing location 0x002a3000 at the 
line "sws_scale". Even in the previous complete program that I posted to 
the mailing list, getting the RGB values were a problem because of a 
similar crash while iterating through frame->data.
Could anyone please help out with at least this program? Is it working 
on your end?


#include "stdio.h"
#include "stdlib.h"
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
#include<iostream>


void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
   FILE *pFile;
   char szFilename[32];
   int  y;

   sprintf(szFilename, "frame%d.ppm", iFrame);// Open file
   pFile=fopen(szFilename, "wb");
   if(pFile==NULL) return;
   fprintf(pFile, "P6\n%d %d\n255\n", width, height);// Write header
   for(y=0; y<height; y++) fwrite(pFrame->data[0]+y*pFrame->linesize[0], 
1, width*3, pFile);// Write pixel data
   fclose(pFile);// Close file
}//SaveFrame

int main(int argc, char *argv[])
{
   AVFormatContext *pFormatCtx = NULL;
   int             i, videoStream;
   AVCodecContext  *pCodecCtx = NULL;
   AVCodec         *pCodec = NULL;
   AVFrame         *pFrame = NULL;
   AVFrame         *pFrameRGB = NULL;
   AVPacket        packet;
   int             frameFinished;
   int             numBytes;
   uint8_t         *buffer = NULL;

   AVDictionary    *optionsDict = NULL;
   struct SwsContext      *sws_ctx = NULL;

   if(argc < 2) { printf("Please provide a movie file\n"); return -1; }
   av_register_all();// Register all formats and codecs

   if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)    
return -1; // Couldn't open file

   if(avformat_find_stream_info(pFormatCtx, NULL)<0)  return -1; // 
Couldn't find stream information

   // Dump information about file onto standard error
   av_dump_format(pFormatCtx, 0, argv[1], 0);

   // Find the first video stream
   videoStream=-1;
   for(i=0; i<pFormatCtx->nb_streams; i++) 
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { 
videoStream=i; break; }
   if(videoStream==-1) return -1; // Didn't find a video stream

   // Get a pointer to the codec context for the video stream
   pCodecCtx=pFormatCtx->streams[videoStream]->codec;

   // Find the decoder for the video stream
   pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
   if(pCodec==NULL) { fprintf(stderr, "Unsupported codec!\n"); return 
-1; }// Codec not found

   if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0) return -1; // 
Could not open codec

   pFrame=avcodec_alloc_frame();// Allocate video frame

   // Allocate an AVFrame structure
   pFrameRGB=avcodec_alloc_frame();
   if(pFrameRGB==NULL)  return -1;

   // Determine required buffer size and allocate buffer
   numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, 
pCodecCtx->height);
   buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

   sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, 
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, 
SWS_BILINEAR, NULL, NULL, NULL );

   // Assign appropriate parts of buffer to image planes in pFrameRGB. 
Note that pFrameRGB is an AVFrame, but AVFrame is a superset of AVPicture
   avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, 
pCodecCtx->width, pCodecCtx->height);

   // Read frames and save first five frames to disk
   i=0;
   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)
       {
         // Convert the image from its native format to RGB
         sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, 
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, 
pFrameRGB->linesize );

         // Save the frame to disk
         if(++i<=5) SaveFrame(pFrameRGB, pCodecCtx->width, 
pCodecCtx->height, i);
       }
     }

     // Free the packet that was allocated by av_read_frame
     av_free_packet(&packet);
   }//while

   av_free(buffer);av_free(pFrameRGB);// Free the RGB image
   av_free(pFrame);// Free the YUV frame
   avcodec_close(pCodecCtx);// Close the codec
   avformat_close_input(&pFormatCtx);// Close the video file

   return 0;
}

Navin


On 11/20/2012 6:16 PM, Malik Cissé wrote:
> Navin,
>> Macros and datatypes like LT_SUCCESS, MAX_FR_SZ, metaD_t, LtHandle, ASF_IDX_SZ etc. seem new. Am a bit puzzled.
> The code is taken from a proprietary stuff and I did not want to disclose everything but the main idea is there.
>


More information about the Libav-user mailing list