[Libav-user] timestamp error

Влад Гапчич gavlig at gmail.com
Sat Jun 23 20:01:54 CEST 2012


Hello!

I can't find an error in your code for the first look, but you can take my
code(which is slighlty modified code from an example :)), where i do the
same thing and it works http://www.pasteall.org/33175/cpp
If that will cause segfault, then you're doing something wrong before
getting to this part :)

Hope that help!

Best regards,
Vlad

2012/6/23 Florin Bratu <killerappzz at gmail.com>

> Hello,
>
> Still struggling with this one. I've changed a bit the approach; what I've
> noticed is that the AVFrame's created in the api-example.c (with random
> generated content) are well encoded. So my approach now is to create
> AVFrames just like in the api example the fill them in with the information
> from the source JPEGs(and of course with format conversion), I am using
> sws_scale for this. But now I am getting segmentation fault when calling
> sws_scale. I've well checked my pointers they have valid values before
> entering the sws_scale call. But I'm not sure I am calling it as I should:
>
> void copyFrame(AVCodecContext *destContext, AVFrame* dest,
>         AVCodecContext *srcContext, AVFrame* source) {
>     static struct SwsContext *swsContext;
>
>     swsContext = sws_getContext(srcContext->width,
> srcContext->height,PIX_FMT_YUVJ420P,
>             destContext->width, destContext->height, PIX_FMT_YUV420P,
>             SWS_FAST_BILINEAR, NULL, NULL, NULL);
>
>     sws_scale(swsContext, source->data, source->linesize, 0,
> srcContext->height, dest->data, dest->linesize);
>
>     sws_freeContext(swsContext);
> }
>
> destContext is the context used for encoding; dest is the AVFrame to be
> encoded.
> srcContext is the context used for decoding the JPEGs; source is the
> AVFrame the result of reading one JPG file.
>
> I attach the new version for source code.
>
> Thanks in advance for any helpful info you might have.
>
> Best regards,
> Florin.
>
> On Thu, Jun 14, 2012 at 8:56 PM, Florin Bratu <killerappzz at gmail.com>wrote:
>
>> 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>
>>
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120623/43c1797f/attachment.html>


More information about the Libav-user mailing list