[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