[Libav-user] av_write_frame crashes without error message

Jan drabner drabner at zoobe.com
Thu Sep 22 14:37:26 CEST 2011


Hey there,

Before I start, I should point out that I have almost no expertise in audio
and video codecs, and the same goes for ffmpeg/libav.
Also, I'm not used to mailing lists, so sorry if I'm doing something wrong
related to that. :)

I'm trying to get all frames of an audio file (*.wav) and then save those
frames to a new audio file with the same format (so a more or less copied
file should be the result). This works well.

But now I'm trying to get all video frames of a file (*.mp4) that has both
audio and video content.
The getting seems to work fine without any errors.

But when trying to write the frames I got into a new video file with the
same format - but this time, using video frames only, no audio -
av_write_frame just crashes (always at same the frame interestingly) without
giving any clue why.


Here is the function that reads the frames in:
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//---------------------------------------------------------------------
void
FramesCollection::DecodeVideo(const char* p_filename)
{
    av_log(NULL, AV_LOG_ERROR, "%s","Starting video decoding\n");

    // Get the format context...
    int ret = avformat_open_input(&_videoFormatContext, p_filename, NULL,
NULL);
    if (ret < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "%s","Error opening file '%s'\n",
p_filename);
        exit(-1);
    }
    // ... and fill it with stream info (contains number of frames, etc.)
    av_find_stream_info(_videoFormatContext);

    // Find the audio stream
    AVStream* stream;
    for(int i = 0; i < (int)_videoFormatContext->nb_streams; i++)
    {
        if(_videoFormatContext->streams[i]->codec->codec_type ==
AVMEDIA_TYPE_VIDEO)
        {
            stream = _videoFormatContext->streams[i];
            break;
        }
    }

    // Use stream to set the context
    _videoCodecContext = stream->codec;

    // Find the codec
    _videoCodec = avcodec_find_decoder(_videoCodecContext->codec_id);
    if (!_videoCodec)
    {
        av_log(_videoCodecContext, AV_LOG_ERROR, "%s","codec not found\n");
        exit(-1);
    }
    // Open the codec
    if (avcodec_open(_videoCodecContext, _videoCodec) < 0)
    {
        av_log(_videoCodecContext, AV_LOG_ERROR, "%s","could not open
codec\n");
        exit(-1);
    }

    // Read each frame into a packet
    AVPacket packet;
    av_init_packet(&packet);
    int frameCount = 0;
    while (av_read_frame(_videoFormatContext, &packet) == 0)
    {
        // Save the frame
        AVPacket* tempPacket = new AVPacket(packet);
        _videoPackets.push_back(tempPacket);
    } // END reading each frame
    av_free_packet(&packet);
}


And here is the function that should write the new video:
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//---------------------------------------------------------------------
void
FramesCollection::TestVideoEncode()
{
    // Try writing
    AVFormatContext* outputContext;
    outputContext = avformat_alloc_context();
    outputContext->oformat =
        av_guess_format(NULL, _videoFormatContext->filename, NULL);
    char buffer[512];
    sprintf(buffer, "C:\\test\\outTest.%s", outputContext->oformat->name);
    _snprintf_s(outputContext->filename,
                sizeof(outputContext->filename),
                strlen(buffer),
                "%s", buffer);

    // Add stream
    if (!av_new_stream(outputContext, 0))
    {
        av_log(outputContext, AV_LOG_ERROR, "%s","Error while creating
stream.\n");
        exit(-1);
    }

    // Open Codec
    if (avcodec_open(outputContext->streams[0]->codec, _videoCodec) < 0)
    {
        av_log(outputContext->streams[0]->codec, AV_LOG_ERROR, "%s","Error
while opening codec for context.\n");
        exit(-1);
    }

    // Set time base, dimensions, etc.
    outputContext->streams[0]->codec->time_base =
_videoCodecContext->time_base;
    outputContext->streams[0]->codec->width = _videoCodecContext->width;
    outputContext->streams[0]->codec->height = _videoCodecContext->height;
    // Some container formats want stream headers to be global
    if(outputContext->oformat->flags & AVFMT_GLOBALHEADER)
    {
        outputContext->streams[0]->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    // Open output file
    if (url_fopen(&outputContext->pb, outputContext->filename, URL_WRONLY) <
0)
    {
        av_log(outputContext,
                AV_LOG_ERROR, "%s","Could not open '%s'\n",
outputContext->filename);
        exit(-1);
    }

    // Write Header
    if (avformat_write_header(outputContext, NULL) < 0)
    {
        av_log(outputContext, AV_LOG_ERROR, "%s","Error while writing
header.\n");
        exit(-1);
    }

    // Write each packet
    for (int i = 0; i < (int)_videoPackets.size(); i++)
    {
        if (av_write_frame(outputContext, _videoPackets[i]) < 0)
        {
            av_log(outputContext, AV_LOG_ERROR, "%s","Error while writing
frame.\n");
            exit(-1);
        }
    }

    // Write trailer
    if (av_write_trailer(outputContext) < 0)
    {
        av_log(outputContext, AV_LOG_ERROR, "%s","Error while writing
trailer.\n");
        exit(-1);
    }

    // Close stuff
    avcodec_close(outputContext->streams[0]->codec);
    url_fclose(outputContext->pb);
    avformat_free_context(outputContext);
}


As said, it always crashes at the same packet when trying to write them.
Maybe I should also point out that the reading and writing of the audio
frames is done in more or less identical functions.

I have no clue... please help! :(
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20110922/62176098/attachment.html>


More information about the Libav-user mailing list