/* 解析TS包 */ int handle_packet(MpegTSContext *ts, const uint8_t *packet) { ... pid = AV_RB16(packet + 1) & 0x1fff; //SYNTAX: PID is_start = packet[1] & 0x40; //SYNTAX: payload_unit_start_indicator ... /* continuity check (currently not used) */ cc = (packet[3] & 0xf); //SYNTAX: continuity_counter expected_cc = (packet[3] & 0x10) ? (tss->last_cc + 1) & 0x0f : tss->last_cc; cc_ok = (tss->last_cc < 0) || (expected_cc == cc); tss->last_cc = cc; /* skip adaptation field */ afc = (packet[3] >> 4) & 3; //SYNTAX: adaptation_field_control p = packet + 4; if (afc == 0) /* reserved value */ return 0; if (afc == 2) /* adaptation field only */ return 0; if (afc == 3) { /* skip adapation field */ p += p[0] + 1; } ... }
1. PTS置零代码分析:
main(){ |-- ... |-- parse_options(){ |-- … |-- opt_input_file(){ |-- … av_find_stream_info(ic); timestamp = start_time; timestamp += ic->start_time; … input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp); … } … } |-- transcode(){ |-- … for( ; received_sigterm == 0; ) { AVPacket pkt; … ret = av_read_frame(is, &pkt); … pkt.dts += av_rescale_q(input_files_ts_offset[nb_input_files], AV_TIME_BASE_Q, ist->st->time_base); } } |
st->time_base.den = 1000 //时钟基, 1 second = 1000 ms frame_size = 1024 //一帧 = 1024个采样点 st->pts = {val=0, num=22050, den=44100}; // 音频采样率 av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size); /* f.val = f.val + ((f.num + incr) / f->den) */ static void av_frac_add(AVFrac *f, int64_t incr) { int64_t num, den; num = f->num + incr; den = f->den; if (num < 0) { f->val += num / den; num = num % den; if (num < 0) { num += den; f->val--; } } else if (num >= den) { f->val += num / den; num = num % den; } f->num = num; } st->pts = {val=23, // 计算后的时间戳 num=31750, // 上一帧未播放完的余值 den=44100}
累加上每帧的增量(1000ms/25frames = 40ms/frame)
time_base.den = 1000 time_base.num = 1 st->pts = {val=0, num=12, den=25}, av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num); st->pts = {val=40, num=12, den=25}
int mpegts_push_data();
pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);
分析:
int mpegts_push_data(MpegTSFilter *filter, const uint8_t *buf, int buf_size, int is_start, int64_t pos) { if (pes->header[0] == 0x00 && //SYNTAX: packet_start_code_prefix pes->header[1] == 0x00 && pes->header[2] == 0x01) { code = pes->header[3] | 0x100; //SYNTAX: stream_id pes->total_size = AV_RB16(pes->header + 4); //SYNTAX: PES_packet_length /* 分配ES的空间 */ pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); if (code != 0x1bc && code != 0x1bf && /* program_stream_map, private_stream_2 */ code != 0x1f0 && code != 0x1f1 && /* ECM, EMM */ code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */ code != 0x1f8) /* ITU-T Rec.H.222.1 type E stream { flags = pes->header[7]; //SYNTAX: PTS_DTS_flags if((flags & 0xc0) == ...) { pes->pts = ff_parse_pes_pts(r); //SYNTAX: PTS[32...0] r += 5; pes->dts = ff_parse_pes_pts(r); //SYNTAX: DTS[32...0] r += 5; } /* 取出PES的负载数据组成TS流 */ memcpy(pes->buffer+pes->data_index, p, buf_size); } } }