]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mpegtsenc.c
Add support for mp3 over RTP in rtpdec.c
[ffmpeg] / libavformat / mpegtsenc.c
index 0d6436eb18bce476808e99a5067f54b6e52e1102..a8d5d38129a7be399453bd784d1e013b791aabab 100644 (file)
@@ -44,7 +44,7 @@ typedef struct MpegTSService {
     char *provider_name;
     int pcr_pid;
     int pcr_packet_count;
-    int pcr_packet_freq;
+    int pcr_packet_period;
 } MpegTSService;
 
 typedef struct MpegTSWrite {
@@ -52,9 +52,9 @@ typedef struct MpegTSWrite {
     MpegTSSection sdt; /* MPEG2 sdt table context */
     MpegTSService **services;
     int sdt_packet_count;
-    int sdt_packet_freq;
+    int sdt_packet_period;
     int pat_packet_count;
-    int pat_packet_freq;
+    int pat_packet_period;
     int nb_services;
     int onid;
     int tsid;
@@ -426,6 +426,20 @@ static int mpegts_write_header(AVFormatContext *s)
             service->pcr_pid == 0x1fff)
             service->pcr_pid = ts_st->pid;
         total_bit_rate += st->codec->bit_rate;
+        /* PES header size */
+        if (st->codec->codec_type == CODEC_TYPE_VIDEO ||
+            st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
+            /* 1 PES per frame
+             * 19 bytes of PES header
+             * on average a half TS-packet (184/2) of padding-overhead every PES */
+            total_bit_rate += (19 + 184/2)*8 / av_q2d(st->codec->time_base);
+        } else {
+            /* 1 PES per DEFAULT_PES_PAYLOAD_SIZE bytes of audio data
+             * 14 bytes of PES header
+             * on average a half TS-packet (184/2) of padding-overhead every PES */
+            total_bit_rate += (14 + 184/2) *
+                st->codec->bit_rate / DEFAULT_PES_PAYLOAD_SIZE;
+        }
     }
 
     /* if no video stream, use the first stream as PCR */
@@ -436,11 +450,11 @@ static int mpegts_write_header(AVFormatContext *s)
 
     if (total_bit_rate <= 8 * 1024)
         total_bit_rate = 8 * 1024;
-    service->pcr_packet_freq = (total_bit_rate * PCR_RETRANS_TIME) /
+    service->pcr_packet_period = (total_bit_rate * PCR_RETRANS_TIME) /
         (TS_PACKET_SIZE * 8 * 1000);
-    ts->sdt_packet_freq = (total_bit_rate * SDT_RETRANS_TIME) /
+    ts->sdt_packet_period = (total_bit_rate * SDT_RETRANS_TIME) /
         (TS_PACKET_SIZE * 8 * 1000);
-    ts->pat_packet_freq = (total_bit_rate * PAT_RETRANS_TIME) /
+    ts->pat_packet_period = (total_bit_rate * PAT_RETRANS_TIME) /
         (TS_PACKET_SIZE * 8 * 1000);
 
     ts->mux_rate = 1; // avoid div by 0
@@ -458,14 +472,13 @@ static int mpegts_write_header(AVFormatContext *s)
     pat_pmt_size = url_ftell(s->pb) - pos;
 
     total_bit_rate +=
-        total_bit_rate * 25 / DEFAULT_PES_PAYLOAD_SIZE + /* PES header size */
         total_bit_rate *  4 / TS_PACKET_SIZE           + /* TS  header size */
         SDT_RETRANS_TIME * 8 * sdt_size     / 1000     + /* SDT size */
         PAT_RETRANS_TIME * 8 * pat_pmt_size / 1000     + /* PAT+PMT size */
         PCR_RETRANS_TIME * 8 * 8            / 1000;      /* PCR size */
 
     av_log(s, AV_LOG_DEBUG, "muxrate %d freq sdt %d pat %d\n",
-           total_bit_rate, ts->sdt_packet_freq, ts->pat_packet_freq);
+           total_bit_rate, ts->sdt_packet_period, ts->pat_packet_period);
 
     if (s->mux_rate)
         ts->mux_rate = s->mux_rate;
@@ -493,11 +506,11 @@ static void retransmit_si_info(AVFormatContext *s)
     MpegTSWrite *ts = s->priv_data;
     int i;
 
-    if (++ts->sdt_packet_count == ts->sdt_packet_freq) {
+    if (++ts->sdt_packet_count == ts->sdt_packet_period) {
         ts->sdt_packet_count = 0;
         mpegts_write_sdt(s);
     }
-    if (++ts->pat_packet_count == ts->pat_packet_freq) {
+    if (++ts->pat_packet_count == ts->pat_packet_period) {
         ts->pat_packet_count = 0;
         mpegts_write_pat(s);
         for(i = 0; i < ts->nb_services; i++) {
@@ -541,7 +554,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
         if (ts_st->pid == ts_st->service->pcr_pid) {
             ts_st->service->pcr_packet_count++;
             if (ts_st->service->pcr_packet_count >=
-                ts_st->service->pcr_packet_freq) {
+                ts_st->service->pcr_packet_period) {
                 ts_st->service->pcr_packet_count = 0;
                 write_pcr = 1;
             }
@@ -696,7 +709,6 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
     uint8_t *buf= pkt->data;
     uint8_t *data= NULL;
     MpegTSWriteStream *ts_st = st->priv_data;
-    const uint8_t *access_unit_index = NULL;
     const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
     int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
 
@@ -727,24 +739,20 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
             buf  = data;
             size = pkt->size+6;
         }
-        access_unit_index = buf;
-    } else {
-        access_unit_index = pkt->data;
-    }
-
-    if (!access_unit_index) {
-        av_log(s, AV_LOG_ERROR, "error, could not find access unit start\n");
-        return -1;
     }
 
-    if (st->codec->codec_type == CODEC_TYPE_SUBTITLE ||
-        st->codec->codec_type == CODEC_TYPE_VIDEO) {
+    if (st->codec->codec_type != CODEC_TYPE_AUDIO) {
         // for video and subtitle, write a single pes packet
         mpegts_write_pes(s, st, buf, size, pts, dts);
         av_free(data);
         return 0;
     }
 
+    if (ts_st->payload_pts == AV_NOPTS_VALUE) {
+        ts_st->payload_dts = dts;
+        ts_st->payload_pts = pts;
+    }
+
     // audio
     while (size > 0) {
         len = DEFAULT_PES_PAYLOAD_SIZE - ts_st->payload_index;
@@ -754,19 +762,12 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
         buf += len;
         size -= len;
         ts_st->payload_index += len;
-        if (access_unit_index && access_unit_index < buf &&
-            ts_st->payload_pts == AV_NOPTS_VALUE &&
-            ts_st->payload_dts == AV_NOPTS_VALUE) {
-            ts_st->payload_dts = dts;
-            ts_st->payload_pts = pts;
-        }
         if (ts_st->payload_index >= DEFAULT_PES_PAYLOAD_SIZE) {
             mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
                              ts_st->payload_pts, ts_st->payload_dts);
             ts_st->payload_pts = AV_NOPTS_VALUE;
             ts_st->payload_dts = AV_NOPTS_VALUE;
             ts_st->payload_index = 0;
-            access_unit_index = NULL; // unset access unit to avoid setting pts/dts again
         }
     }