[Libav-user] Example for recompressing a video?

Christian Brümmer christian.bruemmer at gmx.de
Fri Jun 1 11:57:38 CEST 2012


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
> Libav-user at ffmpeg.org
> 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.


More information about the Libav-user mailing list