[Libav-user] got_picture_ptr of avcodec_decode_video2 always returns 0 for a particular MTS file
Simon Daniels
simondaniels23 at gmail.com
Tue Feb 7 06:47:33 CET 2012
Hi Andrey,
Thanks for the help!
1. Lib versions: Using the shared library and my code below, I tried 0.8.3
(PC) and 08d2cee4 (Mac) and could not scan the file. However, I tried the
static executable of 0.8 and 0.10 on Mac and I *could* transcode it to MP4.
2. Link to video (it's almost 2gb):
http://dl.dropbox.com/u/28441949/00793.MTS
3. Simplified, but compilable source code:
int Scan(const char *inputfile)
{
totalFrames = 0;
frameLocation = 0;
AVFormatContext *pFormatCtx;
unsigned int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameYUV;
int numBytes;
uint8_t *buffer;
clock_t start = clock();
// Register all formats and codecs
av_register_all();
// Open video file
if(av_open_input_file(&pFormatCtx, inputfile, NULL, 0, NULL)!=0)
{
return -1; // Couldn't open file
}
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
{
return -2; // Couldn't find stream information
}
// Dump information about file onto standard error
dump_format(pFormatCtx, 0, inputfile, false);
// 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 -3; // Didn't find a video stream
}
// Get a pointer to the codec context for the video stream
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
// get duration
double duration = double(pFormatCtx->duration) / AV_TIME_BASE;
cout << "Video duration: " << duration << std::endl;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
return -4; // Codec not found
}
// Inform the codec that we can handle truncated bitstreams -- i.e.,
// bitstreams where frame boundaries can fall in the middle of packets
if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0)
{
return -5; // Could not open codec
}
std::cout << "Using codec: " << pCodec->name << std::endl;
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Allocate an AVFrame structure
pFrameYUV=avcodec_alloc_frame();
if(pFrameYUV==NULL)
{
return -6;
}
// Determine required buffer size and allocate buffer
// originally: PIX_FMT_RGB24
numBytes=avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width,
pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in pFrameRGB
// originally: PIX_FMT_RGB24
avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P,
pCodecCtx->width, pCodecCtx->height);
totalFrames = pFormatCtx->streams[videoStream]->nb_frames;
printf("Frames: %d\n", totalFrames);
AVPacket packet;
int isFrameFinished = 0;
int pixelScanCount = 0;
std::cout << "videoWidth = " << pCodecCtx->width << std::endl;
std::cout << "videoHeight = " << pCodecCtx->height << std::endl;
while (av_read_frame(pFormatCtx, &packet) >= 0)
{
// Is this a packet from the video stream?
if (packet.stream_index == videoStream &&
frameLocation++ % frameSkip == 0)
{
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &isFrameFinished,
&packet);
// Did we get a video frame?
if (isFrameFinished) {
// SCANNING GOES HERE
pixelScanCount = 0;
for (int y = 0; y < pCodecCtx->height; y++)
{
uint8_t *p = pFrame->data[0] + y * pFrame->linesize[0];
// this gets Y' in YUV
for (int x = 0; x < pCodecCtx->width; x++)
{
pixelScanCount++;
//printf("Frame %d at %d, %d has Y'=%d\n",
frameLocation, x, y, p[x]);
}
}
av_free_packet(&packet);
}
else // frame isn't finished. not sure why we'd hit this
{
av_free_packet(&packet);
}
}
}
delete [] buffer;
av_free(pFrameYUV);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
}
4. When I enabled av_log_set_level(AV_LOG_DEBUG) in my app, I saw several
of these:
[h264 @ 09FC0940] Frame num gap 10 8
[h264 @ 09FC0940] Frame num gap 15 12
[h264 @ 09FC0940] Frame num gap 15 13
[h264 @ 09FC0940] Frame num gap 20 17
...
So considering the fact that the command-line utility was able to
transcode, I'm assuming there's something wrong in my code. I've seen some
warnings for deprecated functions so maybe that's my problem?
Thanks!
Simon
On Mon, Feb 6, 2012 at 2:56 AM, Andrey Utkin <andrey.krieger.utkin at gmail.com
> wrote:
> Please help us help you - provide
> - version of libs you use
> - compilable minimized source code of your app
> - this sample file
>
> BTW, did you try to transcode it with ffmpeg command-line utility? If
> it also fails, please provide its full output with -loglevel debug
> BTW2 try to av_log_set_level(AV_LOG_DEBUG); in your app - maybe you'll
> see useful messages on stderr.
>
>
> --
> Andrey Utkin
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120206/a0a13ad3/attachment.html>
More information about the Libav-user
mailing list