[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