Am 01.06.2012 01:37, schrieb jettoblack:
Hello,
I'd like to use libavformat to recompress a video file, similar to ffmpeg
standalone but much simpler (fixed codec parameters, etc.).  I've figured
out how to remux (without re-encoding), but I'm not sure on recompressing.

I used the output-example.c as a starting point, but it generates fake
video/audio data in temporal order.  In my case I am demuxing a IPB encoded
video so the frames are decoded out of order.  What is the proper way to
re-encode these in order?  If I simply pass each picture into the encoder in
the order that they come out of the decoder, I get errors like
"non-strictly-monotonic PTS" from the encoder.

Here's my loop, I assume I'm overlooking some major points.

     while (1) {
         av_init_packet(&pkt);
         r = av_read_frame(in,&pkt);
         if (r) {
             if (r == AVERROR_EOF)
                 printf("EOF\n");
             else
                 printf("read error %x\n", r);
             break;
         }
         printf("stream %d, pts %"PRId64", dts %"PRId64"\n",
pkt.stream_index, pkt.pts, pkt.dts);

         if (pkt.stream_index == in_vstream->index) {
             picture = avcodec_alloc_frame();
             assert(picture);
             avcodec_decode_video2(in_vcodec, picture,&got_picture,&pkt);
             if (got_picture) {
                 printf("got picture: pts %"PRId64"\n", pkt.pts);

                 // convert picture to dest format
                 AVFrame *newpicture = avcodec_alloc_frame();
                 avpicture_fill((AVPicture*)newpicture, picbuf,
out_vcodec->pix_fmt, out_vcodec->width, out_vcodec->height);
                 sws_scale(img_convert_ctx, picture->data, picture->linesize,
0, in_vcodec->height, newpicture->data, newpicture->linesize);

                 // write picture
                 int got_packet_ptr = 0;
                 AVPacket newpkt;
                 av_init_packet(&newpkt);
                 r = avcodec_encode_video2(out_vcodec,&newpkt, newpicture,
&got_packet_ptr);
                 assert(!r);
                 if (got_packet_ptr) {
                     printf("got_packet_ptr\n");
                     newpkt.stream_index = out_vstream->index;
                     newpkt.pts = av_rescale_q(out_vcodec->coded_frame->pts,
out_vcodec->time_base, out_vstream->time_base);
                     printf("write newpkt: stream %d, pts %"PRId64", dts
%"PRId64"\n", newpkt.stream_index, newpkt.pts, newpkt.dts);
                     r = av_interleaved_write_frame(out,&newpkt);
                     if (r&&  (r != AVERROR(EINVAL))) {
                         printf("write error %x\n", r);
                     }
                     assert(!r);
                 }
                 av_free_packet(&newpkt);
                 av_free(newpicture);
                 video_frames++;

             }
             av_free(picture);
         }
         else if (pkt.stream_index == in_astream->index) {
             // get audio
             // compress audio
             // write audio

             // write frame
             r = av_interleaved_write_frame(out,&pkt);
             if (r&&  (r != AVERROR(EINVAL))) {
                 printf("write error %x\n", r);
             }
         }

         av_free_packet(&pkt);

     }

This loop chugs along with a bunch of "non-strictly-monotonic PTS" warnings
until it gets to the first time the encoder returns got_packet_ptr = true,
then it segfaults on av_interleaved_write_frame(out,&newpkt);

I'm quite sure I'm doing something wrong, any ideas? :)  Are there any other
better examples out there (other than ffmpeg.c -- too complex) for me to
start with?

Thanks!



--
View this message in context: 
http://libav-users.943685.n4.nabble.com/Example-for-recompressing-a-video-tp4655098.html
Sent from the libav-users mailing list archive at Nabble.com.
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Don't nothing about reordering but you can get rid of the "non-strictly-monotonic PTS" warnings. You have to set the right pts value (and dts if you want to encode audio too) for you AVFrame (newpicture).

This is a codec dependent value in case of h264 its some thing like that:
mPicture->pts = (float) mFrameCount * (1000.0/(float)(mParameters.mFrameRate)) * 90;

So you have to look whats a right pts for your destination video.
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to