Dear:
try:
if (frameFinished)
{
// Encode the video frame (always returns -1 the second time this
line is executed)
int out_size =avcodec_encode_video(pOutputVideoCodecCtx,
pOutputBuffer, buffer_size,pInputFrame);
//---------------------------------------------------------------------------
//add the following hack, by [email protected]
pInputFrame->pts++;
//---------------------------------------------------------------------------
}
On Fri, Jan 16, 2009 at 5:06 AM, Wayne Allen <[email protected]> wrote:
> I have written a routine that converts a file from one file format to
> another - the code is very strongly based on output_example.c. A
> problem occurs the second time I attempt to encode a buffer that has
> been read and decoded from the input file. avcodec_encode_video always
> returns -1. This always happen on the second call - regardless of the
> input file. Can someone please explain what I am doing wrong?
>
> The routine code is as follows:
>
> int frameFinished;
> AVFormatContext* pInputFormatCtx;
> AVFrame* pInputFrame;
> AVPacket inputPacket;
> AVCodec* pInputVideoCodec;
> AVCodecContext* pInputVideoCodecCtx;
> int inputVideoStreamPos = -1;
> uint8_t* pOutputBuffer;
> AVOutputFormat* pOutputFormat;
> AVFormatContext* pOutputFormatCtx;
> AVCodec* pOutputVideoCodec;
> AVCodecContext* pOutputVideoCodecCtx;
> AVStream* pOutputVideoStream;
>
> av_register_all();
>
> // Open the input file
>
> if (av_open_input_file(&pInputFormatCtx, pInput, NULL, 0,
> NULL) != 0) return FileConverterEngine::UnableToOpenInputFile;
> try
> {
> // Get the stream information
> if (av_find_stream_info(pInputFormatCtx) < 0) return
> FileConverterEngine::UnableToRetrieveStreamInformation;
> for (unsigned int i=0; i < pInputFormatCtx->nb_streams; i++)
> {
> if (pInputFormatCtx->streams[i]->codec->codec_type ==
> CODEC_TYPE_VIDEO)
> {
> inputVideoStreamPos = i;
> break;
> }
> }
> if (inputVideoStreamPos == -1) return
> FileConverterEngine::MissingVideoStream;
>
> // Get the codec context for the stream
> pInputVideoCodecCtx =
> pInputFormatCtx->streams[inputVideoStreamPos]->codec;
>
> // Get the codec to decode the video
> pInputVideoCodec =
> avcodec_find_decoder(pInputVideoCodecCtx->codec_id);
> if (pInputVideoCodec == NULL) return
> FileConverterEngine::UnableToFindVideoDecoder;
>
> // Open the codec
>
> if (avcodec_open(pInputVideoCodecCtx, pInputVideoCodec) <
> 0) return FileConverterEngine::UnableToOpenVideoDecoder;
> try
> {
> // What format is the output file?
> if ((pOutputFormat = guess_format(NULL, pOutput, NULL)) ==
> NULL)
> {
>
> if ((pOutputFormat = guess_format("mpeg", NULL,
> NULL)) == NULL) return FileConverterEngine::CannotGuessOutputFormat;
> }
>
> // Allocate the output file context
>
> if ((pOutputFormatCtx = av_alloc_format_context()) ==
> NULL) return FileConverterEngine::CannotAllocateOutputFileContext;
> try
> {
> // Associate it with the output context
> pOutputFormatCtx->oformat = pOutputFormat;
>
> // Save the filename
> _snprintf_s(pOutputFormatCtx->filename,
> sizeof(pOutputFormatCtx->filename), _TRUNCATE, "%s", pOutput);
>
> // Add the video stream to the output file
> if ((pOutputVideoStream = AddVideoStream(pOutputFormatCtx,
> pOutputFormat->video_codec)) == NULL)
> return
> FileConverterEngine::CannotAddVideoStreamToOutputFile;
>
> // Set-up the output video stream
> pOutputVideoCodecCtx = pOutputVideoStream->codec;
> pOutputVideoCodecCtx->width = pInputVideoCodecCtx->width;
> pOutputVideoCodecCtx->height = pInputVideoCodecCtx->height;
> pOutputVideoCodecCtx->pix_fmt =
> pInputVideoCodecCtx->pix_fmt;
>
> // Set the output parameters
>
> if (av_set_parameters(pOutputFormatCtx, NULL) < 0)
> return FileConverterEngine::UnableToSetOutputParameters;
>
> // Get the output video codec
> if (!(pOutputVideoCodec =
> avcodec_find_encoder(pOutputVideoStream->codec->codec_id)))
> return FileConverterEngine::UnableToFindVideoEncoder;
>
> // Open the output video codec
>
> if (avcodec_open(pOutputVideoCodecCtx,
> pOutputVideoCodec) < 0) return
> FileConverterEngine::UnableToOpenVideoEncoder;
> try
> {
> // Open the output file (if needed)
> if (!(pOutputFormat->flags & AVFMT_NOFILE))
> {
>
> if (url_fopen(&pOutputFormatCtx->pb,
> pOutput, URL_WRONLY) < 0) return
> FileConverterEngine::UnableToOpenOutputFile;
> }
> try
> {
> // Create the buffer to hold the encoded frame
>
> int buffer_size =
> avpicture_get_size(pOutputVideoCodecCtx->pix_fmt,
> pOutputVideoCodecCtx->width, pOutputVideoCodecCtx->height);
> pOutputBuffer = (uint8_t*)av_malloc(buffer_size);
>
> // Write the headers to the output file
> av_write_header(pOutputFormatCtx);
>
> // Allocate the input frame
> pInputFrame = avcodec_alloc_frame();
> try
> {
> while (av_read_frame(pInputFormatCtx,
> &inputPacket) >= 0)
> {
> if (inputPacket.stream_index ==
> inputVideoStreamPos)
> {
> // Decode the video frame
>
> if
> (avcodec_decode_video(pInputVideoCodecCtx, pInputFrame,
> &frameFinished, inputPacket.data, inputPacket.size) < 0)
> return
> FileConverterEngine::UnableToDecodeInputVideoPacket;
>
> if (frameFinished)
> {
>
> // Encode the video frame (always
> returns -1 the second time this line is executed)
>
> int out_size =
> avcodec_encode_video(pOutputVideoCodecCtx, pOutputBuffer, buffer_size,
> pInputFrame);
> }
>
> // Free the packet
> av_free_packet(&inputPacket);
> }
> }
> }
> finally
> {
> av_free(pInputFrame);
> }
>
> // Write the trailer
> av_write_trailer(pOutputFormatCtx);
> }
> finally
> {
> if (!(pOutputFormat->flags & AVFMT_NOFILE))
> {
> url_fclose(pOutputFormatCtx->pb);
> }
> }
> }
> finally
> {
> avcodec_close(pOutputVideoCodecCtx);
> }
> }
> finally
> {
> av_free(pOutputFormatCtx);
> }
> }
> finally
> {
> avcodec_close(pInputVideoCodecCtx);
> }
> }
> finally
> {
> av_close_input_file(pInputFormatCtx);
> }
>
--
--------------------------------
Inspired by http://ppnext.com
Your potential. Our passion.
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user