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@ffmpeg.org http://ffmpeg.org/mailman/listinfo/libav-user