user1914692
user1914692

Reputation: 3073

Why frame->pts increases by 20, rather than by 1?

Following the exmaples of ffmpeg: decoding_encoding.c and filtering_video.c, I process one video file taken by iPhone. The video file: .mov, video dimensions; 480x272, video Codec: H.264/AVC, 30 frames per second, bitrate: 605 kbps.

I first extract each frame, which is YUV. I convert YUV to RGB24, and process the RGB24, then write the RGB24 to a .ppm file. It shows the .ppm file is correct.

Then I plan to encode processed RGB24 frames to a video file. Since MPEG does not support RGB24 picture format, I used AV_CODEC_ID_HUFFYUV. But the output video file (showing 18.5 MB) does not play. Movie Player on Ubuntu claims an error: Could not determine type of stream. I also tried it on VCL. It simply does not work, without any error information.

My second questions is: For each extracted fram from the input video file, I get its pts as follows according to filtering_video.c:

frame->pts = av_frame_get_best_effort_timestamp(frame);

I print out each frame's pts, and find that it increases by 20, like below:

pFrameRGB_count: 0,  frame->pts: 0
pFrameRGB_count: 1,  frame->pts: 20
pFrameRGB_count: 2,  frame->pts: 40
pFrameRGB_count: 3,  frame->pts: 60

Where frame is the extracted frame from the input video, and pFrameRGB_count is the count for processed frame in RGB24 form.

Why are they wrong?

Upvotes: 7

Views: 3721

Answers (3)

user1914692
user1914692

Reputation: 3073

I think I find the answer. Due to lack of detailed documentation of ffmpeg, users might be mislead. I find that, to get correct pts, one should always use: video_st->time_base NOT video_st->codec->time_base

(a) Absolute time of a frame:

packet->dts * (1/video_st->time_base.den)

(b) Absolute time between the frame and its next frame:

frame->repeat_pict * (1/video_st->time_base.den)

Upvotes: 0

user1914692
user1914692

Reputation: 3073

I debug to get codec context of the input video file, dec_ctx->time_base.den = 1200; I know the fps, 30, by right-click the input video file to check its properties (Ubuntu 12.04) So it seems the frame duration should be 1200/30 = 40 base units. But it is 20 by using frame->pts = av_frame_get_best_effort_timestamp(frame);

the read packet of the input video has the duration = 20.

I found dec_ctx->ticks_per_frame = 2. I guess ticks_per_frame makes 40 to 20. Maybe there is some inner formula, like: frame duration in base unit = frame duration x ticks_per_frame (but it seems it is different from what is said in the ffmpeg document, such as time_base is equal to 1/frame rate.)

Upvotes: 0

Tuxdude
Tuxdude

Reputation: 49563

H.264 videos use a 90 kHz clock for encoding timestamps. Since your video is 30 fps, the PTS delta between 2 successive frames should be 3000 instead of 20.

A value of 20 indicates one or both of the following:

  • Your encoding clock (i.e. sampling rate) is configured incorrectly (to 600 Hz) for the given frame rate of 30 fps

  • Your frames per second is configured incorrectly (to 4500fps).

The general formula to calculate PTS delta is:

PTS delta = (1/fps) * Encoder sampling rate

Upvotes: 7

Related Questions