Hi,

I'm just getting started using the ffmpeg libraries and am seeing a problem when demuxing/decoding an FLV file. I'm attaching the sample program which is basically just Martin Böhme's overview. My code was originally somewhat more complicated so I've reverted to the attached code. I understand that the code is not clean but it serves to show what I'm seeing. If I run the code against an .flv file on the local file system, the code runs fine to completion. If I access the same file placed on a web server, I receive a series of "skipping flv packet" errors toward the end of the decode. These seem to continue on indefinitely. Here are the two outputs, from a good run (with a local file) and an problem run pulling the file from a web server (The file is still available on the server if anyone is interested).

c:> using_libavcoded.exe  c:\temp\test.flv
reading c:\temp\test.flv
Input #0, flv, from 'c:\temp\test.flv':
 Duration: 00:01:30.13, start: 0.000000, bitrate: 48 kb/s
   Stream #0.0: Video: flv, yuv420p, 320x240, 15.00 tb(r)
   Stream #0.1: Audio: mp3, 44100 Hz, mono, 48 kb/s
[flv @ 00B43670]warning: first frame is no keyframe
...........................................................................................
...........................................................................................
...........................................................................................
...................................................done

C:>using_libavcoded.exe http://www.oberholtzer.net/test.flv
reading http://www.oberholtzer.net/test.flv
Input #0, flv, from 'http://www.oberholtzer.net/test.flv':
 Duration: 00:01:30.13, start: 0.000000, bitrate: 48 kb/s
   Stream #0.0: Video: flv, yuv420p, 320x240, 15.00 tb(r)
   Stream #0.1: Audio: mp3, 44100 Hz, mono, 48 kb/s
[flv @ 00B43670]warning: first frame is no keyframe
...............................................................................................
...............................................................................................
...............................................................................................
...................................................[flv @ 00B29C6C]skipping flv packet: type 68, size 6386789, flags 0
[flv @ 00B29C6C]skipping flv packet: type 68, size 6386789, flags 0
[flv @ 00B29C6C]skipping flv packet: type 68, size 6386789, flags 0
[flv @ 00B29C6C]skipping flv packet: type 68, size 6386789, flags 0
[flv @ 00B29C6C]skipping flv packet: type 68, size 6386789, flags 0

These messages continue on. Am I doing something wrong that is causing these messages?

Thanks for you help,
Brian

// using_libavcoded.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

extern "C"
{
#include "libavformat\avformat.h"
}

bool GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, 
    int videoStream, AVFrame *pFrame)
{
    static AVPacket packet;
    static int      bytesRemaining=0;
    static uint8_t  *rawData;
    static bool     fFirstTime=true;
    int             bytesDecoded;
    int             frameFinished;

    // First time we're called, set packet.data to NULL to indicate it
    // doesn't have to be freed
    if(fFirstTime)
    {
        fFirstTime=false;
        packet.data=NULL;
    }

    // Decode packets until we have decoded a complete frame
    while(true)
    {
        // Work on the current packet until we have decoded all of it
        while(bytesRemaining > 0)
        {
            // Decode the next chunk of data
            bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
                &frameFinished, rawData, bytesRemaining);

            // Was there an error?
            if(bytesDecoded < 0)
            {
                fprintf(stderr, "Error while decoding frame\n");
                return false;
            }

            bytesRemaining-=bytesDecoded;
            rawData+=bytesDecoded;

            // Did we finish the current frame? Then we can return
            if(frameFinished)
                return true;
        }

        // Read the next packet, skipping all packets that aren't for this
        // stream
        do
        {
            // Free old packet
            if(packet.data!=NULL)
                av_free_packet(&packet);

            // Read new packet
            if(av_read_packet(pFormatCtx, &packet)<0)
                goto loop_exit;
        } while(packet.stream_index!=videoStream);

        bytesRemaining=packet.size;
        rawData=packet.data;
    }

loop_exit:

    // Decode the rest of the last frame
    bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, 
        rawData, bytesRemaining);

    // Free last packet
    if(packet.data!=NULL)
        av_free_packet(&packet);

    return frameFinished!=0;
}

int _tmain(int argc, char* argv[])
{
        av_register_all();

        AVFormatContext *pFormatCtx;
        const char      *filename=argv[1];
        printf("reading %s\n", filename );

        // Open video file
        if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)
                return -1; // Couldn't open file

        // Retrieve stream information
        if(av_find_stream_info(pFormatCtx)<0)
                -1; // Couldn't find stream information

        dump_format(pFormatCtx, 0, filename, false);

        unsigned int            i, videoStream;
        AVCodecContext *pCodecCtx;

        // Find the first video stream
        videoStream=-1;
        for(i=0; i<pFormatCtx->nb_streams; i++)
                if(pFormatCtx->streams[i]->codec->codec_type == 
CODEC_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;


        AVCodec *pCodec;

        // Find the decoder for the video stream
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
        if(pCodec==NULL)
                return -1;      // 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 -1; // Could not open codec

        AVFrame *pFrame;

        pFrame=avcodec_alloc_frame();

        while(GetNextFrame(pFormatCtx, pCodecCtx, videoStream, pFrame))
        {
                printf(".");
                // doing nothing with the image
        }

        printf("done\n");
}

_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to