blob: bfc3218b815a0a88f7f349078127c973cddb5816
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 | { { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x6F,0x3C,0x8C,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_VIDEO }, /* LegacyPicture Avid Media Composer MXF */ |
32 | { { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x78,0xE1,0xEB,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_AUDIO }, /* LegacySound Avid Media Composer MXF */ |
33 | { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVMEDIA_TYPE_DATA }, |
34 | }; |
35 | |
36 | const MXFCodecUL ff_mxf_codec_uls[] = { |
37 | /* PictureEssenceCoding */ |
38 | { { 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 */ |
39 | { { 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 */ |
40 | { { 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 */ |
41 | { { 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 */ |
42 | { { 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 */ |
43 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13, AV_CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */ |
44 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000 }, /* JPEG 2000 code stream */ |
45 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x01,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 SP@LL */ |
46 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x02,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 SP@ML */ |
47 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x03,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 MP@LL */ |
48 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x04,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 MP@ML */ |
49 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x05,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 MP@HL */ |
50 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x06,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L0 */ |
51 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x07,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L1 */ |
52 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x08,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L2 */ |
53 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x09,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L3 */ |
54 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x04,0x0A,0x00,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC1 AP@L4 */ |
55 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, AV_CODEC_ID_RAWVIDEO }, /* uncompressed */ |
56 | { { 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 */ |
57 | { { 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 */ |
58 | { { 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 */ |
59 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0E,0x04,0x02,0x01,0x02,0x04,0x01,0x00 }, 16, AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD Legacy Avid Media Composer MXF */ |
60 | { { 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 */ |
61 | { { 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 */ |
62 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x01 }, 16, AV_CODEC_ID_V210 }, /* V210 */ |
63 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0E,0x04,0x02,0x01,0x02,0x11,0x00,0x00 }, 14, AV_CODEC_ID_PRORES }, /* Avid MC7 ProRes */ |
64 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x03,0x06,0x00,0x00 }, 14, AV_CODEC_ID_PRORES }, /* Apple ProRes */ |
65 | /* SoundEssenceCompression */ |
66 | { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14, AV_CODEC_ID_AAC }, /* MPEG-2 AAC ADTS (legacy) */ |
67 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16LE }, /* uncompressed */ |
68 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16LE }, |
69 | { { 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 */ |
70 | { { 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 */ |
71 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15, AV_CODEC_ID_AC3 }, |
72 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15, AV_CODEC_ID_MP2 }, /* MP2 or MP3 */ |
73 | //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, 15, AV_CODEC_ID_DOLBY_E }, /* Dolby-E */ |
74 | { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, |
75 | }; |
76 | |
77 | const MXFCodecUL ff_mxf_pixel_format_uls[] = { |
78 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x01 }, 16, AV_PIX_FMT_UYVY422 }, |
79 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x02 }, 16, AV_PIX_FMT_YUYV422 }, |
80 | { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_PIX_FMT_NONE }, |
81 | }; |
82 | |
83 | const MXFCodecUL ff_mxf_codec_tag_uls[] = { |
84 | { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0E,0x04,0x03,0x01,0x01,0x03,0x01,0x00 }, 15, MKTAG('A', 'V', 'u', 'p') }, /* Avid 1:1 */ |
85 | { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 }, |
86 | }; |
87 | |
88 | static const struct { |
89 | enum AVPixelFormat pix_fmt; |
90 | const char data[16]; |
91 | } ff_mxf_pixel_layouts[] = { |
92 | /** |
93 | * See SMPTE 377M E.2.46 |
94 | * |
95 | * Note: Only RGB, palette based and "abnormal" YUV pixel formats like 4:2:2:4 go here. |
96 | * For regular YUV, use CDCIPictureEssenceDescriptor. |
97 | * |
98 | * Note: Do not use these for encoding descriptors for little-endian formats until we |
99 | * get samples or official word from SMPTE on how/if those can be encoded. |
100 | */ |
101 | {AV_PIX_FMT_ABGR, {'A', 8, 'B', 8, 'G', 8, 'R', 8 }}, |
102 | {AV_PIX_FMT_ARGB, {'A', 8, 'R', 8, 'G', 8, 'B', 8 }}, |
103 | {AV_PIX_FMT_BGR24, {'B', 8, 'G', 8, 'R', 8 }}, |
104 | {AV_PIX_FMT_BGRA, {'B', 8, 'G', 8, 'R', 8, 'A', 8 }}, |
105 | {AV_PIX_FMT_RGB24, {'R', 8, 'G', 8, 'B', 8 }}, |
106 | {AV_PIX_FMT_RGB444BE,{'F', 4, 'R', 4, 'G', 4, 'B', 4 }}, |
107 | {AV_PIX_FMT_RGB48BE, {'R', 8, 'r', 8, 'G', 8, 'g', 8, 'B', 8, 'b', 8 }}, |
108 | {AV_PIX_FMT_RGB48BE, {'R', 16, 'G', 16, 'B', 16 }}, |
109 | {AV_PIX_FMT_RGB48LE, {'r', 8, 'R', 8, 'g', 8, 'G', 8, 'b', 8, 'B', 8 }}, |
110 | {AV_PIX_FMT_RGB555BE,{'F', 1, 'R', 5, 'G', 5, 'B', 5 }}, |
111 | {AV_PIX_FMT_RGB565BE,{'R', 5, 'G', 6, 'B', 5 }}, |
112 | {AV_PIX_FMT_RGBA, {'R', 8, 'G', 8, 'B', 8, 'A', 8 }}, |
113 | {AV_PIX_FMT_PAL8, {'P', 8 }}, |
114 | {AV_PIX_FMT_GRAY8, {'A', 8 }}, |
115 | }; |
116 | |
117 | static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts); |
118 | |
119 | int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt) |
120 | { |
121 | int x; |
122 | |
123 | for(x = 0; x < num_pixel_layouts; x++) { |
124 | if (!memcmp(pixel_layout, ff_mxf_pixel_layouts[x].data, 16)) { |
125 | *pix_fmt = ff_mxf_pixel_layouts[x].pix_fmt; |
126 | return 0; |
127 | } |
128 | } |
129 | |
130 | return -1; |
131 | } |
132 | |
133 | static const MXFSamplesPerFrame mxf_spf[] = { |
134 | { { 1001, 24000 }, { 2002, 0, 0, 0, 0, 0 } }, // FILM 23.976 |
135 | { { 1, 24}, { 2000, 0, 0, 0, 0, 0 } }, // FILM 24 |
136 | { { 1001, 30000 }, { 1602, 1601, 1602, 1601, 1602, 0 } }, // NTSC 29.97 |
137 | { { 1001, 60000 }, { 801, 801, 801, 801, 800, 0 } }, // NTSC 59.94 |
138 | { { 1, 25 }, { 1920, 0, 0, 0, 0, 0 } }, // PAL 25 |
139 | { { 1, 50 }, { 960, 0, 0, 0, 0, 0 } }, // PAL 50 |
140 | }; |
141 | |
142 | static const AVRational mxf_time_base[] = { |
143 | { 1001, 24000 }, |
144 | { 1, 24}, |
145 | { 1001, 30000 }, |
146 | { 1001, 60000 }, |
147 | { 1, 25 }, |
148 | { 1, 50 }, |
149 | { 0, 0} |
150 | }; |
151 | |
152 | const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, |
153 | AVRational time_base) |
154 | { |
155 | int idx = av_find_nearest_q_idx(time_base, mxf_time_base); |
156 | AVRational diff = av_sub_q(time_base, mxf_time_base[idx]); |
157 | |
158 | diff.num = abs(diff.num); |
159 | |
160 | if (av_cmp_q(diff, (AVRational){1, 1000}) >= 0) |
161 | return NULL; |
162 | |
163 | if (av_cmp_q(time_base, mxf_time_base[idx])) |
164 | av_log(s, AV_LOG_WARNING, |
165 | "%d/%d input time base matched %d/%d container time base\n", |
166 | time_base.num, time_base.den, |
167 | mxf_spf[idx].time_base.num, |
168 | mxf_spf[idx].time_base.den); |
169 | |
170 | return &mxf_spf[idx]; |
171 | } |
172 |