FFmpeg
dv_profile.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "config.h"
20 
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/log.h"
26 #include "libavutil/macros.h"
27 #include "libavutil/pixdesc.h"
28 
29 #include "avcodec.h"
30 #include "dv_profile.h"
31 #include "dv_profile_internal.h"
32 
33 #if CONFIG_DVPROFILE
34 
35 static const uint8_t dv_audio_shuffle525[10][9] = {
36  { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
37  { 6, 36, 66, 26, 56, 86, 16, 46, 76 },
38  { 12, 42, 72, 2, 32, 62, 22, 52, 82 },
39  { 18, 48, 78, 8, 38, 68, 28, 58, 88 },
40  { 24, 54, 84, 14, 44, 74, 4, 34, 64 },
41 
42  { 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */
43  { 7, 37, 67, 27, 57, 87, 17, 47, 77 },
44  { 13, 43, 73, 3, 33, 63, 23, 53, 83 },
45  { 19, 49, 79, 9, 39, 69, 29, 59, 89 },
46  { 25, 55, 85, 15, 45, 75, 5, 35, 65 },
47 };
48 
49 static const uint8_t dv_audio_shuffle625[12][9] = {
50  { 0, 36, 72, 26, 62, 98, 16, 52, 88 }, /* 1st channel */
51  { 6, 42, 78, 32, 68, 104, 22, 58, 94 },
52  { 12, 48, 84, 2, 38, 74, 28, 64, 100 },
53  { 18, 54, 90, 8, 44, 80, 34, 70, 106 },
54  { 24, 60, 96, 14, 50, 86, 4, 40, 76 },
55  { 30, 66, 102, 20, 56, 92, 10, 46, 82 },
56 
57  { 1, 37, 73, 27, 63, 99, 17, 53, 89 }, /* 2nd channel */
58  { 7, 43, 79, 33, 69, 105, 23, 59, 95 },
59  { 13, 49, 85, 3, 39, 75, 29, 65, 101 },
60  { 19, 55, 91, 9, 45, 81, 35, 71, 107 },
61  { 25, 61, 97, 15, 51, 87, 5, 41, 77 },
62  { 31, 67, 103, 21, 57, 93, 11, 47, 83 },
63 };
64 
65 /* macroblock bit budgets */
66 static const uint8_t block_sizes_dv2550[8] = {
67  112, 112, 112, 112, 80, 80, 0, 0,
68 };
69 
70 static const uint8_t block_sizes_dv100[8] = {
71  80, 80, 80, 80, 80, 80, 64, 64,
72 };
73 
74 static const AVDVProfile dv_profiles[] = {
75  { .dsf = 0,
76  .video_stype = 0x0,
77  .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */
78  .difseg_size = 10,
79  .n_difchan = 1,
80  .time_base = { 1001, 30000 },
81  .ltc_divisor = 30,
82  .height = 480,
83  .width = 720,
84  .sar = { { 8, 9 }, { 32, 27 } },
85  .pix_fmt = AV_PIX_FMT_YUV411P,
86  .bpm = 6,
87  .block_sizes = block_sizes_dv2550,
88  .audio_stride = 90,
89  .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
90  .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
91  .audio_shuffle = dv_audio_shuffle525, },
92  { .dsf = 1,
93  .video_stype = 0x0,
94  .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */
95  .difseg_size = 12,
96  .n_difchan = 1,
97  .time_base = { 1, 25 },
98  .ltc_divisor = 25,
99  .height = 576,
100  .width = 720,
101  .sar = { { 16, 15 }, { 64, 45 } },
102  .pix_fmt = AV_PIX_FMT_YUV420P,
103  .bpm = 6,
104  .block_sizes = block_sizes_dv2550,
105  .audio_stride = 108,
106  .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
107  .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
108  .audio_shuffle = dv_audio_shuffle625, },
109  { .dsf = 1,
110  .video_stype = 0x0,
111  .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */
112  .difseg_size = 12,
113  .n_difchan = 1,
114  .time_base = { 1, 25 },
115  .ltc_divisor = 25,
116  .height = 576,
117  .width = 720,
118  .sar = { { 16, 15 }, { 64, 45 } },
119  .pix_fmt = AV_PIX_FMT_YUV411P,
120  .bpm = 6,
121  .block_sizes = block_sizes_dv2550,
122  .audio_stride = 108,
123  .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
124  .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
125  .audio_shuffle = dv_audio_shuffle625, },
126  { .dsf = 0,
127  .video_stype = 0x4,
128  .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */
129  .difseg_size = 10, /* also known as "DVCPRO50" */
130  .n_difchan = 2,
131  .time_base = { 1001, 30000 },
132  .ltc_divisor = 30,
133  .height = 480,
134  .width = 720,
135  .sar = { { 8, 9 }, { 32, 27 } },
136  .pix_fmt = AV_PIX_FMT_YUV422P,
137  .bpm = 6,
138  .block_sizes = block_sizes_dv2550,
139  .audio_stride = 90,
140  .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
141  .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
142  .audio_shuffle = dv_audio_shuffle525, },
143  { .dsf = 1,
144  .video_stype = 0x4,
145  .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */
146  .difseg_size = 12, /* also known as "DVCPRO50" */
147  .n_difchan = 2,
148  .time_base = { 1, 25 },
149  .ltc_divisor = 25,
150  .height = 576,
151  .width = 720,
152  .sar = { { 16, 15 }, { 64, 45 } },
153  .pix_fmt = AV_PIX_FMT_YUV422P,
154  .bpm = 6,
155  .block_sizes = block_sizes_dv2550,
156  .audio_stride = 108,
157  .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
158  .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
159  .audio_shuffle = dv_audio_shuffle625, },
160  { .dsf = 0,
161  .video_stype = 0x14,
162  .frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */
163  .difseg_size = 10, /* also known as "DVCPRO HD" */
164  .n_difchan = 4,
165  .time_base = { 1001, 30000 },
166  .ltc_divisor = 30,
167  .height = 1080,
168  .width = 1280,
169  .sar = { { 1, 1 }, { 3, 2 } },
170  .pix_fmt = AV_PIX_FMT_YUV422P,
171  .bpm = 8,
172  .block_sizes = block_sizes_dv100,
173  .audio_stride = 90,
174  .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
175  .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
176  .audio_shuffle = dv_audio_shuffle525, },
177  { .dsf = 1,
178  .video_stype = 0x14,
179  .frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */
180  .difseg_size = 12, /* also known as "DVCPRO HD" */
181  .n_difchan = 4,
182  .time_base = { 1, 25 },
183  .ltc_divisor = 25,
184  .height = 1080,
185  .width = 1440,
186  .sar = { { 1, 1 }, { 4, 3 } },
187  .pix_fmt = AV_PIX_FMT_YUV422P,
188  .bpm = 8,
189  .block_sizes = block_sizes_dv100,
190  .audio_stride = 108,
191  .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
192  .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
193  .audio_shuffle = dv_audio_shuffle625, },
194  { .dsf = 0,
195  .video_stype = 0x18,
196  .frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */
197  .difseg_size = 10, /* also known as "DVCPRO HD" */
198  .n_difchan = 2,
199  .time_base = { 1001, 60000 },
200  .ltc_divisor = 60,
201  .height = 720,
202  .width = 960,
203  .sar = { { 1, 1 }, { 4, 3 } },
204  .pix_fmt = AV_PIX_FMT_YUV422P,
205  .bpm = 8,
206  .block_sizes = block_sizes_dv100,
207  .audio_stride = 90,
208  .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
209  .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
210  .audio_shuffle = dv_audio_shuffle525, },
211  { .dsf = 1,
212  .video_stype = 0x18,
213  .frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */
214  .difseg_size = 12, /* also known as "DVCPRO HD" */
215  .n_difchan = 2,
216  .time_base = { 1, 50 },
217  .ltc_divisor = 50,
218  .height = 720,
219  .width = 960,
220  .sar = { { 1, 1 }, { 4, 3 } },
221  .pix_fmt = AV_PIX_FMT_YUV422P,
222  .bpm = 8,
223  .block_sizes = block_sizes_dv100,
224  .audio_stride = 90,
225  .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
226  .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
227  .audio_shuffle = dv_audio_shuffle625, },
228  { .dsf = 1,
229  .video_stype = 0x1,
230  .frame_size = 144000, /* IEC 61883-5 - 625/50 (PAL) */
231  .difseg_size = 12,
232  .n_difchan = 1,
233  .time_base = { 1, 25 },
234  .ltc_divisor = 25,
235  .height = 576,
236  .width = 720,
237  .sar = { { 16, 15 }, { 64, 45 } },
238  .pix_fmt = AV_PIX_FMT_YUV420P,
239  .bpm = 6,
240  .block_sizes = block_sizes_dv2550,
241  .audio_stride = 108,
242  .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
243  .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
244  .audio_shuffle = dv_audio_shuffle625, }
245 };
246 
247 void ff_dv_print_profiles(void *logctx, int loglevel)
248 {
249  int i;
250  for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) {
251  const AVDVProfile *p = &dv_profiles[i];
252  av_log(logctx, loglevel,
253  "Frame size: %dx%d; pixel format: %s, framerate: %d/%d\n",
255  p->time_base.den, p->time_base.num);
256  }
257 }
258 
259 #endif /* CONFIG_DVPROFILE */
260 
262  const uint8_t *frame, unsigned buf_size)
263 {
264 #if CONFIG_DVPROFILE
265  int i, dsf, stype, pal;
266 
267  if(buf_size < DV_PROFILE_BYTES)
268  return NULL;
269 
270  dsf = (frame[3] & 0x80) >> 7;
271  stype = frame[80 * 5 + 48 + 3] & 0x1f;
272  pal = !!(frame[80 * 5 + 48 + 3] & 0x20);
273 
274  /* 576i50 25Mbps 4:1:1 is a special case */
275  if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) ||
276  (stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576))
277  return &dv_profiles[2];
278 
279  /* hack for trac issues #8333 and #2177, PAL DV files with dsf flag 0 - detect via pal flag and buf_size */
280  if (dsf == 0 && pal == 1 && stype == dv_profiles[1].video_stype && buf_size == dv_profiles[1].frame_size)
281  return &dv_profiles[1];
282 
283  for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
284  if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype)
285  return &dv_profiles[i];
286 
287  /* check if old sys matches and assumes corrupted input */
288  if (sys && buf_size == sys->frame_size)
289  return sys;
290 
291  /* hack for trac issue #217, dv files created with QuickTime 3 */
292  if ((frame[3] & 0x7f) == 0x3f && frame[80 * 5 + 48 + 3] == 0xff)
293  return &dv_profiles[dsf];
294 #endif
295 
296  return NULL;
297 }
298 
300  const uint8_t *frame, unsigned buf_size)
301 {
302  return ff_dv_frame_profile(NULL, sys, frame, buf_size);
303 }
304 
306  enum AVPixelFormat pix_fmt)
307 {
308 #if CONFIG_DVPROFILE
310 #endif
311 
312  return NULL;
313 }
314 
316  enum AVPixelFormat pix_fmt,
317  AVRational frame_rate)
318 {
319  const AVDVProfile *p = NULL;
320 #if CONFIG_DVPROFILE
321  int i;
322  /* frame rate is necessary to select between 720p50 and 720p60 profiles */
323  int invalid_framerate = frame_rate.num == 0 || frame_rate.den == 0;
324 
325  for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
326  if (height == dv_profiles[i].height &&
327  pix_fmt == dv_profiles[i].pix_fmt &&
328  width == dv_profiles[i].width)
329  {
330  if( invalid_framerate || av_div_q(dv_profiles[i].time_base, frame_rate).num == 1 )
331  return &dv_profiles[i];
332 
333  if(!p)
334  p = &dv_profiles[i];
335  }
336 #endif
337 
338  return p;
339 }
340 
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
dv_profile_internal.h
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
ff_dv_frame_profile
const AVDVProfile * ff_dv_frame_profile(AVCodecContext *codec, const AVDVProfile *sys, const uint8_t *frame, unsigned buf_size)
Get a DV profile for the provided compressed frame.
Definition: dv_profile.c:261
pixdesc.h
av_dv_codec_profile
const AVDVProfile * av_dv_codec_profile(int width, int height, enum AVPixelFormat pix_fmt)
Get a DV profile for the provided stream parameters.
Definition: dv_profile.c:305
DV_PROFILE_BYTES
#define DV_PROFILE_BYTES
Definition: dv_profile.h:29
ff_dv_print_profiles
void ff_dv_print_profiles(void *logctx, int loglevel)
Print all allowed DV profiles into logctx at specified logging level.
macros.h
AVDVProfile::dsf
int dsf
Definition: dv_profile.h:39
dv_profile.h
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:613
AVRational::num
int num
Numerator.
Definition: rational.h:59
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
width
#define width
intreadwrite.h
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
frame_size
int frame_size
Definition: mxfenc.c:2205
AVDVProfile::pix_fmt
enum AVPixelFormat pix_fmt
Definition: dv_profile.h:49
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_dv_frame_profile
const AVDVProfile * av_dv_frame_profile(const AVDVProfile *sys, const uint8_t *frame, unsigned buf_size)
Get a DV profile for the provided compressed frame.
Definition: dv_profile.c:299
AVDVProfile::height
int height
Definition: dv_profile.h:46
height
#define height
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVDVProfile::width
int width
Definition: dv_profile.h:47
avcodec.h
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVCodecContext
main external API structure.
Definition: avcodec.h:426
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVDVProfile
Definition: dv_profile.h:38
AVDVProfile::time_base
AVRational time_base
Definition: dv_profile.h:44
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:613
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
AVCodecContext::codec_tag
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:451
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_dv_codec_profile2
const AVDVProfile * av_dv_codec_profile2(int width, int height, enum AVPixelFormat pix_fmt, AVRational frame_rate)
Get a DV profile for the provided stream parameters.
Definition: dv_profile.c:315
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2808
AVDVProfile::frame_size
int frame_size
Definition: dv_profile.h:41