FFMPEG PCR PID修改以及插入间隔计算

用FFMPEG输出MPEGTS格式时,发现视频和PCR的PID总是一样。

查看源码如下:

 

  /* update PCR pid by using the first video stream */
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
            service->pcr_pid == 0x1fff) {
            service->pcr_pid = ts_st->pid;
            pcr_st           = st;
        }

/* if no video stream, use the first stream as PCR */
    if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
        pcr_st           = s->streams[0];
        ts_st            = pcr_st->priv_data;
        service->pcr_pid = ts_st->pid;
    } else

也就是说PCR PID总是会和VIDEO PID一样。

解决办法:修改源码,在现在源码写PCR的时候,替换成自己的PCR写入函数。


-------------------------------- 华丽的分割线 --------------------------------------

关于PCR插入间隔的计算:

由复用总码率,计算出PCR需要间隔多少包插入一次

#define PCR_RETRANS_TIME 20

 { "pcr_period", "PCR retransmission time",
      offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT,
      { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },

  if (ts->mux_rate > 1) {
        service->pcr_packet_period = (ts->mux_rate * ts->pcr_period) /
                                     (TS_PACKET_SIZE * 8 * 1000);
        ts->sdt_packet_period      = (ts->mux_rate * SDT_RETRANS_TIME) /
                                     (TS_PACKET_SIZE * 8 * 1000);
        ts->pat_packet_period      = (ts->mux_rate * PAT_RETRANS_TIME) /
                                     (TS_PACKET_SIZE * 8 * 1000);

 // output a PCR as soon as possible
    service->pcr_packet_count = service->pcr_packet_period;

在写PES时,根据这个值来写入PES:
 write_pcr = 0;
        if (ts_st->pid == ts_st->service->pcr_pid) {
            if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames
                ts_st->service->pcr_packet_count++;
            if (ts_st->service->pcr_packet_count >=
                ts_st->service->pcr_packet_period) {
                ts_st->service->pcr_packet_count = 0;
                write_pcr = 1;
            }
        }


。。。 。。。
 if (write_pcr) {
            set_af_flag(buf, 0x10);
            q = get_ts_payload_start(buf);
            // add 11, pcr references the last byte of program clock reference base
            if (ts->mux_rate > 1)
                pcr = get_pcr(ts, s->pb);
            else
                pcr = (dts - delay) * 300;
            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
                av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
            extend_af(buf, write_pcr_bits(q, pcr));
            q = get_ts_payload_start(buf);
        }



你可能感兴趣的:(FFMPEG)