]> git.sesse.net Git - ffmpeg/blob - libavformat/mxf.c
Move frame_size fallback from ff_get_audio_frame_size() to av_get_audio_frame_duration()
[ffmpeg] / libavformat / mxf.c
1 /*
2  * MXF
3  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/common.h"
23 #include "mxf.h"
24
25 /**
26  * SMPTE RP224 http://www.smpte-ra.org/mdd/index.html
27  */
28 const MXFCodecUL ff_mxf_data_definition_uls[] = {
29     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO },
30     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO },
31     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,  AVMEDIA_TYPE_DATA },
32 };
33
34 const MXFCodecUL ff_mxf_codec_uls[] = {
35     /* PictureEssenceCoding */
36     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MP@ML Long GoP */
37     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* D-10 50Mbps PAL */
38     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MP@HL Long GoP */
39     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* 422P@HL I-Frame */
40     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14,      AV_CODEC_ID_MPEG4 }, /* XDCAM proxy_pal030926.mxf */
41     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13,    AV_CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */
42     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,   AV_CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
43     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,   AV_CODEC_ID_RAWVIDEO }, /* Uncompressed */
44     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, 15,   AV_CODEC_ID_RAWVIDEO }, /* Uncompressed 422 8-bit */
45     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x71,0x00,0x00,0x00 }, 13,      AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
46     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x03,0x02,0x00,0x00 }, 14,      AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
47     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14,       AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra */
48     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x31,0x11,0x01 }, 14,       AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC SPS/PPS in-band */
49     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x01 }, 16,       AV_CODEC_ID_V210 }, /* V210 */
50     /* SoundEssenceCompression */
51     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13,  AV_CODEC_ID_PCM_S16LE }, /* Uncompressed */
52     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,  AV_CODEC_ID_PCM_S16LE },
53     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, 13,  AV_CODEC_ID_PCM_S16BE }, /* From Omneon MXF file */
54     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, 15,   AV_CODEC_ID_PCM_ALAW }, /* XDCAM Proxy C0023S01.mxf */
55     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15,        AV_CODEC_ID_AC3 },
56     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15,        AV_CODEC_ID_MP2 }, /* MP2 or MP3 */
57   //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, 15,    AV_CODEC_ID_DOLBY_E }, /* Dolby-E */
58     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       AV_CODEC_ID_NONE },
59 };
60
61 const MXFCodecUL ff_mxf_pixel_format_uls[] = {
62     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x01 }, 16, AV_PIX_FMT_UYVY422 },
63     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x02 }, 16, AV_PIX_FMT_YUYV422 },
64     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,    AV_PIX_FMT_NONE },
65 };
66
67 static const struct {
68     enum AVPixelFormat pix_fmt;
69     const char data[16];
70 } ff_mxf_pixel_layouts[] = {
71     /**
72      * See SMPTE 377M E.2.46
73      *
74      * Note: Only RGB, palette based and "abnormal" YUV pixel formats like 4:2:2:4 go here.
75      *       For regular YUV, use CDCIPictureEssenceDescriptor.
76      *
77      * Note: Do not use these for encoding descriptors for little-endian formats until we
78      *       get samples or official word from SMPTE on how/if those can be encoded.
79      */
80     {AV_PIX_FMT_ABGR,    {'A', 8,  'B', 8,  'G', 8, 'R', 8                 }},
81     {AV_PIX_FMT_ARGB,    {'A', 8,  'R', 8,  'G', 8, 'B', 8                 }},
82     {AV_PIX_FMT_BGR24,   {'B', 8,  'G', 8,  'R', 8                         }},
83     {AV_PIX_FMT_BGRA,    {'B', 8,  'G', 8,  'R', 8, 'A', 8                 }},
84     {AV_PIX_FMT_RGB24,   {'R', 8,  'G', 8,  'B', 8                         }},
85     {AV_PIX_FMT_RGB444BE,{'F', 4,  'R', 4,  'G', 4, 'B', 4                 }},
86     {AV_PIX_FMT_RGB48BE, {'R', 8,  'r', 8,  'G', 8, 'g', 8, 'B', 8, 'b', 8 }},
87     {AV_PIX_FMT_RGB48BE, {'R', 16, 'G', 16, 'B', 16                        }},
88     {AV_PIX_FMT_RGB48LE, {'r', 8,  'R', 8,  'g', 8, 'G', 8, 'b', 8, 'B', 8 }},
89     {AV_PIX_FMT_RGB555BE,{'F', 1,  'R', 5,  'G', 5, 'B', 5                 }},
90     {AV_PIX_FMT_RGB565BE,{'R', 5,  'G', 6,  'B', 5                         }},
91     {AV_PIX_FMT_RGBA,    {'R', 8,  'G', 8,  'B', 8, 'A', 8                 }},
92     {AV_PIX_FMT_PAL8,    {'P', 8                                           }},
93 };
94
95 static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts);
96
97 int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt)
98 {
99     int x;
100
101     for(x = 0; x < num_pixel_layouts; x++) {
102         if (!memcmp(pixel_layout, ff_mxf_pixel_layouts[x].data, 16)) {
103             *pix_fmt = ff_mxf_pixel_layouts[x].pix_fmt;
104             return 0;
105         }
106     }
107
108     return -1;
109 }
110
111 static const MXFSamplesPerFrame mxf_spf[] = {
112     { { 1001, 24000 }, { 2002, 0,    0,    0,    0,    0 } }, // FILM 23.976
113     { { 1, 24},        { 2000, 0,    0,    0,    0,    0 } }, // FILM 24
114     { { 1001, 30000 }, { 1602, 1601, 1602, 1601, 1602, 0 } }, // NTSC 29.97
115     { { 1001, 60000 }, { 801,  801,  801,  801,  800,  0 } }, // NTSC 59.94
116     { { 1, 25 },       { 1920, 0,    0,    0,    0,    0 } }, // PAL 25
117     { { 1, 50 },       { 960,  0,    0,    0,    0,    0 } }, // PAL 50
118 };
119
120 static const AVRational mxf_time_base[] = {
121     { 1001, 24000 },
122     { 1, 24},
123     { 1001, 30000 },
124     { 1001, 60000 },
125     { 1, 25 },
126     { 1, 50 },
127     { 0, 0}
128 };
129
130 const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s,
131                                                        AVRational time_base)
132 {
133     int idx = av_find_nearest_q_idx(time_base, mxf_time_base);
134     AVRational diff = av_sub_q(time_base, mxf_time_base[idx]);
135
136     diff.num = abs(diff.num);
137
138     if (av_cmp_q(diff, (AVRational){1, 1000}) >= 0)
139         return NULL;
140
141     if (av_cmp_q(time_base, mxf_time_base[idx]))
142         av_log(s, AV_LOG_WARNING,
143                "%d/%d input time base matched %d/%d container time base\n",
144                time_base.num, time_base.den,
145                mxf_spf[idx].time_base.num,
146                mxf_spf[idx].time_base.den);
147
148     return &mxf_spf[idx];
149 }