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:
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
