[Libav-user] timestamp error

Florin Bratu killerappzz at gmail.com
Thu Jun 14 20:56:39 CEST 2012


Hello,

I have a problem while using the ffmpeg development libraries. What I want
to achieve is to create a video file from a sequence of images. The effect
should be as similar as the one of issuing the ffmpeg command:
$ ffmpeg -i test_%d.jpg -vcodec h263 -s 352x288 out.mp4
However, I need to achieve this programatically as I need to integrate it
in a bigger application.

As a start I thought of a simple approach: I read each image as an AVFrame
and I encode it in the final video. I've quickly hacked an implementation
of this approach, you can find the source code at the end of the email.

However, when I compile and run it, I get the following error:
[h263 @ 0x8058020] Error, Invalid timestamp=0, last=0

I get this error for each AVFrame I try to encode, starting with the second
one, the first one is(or seems to be) correctly encoded.

What can I do to overcome this issue? While searching through ffmpeg source
code I found out that this error is related to PTS, so I tried a quick fix
of setting it like this:
  picture->pts = i;

but unfortunately I still get the same error! seems like the new pts value
is not even taken into account!

Do you have any ideas how to overcome this error? Am I doing something
wrong?

I am new to ffmpeg development and to the libav-users mailing list, so
please pardon my hackish way of using ffmpeg. And feel free to point me any
other better ways I could use ffmpeg(apart from the obvious refactoring
this code could benefit from) hopefully in time I will arrive to cleanly
master its power.

Best regards,
Florin.

<code>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

#include <stdio.h>

#define W_VIDEO 320
#define H_VIDEO 240

AVFrame* OpenImage(const char* imageFileName)
{
    AVFormatContext *pFormatCtx;

    int ret = av_open_input_file(&pFormatCtx, imageFileName, NULL, 0, NULL);
    if(ret!=0)
    {
        printf("Can't open image file '%s': code %d, %s\n",
            imageFileName, ret, strerror(AVERROR(ret)));
        return NULL;
    }

    dump_format(pFormatCtx, 0, imageFileName, 0);

    AVCodecContext *pCodecCtx;

    pCodecCtx = pFormatCtx->streams[0]->codec;
    pCodecCtx->width = W_VIDEO;
    pCodecCtx->height = H_VIDEO;
    pCodecCtx->pix_fmt = PIX_FMT_YUV420P;

    // Find the decoder for the video stream
    AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if (!pCodec)
    {
        printf("Codec not found\n");
        return NULL;
    }

    // Open codec
    if(avcodec_open(pCodecCtx, pCodec)<0)
    {
        printf("Could not open codec\n");
        return NULL;
    }

    //
    AVFrame *pFrame;

    pFrame = avcodec_alloc_frame();

    if (!pFrame)
    {
        printf("Can't allocate memory for AVFrame\n");
        return NULL;
    }

    int frameFinished;
    int numBytes;

    // Determine required buffer size and allocate buffer
    numBytes = avpicture_get_size(PIX_FMT_YUVJ420P, pCodecCtx->width,
pCodecCtx->height);
    uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));

    avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUVJ420P,
pCodecCtx->width, pCodecCtx->height);

    // Read frame

    AVPacket packet;

    int framesNumber = 0;
    while (av_read_frame(pFormatCtx, &packet) >= 0)
    {
        if(packet.stream_index != 0)
            continue;

        ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
&packet);
        if (ret > 0)
        {
            printf("Frame is decoded, size %d\n", ret);
            pFrame->quality = 4;
        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
            return pFrame;
        }
        else
            printf("Error [%d] while decoding frame: %s\n", ret,
strerror(AVERROR(ret)));
    }

  // close codec
  avcodec_close(pCodecCtx);

  // Close the video file
  av_close_input_file(pFormatCtx);

    return pFrame;
}


int main(int argc, char *argv[])
    {
     AVCodec *codec;
     AVCodecContext *c= NULL;
     int i, out_size, size, x, y, outbuf_size;
     FILE *f;
     uint8_t *outbuf;
     char* vidFileName = argv[1];

     printf("Video encoding\n");

/* must be called before using avcodec lib */
  avcodec_init();

  /* register all the codecs */
  avcodec_register_all();
  av_register_all();

     /* find the mpeg1 video encoder */
     codec = avcodec_find_encoder(CODEC_ID_H263);
     if (!codec) {
         fprintf(stderr, "codec not found\n");
         exit(1);
     }

     c= avcodec_alloc_context();

     /* put sample parameters */
     c->bit_rate = 400000;
     /* resolution must be a multiple of two */
     c->width = 352;
     c->height = 288;
     /* frames per second */
     c->time_base= (AVRational){1,25};
     c->gop_size = 10; /* emit one intra frame every ten frames */
     c->pix_fmt = PIX_FMT_YUV420P;

     /* open it */
     if (avcodec_open(c, codec) < 0) {
         fprintf(stderr, "could not open codec\n");
         exit(1);
     }

     f = fopen(vidFileName, "wb");
     if (!f) {
         fprintf(stderr, "could not open %s\n", vidFileName);
         exit(1);
     }

     /* alloc image and output buffer */
     outbuf_size = 100000;
     outbuf = malloc(outbuf_size);
     AVFrame *picture;

     for(i=2;i<argc;i++) {
         fflush(stdout);
     printf("encoding file %s \n", argv[i]);
         /* load the image to be encoded*/
     picture = OpenImage(argv[i]);
//     The above line was my initial attempt to fix, but to no avail
//     picture->pts = i;

         /* encode the image */
         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
         printf("encoding frame %3d (size=%5d)\n", i, out_size);
         fwrite(outbuf, 1, out_size, f);
     }

     /* get the delayed frames */
     for(; out_size; i++) {
         fflush(stdout);

         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
         printf("write frame %3d (size=%5d)\n", i, out_size);
         fwrite(outbuf, 1, out_size, f);
     }

     /* add sequence end code to have a real mpeg file */
     outbuf[0] = 0x00;
     outbuf[1] = 0x00;
     outbuf[2] = 0x01;
     outbuf[3] = 0xb7;
     fwrite(outbuf, 1, 4, f);
     fclose(f);
     free(outbuf);

     avcodec_close(c);
     av_free(c);
     av_free(picture);
     printf("\n");
    }
</code>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120614/dedfc742/attachment.html>


More information about the Libav-user mailing list