LCOV - code coverage report
Current view: top level - libavformat - mxfenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1203 1513 79.5 %
Date: 2018-05-20 11:54:08 Functions: 62 67 92.5 %

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

Generated by: LCOV version 1.13