Source:http://www.xuebuyuan.com/1466771.html
FFmpeg main logic for processing audio timestampsDecember 09, 2013 ⁄ general ⁄ a total of 2226 characters ⁄ font size small medium big ⁄ comments off
The main logic for ffmpeg processing audio timestamps is:
1. Demux Read Avpacket. Take the input FLV example, Timebase is 1/1000, the first audio packet may be 46, which represents 0.046 seconds.
2. Decoder decoding Avpacket to avframe,frame pts as nopts, need to be set up, or there will be problems later. The main call is: Av_rescale_delta:
Avrational IN_TB = DECODED_FRAME_TB; Avrational FS_TB = (avrational) {1, ist->codec->sample_rate};int duration = decoded_frame->nb_samples; Avrational OUT_TB = (avrational) {1, ist->codec->sample_rate};d ecoded_frame->pts = Av_rescale_delta (IN_TB, Decoded_frame->pts, FS_TB, Duration, &rescale_last_pts, OUT_TB);
Corresponds to the following logic:
Init the rescale_last_pts, set to 0 for the first decoded_frame->pts is 0if (rescale_last_pts = = Av_nopts_value) {
rescale_last_pts = Av_rescale_q (decoded_frame->pts, IN_TB, FS_TB) + duration;} The FS_TB equals to OUT_TB, so decoded_frame->pts equals to rescale_last_ptsdecoded_frame->pts = Av_rescale_q (res Cale_last_pts, FS_TB, OUT_TB);; Rescale_last_pts + = Duration;
It can also be simplified to:
/** * For audio encoding, we simplify the rescale algorithm to following. * /if (rescale_last_pts = = av_nopts_value) { rescale_last_pts = 0; } decoded_frame->pts = rescale_last_pts; Rescale_last_pts + = decoded_frame->nb_samples; Duration
In fact, the nb_samples is long, let pts for this sum, the cumulative samples can be. Because the TB is set to Sample_rate by default, the number of samples is PTS.
3. Filter filtering, actually no processing.
Correct the pts int64_t filtered_frame_pts = av_nopts_value; if (picref->pts! = av_nopts_value) { //Rescale The TB, actual the Ofilter TB equals to OST TB, //So this step Canbe ignored and we always set Start_time to 0. filtered_frame_pts = Av_rescale_q (picref->pts, Ofilter->inputs[0]->time_base, ost->codec->time_base ) -Av_rescale_q (Start_time, Av_time_base_q, ost->codec->time_base); } Convert to Frame avfilter_copy_buf_props (filtered_frame, picref); printf ("Filter-picref_pts=%" PRId64 ", frame_pts=%" PRId64 ", filtered_pts=%" PRId64 "\ n", picref->pts, Filtered_frame->pts, filtered_frame_pts); filtered_frame->pts = filtered_frame_pts;
4. Encoder encoding, mainly to generate DTS.
5. Before muxer output, you need to do the processing. For example, to output rtmp streams, to turn TB into 1/1000,flv TB, which is the millisecond unit.
In addition, the timestamp starts from zero.
Correct the output, enforce start at 0. static int64_t starttime =-1; #if 1 if (StartTime < 0) { StartTime = (Pkt.dts < pkt.pts)? pkt.dts:pkt.pts; } Pkt.dts-= StartTime; Pkt.pts-= StartTime; #endif # if 1 //rescale audio ts to avrational (1, +) for FLV format. Avrational FLV_TB = (avrational) {1, +}; Pkt.dts = Av_rescale_q (Pkt.dts, Ost->codec->time_base, FLV_TB); pkt.pts = Av_rescale_q (pkt.pts, Ost->codec->time_base, FLV_TB); #endif
6. Last step, write:
ret = Av_interleaved_write_frame (OC, &PKT);
It's OK.
FFmpeg main logic for processing audio timestamps