4

I recently started to use ffmpeg C libraries in order to analyze the integrity of video frames in a file. I started (like a lot of people) with Dranger's tutorials, then I made my own research from them. But I have a problem: I can't detect corrupted packets or frames while reading a video file with corrupted data. For example, there is this code below (it does work but I haven't worried too much about freeing resources):

extern "C" {
#include <libavformat\avformat.h>
#include <libavcodec\avcodec.h>
#include <libavutil\frame.h>
}
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avutil.lib")

int main(int argc, char *argv[]) {

av_register_all();

AVFormatContext* pFormatContext = 0;

if (avformat_open_input(&pFormatContext, "errorVideo.mpg", NULL, NULL) < 0) {
    //Error opening file
    exit(1);
    }

if (avformat_find_stream_info(pFormatContext, NULL) < 0) {
    //Error finding stream...
    exit(1);
    }

//Finding first video stream:
unsigned int iStream;
for (iStream = 0; iStream < pFormatContext->nb_streams && pFormatContext->streams[iStream]->codec->codec_type != AVMEDIA_TYPE_VIDEO;    iStream++);
if (iStream >= pFormatContext->nb_streams) {
    //Error finding video stream.
    exit(1);
    }

AVCodecContext* pOrigCodecCtx = pFormatContext->streams[iStream]->codec;
AVCodec* pCodec = avcodec_find_decoder(pOrigCodecCtx->codec_id);
if (!pCodec) {
    //Codec no supported
    exit(1);
    }

AVCodecContext* pNewCodecCtx = avcodec_alloc_context3(pCodec);
if (!pNewCodecCtx || avcodec_copy_context(pNewCodecCtx, pOrigCodecCtx) != 0) {
    //Error allocating or copying context
    exit(1);
    }

if (avcodec_open2(pNewCodecCtx, pCodec, NULL) < 0) {
    //Error initializing codec
    exit(1);
    }

AVPacket packet;
int gotFrame;
while (av_read_frame(pFormatContext, &packet) >= 0) {

    if (packet.stream_index == iStream) {
        AVFrame* pFrame = av_frame_alloc();

        if (avcodec_decode_video2(pNewCodecCtx, pFrame, &gotFrame, &packet) < 0) {
            //Error decoding frame.
            exit(1);
            }

        if (gotFrame) {
            //do something with frame...
            }

        av_frame_unref(pFrame);
        }

    av_free_packet(&packet);
    }
if (pFormatContext->pb->error != 0) {
    //Error reading packet
    exit(1);
    }
}

When I try to read a video with corrupted data, I get output from the ffmpeg libraries indicating that there is invalid data, e.g.:

[mpeg2video @ 0000000000B68A40] invalid cbp -1 at 19 6
[mpeg2video @ 0000000000B68A40] Warning MVs not available
[mpeg2video @ 0000000000B68A40] concealing 45 DC, 45 AC, 45 MV errors in P frame
[mpeg2video @ 0000000000B68A40] invalid mb type in P Frame at 21 16
[mpeg2video @ 0000000000B68A40] Warning MVs not available
[mpeg2video @ 0000000000B68A40] concealing 45 DC, 45 AC, 45 MV errors in P frame
[mpeg2video @ 0000000000B68A40] slice mismatch
[mpeg2video @ 0000000000B68A40] 00 motion_type at 25 8
[mpeg2video @ 0000000000B68A40] Warning MVs not available
[mpeg2video @ 0000000000B68A40] concealing 90 DC, 90 AC, 90 MV errors in B frame

but I can't detect all those failing frames from my code: neither av_read_frame nor avcodec_decode_video2 functions ever return error codes! What am I doing wrong?

Nextor
  • 95
  • 1
  • 1
  • 7
  • Could it be that you are getting these outputs *before* these functions are called? – Eugene Sh. Mar 08 '16 at 16:10
  • @EugeneSh. Nope, I have traced the code and the errors are output on the error standard stream at the moment of calling those functions, specially **avcodec_decode_video2** and occasionally **av_read_frame**. But none of them return negative values indicating error though... – Nextor Mar 09 '16 at 08:31

0 Answers0