[Libav-user] Example for recompressing a video?
jettoblack
jettoblack at gmail.com
Fri Jun 1 01:37:13 CEST 2012
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.
More information about the Libav-user
mailing list