LCOV - code coverage report
Current view: top level - libavformat - mxfenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1125 1406 80.0 %
Date: 2017-12-17 23:02:56 Functions: 60 65 92.3 %

          Line data    Source code
       1             : /*
       2             :  * MXF muxer
       3             :  * Copyright (c) 2008 GUCAS, Zhentan Feng <spyfeng at gmail dot com>
       4             :  * Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : /*
      24             :  * signal_standard, color_siting, store_user_comments, sample rate and klv_fill_key version
      25             :  * fixes sponsored by NOA GmbH
      26             :  */
      27             : 
      28             : /*
      29             :  * References
      30             :  * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
      31             :  * SMPTE 377M MXF File Format Specifications
      32             :  * SMPTE 379M MXF Generic Container
      33             :  * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
      34             :  * SMPTE 422M Mapping JPEG 2000 Codestreams into the MXF Generic Container
      35             :  * SMPTE RP210: SMPTE Metadata Dictionary
      36             :  * SMPTE RP224: Registry of SMPTE Universal Labels
      37             :  */
      38             : 
      39             : #include <inttypes.h>
      40             : #include <math.h>
      41             : #include <time.h>
      42             : 
      43             : #include "libavutil/opt.h"
      44             : #include "libavutil/random_seed.h"
      45             : #include "libavutil/timecode.h"
      46             : #include "libavutil/avassert.h"
      47             : #include "libavutil/pixdesc.h"
      48             : #include "libavutil/time_internal.h"
      49             : #include "libavcodec/bytestream.h"
      50             : #include "libavcodec/dnxhddata.h"
      51             : #include "libavcodec/dv_profile.h"
      52             : #include "libavcodec/h264.h"
      53             : #include "libavcodec/internal.h"
      54             : #include "audiointerleave.h"
      55             : #include "avformat.h"
      56             : #include "avio_internal.h"
      57             : #include "internal.h"
      58             : #include "mxf.h"
      59             : #include "config.h"
      60             : 
      61             : extern AVOutputFormat ff_mxf_d10_muxer;
      62             : extern AVOutputFormat ff_mxf_opatom_muxer;
      63             : 
      64             : #define EDIT_UNITS_PER_BODY 250
      65             : #define KAG_SIZE 512
      66             : 
      67             : typedef struct MXFLocalTagPair {
      68             :     int local_tag;
      69             :     UID uid;
      70             : } MXFLocalTagPair;
      71             : 
      72             : typedef struct MXFIndexEntry {
      73             :     uint8_t flags;
      74             :     uint64_t offset;
      75             :     unsigned slice_offset; ///< offset of audio slice
      76             :     uint16_t temporal_ref;
      77             : } MXFIndexEntry;
      78             : 
      79             : typedef struct MXFStreamContext {
      80             :     AudioInterleaveContext aic;
      81             :     UID track_essence_element_key;
      82             :     int index;               ///< index in mxf_essence_container_uls table
      83             :     const UID *codec_ul;
      84             :     int order;               ///< interleaving order if dts are equal
      85             :     int interlaced;          ///< whether picture is interlaced
      86             :     int field_dominance;     ///< tff=1, bff=2
      87             :     int component_depth;
      88             :     int color_siting;
      89             :     int signal_standard;
      90             :     int h_chroma_sub_sample;
      91             :     int temporal_reordering;
      92             :     AVRational aspect_ratio; ///< display aspect ratio
      93             :     int closed_gop;          ///< gop is closed, used in mpeg-2 frame parsing
      94             :     int video_bit_rate;
      95             : } MXFStreamContext;
      96             : 
      97             : typedef struct MXFContainerEssenceEntry {
      98             :     UID container_ul;
      99             :     UID element_ul;
     100             :     UID codec_ul;
     101             :     void (*write_desc)(AVFormatContext *, AVStream *);
     102             : } MXFContainerEssenceEntry;
     103             : 
     104             : typedef struct MXFPackage {
     105             :     char *name;
     106             :     enum MXFMetadataSetType type;
     107             :     int instance;
     108             :     struct MXFPackage *ref;
     109             : } MXFPackage;
     110             : 
     111             : enum ULIndex {
     112             :     INDEX_MPEG2 = 0,
     113             :     INDEX_AES3,
     114             :     INDEX_WAV,
     115             :     INDEX_D10_625_50_50_VIDEO,
     116             :     INDEX_D10_625_50_50_AUDIO,
     117             :     INDEX_D10_525_60_50_VIDEO,
     118             :     INDEX_D10_525_60_50_AUDIO,
     119             :     INDEX_D10_625_50_40_VIDEO,
     120             :     INDEX_D10_625_50_40_AUDIO,
     121             :     INDEX_D10_525_60_40_VIDEO,
     122             :     INDEX_D10_525_60_40_AUDIO,
     123             :     INDEX_D10_625_50_30_VIDEO,
     124             :     INDEX_D10_625_50_30_AUDIO,
     125             :     INDEX_D10_525_60_30_VIDEO,
     126             :     INDEX_D10_525_60_30_AUDIO,
     127             :     INDEX_DV,
     128             :     INDEX_DV25_525_60,
     129             :     INDEX_DV25_625_50,
     130             :     INDEX_DV25_525_60_IEC,
     131             :     INDEX_DV25_625_50_IEC,
     132             :     INDEX_DV50_525_60,
     133             :     INDEX_DV50_625_50,
     134             :     INDEX_DV100_1080_60,
     135             :     INDEX_DV100_1080_50,
     136             :     INDEX_DV100_720_60,
     137             :     INDEX_DV100_720_50,
     138             :     INDEX_DNXHD_1080p_10bit_HIGH,
     139             :     INDEX_DNXHD_1080p_8bit_MEDIUM,
     140             :     INDEX_DNXHD_1080p_8bit_HIGH,
     141             :     INDEX_DNXHD_1080i_10bit_HIGH,
     142             :     INDEX_DNXHD_1080i_8bit_MEDIUM,
     143             :     INDEX_DNXHD_1080i_8bit_HIGH,
     144             :     INDEX_DNXHD_720p_10bit,
     145             :     INDEX_DNXHD_720p_8bit_HIGH,
     146             :     INDEX_DNXHD_720p_8bit_MEDIUM,
     147             :     INDEX_DNXHD_720p_8bit_LOW,
     148             :     INDEX_JPEG2000,
     149             :     INDEX_H264,
     150             : };
     151             : 
     152             : static const struct {
     153             :     enum AVCodecID id;
     154             :     enum ULIndex index;
     155             : } mxf_essence_mappings[] = {
     156             :     { AV_CODEC_ID_MPEG2VIDEO, INDEX_MPEG2 },
     157             :     { AV_CODEC_ID_PCM_S24LE,  INDEX_AES3 },
     158             :     { AV_CODEC_ID_PCM_S16LE,  INDEX_AES3 },
     159             :     { AV_CODEC_ID_DVVIDEO,    INDEX_DV },
     160             :     { AV_CODEC_ID_DNXHD,      INDEX_DNXHD_1080p_10bit_HIGH },
     161             :     { AV_CODEC_ID_JPEG2000,   INDEX_JPEG2000 },
     162             :     { AV_CODEC_ID_H264,       INDEX_H264 },
     163             :     { AV_CODEC_ID_NONE }
     164             : };
     165             : 
     166             : static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st);
     167             : static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
     168             : static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
     169             : static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
     170             : static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
     171             : 
     172             : static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
     173             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
     174             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     175             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
     176             :       mxf_write_mpegvideo_desc },
     177             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },
     178             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 },
     179             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     180             :       mxf_write_aes3_desc },
     181             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 },
     182             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 },
     183             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     184             :       mxf_write_wav_desc },
     185             :     // D-10 625/50 PAL 50mb/s
     186             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
     187             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
     188             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 },
     189             :       mxf_write_cdci_desc },
     190             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
     191             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
     192             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     193             :       mxf_write_generic_sound_desc },
     194             :     // D-10 525/60 NTSC 50mb/s
     195             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
     196             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
     197             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 },
     198             :       mxf_write_cdci_desc },
     199             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
     200             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
     201             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     202             :       mxf_write_generic_sound_desc },
     203             :     // D-10 625/50 PAL 40mb/s
     204             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
     205             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
     206             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 },
     207             :       mxf_write_cdci_desc },
     208             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
     209             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
     210             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     211             :       mxf_write_generic_sound_desc },
     212             :     // D-10 525/60 NTSC 40mb/s
     213             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
     214             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
     215             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 },
     216             :       mxf_write_cdci_desc },
     217             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
     218             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
     219             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     220             :       mxf_write_generic_sound_desc },
     221             :     // D-10 625/50 PAL 30mb/s
     222             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
     223             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
     224             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 },
     225             :       mxf_write_cdci_desc },
     226             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
     227             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
     228             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     229             :       mxf_write_generic_sound_desc },
     230             :     // D-10 525/60 NTSC 30mb/s
     231             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
     232             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
     233             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 },
     234             :       mxf_write_cdci_desc },
     235             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
     236             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
     237             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
     238             :       mxf_write_generic_sound_desc },
     239             :     // DV Unknown
     240             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 },
     241             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     242             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 },
     243             :       mxf_write_cdci_desc },
     244             : 
     245             :     // DV25 525/60
     246             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 },
     247             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     248             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 },
     249             :       mxf_write_cdci_desc },
     250             :     // DV25 625/50
     251             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 },
     252             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     253             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 },
     254             :       mxf_write_cdci_desc },
     255             : 
     256             :     // IEC DV25 525/60
     257             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x01,0x01 },
     258             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     259             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 },
     260             :       mxf_write_cdci_desc },
     261             :     // IEC DV25 625/50
     262             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x02,0x01 },
     263             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     264             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 },
     265             :       mxf_write_cdci_desc },
     266             : 
     267             :       // DV50 525/60
     268             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 },
     269             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     270             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 },
     271             :       mxf_write_cdci_desc },
     272             :     // DV50 625/50
     273             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 },
     274             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     275             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },
     276             :       mxf_write_cdci_desc },
     277             :     // DV100 1080/60
     278             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 },
     279             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     280             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 },
     281             :       mxf_write_cdci_desc },
     282             :     // DV100 1080/50
     283             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 },
     284             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     285             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 },
     286             :       mxf_write_cdci_desc },
     287             :     // DV100 720/60
     288             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 },
     289             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     290             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 },
     291             :       mxf_write_cdci_desc },
     292             :     // DV100 720/50
     293             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 },
     294             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
     295             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 },
     296             :       mxf_write_cdci_desc },
     297             :     // DNxHD 1080p 10bit high
     298             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     299             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     300             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x01,0x00,0x00 },
     301             :       mxf_write_cdci_desc },
     302             :     // DNxHD 1080p 8bit medium
     303             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     304             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     305             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x03,0x00,0x00 },
     306             :       mxf_write_cdci_desc },
     307             :     // DNxHD 1080p 8bit high
     308             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     309             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     310             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x04,0x00,0x00 },
     311             :       mxf_write_cdci_desc },
     312             :     // DNxHD 1080i 10bit high
     313             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     314             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     315             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x07,0x00,0x00 },
     316             :       mxf_write_cdci_desc },
     317             :     // DNxHD 1080i 8bit medium
     318             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     319             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     320             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x08,0x00,0x00 },
     321             :       mxf_write_cdci_desc },
     322             :     // DNxHD 1080i 8bit high
     323             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     324             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     325             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x09,0x00,0x00 },
     326             :       mxf_write_cdci_desc },
     327             :     // DNxHD 720p 10bit
     328             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     329             :       { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     330             :       { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x10,0x00,0x00 },
     331             :       mxf_write_cdci_desc },
     332             :     // DNxHD 720p 8bit high
     333             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     334             :       { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     335             :       { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x11,0x00,0x00 },
     336             :       mxf_write_cdci_desc },
     337             :     // DNxHD 720p 8bit medium
     338             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     339             :       { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     340             :       { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x12,0x00,0x00 },
     341             :       mxf_write_cdci_desc },
     342             :     // DNxHD 720p 8bit low
     343             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
     344             :       { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     345             :       { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 },
     346             :       mxf_write_cdci_desc },
     347             :     // JPEG2000
     348             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 },
     349             :       { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x08,0x00 },
     350             :       { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 },
     351             :       mxf_write_cdci_desc },
     352             :     // H.264
     353             :     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x0D,0x01,0x03,0x01,0x02,0x10,0x60,0x01 },
     354             :       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
     355             :       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
     356             :       mxf_write_mpegvideo_desc },
     357             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
     358             :       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
     359             :       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
     360             :       NULL },
     361             : };
     362             : 
     363             : typedef struct MXFContext {
     364             :     AVClass *av_class;
     365             :     int64_t footer_partition_offset;
     366             :     int essence_container_count;
     367             :     AVRational time_base;
     368             :     int header_written;
     369             :     MXFIndexEntry *index_entries;
     370             :     unsigned edit_units_count;
     371             :     uint64_t timestamp;   ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8)
     372             :     uint8_t slice_count;  ///< index slice count minus 1 (1 if no audio, 0 otherwise)
     373             :     int last_indexed_edit_unit;
     374             :     uint64_t *body_partition_offset;
     375             :     unsigned body_partitions_count;
     376             :     int last_key_index;  ///< index of last key frame
     377             :     uint64_t duration;
     378             :     AVTimecode tc;       ///< timecode context
     379             :     AVStream *timecode_track;
     380             :     int timecode_base;       ///< rounded time code base (25 or 30)
     381             :     int edit_unit_byte_count; ///< fixed edit unit byte count
     382             :     uint64_t body_offset;
     383             :     uint32_t instance_number;
     384             :     uint8_t umid[16];        ///< unique material identifier
     385             :     int channel_count;
     386             :     int signal_standard;
     387             :     uint32_t tagged_value_count;
     388             :     AVRational audio_edit_rate;
     389             :     int store_user_comments;
     390             :     int track_instance_count; // used to generate MXFTrack uuids
     391             : } MXFContext;
     392             : 
     393             : static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
     394             : static const uint8_t umid_ul[]              = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
     395             : 
     396             : /**
     397             :  * complete key for operation pattern, partitions, and primer pack
     398             :  */
     399             : static const uint8_t op1a_ul[]                     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
     400             : static const uint8_t opatom_ul[]                   = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x02,0x01,0x10,0x03,0x00,0x00 };
     401             : static const uint8_t footer_partition_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
     402             : static const uint8_t primer_pack_key[]             = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
     403             : static const uint8_t index_table_segment_key[]     = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
     404             : static const uint8_t random_index_pack_key[]       = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
     405             : static const uint8_t header_open_partition_key[]   = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; // OpenIncomplete
     406             : static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete
     407             : static const uint8_t klv_fill_key[]                = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
     408             : static const uint8_t body_partition_key[]          = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; // ClosedComplete
     409             : 
     410             : /**
     411             :  * partial key for header metadata
     412             :  */
     413             : static const uint8_t header_metadata_key[]  = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
     414             : static const uint8_t multiple_desc_ul[]     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
     415             : 
     416             : /**
     417             :  * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
     418             :  *             https://smpte-ra.org/sites/default/files/Labels.xml
     419             :  */
     420             : static const MXFLocalTagPair mxf_local_tag_batch[] = {
     421             :     // preface set
     422             :     { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
     423             :     { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
     424             :     { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
     425             :     { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
     426             :     { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
     427             :     { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
     428             :     { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
     429             :     { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
     430             :     // Identification
     431             :     { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
     432             :     { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
     433             :     { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
     434             :     { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */
     435             :     { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
     436             :     { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
     437             :     // Content Storage
     438             :     { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
     439             :     { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */
     440             :     // Essence Container Data
     441             :     { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
     442             :     { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
     443             :     // Package
     444             :     { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
     445             :     { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
     446             :     { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
     447             :     { 0x4402, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x03,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Package Name */
     448             :     { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
     449             :     { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
     450             :     // Track
     451             :     { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
     452             :     { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */
     453             :     { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
     454             :     { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
     455             :     { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
     456             :     // Sequence
     457             :     { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
     458             :     { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
     459             :     { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
     460             :     // Source Clip
     461             :     { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */
     462             :     { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
     463             :     { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
     464             :     // Timecode Component
     465             :     { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */
     466             :     { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */
     467             :     { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */
     468             :     // File Descriptor
     469             :     { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */
     470             :     { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
     471             :     { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
     472             :     { 0x3002, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x02,0x00,0x00,0x00,0x00}}, /* ContainerDuration */
     473             :     { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */
     474             :     // Generic Picture Essence Descriptor
     475             :     { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */
     476             :     { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */
     477             :     { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */
     478             :     { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
     479             :     { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
     480             :     { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
     481             :     { 0x320B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0E,0x00,0x00,0x00}}, /* Presentation Y offset */
     482             :     { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
     483             :     { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
     484             :     { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
     485             :     { 0x3215, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x05,0x01,0x13,0x00,0x00,0x00,0x00}}, /* Signal Standard */
     486             :     // CDCI Picture Essence Descriptor
     487             :     { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */
     488             :     { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */
     489             :     { 0x3303, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x06,0x00,0x00,0x00}}, /* Color Siting */
     490             :     // Generic Sound Essence Descriptor
     491             :     { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */
     492             :     { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
     493             :     { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
     494             :     { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
     495             :     { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
     496             :     // Index Table Segment
     497             :     { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */
     498             :     { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */
     499             :     { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */
     500             :     { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */
     501             :     { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */
     502             :     { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */
     503             :     { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */
     504             :     { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */
     505             :     // MPEG video Descriptor
     506             :     { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */
     507             :     { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */
     508             :     // Wave Audio Essence Descriptor
     509             :     { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */
     510             :     { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */
     511             : };
     512             : 
     513             : static const MXFLocalTagPair mxf_user_comments_local_tag[] = {
     514             :     { 0x4406, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0C,0x00,0x00,0x00}}, /* User Comments */
     515             :     { 0x5001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x09,0x01,0x00,0x00}}, /* Name */
     516             :     { 0x5003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0A,0x01,0x00,0x00}}, /* Value */
     517             : };
     518             : 
     519        1172 : static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value)
     520             : {
     521        1172 :     avio_write(pb, uuid_base, 12);
     522        1172 :     avio_wb16(pb, type);
     523        1172 :     avio_wb16(pb, value);
     524        1172 : }
     525             : 
     526         288 : static void mxf_write_umid(AVFormatContext *s, int type)
     527             : {
     528         288 :     MXFContext *mxf = s->priv_data;
     529         288 :     avio_write(s->pb, umid_ul, 13);
     530         288 :     avio_wb24(s->pb, mxf->instance_number);
     531         288 :     avio_write(s->pb, mxf->umid, 15);
     532         288 :     avio_w8(s->pb, type);
     533         288 : }
     534             : 
     535         319 : static void mxf_write_refs_count(AVIOContext *pb, int ref_count)
     536             : {
     537         319 :     avio_wb32(pb, ref_count);
     538         319 :     avio_wb32(pb, 16);
     539         319 : }
     540             : 
     541          14 : static int klv_ber_length(uint64_t len)
     542             : {
     543          14 :     if (len < 128)
     544           8 :         return 1;
     545             :     else
     546           6 :         return (av_log2(len) >> 3) + 2;
     547             : }
     548             : 
     549         620 : static int klv_encode_ber_length(AVIOContext *pb, uint64_t len)
     550             : {
     551             :     // Determine the best BER size
     552             :     int size;
     553         620 :     if (len < 128) {
     554             :         //short form
     555         482 :         avio_w8(pb, len);
     556         482 :         return 1;
     557             :     }
     558             : 
     559         138 :     size = (av_log2(len) >> 3) + 1;
     560             : 
     561             :     // long form
     562         138 :     avio_w8(pb, 0x80 + size);
     563         440 :     while(size) {
     564         164 :         size--;
     565         164 :         avio_w8(pb, len >> 8 * size & 0xff);
     566             :     }
     567         138 :     return 0;
     568             : }
     569             : 
     570        1352 : static void klv_encode_ber4_length(AVIOContext *pb, int len)
     571             : {
     572        1352 :     avio_w8(pb, 0x80 + 3);
     573        1352 :     avio_wb24(pb, len);
     574        1352 : }
     575             : 
     576           4 : static void klv_encode_ber9_length(AVIOContext *pb, uint64_t len)
     577             : {
     578           4 :     avio_w8(pb, 0x80 + 8);
     579           4 :     avio_wb64(pb, len);
     580           4 : }
     581             : 
     582             : /*
     583             :  * Get essence container ul index
     584             :  */
     585          16 : static int mxf_get_essence_container_ul_index(enum AVCodecID id)
     586             : {
     587             :     int i;
     588          40 :     for (i = 0; mxf_essence_mappings[i].id; i++)
     589          40 :         if (mxf_essence_mappings[i].id == id)
     590          16 :             return mxf_essence_mappings[i].index;
     591           0 :     return -1;
     592             : }
     593             : 
     594          22 : static void mxf_write_primer_pack(AVFormatContext *s)
     595             : {
     596          22 :     MXFContext *mxf = s->priv_data;
     597          22 :     AVIOContext *pb = s->pb;
     598          22 :     int local_tag_number, i = 0;
     599             : 
     600          22 :     local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch);
     601          22 :     local_tag_number += mxf->store_user_comments * FF_ARRAY_ELEMS(mxf_user_comments_local_tag);
     602             : 
     603          22 :     avio_write(pb, primer_pack_key, 16);
     604          22 :     klv_encode_ber_length(pb, local_tag_number * 18 + 8);
     605             : 
     606          22 :     avio_wb32(pb, local_tag_number); // local_tag num
     607          22 :     avio_wb32(pb, 18); // item size, always 18 according to the specs
     608             : 
     609        1650 :     for (i = 0; i < FF_ARRAY_ELEMS(mxf_local_tag_batch); i++) {
     610        1628 :         avio_wb16(pb, mxf_local_tag_batch[i].local_tag);
     611        1628 :         avio_write(pb, mxf_local_tag_batch[i].uid, 16);
     612             :     }
     613          22 :     if (mxf->store_user_comments)
     614           0 :         for (i = 0; i < FF_ARRAY_ELEMS(mxf_user_comments_local_tag); i++) {
     615           0 :             avio_wb16(pb, mxf_user_comments_local_tag[i].local_tag);
     616           0 :             avio_write(pb, mxf_user_comments_local_tag[i].uid, 16);
     617             :         }
     618          22 : }
     619             : 
     620        3466 : static void mxf_write_local_tag(AVIOContext *pb, int size, int tag)
     621             : {
     622        3466 :     avio_wb16(pb, tag);
     623        3466 :     avio_wb16(pb, size);
     624        3466 : }
     625             : 
     626         530 : static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value)
     627             : {
     628         530 :     avio_write(pb, header_metadata_key, 13);
     629         530 :     avio_wb24(pb, value);
     630         530 : }
     631             : 
     632          11 : static void mxf_free(AVFormatContext *s)
     633             : {
     634             :     int i;
     635             : 
     636          30 :     for (i = 0; i < s->nb_streams; i++) {
     637          19 :         AVStream *st = s->streams[i];
     638          19 :         av_freep(&st->priv_data);
     639             :     }
     640          11 : }
     641             : 
     642         160 : static const MXFCodecUL *mxf_get_data_definition_ul(int type)
     643             : {
     644         160 :     const MXFCodecUL *uls = ff_mxf_data_definition_uls;
     645         396 :     while (uls->uid[0]) {
     646         236 :         if (type == uls->id)
     647         160 :             break;
     648          76 :         uls++;
     649             :     }
     650         160 :     return uls;
     651             : }
     652             : 
     653             : //one EC -> one descriptor. N ECs -> MultipleDescriptor + N descriptors
     654             : #define DESCRIPTOR_COUNT(essence_container_count) \
     655             :     (essence_container_count > 1 ? essence_container_count + 1 : essence_container_count)
     656             : 
     657          65 : static void mxf_write_essence_container_refs(AVFormatContext *s)
     658             : {
     659          65 :     MXFContext *c = s->priv_data;
     660          65 :     AVIOContext *pb = s->pb;
     661             :     int i;
     662             : 
     663          65 :     mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count));
     664          65 :     av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
     665         170 :     for (i = 0; i < c->essence_container_count; i++) {
     666         105 :         MXFStreamContext *sc = s->streams[i]->priv_data;
     667         105 :         avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
     668             :     }
     669             : 
     670          65 :     if (c->essence_container_count > 1)
     671          40 :         avio_write(pb, multiple_desc_ul, 16);
     672          65 : }
     673             : 
     674          22 : static void mxf_write_preface(AVFormatContext *s)
     675             : {
     676          22 :     MXFContext *mxf = s->priv_data;
     677          22 :     AVIOContext *pb = s->pb;
     678             : 
     679          22 :     mxf_write_metadata_key(pb, 0x012f00);
     680             :     PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
     681          22 :     klv_encode_ber_length(pb, 130 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
     682             : 
     683             :     // write preface set uid
     684          22 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     685          22 :     mxf_write_uuid(pb, Preface, 0);
     686             :     PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
     687             : 
     688             :     // last modified date
     689          22 :     mxf_write_local_tag(pb, 8, 0x3B02);
     690          22 :     avio_wb64(pb, mxf->timestamp);
     691             : 
     692             :     // write version
     693          22 :     mxf_write_local_tag(pb, 2, 0x3B05);
     694          22 :     avio_wb16(pb, 258); // v1.2
     695             : 
     696             :     // write identification_refs
     697          22 :     mxf_write_local_tag(pb, 16 + 8, 0x3B06);
     698          22 :     mxf_write_refs_count(pb, 1);
     699          22 :     mxf_write_uuid(pb, Identification, 0);
     700             : 
     701             :     // write content_storage_refs
     702          22 :     mxf_write_local_tag(pb, 16, 0x3B03);
     703          22 :     mxf_write_uuid(pb, ContentStorage, 0);
     704             : 
     705             :     // operational pattern
     706          22 :     mxf_write_local_tag(pb, 16, 0x3B09);
     707          22 :     if (s->oformat == &ff_mxf_opatom_muxer)
     708           4 :         avio_write(pb, opatom_ul, 16);
     709             :     else
     710          18 :         avio_write(pb, op1a_ul, 16);
     711             : 
     712             :     // write essence_container_refs
     713          22 :     mxf_write_local_tag(pb, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A);
     714          22 :     mxf_write_essence_container_refs(s);
     715             : 
     716             :     // write dm_scheme_refs
     717          22 :     mxf_write_local_tag(pb, 8, 0x3B0B);
     718          22 :     avio_wb64(pb, 0);
     719          22 : }
     720             : 
     721             : /*
     722             :  * Returns the length of the UTF-16 string, in 16-bit characters, that would result
     723             :  * from decoding the utf-8 string.
     724             :  */
     725         136 : static uint64_t mxf_utf16len(const char *utf8_str)
     726             : {
     727         136 :     const uint8_t *q = utf8_str;
     728         136 :     uint64_t size = 0;
     729        1248 :     while (*q) {
     730             :         uint32_t ch;
     731        1952 :         GET_UTF8(ch, *q++, goto invalid;)
     732         976 :         if (ch < 0x10000)
     733         976 :             size++;
     734             :         else
     735           0 :             size += 2;
     736         976 :         continue;
     737           0 : invalid:
     738           0 :         av_log(NULL, AV_LOG_ERROR, "Invalid UTF8 sequence in mxf_utf16len\n\n");
     739             :     }
     740         136 :     size += 1;
     741         136 :     return size;
     742             : }
     743             : 
     744             : /*
     745             :  * Returns the calculated length a local tag containing an utf-8 string as utf-16
     746             :  */
     747         112 : static int mxf_utf16_local_tag_length(const char *utf8_str)
     748             : {
     749             :     uint64_t size;
     750             : 
     751         112 :     if (!utf8_str)
     752          44 :         return 0;
     753             : 
     754          68 :     size = mxf_utf16len(utf8_str);
     755          68 :     if (size >= UINT16_MAX/2) {
     756           0 :         av_log(NULL, AV_LOG_ERROR, "utf16 local tag size %"PRIx64" invalid (too large), ignoring\n", size);
     757           0 :         return 0;
     758             :     }
     759             : 
     760          68 :     return 4 + size * 2;
     761             : }
     762             : 
     763             : /*
     764             :  * Write a local tag containing an utf-8 string as utf-16
     765             :  */
     766          68 : static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value)
     767             : {
     768          68 :     uint64_t size = mxf_utf16len(value);
     769             : 
     770          68 :     if (size >= UINT16_MAX/2) {
     771           0 :         av_log(NULL, AV_LOG_ERROR, "utf16 local tag size %"PRIx64" invalid (too large), ignoring\n", size);
     772           0 :         return;
     773             :     }
     774             : 
     775          68 :     mxf_write_local_tag(pb, size*2, tag);
     776          68 :     avio_put_str16be(pb, value);
     777             : }
     778             : 
     779          22 : static void mxf_write_identification(AVFormatContext *s)
     780             : {
     781          22 :     MXFContext *mxf = s->priv_data;
     782          22 :     AVIOContext *pb = s->pb;
     783          22 :     const char *company = "FFmpeg";
     784          22 :     const char *product = s->oformat != &ff_mxf_opatom_muxer ? "OP1a Muxer" : "OPAtom Muxer";
     785             :     const char *version;
     786             :     int length;
     787             : 
     788          22 :     mxf_write_metadata_key(pb, 0x013000);
     789             :     PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
     790             : 
     791          44 :     version = s->flags & AVFMT_FLAG_BITEXACT ?
     792          22 :         "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
     793          66 :     length = 72 + mxf_utf16_local_tag_length(company) +
     794          22 :                   mxf_utf16_local_tag_length(product) +
     795          22 :                   mxf_utf16_local_tag_length(version);
     796          22 :     klv_encode_ber_length(pb, length);
     797             : 
     798             :     // write uid
     799          22 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     800          22 :     mxf_write_uuid(pb, Identification, 0);
     801             :     PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
     802             : 
     803             :     // write generation uid
     804          22 :     mxf_write_local_tag(pb, 16, 0x3C09);
     805          22 :     mxf_write_uuid(pb, Identification, 1);
     806          22 :     mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name
     807          22 :     mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name
     808          22 :     mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String
     809             : 
     810             :     // write product uid
     811          22 :     mxf_write_local_tag(pb, 16, 0x3C05);
     812          22 :     mxf_write_uuid(pb, Identification, 2);
     813             : 
     814             :     // modification date
     815          22 :     mxf_write_local_tag(pb, 8, 0x3C06);
     816          22 :     avio_wb64(pb, mxf->timestamp);
     817          22 : }
     818             : 
     819          22 : static void mxf_write_content_storage(AVFormatContext *s, MXFPackage *packages, int package_count)
     820             : {
     821          22 :     AVIOContext *pb = s->pb;
     822             :     int i;
     823             : 
     824          22 :     mxf_write_metadata_key(pb, 0x011800);
     825             :     PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
     826          22 :     klv_encode_ber_length(pb, 60 + (16 * package_count));
     827             : 
     828             :     // write uid
     829          22 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     830          22 :     mxf_write_uuid(pb, ContentStorage, 0);
     831             :     PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
     832             : 
     833             :     // write package reference
     834          22 :     mxf_write_local_tag(pb, 16 * package_count + 8, 0x1901);
     835          22 :     mxf_write_refs_count(pb, package_count);
     836          68 :     for (i = 0; i < package_count; i++) {
     837          46 :         mxf_write_uuid(pb, packages[i].type, packages[i].instance);
     838             :     }
     839             : 
     840             :     // write essence container data
     841          22 :     mxf_write_local_tag(pb, 8 + 16, 0x1902);
     842          22 :     mxf_write_refs_count(pb, 1);
     843          22 :     mxf_write_uuid(pb, EssenceContainerData, 0);
     844          22 : }
     845             : 
     846         126 : static void mxf_write_track(AVFormatContext *s, AVStream *st, MXFPackage *package)
     847             : {
     848         126 :     MXFContext *mxf = s->priv_data;
     849         126 :     AVIOContext *pb = s->pb;
     850         126 :     MXFStreamContext *sc = st->priv_data;
     851             : 
     852         126 :     mxf_write_metadata_key(pb, 0x013b00);
     853             :     PRINT_KEY(s, "track key", pb->buf_ptr - 16);
     854         126 :     klv_encode_ber_length(pb, 80);
     855             : 
     856             :     // write track uid
     857         126 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     858         126 :     mxf_write_uuid(pb, Track, mxf->track_instance_count);
     859             :     PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
     860             : 
     861             :     // write track id
     862         126 :     mxf_write_local_tag(pb, 4, 0x4801);
     863         126 :     avio_wb32(pb, st->index+2);
     864             : 
     865             :     // write track number
     866         126 :     mxf_write_local_tag(pb, 4, 0x4804);
     867         126 :     if (package->type == MaterialPackage)
     868          60 :         avio_wb32(pb, 0); // track number of material package is 0
     869             :     else
     870          66 :         avio_write(pb, sc->track_essence_element_key + 12, 4);
     871             : 
     872             :     // write edit rate
     873         126 :     mxf_write_local_tag(pb, 8, 0x4B01);
     874             : 
     875         126 :     if (st == mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer) {
     876           8 :         avio_wb32(pb, mxf->tc.rate.num);
     877           8 :         avio_wb32(pb, mxf->tc.rate.den);
     878             :     } else {
     879         118 :         avio_wb32(pb, mxf->time_base.den);
     880         118 :         avio_wb32(pb, mxf->time_base.num);
     881             :     }
     882             : 
     883             :     // write origin
     884         126 :     mxf_write_local_tag(pb, 8, 0x4B02);
     885         126 :     avio_wb64(pb, 0);
     886             : 
     887             :     // write sequence refs
     888         126 :     mxf_write_local_tag(pb, 16, 0x4803);
     889         126 :     mxf_write_uuid(pb, Sequence, mxf->track_instance_count);
     890         126 : }
     891             : 
     892             : static const uint8_t smpte_12m_timecode_track_data_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x01,0x01,0x00,0x00,0x00 };
     893             : 
     894         252 : static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
     895             : {
     896         252 :     MXFContext *mxf = s->priv_data;
     897         252 :     AVIOContext *pb = s->pb;
     898             : 
     899             :     // find data define uls
     900         252 :     mxf_write_local_tag(pb, 16, 0x0201);
     901         252 :     if (st == mxf->timecode_track)
     902          92 :         avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
     903             :     else {
     904         160 :         const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codecpar->codec_type);
     905         160 :         avio_write(pb, data_def_ul->uid, 16);
     906             :     }
     907             : 
     908             :     // write duration
     909         252 :     mxf_write_local_tag(pb, 8, 0x0202);
     910             : 
     911         252 :     if (st != mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
     912           8 :         avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count);
     913             :     } else {
     914         244 :         avio_wb64(pb, mxf->duration);
     915             :     }
     916         252 : }
     917             : 
     918         126 : static void mxf_write_sequence(AVFormatContext *s, AVStream *st, MXFPackage *package)
     919             : {
     920         126 :     MXFContext *mxf = s->priv_data;
     921         126 :     AVIOContext *pb = s->pb;
     922             :     enum MXFMetadataSetType component;
     923             : 
     924         126 :     mxf_write_metadata_key(pb, 0x010f00);
     925             :     PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
     926         126 :     klv_encode_ber_length(pb, 80);
     927             : 
     928         126 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     929         126 :     mxf_write_uuid(pb, Sequence, mxf->track_instance_count);
     930             : 
     931             :     PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
     932         126 :     mxf_write_common_fields(s, st);
     933             : 
     934             :     // write structural component
     935         126 :     mxf_write_local_tag(pb, 16 + 8, 0x1001);
     936         126 :     mxf_write_refs_count(pb, 1);
     937         126 :     if (st == mxf->timecode_track)
     938          46 :         component = TimecodeComponent;
     939             :     else
     940          80 :         component = SourceClip;
     941             : 
     942         126 :     mxf_write_uuid(pb, component, mxf->track_instance_count);
     943         126 : }
     944             : 
     945          46 : static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, MXFPackage *package)
     946             : {
     947          46 :     MXFContext *mxf = s->priv_data;
     948          46 :     AVIOContext *pb = s->pb;
     949             : 
     950          46 :     mxf_write_metadata_key(pb, 0x011400);
     951          46 :     klv_encode_ber_length(pb, 75);
     952             : 
     953             :     // UID
     954          46 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     955          46 :     mxf_write_uuid(pb, TimecodeComponent, mxf->track_instance_count);
     956             : 
     957          46 :     mxf_write_common_fields(s, st);
     958             : 
     959             :     // Start Time Code
     960          46 :     mxf_write_local_tag(pb, 8, 0x1501);
     961          46 :     avio_wb64(pb, mxf->tc.start);
     962             : 
     963             :     // Rounded Time Code Base
     964          46 :     mxf_write_local_tag(pb, 2, 0x1502);
     965          46 :     avio_wb16(pb, mxf->timecode_base);
     966             : 
     967             :     // Drop Frame
     968          46 :     mxf_write_local_tag(pb, 1, 0x1503);
     969          46 :     avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
     970          46 : }
     971             : 
     972          80 : static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, MXFPackage *package)
     973             : {
     974          80 :     MXFContext *mxf = s->priv_data;
     975          80 :     AVIOContext *pb = s->pb;
     976             :     int i;
     977             : 
     978          80 :     mxf_write_metadata_key(pb, 0x011100);
     979             :     PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
     980          80 :     klv_encode_ber_length(pb, 108);
     981             : 
     982             :     // write uid
     983          80 :     mxf_write_local_tag(pb, 16, 0x3C0A);
     984          80 :     mxf_write_uuid(pb, SourceClip, mxf->track_instance_count);
     985             : 
     986             :     PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
     987          80 :     mxf_write_common_fields(s, st);
     988             : 
     989             :     // write start_position
     990          80 :     mxf_write_local_tag(pb, 8, 0x1201);
     991          80 :     avio_wb64(pb, 0);
     992             : 
     993             :     // write source package uid, end of the reference
     994          80 :     mxf_write_local_tag(pb, 32, 0x1101);
     995          80 :     if (!package->ref) {
     996         190 :         for (i = 0; i < 4; i++)
     997         152 :             avio_wb64(pb, 0);
     998             :     } else
     999          42 :         mxf_write_umid(s, package->ref->instance);
    1000             : 
    1001             :     // write source track id
    1002          80 :     mxf_write_local_tag(pb, 4, 0x1102);
    1003          80 :     if (package->type == SourcePackage && !package->ref)
    1004          38 :         avio_wb32(pb, 0);
    1005             :     else
    1006          42 :         avio_wb32(pb, st->index+2);
    1007          80 : }
    1008             : 
    1009           2 : static void mxf_write_tape_descriptor(AVFormatContext *s)
    1010             : {
    1011           2 :     AVIOContext *pb = s->pb;
    1012             : 
    1013           2 :     mxf_write_metadata_key(pb, 0x012e00);
    1014             :     PRINT_KEY(s, "tape descriptor key", pb->buf_ptr - 16);
    1015           2 :     klv_encode_ber_length(pb, 20);
    1016           2 :     mxf_write_local_tag(pb, 16, 0x3C0A);
    1017           2 :     mxf_write_uuid(pb, TapeDescriptor, 0);
    1018             :     PRINT_KEY(s, "tape_desc uid", pb->buf_ptr - 16);
    1019           2 : }
    1020             : 
    1021             : 
    1022          16 : static void mxf_write_multi_descriptor(AVFormatContext *s)
    1023             : {
    1024          16 :     MXFContext *mxf = s->priv_data;
    1025          16 :     AVIOContext *pb = s->pb;
    1026             :     const uint8_t *ul;
    1027             :     int i;
    1028             : 
    1029          16 :     mxf_write_metadata_key(pb, 0x014400);
    1030             :     PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
    1031          16 :     klv_encode_ber_length(pb, 64 + 16LL * s->nb_streams);
    1032             : 
    1033          16 :     mxf_write_local_tag(pb, 16, 0x3C0A);
    1034          16 :     mxf_write_uuid(pb, MultipleDescriptor, 0);
    1035             :     PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
    1036             : 
    1037             :     // write sample rate
    1038          16 :     mxf_write_local_tag(pb, 8, 0x3001);
    1039          16 :     avio_wb32(pb, mxf->time_base.den);
    1040          16 :     avio_wb32(pb, mxf->time_base.num);
    1041             : 
    1042             :     // write essence container ul
    1043          16 :     mxf_write_local_tag(pb, 16, 0x3004);
    1044          16 :     if (mxf->essence_container_count > 1)
    1045          14 :         ul = multiple_desc_ul;
    1046             :     else {
    1047           2 :         MXFStreamContext *sc = s->streams[0]->priv_data;
    1048           2 :         ul = mxf_essence_container_uls[sc->index].container_ul;
    1049             :     }
    1050          16 :     avio_write(pb, ul, 16);
    1051             : 
    1052             :     // write sub descriptor refs
    1053          16 :     mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
    1054          16 :     mxf_write_refs_count(pb, s->nb_streams);
    1055          48 :     for (i = 0; i < s->nb_streams; i++)
    1056          32 :         mxf_write_uuid(pb, SubDescriptor, i);
    1057          16 : }
    1058             : 
    1059          38 : static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
    1060             : {
    1061          38 :     MXFContext *mxf = s->priv_data;
    1062          38 :     MXFStreamContext *sc = st->priv_data;
    1063          38 :     AVIOContext *pb = s->pb;
    1064             : 
    1065          38 :     avio_write(pb, key, 16);
    1066          38 :     klv_encode_ber4_length(pb, size+20+8+12+20);
    1067             : 
    1068          38 :     mxf_write_local_tag(pb, 16, 0x3C0A);
    1069          38 :     mxf_write_uuid(pb, SubDescriptor, st->index);
    1070             : 
    1071          38 :     mxf_write_local_tag(pb, 4, 0x3006);
    1072          38 :     avio_wb32(pb, st->index+2);
    1073             : 
    1074          38 :     mxf_write_local_tag(pb, 8, 0x3001);
    1075          38 :     if (s->oformat == &ff_mxf_d10_muxer) {
    1076           4 :         avio_wb32(pb, mxf->time_base.den);
    1077           4 :         avio_wb32(pb, mxf->time_base.num);
    1078             :     } else {
    1079          52 :         if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE ||
    1080          18 :             st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE) {
    1081          16 :             avio_wb32(pb, st->codecpar->sample_rate);
    1082          16 :             avio_wb32(pb, 1);
    1083             :         } else {
    1084          18 :             avio_wb32(pb, mxf->time_base.den);
    1085          18 :             avio_wb32(pb, mxf->time_base.num);
    1086             :         }
    1087             :     }
    1088             : 
    1089          38 :     mxf_write_local_tag(pb, 16, 0x3004);
    1090          38 :     avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
    1091          38 : }
    1092             : 
    1093             : static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
    1094             : static const UID mxf_wav_descriptor_key       = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
    1095             : static const UID mxf_aes3_descriptor_key      = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
    1096             : static const UID mxf_cdci_descriptor_key      = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
    1097             : static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
    1098             : 
    1099          20 : static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
    1100             : {
    1101          20 :     MXFStreamContext *sc = st->priv_data;
    1102          20 :     AVIOContext *pb = s->pb;
    1103          20 :     int stored_height = (st->codecpar->height+15)/16*16;
    1104             :     int display_height;
    1105             :     int f1, f2;
    1106          20 :     unsigned desc_size = size+8+8+8+8+8+8+8+5+16+4+12+20+5;
    1107          20 :     if (sc->interlaced && sc->field_dominance)
    1108           4 :         desc_size += 5;
    1109          20 :     if (sc->signal_standard)
    1110           2 :         desc_size += 5;
    1111             : 
    1112          20 :     mxf_write_generic_desc(s, st, key, desc_size);
    1113             : 
    1114          20 :     mxf_write_local_tag(pb, 4, 0x3203);
    1115          20 :     avio_wb32(pb, st->codecpar->width);
    1116             : 
    1117          20 :     mxf_write_local_tag(pb, 4, 0x3202);
    1118          20 :     avio_wb32(pb, stored_height>>sc->interlaced);
    1119             : 
    1120          20 :     mxf_write_local_tag(pb, 4, 0x3209);
    1121          20 :     avio_wb32(pb, st->codecpar->width);
    1122             : 
    1123          20 :     if (st->codecpar->height == 608) // PAL + VBI
    1124           4 :         display_height = 576;
    1125          16 :     else if (st->codecpar->height == 512)  // NTSC + VBI
    1126           0 :         display_height = 486;
    1127             :     else
    1128          16 :         display_height = st->codecpar->height;
    1129             : 
    1130          20 :     mxf_write_local_tag(pb, 4, 0x3208);
    1131          20 :     avio_wb32(pb, display_height>>sc->interlaced);
    1132             : 
    1133             :     // presentation Y offset
    1134          20 :     mxf_write_local_tag(pb, 4, 0x320B);
    1135          20 :     avio_wb32(pb, (st->codecpar->height - display_height)>>sc->interlaced);
    1136             : 
    1137             :     // component depth
    1138          20 :     mxf_write_local_tag(pb, 4, 0x3301);
    1139          20 :     avio_wb32(pb, sc->component_depth);
    1140             : 
    1141             :     // horizontal subsampling
    1142          20 :     mxf_write_local_tag(pb, 4, 0x3302);
    1143          20 :     avio_wb32(pb, sc->h_chroma_sub_sample);
    1144             : 
    1145             :     // color siting
    1146          20 :     mxf_write_local_tag(pb, 1, 0x3303);
    1147          20 :     avio_w8(pb, sc->color_siting);
    1148             : 
    1149          20 :     if (sc->signal_standard) {
    1150           2 :         mxf_write_local_tag(pb, 1, 0x3215);
    1151           2 :         avio_w8(pb, sc->signal_standard);
    1152             :     }
    1153             : 
    1154             :     // frame layout
    1155          20 :     mxf_write_local_tag(pb, 1, 0x320C);
    1156          20 :     avio_w8(pb, sc->interlaced);
    1157             : 
    1158             :     // video line map
    1159          20 :     switch (st->codecpar->height) {
    1160           6 :     case  576: f1 = 23; f2 = st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO ? 335 : 336; break;
    1161           4 :     case  608: f1 =  7; f2 = 320; break;
    1162           0 :     case  480: f1 = 20; f2 = st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO ? 285 : 283; break;
    1163           0 :     case  512: f1 =  7; f2 = 270; break;
    1164           0 :     case  720: f1 = 26; f2 =   0; break; // progressive
    1165           2 :     case 1080: f1 = 21; f2 = 584; break;
    1166           8 :     default:   f1 =  0; f2 =   0; break;
    1167             :     }
    1168             : 
    1169          20 :     if (!sc->interlaced) {
    1170          12 :         f2  = 0;
    1171          12 :         f1 *= 2;
    1172             :     }
    1173             : 
    1174             : 
    1175          20 :     mxf_write_local_tag(pb, 16, 0x320D);
    1176          20 :     avio_wb32(pb, 2);
    1177          20 :     avio_wb32(pb, 4);
    1178          20 :     avio_wb32(pb, f1);
    1179          20 :     avio_wb32(pb, f2);
    1180             : 
    1181          20 :     mxf_write_local_tag(pb, 8, 0x320E);
    1182          20 :     avio_wb32(pb, sc->aspect_ratio.num);
    1183          20 :     avio_wb32(pb, sc->aspect_ratio.den);
    1184             : 
    1185          20 :     mxf_write_local_tag(pb, 16, 0x3201);
    1186          20 :     avio_write(pb, *sc->codec_ul, 16);
    1187             : 
    1188          20 :     if (sc->interlaced && sc->field_dominance) {
    1189           4 :         mxf_write_local_tag(pb, 1, 0x3212);
    1190           4 :         avio_w8(pb, sc->field_dominance);
    1191             :     }
    1192             : 
    1193          20 : }
    1194             : 
    1195           8 : static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
    1196             : {
    1197           8 :     mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0);
    1198           8 : }
    1199             : 
    1200          12 : static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
    1201             : {
    1202          12 :     AVIOContext *pb = s->pb;
    1203          12 :     MXFStreamContext *sc = st->priv_data;
    1204          12 :     int profile_and_level = (st->codecpar->profile<<4) | st->codecpar->level;
    1205             : 
    1206          12 :     if (st->codecpar->codec_id != AV_CODEC_ID_H264) {
    1207          12 :         mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
    1208             : 
    1209             :         // bit rate
    1210          12 :         mxf_write_local_tag(pb, 4, 0x8000);
    1211          12 :         avio_wb32(pb, sc->video_bit_rate);
    1212             : 
    1213             :         // profile and level
    1214          12 :         mxf_write_local_tag(pb, 1, 0x8007);
    1215          12 :         if (!st->codecpar->profile)
    1216           4 :             profile_and_level |= 0x80; // escape bit
    1217          12 :         avio_w8(pb, profile_and_level);
    1218             :     } else {
    1219           0 :         mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 0);
    1220             :     }
    1221          12 : }
    1222             : 
    1223          18 : static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
    1224             : {
    1225          18 :     AVIOContext *pb = s->pb;
    1226          18 :     MXFContext *mxf = s->priv_data;
    1227          18 :     int show_warnings = !mxf->footer_partition_offset;
    1228          18 :     int duration_size = 0;
    1229             : 
    1230          18 :     if (s->oformat == &ff_mxf_opatom_muxer)
    1231           2 :         duration_size = 12;
    1232             : 
    1233          18 :     mxf_write_generic_desc(s, st, key, size+duration_size+5+12+8+8);
    1234             : 
    1235          18 :     if (duration_size > 0) {
    1236           2 :         mxf_write_local_tag(pb, 8, 0x3002);
    1237           2 :         avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count);
    1238             :     }
    1239             : 
    1240             :     // audio locked
    1241          18 :     mxf_write_local_tag(pb, 1, 0x3D02);
    1242          18 :     avio_w8(pb, 1);
    1243             : 
    1244             :     // write audio sampling rate
    1245          18 :     mxf_write_local_tag(pb, 8, 0x3D03);
    1246          18 :     avio_wb32(pb, st->codecpar->sample_rate);
    1247          18 :     avio_wb32(pb, 1);
    1248             : 
    1249          18 :     mxf_write_local_tag(pb, 4, 0x3D07);
    1250          18 :     if (mxf->channel_count == -1) {
    1251           2 :         if (show_warnings && (s->oformat == &ff_mxf_d10_muxer) && (st->codecpar->channels != 4) && (st->codecpar->channels != 8))
    1252           1 :             av_log(s, AV_LOG_WARNING, "the number of audio channels shall be 4 or 8 : the output will not comply to MXF D-10 specs, use -d10_channelcount to fix this\n");
    1253           2 :         avio_wb32(pb, st->codecpar->channels);
    1254          16 :     } else if (s->oformat == &ff_mxf_d10_muxer) {
    1255           0 :         if (show_warnings && (mxf->channel_count < st->codecpar->channels))
    1256           0 :             av_log(s, AV_LOG_WARNING, "d10_channelcount < actual number of audio channels : some channels will be discarded\n");
    1257           0 :         if (show_warnings && (mxf->channel_count != 4) && (mxf->channel_count != 8))
    1258           0 :             av_log(s, AV_LOG_WARNING, "d10_channelcount shall be set to 4 or 8 : the output will not comply to MXF D-10 specs\n");
    1259           0 :         avio_wb32(pb, mxf->channel_count);
    1260             :     } else {
    1261          16 :         avio_wb32(pb, st->codecpar->channels);
    1262             :     }
    1263             : 
    1264          18 :     mxf_write_local_tag(pb, 4, 0x3D01);
    1265          18 :     avio_wb32(pb, av_get_bits_per_sample(st->codecpar->codec_id));
    1266          18 : }
    1267             : 
    1268          16 : static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
    1269             : {
    1270          16 :     AVIOContext *pb = s->pb;
    1271             : 
    1272          16 :     mxf_write_generic_sound_common(s, st, key, size+6+8);
    1273             : 
    1274          16 :     mxf_write_local_tag(pb, 2, 0x3D0A);
    1275          16 :     avio_wb16(pb, st->codecpar->block_align);
    1276             : 
    1277             :     // avg bytes per sec
    1278          16 :     mxf_write_local_tag(pb, 4, 0x3D09);
    1279          16 :     avio_wb32(pb, st->codecpar->block_align*st->codecpar->sample_rate);
    1280          16 : }
    1281             : 
    1282           2 : static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st)
    1283             : {
    1284           2 :     mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0);
    1285           2 : }
    1286             : 
    1287          14 : static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st)
    1288             : {
    1289          14 :     mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0);
    1290          14 : }
    1291             : 
    1292           2 : static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
    1293             : {
    1294           2 :     mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0);
    1295           2 : }
    1296             : 
    1297             : static const uint8_t mxf_indirect_value_utf16le[] = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 };
    1298             : 
    1299           0 : static int mxf_write_tagged_value(AVFormatContext *s, const char* name, const char* value)
    1300             : {
    1301           0 :     MXFContext *mxf = s->priv_data;
    1302           0 :     AVIOContext *pb = s->pb;
    1303           0 :     int name_size = mxf_utf16_local_tag_length(name);
    1304           0 :     int indirect_value_size = 13 + mxf_utf16_local_tag_length(value);
    1305             : 
    1306           0 :     if (!name_size || indirect_value_size == 13)
    1307           0 :         return 1;
    1308             : 
    1309           0 :     mxf_write_metadata_key(pb, 0x013f00);
    1310           0 :     klv_encode_ber_length(pb, 24 + name_size + indirect_value_size);
    1311             : 
    1312             :     // write instance UID
    1313           0 :     mxf_write_local_tag(pb, 16, 0x3C0A);
    1314           0 :     mxf_write_uuid(pb, TaggedValue, mxf->tagged_value_count);
    1315             : 
    1316             :     // write name
    1317           0 :     mxf_write_local_tag_utf16(pb, 0x5001, name); // Name
    1318             : 
    1319             :     // write indirect value
    1320           0 :     mxf_write_local_tag(pb, indirect_value_size, 0x5003);
    1321           0 :     avio_write(pb, mxf_indirect_value_utf16le, 17);
    1322           0 :     avio_put_str16le(pb, value);
    1323             : 
    1324           0 :     mxf->tagged_value_count++;
    1325           0 :     return 0;
    1326             : }
    1327             : 
    1328           0 : static int mxf_write_user_comments(AVFormatContext *s, const AVDictionary *m)
    1329             : {
    1330           0 :     MXFContext *mxf = s->priv_data;
    1331           0 :     AVDictionaryEntry *t = NULL;
    1332           0 :     int count = 0;
    1333             : 
    1334           0 :     while ((t = av_dict_get(m, "comment_", t, AV_DICT_IGNORE_SUFFIX))) {
    1335           0 :         if (mxf->tagged_value_count >= UINT16_MAX) {
    1336           0 :             av_log(s, AV_LOG_ERROR, "too many tagged values, ignoring remaining\n");
    1337           0 :             return count;
    1338             :         }
    1339             : 
    1340           0 :         if (mxf_write_tagged_value(s, t->key + 8, t->value) == 0)
    1341           0 :             count++;
    1342             :     }
    1343           0 :     return count;
    1344             : }
    1345             : 
    1346          46 : static void mxf_write_package(AVFormatContext *s, MXFPackage *package)
    1347             : {
    1348          46 :     MXFContext *mxf = s->priv_data;
    1349          46 :     AVIOContext *pb = s->pb;
    1350          46 :     int i, track_count = s->nb_streams+1;
    1351          46 :     int name_size = mxf_utf16_local_tag_length(package->name);
    1352          46 :     int user_comment_count = 0;
    1353             : 
    1354          46 :     if (package->type == MaterialPackage) {
    1355          22 :         if (mxf->store_user_comments)
    1356           0 :             user_comment_count = mxf_write_user_comments(s, s->metadata);
    1357          22 :         mxf_write_metadata_key(pb, 0x013600);
    1358             :         PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
    1359          22 :         klv_encode_ber_length(pb, 92 + name_size + (16*track_count) + (16*user_comment_count) + 12LL*mxf->store_user_comments);
    1360             :     } else {
    1361          24 :         mxf_write_metadata_key(pb, 0x013700);
    1362             :         PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
    1363          24 :         klv_encode_ber_length(pb, 112 + name_size + (16*track_count) + 12LL*mxf->store_user_comments); // 20 bytes length for descriptor reference
    1364             :     }
    1365             : 
    1366             :     // write uid
    1367          46 :     mxf_write_local_tag(pb, 16, 0x3C0A);
    1368          46 :     mxf_write_uuid(pb, package->type, package->instance);
    1369          46 :     av_log(s, AV_LOG_DEBUG, "package type:%d\n", package->type);
    1370             :     PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
    1371             : 
    1372             :     // write package umid
    1373          46 :     mxf_write_local_tag(pb, 32, 0x4401);
    1374          46 :     mxf_write_umid(s, package->instance);
    1375             :     PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
    1376             : 
    1377             :     // package name
    1378          46 :     if (name_size)
    1379           2 :         mxf_write_local_tag_utf16(pb, 0x4402, package->name);
    1380             : 
    1381             :     // package creation date
    1382          46 :     mxf_write_local_tag(pb, 8, 0x4405);
    1383          46 :     avio_wb64(pb, mxf->timestamp);
    1384             : 
    1385             :     // package modified date
    1386          46 :     mxf_write_local_tag(pb, 8, 0x4404);
    1387          46 :     avio_wb64(pb, mxf->timestamp);
    1388             : 
    1389             :     // write track refs
    1390          46 :     mxf_write_local_tag(pb, track_count*16 + 8, 0x4403);
    1391          46 :     mxf_write_refs_count(pb, track_count);
    1392             :     // these are the uuids of the tracks the will be written in mxf_write_track
    1393         172 :     for (i = 0; i < track_count; i++)
    1394         126 :         mxf_write_uuid(pb, Track,  mxf->track_instance_count + i);
    1395             : 
    1396             :     // write user comment refs
    1397          46 :     if (mxf->store_user_comments) {
    1398           0 :         mxf_write_local_tag(pb, user_comment_count*16 + 8, 0x4406);
    1399           0 :         mxf_write_refs_count(pb, user_comment_count);
    1400           0 :         for (i = 0; i < user_comment_count; i++)
    1401           0 :             mxf_write_uuid(pb, TaggedValue, mxf->tagged_value_count - user_comment_count + i);
    1402             :     }
    1403             : 
    1404             :     // write multiple descriptor reference
    1405          46 :     if (package->type == SourcePackage && package->instance == 1) {
    1406          22 :         mxf_write_local_tag(pb, 16, 0x4701);
    1407          44 :         if (s->nb_streams > 1) {
    1408          16 :             mxf_write_uuid(pb, MultipleDescriptor, 0);
    1409          16 :             mxf_write_multi_descriptor(s);
    1410             :         } else
    1411           6 :             mxf_write_uuid(pb, SubDescriptor, 0);
    1412          24 :     } else if (package->type == SourcePackage && package->instance == 2) {
    1413           2 :         mxf_write_local_tag(pb, 16, 0x4701);
    1414           2 :         mxf_write_uuid(pb, TapeDescriptor, 0);
    1415           2 :         mxf_write_tape_descriptor(s);
    1416             :     }
    1417             : 
    1418             :     /*
    1419             :      * for every 1 track in a package there is 1 sequence and 1 component.
    1420             :      * all 3 of these elements share the same instance number for generating
    1421             :      * there instance uuids. mxf->track_instance_count stores this value.
    1422             :      * mxf->track_instance_count is incremented after a group of all 3 of
    1423             :      * these elements are written.
    1424             :      */
    1425             : 
    1426             :     // write timecode track
    1427          46 :     mxf_write_track(s, mxf->timecode_track, package);
    1428          46 :     mxf_write_sequence(s, mxf->timecode_track, package);
    1429          46 :     mxf_write_timecode_component(s, mxf->timecode_track, package);
    1430          46 :     mxf->track_instance_count++;
    1431             : 
    1432         126 :     for (i = 0; i < s->nb_streams; i++) {
    1433          80 :         AVStream *st = s->streams[i];
    1434          80 :         mxf_write_track(s, st, package);
    1435          80 :         mxf_write_sequence(s, st, package);
    1436          80 :         mxf_write_structural_component(s, st, package);
    1437          80 :         mxf->track_instance_count++;
    1438             : 
    1439          80 :         if (package->type == SourcePackage && package->instance == 1) {
    1440          38 :             MXFStreamContext *sc = st->priv_data;
    1441          38 :             mxf_essence_container_uls[sc->index].write_desc(s, st);
    1442             :         }
    1443             :     }
    1444          46 : }
    1445             : 
    1446          22 : static int mxf_write_essence_container_data(AVFormatContext *s)
    1447             : {
    1448          22 :     AVIOContext *pb = s->pb;
    1449             : 
    1450          22 :     mxf_write_metadata_key(pb, 0x012300);
    1451          22 :     klv_encode_ber_length(pb, 72);
    1452             : 
    1453          22 :     mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID
    1454          22 :     mxf_write_uuid(pb, EssenceContainerData, 0);
    1455             : 
    1456          22 :     mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID
    1457          22 :     mxf_write_umid(s, 1);
    1458             : 
    1459          22 :     mxf_write_local_tag(pb, 4, 0x3F07); // BodySID
    1460          22 :     avio_wb32(pb, 1);
    1461             : 
    1462          22 :     mxf_write_local_tag(pb, 4, 0x3F06); // IndexSID
    1463          22 :     avio_wb32(pb, 2);
    1464             : 
    1465          22 :     return 0;
    1466             : }
    1467             : 
    1468          22 : static int mxf_write_header_metadata_sets(AVFormatContext *s)
    1469             : {
    1470          22 :     MXFContext *mxf = s->priv_data;
    1471          22 :     AVDictionaryEntry *entry = NULL;
    1472          22 :     AVStream *st = NULL;
    1473             :     int i;
    1474          22 :     MXFPackage packages[3] = {{0}};
    1475          22 :     int package_count = 2;
    1476          22 :     packages[0].type = MaterialPackage;
    1477          22 :     packages[1].type = SourcePackage;
    1478          22 :     packages[1].instance = 1;
    1479          22 :     packages[0].ref = &packages[1];
    1480             : 
    1481             : 
    1482          22 :     if (entry = av_dict_get(s->metadata, "material_package_name", NULL, 0))
    1483           0 :        packages[0].name = entry->value;
    1484             : 
    1485          22 :     if (entry = av_dict_get(s->metadata, "file_package_name", NULL, 0)) {
    1486           0 :         packages[1].name = entry->value;
    1487             :     } else {
    1488             :         /* check if any of the streams contain a file_package_name */
    1489          60 :         for (i = 0; i < s->nb_streams; i++) {
    1490          38 :             st = s->streams[i];
    1491          38 :             if (entry = av_dict_get(st->metadata, "file_package_name", NULL, 0)) {
    1492           0 :                 packages[1].name = entry->value;
    1493           0 :                 break;
    1494             :             }
    1495             :         }
    1496             :     }
    1497             : 
    1498          22 :     entry = av_dict_get(s->metadata, "reel_name", NULL, 0);
    1499          22 :     if (entry) {
    1500           2 :         packages[2].name = entry->value;
    1501           2 :         packages[2].type = SourcePackage;
    1502           2 :         packages[2].instance = 2;
    1503           2 :         packages[1].ref = &packages[2];
    1504           2 :         package_count = 3;
    1505             :     }
    1506             : 
    1507          22 :     mxf_write_preface(s);
    1508          22 :     mxf_write_identification(s);
    1509          22 :     mxf_write_content_storage(s, packages, package_count);
    1510          22 :     mxf->track_instance_count = 0;
    1511          68 :     for (i = 0; i < package_count; i++)
    1512          46 :         mxf_write_package(s, &packages[i]);
    1513          22 :     mxf_write_essence_container_data(s);
    1514          22 :     return 0;
    1515             : }
    1516             : 
    1517         986 : static unsigned klv_fill_size(uint64_t size)
    1518             : {
    1519         986 :     unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1));
    1520         986 :     if (pad < 20) // smallest fill item possible
    1521           0 :         return pad + KAG_SIZE;
    1522             :     else
    1523         986 :         return pad & (KAG_SIZE-1);
    1524             : }
    1525             : 
    1526          20 : static void mxf_write_index_table_segment(AVFormatContext *s)
    1527             : {
    1528          20 :     MXFContext *mxf = s->priv_data;
    1529          20 :     AVIOContext *pb = s->pb;
    1530          20 :     int i, j, temporal_reordering = 0;
    1531          20 :     int key_index = mxf->last_key_index;
    1532             : 
    1533          20 :     av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
    1534             : 
    1535          20 :     if (!mxf->edit_units_count && !mxf->edit_unit_byte_count)
    1536           6 :         return;
    1537             : 
    1538          14 :     avio_write(pb, index_table_segment_key, 16);
    1539             : 
    1540          14 :     if (mxf->edit_unit_byte_count) {
    1541           8 :         klv_encode_ber_length(pb, 80);
    1542             :     } else {
    1543          12 :         klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1LL)*6 +
    1544           6 :                               12+mxf->edit_units_count*(11+mxf->slice_count*4LL));
    1545             :     }
    1546             : 
    1547             :     // instance id
    1548          14 :     mxf_write_local_tag(pb, 16, 0x3C0A);
    1549          14 :     mxf_write_uuid(pb, IndexTableSegment, 0);
    1550             : 
    1551             :     // index edit rate
    1552          14 :     mxf_write_local_tag(pb, 8, 0x3F0B);
    1553          14 :     avio_wb32(pb, mxf->time_base.den);
    1554          14 :     avio_wb32(pb, mxf->time_base.num);
    1555             : 
    1556             :     // index start position
    1557          14 :     mxf_write_local_tag(pb, 8, 0x3F0C);
    1558          14 :     avio_wb64(pb, mxf->last_indexed_edit_unit);
    1559             : 
    1560             :     // index duration
    1561          14 :     mxf_write_local_tag(pb, 8, 0x3F0D);
    1562          14 :     if (mxf->edit_unit_byte_count)
    1563           8 :         avio_wb64(pb, 0); // index table covers whole container
    1564             :     else
    1565           6 :         avio_wb64(pb, mxf->edit_units_count);
    1566             : 
    1567             :     // edit unit byte count
    1568          14 :     mxf_write_local_tag(pb, 4, 0x3F05);
    1569          14 :     avio_wb32(pb, mxf->edit_unit_byte_count);
    1570             : 
    1571             :     // index sid
    1572          14 :     mxf_write_local_tag(pb, 4, 0x3F06);
    1573          14 :     avio_wb32(pb, 2);
    1574             : 
    1575             :     // body sid
    1576          14 :     mxf_write_local_tag(pb, 4, 0x3F07);
    1577          14 :     avio_wb32(pb, 1);
    1578             : 
    1579          14 :     if (!mxf->edit_unit_byte_count) {
    1580             :         // real slice count - 1
    1581           6 :         mxf_write_local_tag(pb, 1, 0x3F08);
    1582           6 :         avio_w8(pb, mxf->slice_count);
    1583             : 
    1584             :         // delta entry array
    1585           6 :         mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
    1586           6 :         avio_wb32(pb, s->nb_streams+1); // num of entries
    1587           6 :         avio_wb32(pb, 6);               // size of one entry
    1588             :         // write system item delta entry
    1589           6 :         avio_w8(pb, 0);
    1590           6 :         avio_w8(pb, 0); // slice entry
    1591           6 :         avio_wb32(pb, 0); // element delta
    1592          17 :         for (i = 0; i < s->nb_streams; i++) {
    1593          11 :             AVStream *st = s->streams[i];
    1594          11 :             MXFStreamContext *sc = st->priv_data;
    1595          11 :             avio_w8(pb, sc->temporal_reordering);
    1596          11 :             if (sc->temporal_reordering)
    1597           3 :                 temporal_reordering = 1;
    1598          11 :             if (i == 0) { // video track
    1599           6 :                 avio_w8(pb, 0); // slice number
    1600           6 :                 avio_wb32(pb, KAG_SIZE); // system item size including klv fill
    1601             :             } else { // audio track
    1602           5 :                 unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
    1603           5 :                 audio_frame_size += klv_fill_size(audio_frame_size);
    1604           5 :                 avio_w8(pb, 1);
    1605           5 :                 avio_wb32(pb, (i-1)*audio_frame_size); // element delta
    1606             :             }
    1607             :         }
    1608             : 
    1609           6 :         mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A);
    1610           6 :         avio_wb32(pb, mxf->edit_units_count);  // num of entries
    1611           6 :         avio_wb32(pb, 11+mxf->slice_count*4);  // size of one entry
    1612             : 
    1613         109 :         for (i = 0; i < mxf->edit_units_count; i++) {
    1614         103 :             int temporal_offset = 0;
    1615             : 
    1616         103 :             if (!(mxf->index_entries[i].flags & 0x33)) { // I-frame
    1617          16 :                 mxf->last_key_index = key_index;
    1618          16 :                 key_index = i;
    1619             :             }
    1620             : 
    1621         103 :             if (temporal_reordering) {
    1622          80 :                 int pic_num_in_gop = i - key_index;
    1623          80 :                 if (pic_num_in_gop != mxf->index_entries[i].temporal_ref) {
    1624         444 :                     for (j = key_index; j < mxf->edit_units_count; j++) {
    1625         444 :                         if (pic_num_in_gop == mxf->index_entries[j].temporal_ref)
    1626          77 :                             break;
    1627             :                     }
    1628          77 :                     if (j == mxf->edit_units_count)
    1629           0 :                         av_log(s, AV_LOG_WARNING, "missing frames\n");
    1630          77 :                     temporal_offset = j - key_index - pic_num_in_gop;
    1631             :                 }
    1632             :             }
    1633         103 :             avio_w8(pb, temporal_offset);
    1634             : 
    1635         103 :             if ((mxf->index_entries[i].flags & 0x30) == 0x30) { // back and forward prediction
    1636          51 :                 avio_w8(pb, mxf->last_key_index - i);
    1637             :             } else {
    1638          52 :                 avio_w8(pb, key_index - i); // key frame offset
    1639          52 :                 if ((mxf->index_entries[i].flags & 0x20) == 0x20) // only forward
    1640          36 :                     mxf->last_key_index = key_index;
    1641             :             }
    1642             : 
    1643         119 :             if (!(mxf->index_entries[i].flags & 0x33) && // I-frame
    1644          32 :                 mxf->index_entries[i].flags & 0x40 && !temporal_offset)
    1645          10 :                 mxf->index_entries[i].flags |= 0x80; // random access
    1646         103 :             avio_w8(pb, mxf->index_entries[i].flags);
    1647             :             // stream offset
    1648         103 :             avio_wb64(pb, mxf->index_entries[i].offset);
    1649         103 :             if (s->nb_streams > 1)
    1650         102 :                 avio_wb32(pb, mxf->index_entries[i].slice_offset);
    1651             :         }
    1652             : 
    1653           6 :         mxf->last_key_index = key_index - mxf->edit_units_count;
    1654           6 :         mxf->last_indexed_edit_unit += mxf->edit_units_count;
    1655           6 :         mxf->edit_units_count = 0;
    1656             :     }
    1657             : }
    1658             : 
    1659         609 : static void mxf_write_klv_fill(AVFormatContext *s)
    1660             : {
    1661         609 :     unsigned pad = klv_fill_size(avio_tell(s->pb));
    1662         609 :     if (pad) {
    1663         578 :         avio_write(s->pb, klv_fill_key, 16);
    1664         578 :         pad -= 16 + 4;
    1665         578 :         klv_encode_ber4_length(s->pb, pad);
    1666         578 :         ffio_fill(s->pb, 0, pad);
    1667             :         av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
    1668             :     }
    1669         609 : }
    1670             : 
    1671          43 : static int mxf_write_partition(AVFormatContext *s, int bodysid,
    1672             :                                 int indexsid,
    1673             :                                 const uint8_t *key, int write_metadata)
    1674             : {
    1675          43 :     MXFContext *mxf = s->priv_data;
    1676          43 :     AVIOContext *pb = s->pb;
    1677             :     int64_t header_byte_count_offset;
    1678          43 :     unsigned index_byte_count = 0;
    1679          43 :     uint64_t partition_offset = avio_tell(pb);
    1680             :     int err;
    1681             : 
    1682          43 :     if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
    1683          12 :         index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
    1684           6 :             12+mxf->edit_units_count*(11+mxf->slice_count*4);
    1685          37 :     else if (mxf->edit_unit_byte_count && indexsid)
    1686           8 :         index_byte_count = 80;
    1687             : 
    1688          43 :     if (index_byte_count) {
    1689             :         // add encoded ber length
    1690          14 :         index_byte_count += 16 + klv_ber_length(index_byte_count);
    1691          14 :         index_byte_count += klv_fill_size(index_byte_count);
    1692             :     }
    1693             : 
    1694          43 :     if (key && !memcmp(key, body_partition_key, 16)) {
    1695           8 :         if ((err = av_reallocp_array(&mxf->body_partition_offset, mxf->body_partitions_count + 1,
    1696             :                                      sizeof(*mxf->body_partition_offset))) < 0) {
    1697           0 :             mxf->body_partitions_count = 0;
    1698           0 :             return err;
    1699             :         }
    1700           8 :         mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
    1701             :     }
    1702             : 
    1703             :     // write klv
    1704          43 :     if (key)
    1705          41 :         avio_write(pb, key, 16);
    1706             :     else
    1707           2 :         avio_write(pb, body_partition_key, 16);
    1708             : 
    1709          43 :     klv_encode_ber_length(pb, 88 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
    1710             : 
    1711             :     // write partition value
    1712          43 :     avio_wb16(pb, 1); // majorVersion
    1713          43 :     avio_wb16(pb, 2); // minorVersion
    1714          43 :     avio_wb32(pb, KAG_SIZE); // KAGSize
    1715             : 
    1716          43 :     avio_wb64(pb, partition_offset); // ThisPartition
    1717             : 
    1718          43 :     if (key && !memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1)
    1719           0 :         avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]); // PreviousPartition
    1720          43 :     else if (key && !memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count)
    1721           8 :         avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]); // PreviousPartition
    1722             :     else
    1723          35 :         avio_wb64(pb, 0);
    1724             : 
    1725          43 :     avio_wb64(pb, mxf->footer_partition_offset); // footerPartition
    1726             : 
    1727             :     // set offset
    1728          43 :     header_byte_count_offset = avio_tell(pb);
    1729          43 :     avio_wb64(pb, 0); // headerByteCount, update later
    1730             : 
    1731             :     // indexTable
    1732          43 :     avio_wb64(pb, index_byte_count); // indexByteCount
    1733          43 :     avio_wb32(pb, index_byte_count ? indexsid : 0); // indexSID
    1734             : 
    1735             :     // BodyOffset
    1736          43 :     if (bodysid && mxf->edit_units_count && mxf->body_partitions_count && s->oformat != &ff_mxf_opatom_muxer)
    1737           0 :         avio_wb64(pb, mxf->body_offset);
    1738             :     else
    1739          43 :         avio_wb64(pb, 0);
    1740             : 
    1741          43 :     avio_wb32(pb, bodysid); // bodySID
    1742             : 
    1743             :     // operational pattern
    1744          43 :     if (s->oformat == &ff_mxf_opatom_muxer)
    1745          10 :         avio_write(pb, opatom_ul, 16);
    1746             :     else
    1747          33 :         avio_write(pb, op1a_ul, 16);
    1748             : 
    1749             :     // essence container
    1750          43 :     mxf_write_essence_container_refs(s);
    1751             : 
    1752          43 :     if (write_metadata) {
    1753             :         // mark the start of the headermetadata and calculate metadata size
    1754             :         int64_t pos, start;
    1755             :         unsigned header_byte_count;
    1756             : 
    1757          22 :         mxf_write_klv_fill(s);
    1758          22 :         start = avio_tell(s->pb);
    1759          22 :         mxf_write_primer_pack(s);
    1760          22 :         mxf_write_header_metadata_sets(s);
    1761          22 :         pos = avio_tell(s->pb);
    1762          22 :         header_byte_count = pos - start + klv_fill_size(pos);
    1763             : 
    1764             :         // update header_byte_count
    1765          22 :         avio_seek(pb, header_byte_count_offset, SEEK_SET);
    1766          22 :         avio_wb64(pb, header_byte_count);
    1767          22 :         avio_seek(pb, pos, SEEK_SET);
    1768             :     }
    1769             : 
    1770          43 :     if(key)
    1771          41 :         avio_flush(pb);
    1772             : 
    1773          43 :     return 0;
    1774             : }
    1775             : 
    1776          25 : static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
    1777             : AVPacket *pkt)
    1778             : {
    1779          25 :     MXFContext *mxf = s->priv_data;
    1780          25 :     MXFStreamContext *sc = st->priv_data;
    1781             :     int i, cid;
    1782             :     uint8_t* header_cid;
    1783          25 :     int frame_size = 0;
    1784             : 
    1785          25 :     if (mxf->header_written)
    1786          24 :         return 1;
    1787             : 
    1788           1 :     if (pkt->size < 43)
    1789           0 :         return -1;
    1790             : 
    1791           1 :     header_cid = pkt->data + 0x28;
    1792           1 :     cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3];
    1793             : 
    1794           1 :     if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) < 0)
    1795           0 :         return -1;
    1796           1 :     if ((sc->interlaced = avpriv_dnxhd_get_interlaced(cid)) < 0)
    1797           0 :         return AVERROR_INVALIDDATA;
    1798             : 
    1799           1 :     switch (cid) {
    1800           0 :     case 1235:
    1801           0 :         sc->index = INDEX_DNXHD_1080p_10bit_HIGH;
    1802           0 :         sc->component_depth = 10;
    1803           0 :         break;
    1804           0 :     case 1237:
    1805           0 :         sc->index = INDEX_DNXHD_1080p_8bit_MEDIUM;
    1806           0 :         break;
    1807           0 :     case 1238:
    1808           0 :         sc->index = INDEX_DNXHD_1080p_8bit_HIGH;
    1809           0 :         break;
    1810           0 :     case 1241:
    1811           0 :         sc->index = INDEX_DNXHD_1080i_10bit_HIGH;
    1812           0 :         sc->component_depth = 10;
    1813           0 :         break;
    1814           0 :     case 1242:
    1815           0 :         sc->index = INDEX_DNXHD_1080i_8bit_MEDIUM;
    1816           0 :         break;
    1817           0 :     case 1243:
    1818           0 :         sc->index = INDEX_DNXHD_1080i_8bit_HIGH;
    1819           0 :         break;
    1820           0 :     case 1250:
    1821           0 :         sc->index = INDEX_DNXHD_720p_10bit;
    1822           0 :         sc->component_depth = 10;
    1823           0 :         break;
    1824           0 :     case 1251:
    1825           0 :         sc->index = INDEX_DNXHD_720p_8bit_HIGH;
    1826           0 :         break;
    1827           0 :     case 1252:
    1828           0 :         sc->index = INDEX_DNXHD_720p_8bit_MEDIUM;
    1829           0 :         break;
    1830           1 :     case 1253:
    1831           1 :         sc->index = INDEX_DNXHD_720p_8bit_LOW;
    1832           1 :         break;
    1833           0 :     default:
    1834           0 :         return -1;
    1835             :     }
    1836             : 
    1837           1 :     sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
    1838           1 :     sc->aspect_ratio = (AVRational){ 16, 9 };
    1839             : 
    1840           1 :     if (s->oformat == &ff_mxf_opatom_muxer) {
    1841           1 :         mxf->edit_unit_byte_count = frame_size;
    1842           1 :         return 1;
    1843             :     }
    1844             : 
    1845           0 :     mxf->edit_unit_byte_count = KAG_SIZE;
    1846           0 :     for (i = 0; i < s->nb_streams; i++) {
    1847           0 :         AVStream *st = s->streams[i];
    1848           0 :         MXFStreamContext *sc = st->priv_data;
    1849           0 :         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
    1850           0 :             mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
    1851           0 :             mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
    1852           0 :         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
    1853           0 :             mxf->edit_unit_byte_count += 16 + 4 + frame_size;
    1854           0 :             mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
    1855             :         }
    1856             :     }
    1857             : 
    1858           0 :     return 1;
    1859             : }
    1860             : 
    1861          50 : static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt)
    1862             : {
    1863          50 :     MXFContext *mxf = s->priv_data;
    1864          50 :     MXFStreamContext *sc = st->priv_data;
    1865             :     uint8_t *vs_pack, *vsc_pack;
    1866             :     int i, ul_index, frame_size, stype, pal;
    1867             :     const AVDVProfile *profile;
    1868             : 
    1869          50 :     if (mxf->header_written)
    1870          48 :         return 1;
    1871             : 
    1872             :     // Check for minimal frame size
    1873           2 :     if (pkt->size < 120000)
    1874           0 :         return -1;
    1875             : 
    1876           2 :     profile = av_dv_frame_profile(NULL, pkt->data, pkt->size);
    1877             : 
    1878           2 :     vs_pack  = pkt->data + 80*5 + 48;
    1879           2 :     vsc_pack = pkt->data + 80*5 + 53;
    1880           2 :     stype    = vs_pack[3] & 0x1f;
    1881           2 :     pal      = (vs_pack[3] >> 5) & 0x1;
    1882             : 
    1883           2 :     if ((vsc_pack[2] & 0x07) == 0x02) {
    1884           1 :         sc->aspect_ratio = (AVRational){ 16, 9 };
    1885             :     } else {
    1886           1 :         sc->aspect_ratio = (AVRational){ 4, 3 };
    1887             :     }
    1888             : 
    1889           2 :     sc->interlaced = (vsc_pack[3] >> 4) & 0x01;
    1890             :     // TODO: fix dv encoder to set proper FF/FS value in VSC pack
    1891             :     // and set field dominance accordingly
    1892             :     // av_log(s, AV_LOG_DEBUG, "DV vsc pack ff/ss = %x\n", vsc_pack[2] >> 6);
    1893             : 
    1894           2 :     switch (stype) {
    1895           0 :     case 0x18: // DV100 720p
    1896           0 :         ul_index = INDEX_DV100_720_50 + pal;
    1897           0 :         frame_size = pal ? 288000 : 240000;
    1898           0 :         if (sc->interlaced) {
    1899           0 :             av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n");
    1900           0 :             sc->interlaced = 0;
    1901             :         }
    1902           0 :         break;
    1903           0 :     case 0x14: // DV100 1080i
    1904           0 :         ul_index = INDEX_DV100_1080_50 + pal;
    1905           0 :         frame_size = pal ? 576000 : 480000;
    1906           0 :         break;
    1907           1 :     case 0x04: // DV50
    1908           1 :         ul_index = INDEX_DV50_525_60 + pal;
    1909           1 :         frame_size = pal ? 288000 : 240000;
    1910           1 :         break;
    1911           1 :     default: // DV25
    1912           1 :         if (profile && profile->pix_fmt == AV_PIX_FMT_YUV420P && pal) {
    1913           1 :             ul_index = INDEX_DV25_525_60_IEC + pal;
    1914           1 :             frame_size = pal ? 144000 : 120000;
    1915           1 :             break;
    1916             :         }
    1917           0 :         ul_index = INDEX_DV25_525_60 + pal;
    1918           0 :         frame_size = pal ? 144000 : 120000;
    1919             :     }
    1920             : 
    1921           2 :     sc->index = ul_index;
    1922           2 :     sc->codec_ul =  &mxf_essence_container_uls[sc->index].codec_ul;
    1923             : 
    1924           2 :     if(s->oformat == &ff_mxf_opatom_muxer) {
    1925           0 :         mxf->edit_unit_byte_count = frame_size;
    1926           0 :         return 1;
    1927             :     }
    1928             : 
    1929           2 :     mxf->edit_unit_byte_count = KAG_SIZE;
    1930           6 :     for (i = 0; i < s->nb_streams; i++) {
    1931           4 :         AVStream *st = s->streams[i];
    1932           4 :         MXFStreamContext *sc = st->priv_data;
    1933           4 :         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
    1934           2 :             mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
    1935           2 :             mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
    1936           2 :         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
    1937           2 :             mxf->edit_unit_byte_count += 16 + 4 + frame_size;
    1938           2 :             mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
    1939             :         }
    1940             :     }
    1941             : 
    1942           2 :     return 1;
    1943             : }
    1944             : 
    1945             : static const struct {
    1946             :     UID uid;
    1947             :     int frame_size;
    1948             :     int profile;
    1949             :     uint8_t interlaced;
    1950             : } mxf_h264_codec_uls[] = {
    1951             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x11,0x01 },      0,  66, 0 }, // AVC Baseline, Unconstrained Coding
    1952             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x20,0x01 },      0, 110, 0 }, // AVC High 10 Intra
    1953             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 232960,   0, 1 }, // AVC Intra 50 1080i60
    1954             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 281088,   0, 1 }, // AVC Intra 50 1080i50
    1955             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 232960,   0, 0 }, // AVC Intra 50 1080p30
    1956             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 281088,   0, 0 }, // AVC Intra 50 1080p25
    1957             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x08 }, 116736,   0, 0 }, // AVC Intra 50 720p60
    1958             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x09 }, 140800,   0, 0 }, // AVC Intra 50 720p50
    1959             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x30,0x01 },      0, 122, 0 }, // AVC High 422 Intra
    1960             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x01 }, 472576,   0, 1 }, // AVC Intra 100 1080i60
    1961             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x02 }, 568832,   0, 1 }, // AVC Intra 100 1080i50
    1962             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x03 }, 472576,   0, 0 }, // AVC Intra 100 1080p30
    1963             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x04 }, 568832,   0, 0 }, // AVC Intra 100 1080p25
    1964             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x08 }, 236544,   0, 0 }, // AVC Intra 100 720p60
    1965             :     {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x09 }, 284672,   0, 0 }, // AVC Intra 100 720p50
    1966             : };
    1967             : 
    1968           0 : static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
    1969             :                                 AVPacket *pkt, MXFIndexEntry *e)
    1970             : {
    1971           0 :     MXFContext *mxf = s->priv_data;
    1972           0 :     MXFStreamContext *sc = st->priv_data;
    1973             :     static const int mxf_h264_num_codec_uls = sizeof(mxf_h264_codec_uls) / sizeof(mxf_h264_codec_uls[0]);
    1974           0 :     const uint8_t *buf = pkt->data;
    1975           0 :     const uint8_t *buf_end = pkt->data + pkt->size;
    1976           0 :     uint32_t state = -1;
    1977           0 :     int extra_size = 512; // support AVC Intra files without SPS/PPS header
    1978             :     int i, frame_size;
    1979             :     uint8_t uid_found;
    1980             : 
    1981           0 :     if (pkt->size > extra_size)
    1982           0 :         buf_end -= pkt->size - extra_size; // no need to parse beyond SPS/PPS header
    1983             : 
    1984             :     for (;;) {
    1985           0 :         buf = avpriv_find_start_code(buf, buf_end, &state);
    1986           0 :         if (buf >= buf_end)
    1987           0 :             break;
    1988           0 :         --buf;
    1989           0 :         switch (state & 0x1f) {
    1990           0 :         case H264_NAL_SPS:
    1991           0 :             st->codecpar->profile = buf[1];
    1992           0 :             e->flags |= 0x40;
    1993           0 :             break;
    1994           0 :         case H264_NAL_PPS:
    1995           0 :             if (e->flags & 0x40) { // sequence header present
    1996           0 :                 e->flags |= 0x80; // random access
    1997           0 :                 extra_size = 0;
    1998           0 :                 buf = buf_end;
    1999             :             }
    2000           0 :             break;
    2001           0 :         default:
    2002           0 :             break;
    2003             :         }
    2004             :     }
    2005             : 
    2006           0 :     if (mxf->header_written)
    2007           0 :         return 1;
    2008             : 
    2009           0 :     sc->aspect_ratio = (AVRational){ 16, 9 }; // 16:9 is mandatory for broadcast HD
    2010           0 :     sc->component_depth = 10; // AVC Intra is always 10 Bit
    2011           0 :     sc->interlaced = st->codecpar->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0;
    2012           0 :     if (sc->interlaced)
    2013           0 :         sc->field_dominance = 1; // top field first is mandatory for AVC Intra
    2014             : 
    2015           0 :     uid_found = 0;
    2016           0 :     frame_size = pkt->size + extra_size;
    2017           0 :     for (i = 0; i < mxf_h264_num_codec_uls; i++) {
    2018           0 :         if (frame_size == mxf_h264_codec_uls[i].frame_size && sc->interlaced == mxf_h264_codec_uls[i].interlaced) {
    2019           0 :             sc->codec_ul = &mxf_h264_codec_uls[i].uid;
    2020           0 :             return 1;
    2021           0 :         } else if (st->codecpar->profile == mxf_h264_codec_uls[i].profile) {
    2022           0 :             sc->codec_ul = &mxf_h264_codec_uls[i].uid;
    2023           0 :             uid_found = 1;
    2024             :         }
    2025             :     }
    2026             : 
    2027           0 :     if (!uid_found) {
    2028           0 :         av_log(s, AV_LOG_ERROR, "AVC Intra 50/100 supported only\n");
    2029           0 :         return 0;
    2030             :     }
    2031             : 
    2032           0 :     return 1;
    2033             : }
    2034             : 
    2035             : static const UID mxf_mpeg2_codec_uls[] = {
    2036             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame
    2037             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP
    2038             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, // 422P-ML I-Frame
    2039             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, // 422P-ML Long GOP
    2040             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 }, // MP-HL I-Frame
    2041             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP
    2042             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame
    2043             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP
    2044             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, // MP@H-14 I-Frame
    2045             :     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, // MP@H-14 Long GOP
    2046             : };
    2047             : 
    2048         103 : static const UID *mxf_get_mpeg2_codec_ul(AVCodecParameters *par)
    2049             : {
    2050         103 :     int long_gop = 1;
    2051             : 
    2052         103 :     if (par->profile == 4) { // Main
    2053          81 :         if (par->level == 8) // Main
    2054          81 :             return &mxf_mpeg2_codec_uls[0+long_gop];
    2055           0 :         else if (par->level == 4) // High
    2056           0 :             return &mxf_mpeg2_codec_uls[4+long_gop];
    2057           0 :         else if (par->level == 6) // High 14
    2058           0 :             return &mxf_mpeg2_codec_uls[8+long_gop];
    2059          22 :     } else if (par->profile == 0) { // 422
    2060          22 :         if (par->level == 5) // Main
    2061          22 :             return &mxf_mpeg2_codec_uls[2+long_gop];
    2062           0 :         else if (par->level == 2) // High
    2063           0 :             return &mxf_mpeg2_codec_uls[6+long_gop];
    2064             :     }
    2065           0 :     return NULL;
    2066             : }
    2067             : 
    2068         128 : static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
    2069             :                                  AVPacket *pkt, MXFIndexEntry *e)
    2070             : {
    2071         128 :     MXFStreamContext *sc = st->priv_data;
    2072         128 :     uint32_t c = -1;
    2073             :     int i;
    2074             : 
    2075        2997 :     for(i = 0; i < pkt->size - 4; i++) {
    2076        2997 :         c = (c<<8) + pkt->data[i];
    2077        2997 :         if (c == 0x1b5) {
    2078         169 :             if ((pkt->data[i+1] & 0xf0) == 0x10) { // seq ext
    2079          41 :                 st->codecpar->profile = pkt->data[i+1] & 0x07;
    2080          41 :                 st->codecpar->level   = pkt->data[i+2] >> 4;
    2081         128 :             } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { // pict coding ext
    2082         128 :                 sc->interlaced = !(pkt->data[i+5] & 0x80); // progressive frame
    2083         128 :                 if (sc->interlaced)
    2084          29 :                     sc->field_dominance = 1 + !(pkt->data[i+4] & 0x80); // top field first
    2085         128 :                 break;
    2086             :             }
    2087        2828 :         } else if (c == 0x1b8) { // gop
    2088          41 :             if (pkt->data[i+4]>>6 & 0x01) { // closed
    2089          30 :                 sc->closed_gop = 1;
    2090          30 :                 if (e->flags & 0x40) // sequence header present
    2091          30 :                     e->flags |= 0x80; // random access
    2092             :             }
    2093        2787 :         } else if (c == 0x1b3) { // seq
    2094          41 :             e->flags |= 0x40;
    2095          41 :             switch ((pkt->data[i+4]>>4) & 0xf) {
    2096           4 :             case 2:  sc->aspect_ratio = (AVRational){  4,  3}; break;
    2097           3 :             case 3:  sc->aspect_ratio = (AVRational){ 16,  9}; break;
    2098           0 :             case 4:  sc->aspect_ratio = (AVRational){221,100}; break;
    2099          34 :             default:
    2100          68 :                 av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den,
    2101          68 :                           st->codecpar->width, st->codecpar->height, 1024*1024);
    2102             :             }
    2103        2746 :         } else if (c == 0x100) { // pic
    2104         128 :             int pict_type = (pkt->data[i+2]>>3) & 0x07;
    2105         128 :             e->temporal_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
    2106         128 :             if (pict_type == 2) { // P-frame
    2107          36 :                 e->flags |= 0x22;
    2108          36 :                 sc->closed_gop = 0; // reset closed GOP, don't matter anymore
    2109          92 :             } else if (pict_type == 3) { // B-frame
    2110          51 :                 if (sc->closed_gop)
    2111           0 :                     e->flags |= 0x13; // only backward prediction
    2112             :                 else
    2113          51 :                     e->flags |= 0x33;
    2114          51 :                 sc->temporal_reordering = -1;
    2115          41 :             } else if (!pict_type) {
    2116           0 :                 av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n");
    2117           0 :                 return 0;
    2118             :             }
    2119             :         }
    2120             :     }
    2121         128 :     if (s->oformat != &ff_mxf_d10_muxer)
    2122         103 :         sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codecpar);
    2123         128 :     return !!sc->codec_ul;
    2124             : }
    2125             : 
    2126           0 : static uint64_t mxf_parse_timestamp(time_t timestamp)
    2127             : {
    2128             :     struct tm tmbuf;
    2129           0 :     struct tm *time = gmtime_r(&timestamp, &tmbuf);
    2130           0 :     if (!time)
    2131           0 :         return 0;
    2132           0 :     return (uint64_t)(time->tm_year+1900) << 48 |
    2133           0 :            (uint64_t)(time->tm_mon+1)     << 40 |
    2134           0 :            (uint64_t) time->tm_mday       << 32 |
    2135           0 :                       time->tm_hour       << 24 |
    2136           0 :                       time->tm_min        << 16 |
    2137           0 :                       time->tm_sec        << 8;
    2138             : }
    2139             : 
    2140           0 : static void mxf_gen_umid(AVFormatContext *s)
    2141             : {
    2142           0 :     MXFContext *mxf = s->priv_data;
    2143           0 :     uint32_t seed = av_get_random_seed();
    2144           0 :     uint64_t umid = seed + 0x5294713400000000LL;
    2145             : 
    2146           0 :     AV_WB64(mxf->umid  , umid);
    2147           0 :     AV_WB64(mxf->umid+8, umid>>8);
    2148             : 
    2149           0 :     mxf->instance_number = seed & 0xFFFFFF;
    2150           0 : }
    2151             : 
    2152          11 : static int mxf_init_timecode(AVFormatContext *s, AVStream *st, AVRational rate)
    2153             : {
    2154          11 :     MXFContext *mxf = s->priv_data;
    2155          11 :     AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
    2156          11 :     if (!tcr)
    2157           8 :         tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
    2158             : 
    2159          11 :     if (tcr)
    2160           3 :         return av_timecode_init_from_string(&mxf->tc, rate, tcr->value, s);
    2161             :     else
    2162           8 :         return av_timecode_init(&mxf->tc, rate, 0, 0, s);
    2163             : }
    2164             : 
    2165          11 : static int mxf_write_header(AVFormatContext *s)
    2166             : {
    2167          11 :     MXFContext *mxf = s->priv_data;
    2168             :     int i, ret;
    2169          11 :     uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
    2170          11 :     const MXFSamplesPerFrame *spf = NULL;
    2171          11 :     int64_t timestamp = 0;
    2172             : 
    2173          11 :     if (!s->nb_streams)
    2174           0 :         return -1;
    2175             : 
    2176          11 :     if (s->oformat == &ff_mxf_opatom_muxer && s->nb_streams !=1) {
    2177           0 :         av_log(s, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n");
    2178           0 :         return -1;
    2179             :     }
    2180             : 
    2181          11 :     if (!av_dict_get(s->metadata, "comment_", NULL, AV_DICT_IGNORE_SUFFIX))
    2182          11 :         mxf->store_user_comments = 0;
    2183             : 
    2184          30 :     for (i = 0; i < s->nb_streams; i++) {
    2185          19 :         AVStream *st = s->streams[i];
    2186          19 :         MXFStreamContext *sc = av_mallocz(sizeof(*sc));
    2187          19 :         if (!sc)
    2188           0 :             return AVERROR(ENOMEM);
    2189          19 :         st->priv_data = sc;
    2190             : 
    2191          19 :         if (((i == 0) ^ (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) && s->oformat != &ff_mxf_opatom_muxer) {
    2192           0 :             av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");
    2193           0 :             return -1;
    2194             :         }
    2195             : 
    2196          19 :         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
    2197          10 :             const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(st->codecpar->format);
    2198             :             // TODO: should be avg_frame_rate
    2199          10 :             AVRational rate, tbc = st->time_base;
    2200             :             // Default component depth to 8
    2201          10 :             sc->component_depth = 8;
    2202          10 :             sc->h_chroma_sub_sample = 2;
    2203          10 :             sc->color_siting = 0xFF;
    2204             : 
    2205          10 :             if (pix_desc) {
    2206          10 :                 sc->component_depth     = pix_desc->comp[0].depth;
    2207          10 :                 sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w;
    2208             :             }
    2209          10 :             switch (ff_choose_chroma_location(s, st)) {
    2210           6 :             case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break;
    2211           1 :             case AVCHROMA_LOC_LEFT:    sc->color_siting = 6; break;
    2212           0 :             case AVCHROMA_LOC_TOP:     sc->color_siting = 1; break;
    2213           0 :             case AVCHROMA_LOC_CENTER:  sc->color_siting = 3; break;
    2214             :             }
    2215             : 
    2216          10 :             mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;
    2217          10 :             spf = ff_mxf_get_samples_per_frame(s, tbc);
    2218          10 :             if (!spf) {
    2219           0 :                 av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",
    2220             :                        tbc.den, tbc.num);
    2221           0 :                 return AVERROR(EINVAL);
    2222             :             }
    2223          10 :             mxf->time_base = spf->time_base;
    2224          10 :             rate = av_inv_q(mxf->time_base);
    2225          10 :             avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
    2226          10 :             if((ret = mxf_init_timecode(s, st, rate)) < 0)
    2227           0 :                 return ret;
    2228             : 
    2229          10 :             sc->video_bit_rate = st->codecpar->bit_rate;
    2230          10 :             if (s->oformat == &ff_mxf_d10_muxer) {
    2231           1 :                 if (st->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO) {
    2232           0 :                     av_log(s, AV_LOG_ERROR, "error MXF D-10 only support MPEG-2 Video\n");
    2233           0 :                     return AVERROR(EINVAL);
    2234             :                 }
    2235           1 :                 if ((sc->video_bit_rate == 50000000) && (mxf->time_base.den == 25)) {
    2236           0 :                     sc->index = INDEX_D10_625_50_50_VIDEO;
    2237           1 :                 } else if ((sc->video_bit_rate == 49999840 || sc->video_bit_rate == 50000000) && (mxf->time_base.den != 25)) {
    2238           0 :                     sc->index = INDEX_D10_525_60_50_VIDEO;
    2239           1 :                 } else if (sc->video_bit_rate == 40000000) {
    2240           0 :                     if (mxf->time_base.den == 25) sc->index = INDEX_D10_625_50_40_VIDEO;
    2241           0 :                     else                          sc->index = INDEX_D10_525_60_40_VIDEO;
    2242           1 :                 } else if (sc->video_bit_rate == 30000000) {
    2243           1 :                     if (mxf->time_base.den == 25) sc->index = INDEX_D10_625_50_30_VIDEO;
    2244           0 :                     else                          sc->index = INDEX_D10_525_60_30_VIDEO;
    2245             :                 } else {
    2246           0 :                     av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");
    2247           0 :                     return -1;
    2248             :                 }
    2249             : 
    2250           1 :                 mxf->edit_unit_byte_count = KAG_SIZE; // system element
    2251           3 :                 mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate *
    2252           2 :                     mxf->time_base.num / (8*mxf->time_base.den);
    2253           1 :                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
    2254           1 :                 mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;
    2255           1 :                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
    2256             : 
    2257           1 :                 sc->signal_standard = 1;
    2258             :             }
    2259          10 :             if (mxf->signal_standard >= 0)
    2260           0 :                 sc->signal_standard = mxf->signal_standard;
    2261           9 :         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
    2262           9 :             if (st->codecpar->sample_rate != 48000) {
    2263           0 :                 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
    2264           0 :                 return -1;
    2265             :             }
    2266           9 :             avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
    2267           9 :             if (s->oformat == &ff_mxf_d10_muxer) {
    2268           1 :                 if (st->index != 1) {
    2269           0 :                     av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
    2270           0 :                     return -1;
    2271             :                 }
    2272           1 :                 if (st->codecpar->codec_id != AV_CODEC_ID_PCM_S16LE &&
    2273           0 :                     st->codecpar->codec_id != AV_CODEC_ID_PCM_S24LE) {
    2274           0 :                     av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");
    2275             :                 }
    2276           1 :                 sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;
    2277           8 :             } else if (s->oformat == &ff_mxf_opatom_muxer) {
    2278           1 :                 AVRational tbc = av_inv_q(mxf->audio_edit_rate);
    2279             : 
    2280           1 :                 if (st->codecpar->codec_id != AV_CODEC_ID_PCM_S16LE &&
    2281           0 :                     st->codecpar->codec_id != AV_CODEC_ID_PCM_S24LE) {
    2282           0 :                     av_log(s, AV_LOG_ERROR, "Only pcm_s16le and pcm_s24le audio codecs are implemented\n");
    2283           0 :                     return AVERROR_PATCHWELCOME;
    2284             :                 }
    2285           1 :                 if (st->codecpar->channels != 1) {
    2286           0 :                     av_log(s, AV_LOG_ERROR, "MXF OPAtom only supports single channel audio\n");
    2287           0 :                     return AVERROR(EINVAL);
    2288             :                 }
    2289             : 
    2290           1 :                 spf = ff_mxf_get_samples_per_frame(s, tbc);
    2291           1 :                 if (!spf) {
    2292           0 :                     av_log(s, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num);
    2293           0 :                     return AVERROR(EINVAL);
    2294             :                 }
    2295             : 
    2296           1 :                 mxf->time_base = st->time_base;
    2297           1 :                 if((ret = mxf_init_timecode(s, st, av_inv_q(spf->time_base))) < 0)
    2298           0 :                     return ret;
    2299             : 
    2300           1 :                 mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;
    2301           1 :                 mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codecpar->codec_id) * st->codecpar->channels) >> 3;
    2302           1 :                 sc->index = INDEX_WAV;
    2303             :             } else {
    2304           7 :                 mxf->slice_count = 1;
    2305             :             }
    2306             :         }
    2307             : 
    2308          19 :         if (!sc->index) {
    2309          16 :             sc->index = mxf_get_essence_container_ul_index(st->codecpar->codec_id);
    2310          16 :             if (sc->index == -1) {
    2311           0 :                 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
    2312             :                        "codec not currently supported in container\n", i);
    2313           0 :                 return -1;
    2314             :             }
    2315             :         }
    2316             : 
    2317          19 :         sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
    2318             : 
    2319          19 :         memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);
    2320          19 :         sc->track_essence_element_key[15] = present[sc->index];
    2321             :         PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);
    2322             : 
    2323          19 :         if (!present[sc->index])
    2324          19 :             mxf->essence_container_count++;
    2325          19 :         present[sc->index]++;
    2326             :     }
    2327             : 
    2328          11 :     if (s->oformat == &ff_mxf_d10_muxer || s->oformat == &ff_mxf_opatom_muxer) {
    2329           3 :         mxf->essence_container_count = 1;
    2330             :     }
    2331             : 
    2332          11 :     if (!(s->flags & AVFMT_FLAG_BITEXACT))
    2333           0 :         mxf_gen_umid(s);
    2334             : 
    2335          30 :     for (i = 0; i < s->nb_streams; i++) {
    2336          19 :         MXFStreamContext *sc = s->streams[i]->priv_data;
    2337             :         // update element count
    2338          19 :         sc->track_essence_element_key[13] = present[sc->index];
    2339          19 :         if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV
    2340           2 :             sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);
    2341             :         else
    2342          17 :             sc->order = AV_RB32(sc->track_essence_element_key+12);
    2343             :     }
    2344             : 
    2345          11 :     if (ff_parse_creation_time_metadata(s, &timestamp, 1) > 0)
    2346           0 :         mxf->timestamp = mxf_parse_timestamp(timestamp);
    2347          11 :     mxf->duration = -1;
    2348             : 
    2349          11 :     mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
    2350          11 :     if (!mxf->timecode_track)
    2351           0 :         return AVERROR(ENOMEM);
    2352          11 :     mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));
    2353          11 :     if (!mxf->timecode_track->priv_data)
    2354           0 :         return AVERROR(ENOMEM);
    2355          11 :     mxf->timecode_track->index = -1;
    2356             : 
    2357          11 :     if (!spf)
    2358           0 :         spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });
    2359             : 
    2360          11 :     if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)
    2361           0 :         return -1;
    2362             : 
    2363          11 :     return 0;
    2364             : }
    2365             : 
    2366             : static const uint8_t system_metadata_pack_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
    2367             : static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 };
    2368             : 
    2369         178 : static void mxf_write_system_item(AVFormatContext *s)
    2370             : {
    2371         178 :     MXFContext *mxf = s->priv_data;
    2372         178 :     AVIOContext *pb = s->pb;
    2373             :     unsigned frame;
    2374             :     uint32_t time_code;
    2375             : 
    2376         178 :     frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
    2377             : 
    2378             :     // write system metadata pack
    2379         178 :     avio_write(pb, system_metadata_pack_key, 16);
    2380         178 :     klv_encode_ber4_length(pb, 57);
    2381         178 :     avio_w8(pb, 0x5c); // UL, user date/time stamp, picture and sound item present
    2382         178 :     avio_w8(pb, 0x04); // content package rate
    2383         178 :     avio_w8(pb, 0x00); // content package type
    2384         178 :     avio_wb16(pb, 0x00); // channel handle
    2385         178 :     avio_wb16(pb, (mxf->tc.start + frame) & 0xFFFF); // continuity count, supposed to overflow
    2386         178 :     if (mxf->essence_container_count > 1)
    2387         152 :         avio_write(pb, multiple_desc_ul, 16);
    2388             :     else {
    2389          26 :         MXFStreamContext *sc = s->streams[0]->priv_data;
    2390          26 :         avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
    2391             :     }
    2392         178 :     avio_w8(pb, 0);
    2393         178 :     avio_wb64(pb, 0);
    2394         178 :     avio_wb64(pb, 0); // creation date/time stamp
    2395             : 
    2396         178 :     avio_w8(pb, 0x81); // SMPTE 12M time code
    2397         178 :     time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);
    2398         178 :     avio_wb32(pb, time_code);
    2399         178 :     avio_wb32(pb, 0); // binary group data
    2400         178 :     avio_wb64(pb, 0);
    2401             : 
    2402             :     // write system metadata package set
    2403         178 :     avio_write(pb, system_metadata_package_set_key, 16);
    2404         178 :     klv_encode_ber4_length(pb, 35);
    2405         178 :     avio_w8(pb, 0x83); // UMID
    2406         178 :     avio_wb16(pb, 0x20);
    2407         178 :     mxf_write_umid(s, 1);
    2408         178 : }
    2409             : 
    2410          25 : static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
    2411             : {
    2412          25 :     MXFContext *mxf = s->priv_data;
    2413          25 :     AVIOContext *pb = s->pb;
    2414          25 :     MXFStreamContext *sc = st->priv_data;
    2415          50 :     int packet_size = (uint64_t)sc->video_bit_rate*mxf->time_base.num /
    2416          25 :         (8*mxf->time_base.den); // frame size
    2417             :     int pad;
    2418             : 
    2419          25 :     packet_size += 16 + 4;
    2420          25 :     packet_size += klv_fill_size(packet_size);
    2421             : 
    2422          25 :     klv_encode_ber4_length(pb, pkt->size);
    2423          25 :     avio_write(pb, pkt->data, pkt->size);
    2424             : 
    2425             :     // ensure CBR muxing by padding to correct video frame size
    2426          25 :     pad = packet_size - pkt->size - 16 - 4;
    2427          25 :     if (pad > 20) {
    2428          25 :         avio_write(s->pb, klv_fill_key, 16);
    2429          25 :         pad -= 16 + 4;
    2430          25 :         klv_encode_ber4_length(s->pb, pad);
    2431          25 :         ffio_fill(s->pb, 0, pad);
    2432             :         av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
    2433             :     } else {
    2434           0 :         av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
    2435           0 :         ffio_fill(s->pb, 0, pad);
    2436             :     }
    2437          25 : }
    2438             : 
    2439          25 : static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
    2440             : {
    2441          25 :     MXFContext *mxf = s->priv_data;
    2442          25 :     AVIOContext *pb = s->pb;
    2443          25 :     int frame_size = pkt->size / st->codecpar->block_align;
    2444          25 :     uint8_t *samples = pkt->data;
    2445          25 :     uint8_t *end = pkt->data + pkt->size;
    2446             :     int i;
    2447             : 
    2448          25 :     klv_encode_ber4_length(pb, 4 + frame_size*4*8);
    2449             : 
    2450          25 :     avio_w8(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1));
    2451          25 :     avio_wl16(pb, frame_size);
    2452          25 :     avio_w8(pb, (1<<st->codecpar->channels)-1);
    2453             : 
    2454       48050 :     while (samples < end) {
    2455      144000 :         for (i = 0; i < st->codecpar->channels; i++) {
    2456             :             uint32_t sample;
    2457       96000 :             if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE) {
    2458           0 :                 sample = AV_RL24(samples)<< 4;
    2459           0 :                 samples += 3;
    2460             :             } else {
    2461       96000 :                 sample = AV_RL16(samples)<<12;
    2462       96000 :                 samples += 2;
    2463             :             }
    2464       96000 :             avio_wl32(pb, sample | i);
    2465             :         }
    2466      336000 :         for (; i < 8; i++)
    2467      288000 :             avio_wl32(pb, i);
    2468             :     }
    2469          25 : }
    2470             : 
    2471           4 : static int mxf_write_opatom_body_partition(AVFormatContext *s)
    2472             : {
    2473           4 :     MXFContext *mxf = s->priv_data;
    2474           4 :     AVIOContext *pb = s->pb;
    2475           4 :     AVStream *st = s->streams[0];
    2476           4 :     MXFStreamContext *sc = st->priv_data;
    2477           4 :     const uint8_t *key = NULL;
    2478             : 
    2479             :     int err;
    2480             : 
    2481           4 :     if (!mxf->header_written)
    2482           2 :         key = body_partition_key;
    2483             : 
    2484           4 :     if ((err = mxf_write_partition(s, 1, 0, key, 0)) < 0)
    2485           0 :         return err;
    2486           4 :     mxf_write_klv_fill(s);
    2487           4 :     avio_write(pb, sc->track_essence_element_key, 16);
    2488           4 :     klv_encode_ber9_length(pb, mxf->body_offset);
    2489           4 :     return 0;
    2490             : }
    2491             : 
    2492          50 : static int mxf_write_opatom_packet(AVFormatContext *s, AVPacket *pkt, MXFIndexEntry *ie)
    2493             : {
    2494          50 :     MXFContext *mxf = s->priv_data;
    2495          50 :     AVIOContext *pb = s->pb;
    2496             : 
    2497             :     int err;
    2498             : 
    2499          50 :     if (!mxf->header_written) {
    2500           2 :         if ((err = mxf_write_partition(s, 0, 0, header_open_partition_key, 1)) < 0)
    2501           0 :             return err;
    2502           2 :         mxf_write_klv_fill(s);
    2503             : 
    2504           2 :         if ((err = mxf_write_opatom_body_partition(s)) < 0)
    2505           0 :             return err;
    2506           2 :         mxf->header_written = 1;
    2507             :     }
    2508             : 
    2509          50 :     if (!mxf->edit_unit_byte_count) {
    2510           0 :         mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset;
    2511           0 :         mxf->index_entries[mxf->edit_units_count].flags = ie->flags;
    2512           0 :         mxf->index_entries[mxf->edit_units_count].temporal_ref = ie->temporal_ref;
    2513             :     }
    2514          50 :     mxf->edit_units_count++;
    2515          50 :     avio_write(pb, pkt->data, pkt->size);
    2516          50 :     mxf->body_offset += pkt->size;
    2517          50 :     avio_flush(pb);
    2518             : 
    2519          50 :     return 0;
    2520             : }
    2521             : 
    2522         405 : static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
    2523             : {
    2524         405 :     MXFContext *mxf = s->priv_data;
    2525         405 :     AVIOContext *pb = s->pb;
    2526         405 :     AVStream *st = s->streams[pkt->stream_index];
    2527         405 :     MXFStreamContext *sc = st->priv_data;
    2528         405 :     MXFIndexEntry ie = {0};
    2529             :     int err;
    2530             : 
    2531         405 :     if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
    2532          18 :         if ((err = av_reallocp_array(&mxf->index_entries, mxf->edit_units_count
    2533           9 :                                      + EDIT_UNITS_PER_BODY, sizeof(*mxf->index_entries))) < 0) {
    2534           0 :             mxf->edit_units_count = 0;
    2535           0 :             av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
    2536           0 :             return err;
    2537             :         }
    2538             :     }
    2539             : 
    2540         405 :     if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
    2541         128 :         if (!mxf_parse_mpeg2_frame(s, st, pkt, &ie)) {
    2542           0 :             av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
    2543           0 :             return -1;
    2544             :         }
    2545         277 :     } else if (st->codecpar->codec_id == AV_CODEC_ID_DNXHD) {
    2546          25 :         if (!mxf_parse_dnxhd_frame(s, st, pkt)) {
    2547           0 :             av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n");
    2548           0 :             return -1;
    2549             :         }
    2550         252 :     } else if (st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO) {
    2551          50 :         if (!mxf_parse_dv_frame(s, st, pkt)) {
    2552           0 :             av_log(s, AV_LOG_ERROR, "could not get dv profile\n");
    2553           0 :             return -1;
    2554             :         }
    2555         202 :     } else if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
    2556           0 :         if (!mxf_parse_h264_frame(s, st, pkt, &ie)) {
    2557           0 :             av_log(s, AV_LOG_ERROR, "could not get h264 profile\n");
    2558           0 :             return -1;
    2559             :         }
    2560             :     }
    2561             : 
    2562         405 :     if (s->oformat == &ff_mxf_opatom_muxer)
    2563          50 :         return mxf_write_opatom_packet(s, pkt, &ie);
    2564             : 
    2565         355 :     if (!mxf->header_written) {
    2566           9 :         if (mxf->edit_unit_byte_count) {
    2567           3 :             if ((err = mxf_write_partition(s, 1, 2, header_open_partition_key, 1)) < 0)
    2568           0 :                 return err;
    2569           3 :             mxf_write_klv_fill(s);
    2570           3 :             mxf_write_index_table_segment(s);
    2571             :         } else {
    2572           6 :             if ((err = mxf_write_partition(s, 0, 0, header_open_partition_key, 1)) < 0)
    2573           0 :                 return err;
    2574             :         }
    2575           9 :         mxf->header_written = 1;
    2576             :     }
    2577             : 
    2578         355 :     if (st->index == 0) {
    2579         281 :         if (!mxf->edit_unit_byte_count &&
    2580         206 :             (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
    2581           6 :             !(ie.flags & 0x33)) { // I-frame, GOP start
    2582           6 :             mxf_write_klv_fill(s);
    2583           6 :             if ((err = mxf_write_partition(s, 1, 2, body_partition_key, 0)) < 0)
    2584           0 :                 return err;
    2585           6 :             mxf_write_klv_fill(s);
    2586           6 :             mxf_write_index_table_segment(s);
    2587             :         }
    2588             : 
    2589         178 :         mxf_write_klv_fill(s);
    2590         178 :         mxf_write_system_item(s);
    2591             : 
    2592         178 :         if (!mxf->edit_unit_byte_count) {
    2593         103 :             mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset;
    2594         103 :             mxf->index_entries[mxf->edit_units_count].flags = ie.flags;
    2595         103 :             mxf->index_entries[mxf->edit_units_count].temporal_ref = ie.temporal_ref;
    2596         103 :             mxf->body_offset += KAG_SIZE; // size of system element
    2597             :         }
    2598         178 :         mxf->edit_units_count++;
    2599         177 :     } else if (!mxf->edit_unit_byte_count && st->index == 1) {
    2600         102 :         if (!mxf->edit_units_count) {
    2601           0 :             av_log(s, AV_LOG_ERROR, "No packets in first stream\n");
    2602           0 :             return AVERROR_PATCHWELCOME;
    2603             :         }
    2604         204 :         mxf->index_entries[mxf->edit_units_count-1].slice_offset =
    2605         204 :             mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset;
    2606             :     }
    2607             : 
    2608         355 :     mxf_write_klv_fill(s);
    2609         355 :     avio_write(pb, sc->track_essence_element_key, 16); // write key
    2610         355 :     if (s->oformat == &ff_mxf_d10_muxer) {
    2611          50 :         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
    2612          25 :             mxf_write_d10_video_packet(s, st, pkt);
    2613             :         else
    2614          25 :             mxf_write_d10_audio_packet(s, st, pkt);
    2615             :     } else {
    2616         305 :         klv_encode_ber4_length(pb, pkt->size); // write length
    2617         305 :         avio_write(pb, pkt->data, pkt->size);
    2618         305 :         mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size);
    2619             :     }
    2620             : 
    2621         355 :     avio_flush(pb);
    2622             : 
    2623         355 :     return 0;
    2624             : }
    2625             : 
    2626          11 : static void mxf_write_random_index_pack(AVFormatContext *s)
    2627             : {
    2628          11 :     MXFContext *mxf = s->priv_data;
    2629          11 :     AVIOContext *pb = s->pb;
    2630          11 :     uint64_t pos = avio_tell(pb);
    2631             :     int i;
    2632             : 
    2633          11 :     avio_write(pb, random_index_pack_key, 16);
    2634          11 :     klv_encode_ber_length(pb, 28 + 12LL*mxf->body_partitions_count);
    2635             : 
    2636          11 :     if (mxf->edit_unit_byte_count && s->oformat != &ff_mxf_opatom_muxer)
    2637           3 :         avio_wb32(pb, 1); // BodySID of header partition
    2638             :     else
    2639           8 :         avio_wb32(pb, 0);
    2640          11 :     avio_wb64(pb, 0); // offset of header partition
    2641             : 
    2642          19 :     for (i = 0; i < mxf->body_partitions_count; i++) {
    2643           8 :         avio_wb32(pb, 1); // BodySID
    2644           8 :         avio_wb64(pb, mxf->body_partition_offset[i]);
    2645             :     }
    2646             : 
    2647          11 :     avio_wb32(pb, 0); // BodySID of footer partition
    2648          11 :     avio_wb64(pb, mxf->footer_partition_offset);
    2649             : 
    2650          11 :     avio_wb32(pb, avio_tell(pb) - pos + 4);
    2651          11 : }
    2652             : 
    2653          11 : static int mxf_write_footer(AVFormatContext *s)
    2654             : {
    2655          11 :     MXFContext *mxf = s->priv_data;
    2656          11 :     AVIOContext *pb = s->pb;
    2657          11 :     int err = 0;
    2658             : 
    2659          22 :     if (!mxf->header_written ||
    2660          13 :         (s->oformat == &ff_mxf_opatom_muxer && !mxf->body_partition_offset)) {
    2661             :         /* reason could be invalid options/not supported codec/out of memory */
    2662           0 :         err = AVERROR_UNKNOWN;
    2663           0 :         goto end;
    2664             :     }
    2665             : 
    2666          11 :     mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
    2667             : 
    2668          11 :     mxf_write_klv_fill(s);
    2669          11 :     mxf->footer_partition_offset = avio_tell(pb);
    2670          11 :     if (mxf->edit_unit_byte_count && s->oformat != &ff_mxf_opatom_muxer) { // no need to repeat index
    2671           6 :         if ((err = mxf_write_partition(s, 0, 0, footer_partition_key, 0)) < 0)
    2672           0 :             goto end;
    2673             :     } else {
    2674           8 :         if ((err = mxf_write_partition(s, 0, 2, footer_partition_key, 0)) < 0)
    2675           0 :             goto end;
    2676           8 :         mxf_write_klv_fill(s);
    2677           8 :         mxf_write_index_table_segment(s);
    2678             :     }
    2679             : 
    2680          11 :     mxf_write_klv_fill(s);
    2681          11 :     mxf_write_random_index_pack(s);
    2682             : 
    2683          11 :     if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
    2684          11 :         if (s->oformat == &ff_mxf_opatom_muxer) {
    2685             :             /* rewrite body partition to update lengths */
    2686           2 :             avio_seek(pb, mxf->body_partition_offset[0], SEEK_SET);
    2687           2 :             if ((err = mxf_write_opatom_body_partition(s)) < 0)
    2688           0 :                 goto end;
    2689             :         }
    2690             : 
    2691          11 :         avio_seek(pb, 0, SEEK_SET);
    2692          11 :         if (mxf->edit_unit_byte_count && s->oformat != &ff_mxf_opatom_muxer) {
    2693           3 :             if ((err = mxf_write_partition(s, 1, 2, header_closed_partition_key, 1)) < 0)
    2694           0 :                 goto end;
    2695           3 :             mxf_write_klv_fill(s);
    2696           3 :             mxf_write_index_table_segment(s);
    2697             :         } else {
    2698           8 :             if ((err = mxf_write_partition(s, 0, 0, header_closed_partition_key, 1)) < 0)
    2699           0 :                 goto end;
    2700             :         }
    2701             :     }
    2702             : 
    2703          19 : end:
    2704          11 :     ff_audio_interleave_close(s);
    2705             : 
    2706          11 :     av_freep(&mxf->index_entries);
    2707          11 :     av_freep(&mxf->body_partition_offset);
    2708          11 :     av_freep(&mxf->timecode_track->priv_data);
    2709          11 :     av_freep(&mxf->timecode_track);
    2710             : 
    2711          11 :     mxf_free(s);
    2712             : 
    2713          11 :     return err < 0 ? err : 0;
    2714             : }
    2715             : 
    2716         985 : static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
    2717             : {
    2718         985 :     int i, stream_count = 0;
    2719             : 
    2720        2828 :     for (i = 0; i < s->nb_streams; i++)
    2721        1843 :         stream_count += !!s->streams[i]->last_in_packet_buffer;
    2722             : 
    2723        1882 :     if (stream_count && (s->nb_streams == stream_count || flush)) {
    2724         405 :         AVPacketList *pktl = s->internal->packet_buffer;
    2725         405 :         if (s->nb_streams != stream_count) {
    2726           8 :             AVPacketList *last = NULL;
    2727             :             // find last packet in edit unit
    2728          24 :             while (pktl) {
    2729           9 :                 if (!stream_count || pktl->pkt.stream_index == 0)
    2730             :                     break;
    2731           8 :                 last = pktl;
    2732           8 :                 pktl = pktl->next;
    2733           8 :                 stream_count--;
    2734             :             }
    2735             :             // purge packet queue
    2736          29 :             while (pktl) {
    2737          13 :                 AVPacketList *next = pktl->next;
    2738             : 
    2739          13 :                 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
    2740           1 :                     s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
    2741          13 :                 av_packet_unref(&pktl->pkt);
    2742          13 :                 av_freep(&pktl);
    2743          13 :                 pktl = next;
    2744             :             }
    2745           8 :             if (last)
    2746           8 :                 last->next = NULL;
    2747             :             else {
    2748           0 :                 s->internal->packet_buffer = NULL;
    2749           0 :                 s->internal->packet_buffer_end= NULL;
    2750           0 :                 goto out;
    2751             :             }
    2752           8 :             pktl = s->internal->packet_buffer;
    2753             :         }
    2754             : 
    2755         405 :         *out = pktl->pkt;
    2756         405 :         av_log(s, AV_LOG_TRACE, "out st:%d dts:%"PRId64"\n", (*out).stream_index, (*out).dts);
    2757         405 :         s->internal->packet_buffer = pktl->next;
    2758         405 :         if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
    2759         238 :             s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
    2760         405 :         if(!s->internal->packet_buffer)
    2761          59 :             s->internal->packet_buffer_end= NULL;
    2762         405 :         av_freep(&pktl);
    2763         405 :         return 1;
    2764             :     } else {
    2765        1160 :     out:
    2766         580 :         av_init_packet(out);
    2767         580 :         return 0;
    2768             :     }
    2769             : }
    2770             : 
    2771         513 : static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
    2772             : {
    2773         513 :     MXFStreamContext *sc  = s->streams[pkt ->stream_index]->priv_data;
    2774         513 :     MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data;
    2775             : 
    2776        1050 :     return next->dts > pkt->dts ||
    2777         383 :         (next->dts == pkt->dts && sc->order < sc2->order);
    2778             : }
    2779             : 
    2780         985 : static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
    2781             : {
    2782         985 :     return ff_audio_rechunk_interleave(s, out, pkt, flush,
    2783             :                                mxf_interleave_get_packet, mxf_compare_timestamps);
    2784             : }
    2785             : 
    2786             : #define MXF_COMMON_OPTIONS \
    2787             :     { "signal_standard", "Force/set Sigal Standard",\
    2788             :       offsetof(MXFContext, signal_standard), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2789             :     { "bt601", "ITU-R BT.601 and BT.656, also SMPTE 125M (525 and 625 line interlaced)",\
    2790             :       0, AV_OPT_TYPE_CONST, {.i64 = 1}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2791             :     { "bt1358", "ITU-R BT.1358 and ITU-R BT.799-3, also SMPTE 293M (525 and 625 line progressive)",\
    2792             :       0, AV_OPT_TYPE_CONST, {.i64 = 2}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2793             :     { "smpte347m", "SMPTE 347M (540 Mbps mappings)",\
    2794             :       0, AV_OPT_TYPE_CONST, {.i64 = 3}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2795             :     { "smpte274m", "SMPTE 274M (1125 line)",\
    2796             :       0, AV_OPT_TYPE_CONST, {.i64 = 4}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2797             :     { "smpte296m", "SMPTE 296M (750 line progressive)",\
    2798             :       0, AV_OPT_TYPE_CONST, {.i64 = 5}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2799             :     { "smpte349m", "SMPTE 349M (1485 Mbps mappings)",\
    2800             :       0, AV_OPT_TYPE_CONST, {.i64 = 6}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},\
    2801             :     { "smpte428", "SMPTE 428-1 DCDM",\
    2802             :       0, AV_OPT_TYPE_CONST, {.i64 = 7}, -1, 7, AV_OPT_FLAG_ENCODING_PARAM, "signal_standard"},
    2803             : 
    2804             : 
    2805             : 
    2806             : static const AVOption mxf_options[] = {
    2807             :     MXF_COMMON_OPTIONS
    2808             :     { "store_user_comments", "",
    2809             :       offsetof(MXFContext, store_user_comments), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
    2810             :     { NULL },
    2811             : };
    2812             : 
    2813             : static const AVClass mxf_muxer_class = {
    2814             :     .class_name     = "MXF muxer",
    2815             :     .item_name      = av_default_item_name,
    2816             :     .option         = mxf_options,
    2817             :     .version        = LIBAVUTIL_VERSION_INT,
    2818             : };
    2819             : 
    2820             : static const AVOption d10_options[] = {
    2821             :     { "d10_channelcount", "Force/set channelcount in generic sound essence descriptor",
    2822             :       offsetof(MXFContext, channel_count), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 8, AV_OPT_FLAG_ENCODING_PARAM},
    2823             :     MXF_COMMON_OPTIONS
    2824             :     { "store_user_comments", "",
    2825             :       offsetof(MXFContext, store_user_comments), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
    2826             :     { NULL },
    2827             : };
    2828             : 
    2829             : static const AVClass mxf_d10_muxer_class = {
    2830             :     .class_name     = "MXF-D10 muxer",
    2831             :     .item_name      = av_default_item_name,
    2832             :     .option         = d10_options,
    2833             :     .version        = LIBAVUTIL_VERSION_INT,
    2834             : };
    2835             : 
    2836             : static const AVOption opatom_options[] = {
    2837             :     { "mxf_audio_edit_rate", "Audio edit rate for timecode",
    2838             :         offsetof(MXFContext, audio_edit_rate), AV_OPT_TYPE_RATIONAL, {.dbl=25}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
    2839             :     MXF_COMMON_OPTIONS
    2840             :     { NULL },
    2841             : };
    2842             : 
    2843             : static const AVClass mxf_opatom_muxer_class = {
    2844             :     .class_name     = "MXF-OPAtom muxer",
    2845             :     .item_name      = av_default_item_name,
    2846             :     .option         = opatom_options,
    2847             :     .version        = LIBAVUTIL_VERSION_INT,
    2848             : };
    2849             : 
    2850             : AVOutputFormat ff_mxf_muxer = {
    2851             :     .name              = "mxf",
    2852             :     .long_name         = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
    2853             :     .mime_type         = "application/mxf",
    2854             :     .extensions        = "mxf",
    2855             :     .priv_data_size    = sizeof(MXFContext),
    2856             :     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
    2857             :     .video_codec       = AV_CODEC_ID_MPEG2VIDEO,
    2858             :     .write_header      = mxf_write_header,
    2859             :     .write_packet      = mxf_write_packet,
    2860             :     .write_trailer     = mxf_write_footer,
    2861             :     .flags             = AVFMT_NOTIMESTAMPS,
    2862             :     .interleave_packet = mxf_interleave,
    2863             :     .priv_class        = &mxf_muxer_class,
    2864             : };
    2865             : 
    2866             : AVOutputFormat ff_mxf_d10_muxer = {
    2867             :     .name              = "mxf_d10",
    2868             :     .long_name         = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format) D-10 Mapping"),
    2869             :     .mime_type         = "application/mxf",
    2870             :     .priv_data_size    = sizeof(MXFContext),
    2871             :     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
    2872             :     .video_codec       = AV_CODEC_ID_MPEG2VIDEO,
    2873             :     .write_header      = mxf_write_header,
    2874             :     .write_packet      = mxf_write_packet,
    2875             :     .write_trailer     = mxf_write_footer,
    2876             :     .flags             = AVFMT_NOTIMESTAMPS,
    2877             :     .interleave_packet = mxf_interleave,
    2878             :     .priv_class        = &mxf_d10_muxer_class,
    2879             : };
    2880             : 
    2881             : AVOutputFormat ff_mxf_opatom_muxer = {
    2882             :     .name              = "mxf_opatom",
    2883             :     .long_name         = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format) Operational Pattern Atom"),
    2884             :     .mime_type         = "application/mxf",
    2885             :     .extensions        = "mxf",
    2886             :     .priv_data_size    = sizeof(MXFContext),
    2887             :     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
    2888             :     .video_codec       = AV_CODEC_ID_DNXHD,
    2889             :     .write_header      = mxf_write_header,
    2890             :     .write_packet      = mxf_write_packet,
    2891             :     .write_trailer     = mxf_write_footer,
    2892             :     .flags             = AVFMT_NOTIMESTAMPS,
    2893             :     .interleave_packet = mxf_interleave,
    2894             :     .priv_class        = &mxf_opatom_muxer_class,
    2895             : };

Generated by: LCOV version 1.13