[Libav-user] timestamp error
Florin Bratu
killerappzz at gmail.com
Sat Jun 23 19:01:51 CEST 2012
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>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120623/3cbf07c3/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: timestamp_v2.c
Type: text/x-csrc
Size: 5965 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120623/3cbf07c3/attachment.bin>
More information about the Libav-user
mailing list