]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mxfenc.c
We're using generic tag-to-ID functions, so specific codec_id assignments
[ffmpeg] / libavformat / mxfenc.c
index 928f3e153197949d70b7d7fb65417c249b00d6e3..6ca7ee8c086492b4b8838daddbe7a9b35622f829 100644 (file)
@@ -86,7 +86,7 @@ static const struct {
     { CODEC_ID_MPEG2VIDEO, 0 },
     { CODEC_ID_PCM_S24LE,  1 },
     { CODEC_ID_PCM_S16LE,  1 },
-    { 0 }
+    { CODEC_ID_NONE }
 };
 
 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st);
@@ -1072,7 +1072,10 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
 
     // index duration
     mxf_write_local_tag(pb, 8, 0x3F0D);
-    put_be64(pb, mxf->edit_units_count);
+    if (mxf->edit_unit_byte_count)
+        put_be64(pb, 0); // index table covers whole container
+    else
+        put_be64(pb, mxf->edit_units_count);
 
     // edit unit byte count
     mxf_write_local_tag(pb, 4, 0x3F05);
@@ -1284,24 +1287,18 @@ static const UID mxf_mpeg2_codec_uls[] = {
 
 static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
 {
+    int long_gop = avctx->gop_size > 1 || avctx->has_b_frames;
+
     if (avctx->profile == 4) { // Main
         if (avctx->level == 8) // Main
-            return avctx->gop_size ?
-                &mxf_mpeg2_codec_uls[1] :
-                &mxf_mpeg2_codec_uls[0];
+            return &mxf_mpeg2_codec_uls[0+long_gop];
         else if (avctx->level == 4) // High
-            return avctx->gop_size ?
-                &mxf_mpeg2_codec_uls[5] :
-                &mxf_mpeg2_codec_uls[4];
+            return &mxf_mpeg2_codec_uls[4+long_gop];
     } else if (avctx->profile == 0) { // 422
         if (avctx->level == 5) // Main
-            return avctx->gop_size ?
-                &mxf_mpeg2_codec_uls[3] :
-                &mxf_mpeg2_codec_uls[2];
+            return &mxf_mpeg2_codec_uls[2+long_gop];
         else if (avctx->level == 2) // High
-            return avctx->gop_size ?
-                &mxf_mpeg2_codec_uls[7] :
-                &mxf_mpeg2_codec_uls[6];
+            return &mxf_mpeg2_codec_uls[6+long_gop];
     }
     return NULL;
 }
@@ -1360,7 +1357,6 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt
             int pict_type = (pkt->data[i+2]>>3) & 0x07;
             if (pict_type == 2) { // P frame
                 *flags |= 0x22;
-                st->codec->gop_size = 1;
                 sc->closed_gop = 0; // reset closed gop, don't matter anymore
             } else if (pict_type == 3) { // B frame
                 if (sc->closed_gop)
@@ -1393,7 +1389,7 @@ static uint64_t mxf_parse_timestamp(time_t timestamp)
 static void mxf_gen_umid(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
-    uint32_t seed = ff_random_get_seed();
+    uint32_t seed = av_get_random_seed();
     uint64_t umid = seed + 0x5294713400000000LL;
 
     AV_WB64(mxf->umid  , umid);
@@ -1419,7 +1415,7 @@ static int mxf_write_header(AVFormatContext *s)
             return AVERROR(ENOMEM);
         st->priv_data = sc;
 
-        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
             if (i != 0) {
                 av_log(s, AV_LOG_ERROR, "video stream must be first track\n");
                 return -1;
@@ -1459,7 +1455,7 @@ static int mxf_write_header(AVFormatContext *s)
                 mxf->edit_unit_byte_count += 16 + 4 + 4 + samples_per_frame[0]*8*4;
                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
             }
-        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             if (st->codec->sample_rate != 48000) {
                 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
                 return -1;
@@ -1721,7 +1717,7 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
     mxf_write_klv_fill(s);
     put_buffer(pb, sc->track_essence_element_key, 16); // write key
     if (s->oformat == &mxf_d10_muxer) {
-        if (st->codec->codec_type == CODEC_TYPE_VIDEO)
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
             mxf_write_d10_video_packet(s, st, pkt);
         else
             mxf_write_d10_audio_packet(s, st, pkt);
@@ -1811,22 +1807,13 @@ static int mxf_write_footer(AVFormatContext *s)
 
 static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
 {
-    AVPacketList *pktl;
-    int stream_count = 0;
-    int streams[MAX_STREAMS];
-
-    memset(streams, 0, sizeof(streams));
-    pktl = s->packet_buffer;
-    while (pktl) {
-        //av_log(s, AV_LOG_DEBUG, "show st:%d dts:%lld\n", pktl->pkt.stream_index, pktl->pkt.dts);
-        if (!streams[pktl->pkt.stream_index])
-            stream_count++;
-        streams[pktl->pkt.stream_index]++;
-        pktl = pktl->next;
-    }
+    int i, stream_count = 0;
+
+    for (i = 0; i < s->nb_streams; i++)
+        stream_count += !!s->streams[i]->last_in_packet_buffer;
 
     if (stream_count && (s->nb_streams == stream_count || flush)) {
-        pktl = s->packet_buffer;
+        AVPacketList *pktl = s->packet_buffer;
         if (s->nb_streams != stream_count) {
             AVPacketList *last = NULL;
             // find last packet in edit unit
@@ -1840,6 +1827,9 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket
             // purge packet queue
             while (pktl) {
                 AVPacketList *next = pktl->next;
+
+                if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
+                    s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
                 av_free_packet(&pktl->pkt);
                 av_freep(&pktl);
                 pktl = next;
@@ -1848,6 +1838,7 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket
                 last->next = NULL;
             else {
                 s->packet_buffer = NULL;
+                s->packet_buffer_end= NULL;
                 goto out;
             }
             pktl = s->packet_buffer;
@@ -1856,6 +1847,10 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket
         *out = pktl->pkt;
         //av_log(s, AV_LOG_DEBUG, "out st:%d dts:%lld\n", (*out).stream_index, (*out).dts);
         s->packet_buffer = pktl->next;
+        if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
+            s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
+        if(!s->packet_buffer)
+            s->packet_buffer_end= NULL;
         av_freep(&pktl);
         return 1;
     } else {