[Libav-user] unable to decode h264 video within mp4
Shi Yan
billconan at gmail.com
Wed Dec 5 23:52:56 CET 2012
May I ask you a question regarding h264 decoding with libavcodec?
I’m working on a launch animation for our application. The animation is a
h264 mp4 file. I’m not very familiar with video decoding, I started by
following this tutorial:
http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
I verified the tutorial can work fine on other video formats, for example
mpeg, but can’t work on h264.
The reason is that a call to this function:
const auto processedLength = avcodec_decode_video2(avCodecContext,
avFrame, &isFrameAvailable, &packetToSend);
if (processedLength < 0) {
av_free_packet(&packet);
qDebug() << "Error while processing the data";
exit(0);
}
Always returns -1. libav prints an error "no frame!" or "nal is a large
number".
I know that there could be missing nal header that I need to tell the
decoder. But I couldn't find any articles about how to do it.
I’m stuck here.
Thank you,
This is my code:
avcodec_init();
av_register_all();
av_log_set_callback(my_log_callback);
av_log_set_level(AV_LOG_DEBUG);
AVFormatContext *formatContext = avformat_alloc_context();
if (av_open_input_file(&formatContext, "C:\\ani.mp4", NULL, NULL, NULL)
!= 0)
{
qDebug() << "can't open animation";
}
if (av_find_stream_info(formatContext) < 0)
{
qDebug() << "can't find stream info";
}
AVStream* videoStream;
for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
{
AVStream *stream = formatContext->streams[i]; // pointer to
a structure about the stream
AVMediaType codecType = stream->codec->codec_type; // the type of
data in this stream, notable values are AVMEDIA_TYPE_VIDEO and
AVMEDIA_TYPE_AUDIO
CodecID codecID = stream->codec->codec_id; // identifier
for the codec
qDebug() <<"media type"<< codecType << "codec_id:" << codecID;
if (codecType == AVMEDIA_TYPE_VIDEO)
{
videoStream = stream;
}
}
AVCodec *codec = avcodec_find_decoder(videoStream->codec->codec_id);
if (codec == NULL)
{
qDebug() << "can't create codec";
}
AVCodecContext *avCodecContext =
avcodec_alloc_context2(videoStream->codec->codec_type);
avCodecContext->width = 1920;
avCodecContext->height = 1080;
//avCodecContext->flags2 |= CODEC_FLAG2_FAST;
avCodecContext->pix_fmt = (enum PixelFormat)29;
if (avcodec_open(avCodecContext,codec ) < 0)
{
qDebug() << "can't open animation file";
}
qDebug() << "codec width:" << avCodecContext->width << "height:" <<
avCodecContext->height <<avCodecContext->pix_fmt ;
AVFrame * avFrame =avcodec_alloc_frame();
if (avFrame == NULL)
{
qDebug() << "can't allocation avFrame";
}
avcodec_get_frame_defaults(avFrame);
// the current packet of data
AVPacket packet;
av_init_packet(&packet);
packet.size = 0;
// data in the packet of data already processed
size_t offsetInData = 0;
// the decoding loop, running until EOF
while (true)
{
// reading a packet using libavformat
if (offsetInData >= packet.size)
{
av_free_packet(&packet);
while (true)
{
if (av_read_frame(formatContext, &packet) < 0)
{
qDebug() << "EOF";
goto finished;
}
if (packet.stream_index == videoStream->index)
break;
av_free_packet(&packet);
}
}
qDebug() << "packet" << packet.size;
// preparing the packet that we will send to libavcodec
AVPacket packetToSend;
packetToSend.data = packet.data + offsetInData;
packetToSend.size = packet.size - offsetInData;
// sending data to libavcodec
int isFrameAvailable = 0;
const auto processedLength = avcodec_decode_video2(avCodecContext,
avFrame, &isFrameAvailable, &packetToSend);
if (processedLength < 0) {
av_free_packet(&packet);
qDebug() << "Error while processing the data";
exit(0);
}
qDebug() << "processed Length:" << processedLength;
offsetInData += processedLength;
// processing the image if available
if (isFrameAvailable) {
qDebug() << "one frame is ready!";
}
}
finished:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121205/63780863/attachment.html>
More information about the Libav-user
mailing list