3

I'm trying to transcode video files into a standard format. This is the main loop I have:

for(frame_count = 0; av_read_frame(input_ctx, &in_packet) >= 0; frame_count++) {


    if(in_packet.stream_index == video_stream_index) {

        decodedPacket = 0;
        rc = avcodec_decode_video2(video_in_codec, inputFrame, &decodedPacket, &in_packet);
        if(decodedPacket) {

            out_frames++;


            rc = sws_scale(sws_ctx, inputFrame->data, inputFrame->linesize, 0, video_out_codec->height, outputFrame->data, outputFrame->linesize);
            if(rc != video_out_codec->height) {
                puts("scaling error");
            }

            outputFrame->pts = (1.0 / 30.0) * 90.0 * video_out_codec->frame_number;

            rc = avcodec_encode_video2(video_out_codec, &out_packet, outputFrame, &encodedPacket);
            if(rc != 0) {
                puts("encoding error");
            }

            if(encodedPacket) {

                if (video_out_stream->codec->coded_frame->key_frame) { // deprecated, what to use instead
                    out_packet.flags |= AV_PKT_FLAG_KEY;
                }

                out_packet.stream_index = 0;

                rc = av_interleaved_write_frame(output_ctx, &out_packet);
                if(rc != 0) {
                    puts("frame write error");
                }

                av_free_packet(&out_packet);
                memset(&out_packet, 0, sizeof(AVPacket));

                packet_count++;
            }


            av_free_packet(&in_packet);

        }

    }
...

When I run this I get strange values for tbr/tbn/tbc reported by ffprobe and the video is a mess.

I've tried adding code as per this answer e.g.

                if (out_packet.pts != AV_NOPTS_VALUE) {
                    out_packet.pts =  av_rescale_q(out_packet.pts, video_out_stream->codec->time_base, video_out_stream->time_base);
                }
                if (out_packet.pts != AV_NOPTS_VALUE) {
                    out_packet.dts = av_rescale_q(out_packet.dts, video_out_stream->codec->time_base, video_out_stream->time_base);
                }

...but then I get errors such as this is the debug output:

[mp4 @ 0x1038aba00] Delay between the first packet and last packet in the muxing queue is 10100000 > 10000000: forcing output

I'm setting the timebase correctly (I think)...

video_out_stream = avformat_new_stream(output_ctx, videoEncoder);
video_out_stream->id = 0;
video_out_stream->time_base.den = 30;
video_out_stream->time_base.num = 1;

video_out_codec = video_out_stream->codec;
avcodec_get_context_defaults3(video_out_codec, videoEncoder);
video_out_codec->codec_id = AV_CODEC_ID_H264;
video_out_codec->bit_rate = 2048;
video_out_codec->width    = 854;
video_out_codec->height   = 480;
video_out_codec->time_base.den = 30;
video_out_codec->time_base.num = 1;
video_out_codec->gop_size = 30;
video_out_codec->pix_fmt = AV_PIX_FMT_YUV420P;

Any thoughts about how I can calculate the correct output frame pts and encoded packet dts/pts? I'm clearly doing something wrong.

Community
  • 1
  • 1
JohnnyD
  • 477
  • 1
  • 4
  • 19
  • I had a (maybe) unrelated issue somedays back when using the CLI tool. I used the `settb` filter but the encode contained PTS values aligned with the timescale inherited from the input video. I had to use [`video_track_timescale`](https://github.com/FFmpeg/FFmpeg/search?utf8=%E2%9C%93&q=video_track_timescale) to the reciprocal of the needed TB to get a good output. – Gyan Jan 15 '16 at 13:37
  • If your TB (1/30) is the exact reciprocal of the framerate (30), then frame number `n` has simply a PTS of `n` – Gyan Jan 15 '16 at 13:47
  • I have found at least a partial solution by looking at what ffmpeg does. It seems to set the output frame dts to the input frame number i.e. outputFrame->pts = frame_count; This at least creates a video of the right duration and the right frame rate although I get a lot of these errors in the debug output "Delay between the first packet and last packet in the muxing queue is 4369066667 > 10000000: forcing output" – JohnnyD Jan 19 '16 at 16:55

0 Answers0