]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mpegenc.c
mov: Wrap stsc index and count compare in a separate function
[ffmpeg] / libavformat / mpegenc.c
index 1ba7647e80b6919cc2fe5cfd8a68402a5006afee..1507e0ee3024677370e4d2271313d18349c0ef22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * MPEG1/2 muxer
+ * MPEG-1/2 muxer
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
  * This file is part of Libav.
@@ -43,11 +43,10 @@ typedef struct PacketDesc {
     int64_t dts;
     int size;
     int unwritten_size;
-    int flags;
     struct PacketDesc *next;
 } PacketDesc;
 
-typedef struct {
+typedef struct StreamInfo {
     AVFifoBuffer *fifo;
     uint8_t id;
     int max_buffer_size; /* in bytes */
@@ -63,7 +62,7 @@ typedef struct {
     int64_t vobu_start_pts;
 } StreamInfo;
 
-typedef struct {
+typedef struct MpegMuxContext {
     const AVClass *class;
     int packet_size; /* required packet size */
     int packet_number;
@@ -154,7 +153,7 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,
         put_bits(&pb, 1, 1);
     } else {
         put_bits(&pb, 1, 0); /* variable bitrate */
-        put_bits(&pb, 1, 0); /* non constrainted bit stream */
+        put_bits(&pb, 1, 0); /* nonconstrained bitstream */
     }
 
     if (s->is_vcd || s->is_dvd) {
@@ -301,7 +300,7 @@ static int get_system_header_size(AVFormatContext *ctx)
 static av_cold int mpeg_mux_init(AVFormatContext *ctx)
 {
     MpegMuxContext *s = ctx->priv_data;
-    int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j;
+    int bitrate, i, mpa_id, mpv_id, h264_id, mps_id, ac3_id, dts_id, lpcm_id, j;
     AVStream *st;
     StreamInfo *stream;
     int audio_bitrate;
@@ -337,10 +336,13 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
     ac3_id  = AC3_ID;
     dts_id  = DTS_ID;
     mpv_id  = VIDEO_ID;
+    h264_id = H264_ID;
     mps_id  = SUB_ID;
     lpcm_id = LPCM_ID;
 
     for (i = 0; i < ctx->nb_streams; i++) {
+        AVCPBProperties *props;
+
         st     = ctx->streams[i];
         stream = av_mallocz(sizeof(StreamInfo));
         if (!stream)
@@ -349,26 +351,26 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
 
         avpriv_set_pts_info(st, 64, 1, 90000);
 
-        switch (st->codec->codec_type) {
+        switch (st->codecpar->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
-            if (st->codec->codec_id == AV_CODEC_ID_AC3) {
+            if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
                 stream->id = ac3_id++;
-            } else if (st->codec->codec_id == AV_CODEC_ID_DTS) {
+            } else if (st->codecpar->codec_id == AV_CODEC_ID_DTS) {
                 stream->id = dts_id++;
-            } else if (st->codec->codec_id == AV_CODEC_ID_PCM_S16BE) {
+            } else if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) {
                 stream->id = lpcm_id++;
                 for (j = 0; j < 4; j++) {
-                    if (lpcm_freq_tab[j] == st->codec->sample_rate)
+                    if (lpcm_freq_tab[j] == st->codecpar->sample_rate)
                         break;
                 }
                 if (j == 4)
                     goto fail;
-                if (st->codec->channels > 8)
+                if (st->codecpar->channels > 8)
                     return -1;
                 stream->lpcm_header[0] = 0x0c;
-                stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4);
+                stream->lpcm_header[1] = (st->codecpar->channels - 1) | (j << 4);
                 stream->lpcm_header[2] = 0x80;
-                stream->lpcm_align     = st->codec->channels * 2;
+                stream->lpcm_align     = st->codecpar->channels * 2;
             } else {
                 stream->id = mpa_id++;
             }
@@ -379,9 +381,14 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
             s->audio_bound++;
             break;
         case AVMEDIA_TYPE_VIDEO:
-            stream->id = mpv_id++;
-            if (st->codec->rc_buffer_size)
-                stream->max_buffer_size = 6 * 1024 + st->codec->rc_buffer_size / 8;
+            if (st->codecpar->codec_id == AV_CODEC_ID_H264)
+                stream->id = h264_id++;
+            else
+                stream->id = mpv_id++;
+
+            props = (AVCPBProperties*)av_stream_get_side_data(st, AV_PKT_DATA_CPB_PROPERTIES, NULL);
+            if (props && props->buffer_size)
+                stream->max_buffer_size = 6 * 1024 + props->buffer_size / 8;
             else {
                 av_log(ctx, AV_LOG_WARNING,
                        "VBV buffer size not set, muxing may fail\n");
@@ -405,14 +412,16 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
     audio_bitrate = 0;
     video_bitrate = 0;
     for (i = 0; i < ctx->nb_streams; i++) {
+        AVCPBProperties *props;
         int codec_rate;
         st     = ctx->streams[i];
         stream = (StreamInfo *)st->priv_data;
 
-        if (st->codec->rc_max_rate || stream->id == VIDEO_ID)
-            codec_rate = st->codec->rc_max_rate;
+        props = (AVCPBProperties*)av_stream_get_side_data(st, AV_PKT_DATA_CPB_PROPERTIES, NULL);
+        if (props)
+            codec_rate = props->max_bitrate;
         else
-            codec_rate = st->codec->bit_rate;
+            codec_rate = st->codecpar->bit_rate;
 
         if (!codec_rate)
             codec_rate = (1 << 21) * 8 * 50 / ctx->nb_streams;
@@ -421,7 +430,7 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
 
         if ((stream->id & 0xe0) == AUDIO_ID)
             audio_bitrate += codec_rate;
-        else if (stream->id == VIDEO_ID)
+        else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
             video_bitrate += codec_rate;
     }
 
@@ -582,7 +591,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
 
     id = stream->id;
 
-    av_dlog(ctx, "packet ID=%2x PTS=%0.3f\n", id, pts / 90000.0);
+    av_log(ctx, AV_LOG_TRACE, "packet ID=%2x PTS=%0.3f\n", id, pts / 90000.0);
 
     buf_ptr = buffer;
 
@@ -954,7 +963,7 @@ retry:
         /* for subtitle, a single PES packet must be generated,
          * so we flush after every single subtitle packet */
         if (s->packet_size > avail_data && !flush
-            && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
+            && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
             return 0;
         if (avail_data == 0)
             continue;
@@ -984,7 +993,7 @@ retry:
                 best_dts = pkt_desc->dts;
         }
 
-        av_dlog(ctx, "bumping scr, scr:%f, dts:%f\n",
+        av_log(ctx, AV_LOG_TRACE, "bumping scr, scr:%f, dts:%f\n",
                 scr / 90000.0, best_dts / 90000.0);
         if (best_dts == INT64_MAX)
             return 0;
@@ -1018,7 +1027,7 @@ retry:
     }
 
     if (timestamp_packet) {
-        av_dlog(ctx, "dts:%f pts:%f scr:%f stream:%d\n",
+        av_log(ctx, AV_LOG_TRACE, "dts:%f pts:%f scr:%f stream:%d\n",
                 timestamp_packet->dts / 90000.0,
                 timestamp_packet->pts / 90000.0,
                 scr / 90000.0, best_i);
@@ -1052,7 +1061,7 @@ retry:
         es_size              -= stream->premux_packet->unwritten_size;
         stream->premux_packet = stream->premux_packet->next;
     }
-    if (es_size)
+    if (stream->premux_packet && es_size)
         stream->premux_packet->unwritten_size -= es_size;
 
     if (remove_decoded_packets(ctx, s->last_scr) < 0)
@@ -1072,7 +1081,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
     int64_t pts, dts;
     PacketDesc *pkt_desc;
     int preload;
-    const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+    const int is_iframe = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
                           (pkt->flags & AV_PKT_FLAG_KEY);
 
     preload = av_rescale(s->preload, 90000, AV_TIME_BASE);
@@ -1088,7 +1097,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
         dts += 2 * preload;
     }
 
-    av_dlog(ctx, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n",
+    av_log(ctx, AV_LOG_TRACE, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n",
             dts / 90000.0, pts / 90000.0, pkt->flags,
             pkt->stream_index, pts != AV_NOPTS_VALUE);
     if (!stream->premux_packet)
@@ -1139,7 +1148,7 @@ static int mpeg_mux_end(AVFormatContext *ctx)
             break;
     }
 
-    /* End header according to MPEG1 systems standard. We do not write
+    /* End header according to MPEG-1 systems standard. We do not write
      * it as it is usually not needed by decoders and because it
      * complicates MPEG stream concatenation. */
     // avio_wb32(ctx->pb, ISO_11172_END_CODE);
@@ -1157,7 +1166,7 @@ static int mpeg_mux_end(AVFormatContext *ctx)
 #define OFFSET(x) offsetof(MpegMuxContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "muxrate", NULL,                                          OFFSET(mux_rate), AV_OPT_TYPE_INT, { .i64 =      0 }, 0, INT_MAX, E },
+    { "muxrate", NULL,                                          OFFSET(mux_rate), AV_OPT_TYPE_INT, { .i64 =      0 }, 0, (1 << 22) - 1, E },
     { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload),  AV_OPT_TYPE_INT, { .i64 = 500000 }, 0, INT_MAX, E },
     { NULL },
 };