[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