2 * General DV muxer/demuxer
3 * Copyright (c) 2003 Roman Shaposhnick
5 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
6 * of DV technical info.
9 * Copyright (c) 2002 Fabrice Bellard.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 typedef struct DVDemuxContext
{
35 typedef struct DVMuxContext
{
36 const DVprofile
* sys
; /* Current DV profile. E.g.: 525/60, 625/50 */
37 uint8_t frame_buf
[144000]; /* frame under contruction */
38 FifoBuffer audio_data
; /* Fifo for storing excessive amounts of PCM */
39 int frames
; /* Number of a current frame */
40 time_t start_time
; /* Start time of recording */
41 uint8_t aspect
; /* Aspect ID 0 - 4:3, 7 - 16:9 */
42 int has_audio
; /* frame under contruction has audio */
43 int has_video
; /* frame under contruction has video */
46 enum dv_section_type
{
47 dv_sect_header
= 0x1f,
48 dv_sect_subcode
= 0x3f,
55 dv_header525
= 0x3f, /* see dv_write_pack for important details on */
56 dv_header625
= 0xbf, /* these two packs */
58 dv_audio_source
= 0x50,
59 dv_audio_control
= 0x51,
60 dv_audio_recdate
= 0x52,
61 dv_audio_rectime
= 0x53,
62 dv_video_source
= 0x60,
63 dv_video_control
= 0x61,
64 dv_viedo_recdate
= 0x62,
65 dv_video_rectime
= 0x63,
66 dv_unknown_pack
= 0xff,
72 * The reason why the following three big ugly looking tables are
73 * here is my lack of DV spec IEC 61834. The tables were basically
74 * constructed to make code that places packs in SSYB, VAUX and
75 * AAUX blocks very simple and table-driven. They conform to the
76 * SMPTE 314M and the output of my personal DV camcorder, neither
77 * of which is sufficient for a reliable DV stream producing. Thus
78 * while code is still in development I'll be gathering input from
79 * people with different DV equipment and modifying the tables to
80 * accommodate all the quirks. Later on, if possible, some of them
81 * will be folded into smaller tables and/or switch-if logic. For
82 * now, my only excuse is -- they don't eat up that much of a space.
85 static const int dv_ssyb_packs_dist
[12][6] = {
86 { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
87 { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
88 { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
89 { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
90 { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
91 { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
92 { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
93 { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
94 { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
95 { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
96 { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
97 { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
100 static const int dv_vaux_packs_dist
[12][15] = {
101 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
102 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
103 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
104 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
105 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
106 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
107 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
108 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
109 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
110 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
111 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
112 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
113 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
114 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
115 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
116 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
117 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
118 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
119 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
120 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
121 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
122 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
123 { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff,
124 0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
127 static const int dv_aaux_packs_dist
[12][9] = {
128 { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
129 { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
130 { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
131 { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
132 { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
133 { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
134 { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
135 { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
136 { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
137 { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
138 { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
139 { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
142 static inline uint16_t dv_audio_12to16(uint16_t sample
)
144 uint16_t shift
, result
;
146 sample
= (sample
< 0x800) ? sample
: sample
| 0xf000;
147 shift
= (sample
& 0xf00) >> 8;
149 if (shift
< 0x2 || shift
> 0xd) {
151 } else if (shift
< 0x8) {
153 result
= (sample
- (256 * shift
)) << shift
;
156 result
= ((sample
+ ((256 * shift
) + 1)) << shift
) - 1;
162 static int dv_audio_frame_size(const DVprofile
* sys
, int frame
)
164 return sys
->audio_samples_dist
[frame
% (sizeof(sys
->audio_samples_dist
)/
165 sizeof(sys
->audio_samples_dist
[0]))];
168 static int dv_write_pack(enum dv_pack_type pack_id
, DVMuxContext
*c
, uint8_t* buf
)
174 buf
[0] = (uint8_t)pack_id
;
176 case dv_header525
: /* I can't imagine why these two weren't defined as real */
177 case dv_header625
: /* packs in SMPTE314M -- they definitely look like ones */
178 buf
[1] = 0xf8 | /* reserved -- always 1 */
179 (0 & 0x07); /* APT: Track application ID */
180 buf
[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
181 (0x0f << 3) | /* reserved -- always 1 */
182 (0 & 0x07); /* AP1: Audio application ID */
183 buf
[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
184 (0x0f << 3) | /* reserved -- always 1 */
185 (0 & 0x07); /* AP2: Video application ID */
186 buf
[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
187 (0x0f << 3) | /* reserved -- always 1 */
188 (0 & 0x07); /* AP3: Subcode application ID */
191 ct
= (time_t)(c
->frames
/ ((float)c
->sys
->frame_rate
/
192 (float)c
->sys
->frame_rate_base
));
193 localtime_r(&ct
, &tc
);
195 * LTC drop-frame frame counter drops two frames (0 and 1) every
196 * minute, unless it is exactly divisible by 10
198 ltc_frame
= (c
->frames
+ 2*ct
/60 - 2*ct
/600) % c
->sys
->ltc_divisor
;
199 buf
[1] = (0 << 7) | /* Color fame: 0 - unsync; 1 - sync mode */
200 (1 << 6) | /* Drop frame timecode: 0 - nondrop; 1 - drop */
201 ((ltc_frame
/ 10) << 4) | /* Tens of frames */
202 (ltc_frame
% 10); /* Units of frames */
203 buf
[2] = (1 << 7) | /* Biphase mark polarity correction: 0 - even; 1 - odd */
204 ((tc
.tm_sec
/ 10) << 4) | /* Tens of seconds */
205 (tc
.tm_sec
% 10); /* Units of seconds */
206 buf
[3] = (1 << 7) | /* Binary group flag BGF0 */
207 ((tc
.tm_min
/ 10) << 4) | /* Tens of minutes */
208 (tc
.tm_min
% 10); /* Units of minutes */
209 buf
[4] = (1 << 7) | /* Binary group flag BGF2 */
210 (1 << 6) | /* Binary group flag BGF1 */
211 ((tc
.tm_hour
/ 10) << 4) | /* Tens of hours */
212 (tc
.tm_hour
% 10); /* Units of hours */
214 case dv_audio_source
: /* AAUX source pack */
215 buf
[1] = (0 << 7) | /* locked mode */
216 (1 << 6) | /* reserved -- always 1 */
217 (dv_audio_frame_size(c
->sys
, c
->frames
) -
218 c
->sys
->audio_min_samples
[0]);
220 buf
[2] = (0 << 7) | /* multi-stereo */
221 (0 << 5) | /* #of audio channels per block: 0 -- 1 channel */
222 (0 << 4) | /* pair bit: 0 -- one pair of channels */
224 buf
[3] = (1 << 7) | /* res */
225 (1 << 6) | /* multi-language flag */
226 (c
->sys
->dsf
<< 5) | /* system: 60fields/50fields */
227 0; /* definition: 0 -- SD (525/625) */
228 buf
[4] = (1 << 7) | /* emphasis: 1 -- off */
229 (0 << 6) | /* emphasis time constant: 0 -- reserved */
230 (0 << 3) | /* frequency: 0 -- 48Khz, 1 -- 44,1Khz, 2 -- 32Khz */
231 0; /* quantization: 0 -- 16bit linear, 1 -- 12bit nonlinear */
233 case dv_audio_control
:
234 buf
[1] = (0 << 6) | /* copy protection: 0 -- unrestricted */
235 (1 << 4) | /* input source: 1 -- digital input */
236 (3 << 2) | /* compression: 3 -- no information */
237 0; /* misc. info/SMPTE emphasis off */
238 buf
[2] = (1 << 7) | /* recording start point: 1 -- no */
239 (1 << 6) | /* recording end point: 1 -- no */
240 (1 << 3) | /* recording mode: 1 -- original */
242 buf
[3] = (1 << 7) | /* direction: 1 -- forward */
244 buf
[4] = (1 << 7) | /* reserved -- always 1 */
245 0x7f; /* genre category */
247 case dv_audio_recdate
:
248 case dv_viedo_recdate
: /* VAUX recording date */
249 ct
= c
->start_time
+ (time_t)(c
->frames
/
250 ((float)c
->sys
->frame_rate
/ (float)c
->sys
->frame_rate_base
));
251 localtime_r(&ct
, &tc
);
252 buf
[1] = 0xff; /* ds, tm, tens of time zone, units of time zone */
253 /* 0xff is very likely to be "unknown" */
254 buf
[2] = (3 << 6) | /* reserved -- always 1 */
255 ((tc
.tm_mday
/ 10) << 4) | /* Tens of day */
256 (tc
.tm_mday
% 10); /* Units of day */
257 buf
[3] = /* we set high 4 bits to 0, shouldn't we set them to week? */
258 (tc
.tm_mon
% 10); /* Units of month */
259 buf
[4] = (((tc
.tm_year
% 100) / 10) << 4) | /* Tens of year */
260 (tc
.tm_year
% 10); /* Units of year */
262 case dv_audio_rectime
: /* AAUX recording time */
263 case dv_video_rectime
: /* VAUX recording time */
264 ct
= c
->start_time
+ (time_t)(c
->frames
/
265 ((float)c
->sys
->frame_rate
/ (float)c
->sys
->frame_rate_base
));
266 localtime_r(&ct
, &tc
);
267 buf
[1] = (3 << 6) | /* reserved -- always 1 */
268 0x3f; /* tens of frame, units of frame: 0x3f - "unknown" ? */
269 buf
[2] = (1 << 7) | /* reserved -- always 1 */
270 ((tc
.tm_sec
/ 10) << 4) | /* Tens of seconds */
271 (tc
.tm_sec
% 10); /* Units of seconds */
272 buf
[3] = (1 << 7) | /* reserved -- always 1 */
273 ((tc
.tm_min
/ 10) << 4) | /* Tens of minutes */
274 (tc
.tm_min
% 10); /* Units of minutes */
275 buf
[4] = (3 << 6) | /* reserved -- always 1 */
276 ((tc
.tm_hour
/ 10) << 4) | /* Tens of hours */
277 (tc
.tm_hour
% 10); /* Units of hours */
279 case dv_video_source
:
280 buf
[1] = 0xff; /* reserved -- always 1 */
281 buf
[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
282 (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
283 (3 << 4) | /* CLF: color frames id (see ITU-R BT.470-4) */
284 0xf; /* reserved -- always 1 */
285 buf
[3] = (3 << 6) | /* reserved -- always 1 */
286 (c
->sys
->dsf
<< 5) | /* system: 60fields/50fields */
287 0; /* signal type video compression */
288 buf
[4] = 0xff; /* VISC: 0xff -- no information */
290 case dv_video_control
:
291 buf
[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
292 0x3f; /* reserved -- always 1 */
293 buf
[2] = 0xc8 | /* reserved -- always b11001xxx */
295 buf
[3] = (1 << 7) | /* Frame/field flag 1 -- frame, 0 -- field */
296 (1 << 6) | /* First/second field flag 0 -- field 2, 1 -- field 1 */
297 (1 << 5) | /* Frame change flag 0 -- same picture as before, 1 -- different */
298 (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
299 0xc; /* reserved -- always b1100 */
300 buf
[4] = 0xff; /* reserved -- always 1 */
303 buf
[1] = buf
[2] = buf
[3] = buf
[4] = 0xff;
308 static inline int dv_write_dif_id(enum dv_section_type t
, uint8_t seq_num
,
309 uint8_t dif_num
, uint8_t* buf
)
311 buf
[0] = (uint8_t)t
; /* Section type */
312 buf
[1] = (seq_num
<<4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
313 (0 << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
314 7; /* reserved -- always 1 */
315 buf
[2] = dif_num
; /* DIF block number Video: 0-134, Audio: 0-8 */
319 static inline int dv_write_ssyb_id(uint8_t syb_num
, uint8_t fr
, uint8_t* buf
)
321 if (syb_num
== 0 || syb_num
== 6) {
322 buf
[0] = (fr
<<7) | /* FR ID 1 - first half of each channel; 0 - second */
323 (0<<4) | /* AP3 (Subcode application ID) */
324 0x0f; /* reserved -- always 1 */
326 else if (syb_num
== 11) {
327 buf
[0] = (fr
<<7) | /* FR ID 1 - first half of each channel; 0 - second */
328 0x7f; /* reserved -- always 1 */
331 buf
[0] = (fr
<<7) | /* FR ID 1 - first half of each channel; 0 - second */
332 (0<<4) | /* APT (Track application ID) */
333 0x0f; /* reserved -- always 1 */
335 buf
[1] = 0xf0 | /* reserved -- always 1 */
336 (syb_num
& 0x0f); /* SSYB number 0 - 11 */
337 buf
[2] = 0xff; /* reserved -- always 1 */
341 static void dv_format_frame(DVMuxContext
*c
, uint8_t* buf
)
345 for (i
= 0; i
< c
->sys
->difseg_size
; i
++) {
346 memset(buf
, 0xff, 80 * 6); /* First 6 DIF blocks are for control data */
348 /* DV header: 1DIF */
349 buf
+= dv_write_dif_id(dv_sect_header
, i
, 0, buf
);
350 buf
+= dv_write_pack((c
->sys
->dsf ? dv_header625
: dv_header525
), c
, buf
);
351 buf
+= 72; /* unused bytes */
353 /* DV subcode: 2DIFs */
354 for (j
= 0; j
< 2; j
++) {
355 buf
+= dv_write_dif_id( dv_sect_subcode
, i
, j
, buf
);
356 for (k
= 0; k
< 6; k
++) {
357 buf
+= dv_write_ssyb_id(k
, (i
< c
->sys
->difseg_size
/2), buf
);
358 buf
+= dv_write_pack(dv_ssyb_packs_dist
[i
][k
], c
, buf
);
360 buf
+= 29; /* unused bytes */
364 for (j
= 0; j
< 3; j
++) {
365 buf
+= dv_write_dif_id(dv_sect_vaux
, i
, j
, buf
);
366 for (k
= 0; k
< 15 ; k
++)
367 buf
+= dv_write_pack(dv_vaux_packs_dist
[i
][k
], c
, buf
);
368 buf
+= 2; /* unused bytes */
371 /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
372 for (j
= 0; j
< 135; j
++) {
374 buf
+= dv_write_dif_id(dv_sect_audio
, i
, j
/15, buf
);
375 buf
+= dv_write_pack(dv_aaux_packs_dist
[i
][j
/15], c
, buf
);
376 buf
+= 72; /* shuffled PCM audio */
378 buf
+= dv_write_dif_id(dv_sect_video
, i
, j
, buf
);
379 buf
+= 77; /* 1 video macro block: 1 bytes control
380 4 * 14 bytes Y 8x8 data
382 10 bytes Cb 8x8 data */
387 static void dv_inject_audio(DVMuxContext
*c
, const uint8_t* pcm
, uint8_t* frame_ptr
)
390 for (i
= 0; i
< c
->sys
->difseg_size
; i
++) {
391 frame_ptr
+= 6 * 80; /* skip DIF segment header */
392 for (j
= 0; j
< 9; j
++) {
393 for (d
= 8; d
< 80; d
+=2) {
394 of
= c
->sys
->audio_shuffle
[i
][j
] + (d
- 8)/2 * c
->sys
->audio_stride
;
395 frame_ptr
[d
] = pcm
[of
*2+1]; // FIXME: may be we have to admit
396 frame_ptr
[d
+1] = pcm
[of
*2]; // that DV is a big endian PCM
398 frame_ptr
+= 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
403 static void dv_inject_video(DVMuxContext
*c
, const uint8_t* video_data
, uint8_t* frame_ptr
)
408 for (i
= 0; i
< c
->sys
->difseg_size
; i
++) {
409 ptr
+= 6 * 80; /* skip DIF segment header */
410 for (j
= 0; j
< 135; j
++) {
412 ptr
+= 80; /* skip Audio DIF */
414 memcpy(frame_ptr
+ ptr
, video_data
+ ptr
, 77);
421 * This is the dumbest implementation of all -- it simply looks at
422 * a fixed offset and if pack isn't there -- fails. We might want
423 * to have a fallback mechanism for complete search of missing packs.
425 static const uint8_t* dv_extract_pack(uint8_t* frame
, enum dv_pack_type t
)
430 case dv_audio_source
:
431 offs
= (80*6 + 80*16*3 + 3);
433 case dv_audio_control
:
434 offs
= (80*6 + 80*16*4 + 3);
436 case dv_video_control
:
437 offs
= (80*5 + 48 + 5);
443 return (frame
[offs
] == t ?
&frame
[offs
] : NULL
);
447 * There's a couple of assumptions being made here:
448 * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples.
449 * We can pass them upwards when ffmpeg will be ready to deal with them.
450 * 2. We don't do software emphasis.
451 * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
452 * are converted into 16bit linear ones.
454 static int dv_extract_audio(uint8_t* frame
, uint8_t* pcm
)
456 int size
, i
, j
, d
, of
, smpls
, freq
, quant
;
458 const DVprofile
* sys
;
459 const uint8_t* as_pack
;
461 as_pack
= dv_extract_pack(frame
, dv_audio_source
);
462 if (!as_pack
) /* No audio ? */
465 sys
= dv_frame_profile(frame
);
466 smpls
= as_pack
[1] & 0x3f; /* samples in this frame - min. samples */
467 freq
= (as_pack
[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */
468 quant
= as_pack
[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
471 return -1; /* Unsupported quantization */
473 size
= (sys
->audio_min_samples
[freq
] + smpls
) * 4; /* 2ch, 2bytes */
475 /* for each DIF segment */
476 for (i
= 0; i
< sys
->difseg_size
; i
++) {
477 frame
+= 6 * 80; /* skip DIF segment header */
478 for (j
= 0; j
< 9; j
++) {
479 for (d
= 8; d
< 80; d
+= 2) {
480 if (quant
== 0) { /* 16bit quantization */
481 of
= sys
->audio_shuffle
[i
][j
] + (d
- 8)/2 * sys
->audio_stride
;
485 pcm
[of
*2] = frame
[d
+1]; // FIXME: may be we have to admit
486 pcm
[of
*2+1] = frame
[d
]; // that DV is a big endian PCM
487 if (pcm
[of
*2+1] == 0x80 && pcm
[of
*2] == 0x00)
489 } else { /* 12bit quantization */
490 if (i
>= sys
->difseg_size
/2)
491 goto out
; /* We're not doing 4ch at this time */
493 lc
= ((uint16_t)frame
[d
] << 4) |
494 ((uint16_t)frame
[d
+2] >> 4);
495 rc
= ((uint16_t)frame
[d
+1] << 4) |
496 ((uint16_t)frame
[d
+2] & 0x0f);
497 lc
= (lc
== 0x800 ?
0 : dv_audio_12to16(lc
));
498 rc
= (rc
== 0x800 ?
0 : dv_audio_12to16(rc
));
500 of
= sys
->audio_shuffle
[i
][j
] + (d
- 8)/3 * sys
->audio_stride
;
504 pcm
[of
*2] = lc
& 0xff; // FIXME: may be we have to admit
505 pcm
[of
*2+1] = lc
>> 8; // that DV is a big endian PCM
506 of
= sys
->audio_shuffle
[i
+sys
->difseg_size
/2][j
] +
507 (d
- 8)/3 * sys
->audio_stride
;
508 pcm
[of
*2] = rc
& 0xff; // FIXME: may be we have to admit
509 pcm
[of
*2+1] = rc
>> 8; // that DV is a big endian PCM
514 frame
+= 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
522 static int dv_extract_audio_info(uint8_t* frame
, AVCodecContext
* avctx
)
524 const uint8_t* as_pack
;
525 const DVprofile
* sys
;
528 sys
= dv_frame_profile(frame
);
529 as_pack
= dv_extract_pack(frame
, dv_audio_source
);
530 if (!as_pack
|| !sys
) /* No audio ? */
533 smpls
= as_pack
[1] & 0x3f; /* samples in this frame - min. samples */
534 freq
= (as_pack
[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */
536 avctx
->sample_rate
= dv_audio_frequency
[freq
];
538 avctx
->bit_rate
= avctx
->channels
* avctx
->sample_rate
* 16;
540 return (sys
->audio_min_samples
[freq
] + smpls
) * 4; /* 2ch, 2bytes */;
543 static int dv_extract_video_info(uint8_t* frame
, AVCodecContext
* avctx
)
545 const DVprofile
* sys
;
546 const uint8_t* vsc_pack
;
550 sys
= dv_frame_profile(frame
);
552 apt
= frame
[4] & 0x07;
553 avctx
->frame_rate
= sys
->frame_rate
;
554 avctx
->frame_rate_base
= sys
->frame_rate_base
;
555 avctx
->width
= sys
->width
;
556 avctx
->height
= sys
->height
;
557 avctx
->pix_fmt
= sys
->pix_fmt
;
558 vsc_pack
= dv_extract_pack(frame
, dv_video_control
);
559 if (vsc_pack
&& (vsc_pack
[2] & 0x07) == (apt?
0x02:0x07))
560 avctx
->aspect_ratio
= 16.0 / 9.0;
562 avctx
->aspect_ratio
= 4.0 / 3.0;
563 size
= sys
->frame_size
;
569 * The following 6 functions constitute our interface to the world
572 int dv_assemble_frame(DVMuxContext
*c
, AVStream
* st
,
573 const uint8_t* data
, int data_size
, uint8_t** frame
)
578 *frame
= &c
->frame_buf
[0];
579 if (c
->has_audio
&& c
->has_video
) { /* must be a stale frame */
580 dv_format_frame(c
, *frame
);
582 c
->has_audio
= c
->has_video
= 0;
585 if (st
->codec
.codec_type
== CODEC_TYPE_VIDEO
) {
586 /* FIXME: we have to have more sensible approach than this one */
588 fprintf(stderr
, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c
->frames
);
590 dv_inject_video(c
, data
, *frame
);
595 reqasize
= 4 * dv_audio_frame_size(c
->sys
, c
->frames
);
596 fsize
= fifo_size(&c
->audio_data
, c
->audio_data
.rptr
);
597 if (st
->codec
.codec_type
== CODEC_TYPE_AUDIO
|| (c
->has_video
&& fsize
>= reqasize
)) {
598 if (fsize
+ data_size
>= reqasize
&& !c
->has_audio
) {
599 if (fsize
>= reqasize
) {
600 fifo_read(&c
->audio_data
, &pcm
[0], reqasize
, &c
->audio_data
.rptr
);
602 fifo_read(&c
->audio_data
, &pcm
[0], fsize
, &c
->audio_data
.rptr
);
603 memcpy(&pcm
[fsize
], &data
[0], reqasize
- fsize
);
604 data
+= reqasize
- fsize
;
605 data_size
-= reqasize
- fsize
;
607 dv_inject_audio(c
, &pcm
[0], *frame
);
611 /* FIXME: we have to have more sensible approach than this one */
612 if (fifo_size(&c
->audio_data
, c
->audio_data
.rptr
) + data_size
>= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE
)
613 fprintf(stderr
, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c
->frames
);
614 fifo_write(&c
->audio_data
, (uint8_t *)data
, data_size
, &c
->audio_data
.wptr
);
617 return (c
->has_audio
&& c
->has_video
) ? c
->sys
->frame_size
: 0;
620 DVMuxContext
* dv_init_mux(AVFormatContext
* s
)
626 c
= av_mallocz(sizeof(DVMuxContext
));
630 if (s
->nb_streams
!= 2)
633 /* We have to sort out where audio and where video stream is */
634 if (s
->streams
[0]->codec
.codec_type
== CODEC_TYPE_VIDEO
&&
635 s
->streams
[1]->codec
.codec_type
== CODEC_TYPE_AUDIO
) {
639 else if (s
->streams
[1]->codec
.codec_type
== CODEC_TYPE_VIDEO
&&
640 s
->streams
[0]->codec
.codec_type
== CODEC_TYPE_AUDIO
) {
646 /* Some checks -- DV format is very picky about its incoming streams */
647 if (vst
->codec
.codec_id
!= CODEC_ID_DVVIDEO
||
648 ast
->codec
.codec_id
!= CODEC_ID_PCM_S16LE
)
650 if (ast
->codec
.sample_rate
!= 48000 ||
651 ast
->codec
.channels
!= 2)
654 c
->sys
= dv_codec_profile(&vst
->codec
);
658 /* Ok, everything seems to be in working order */
660 c
->has_audio
= c
->has_video
= 0;
661 c
->start_time
= time(NULL
);
662 c
->aspect
= 0; /* 4:3 is the default */
663 if ((int)(vst
->codec
.aspect_ratio
* 10) == 17) /* 16:9 */
666 if (fifo_init(&c
->audio_data
, 100*AVCODEC_MAX_AUDIO_FRAME_SIZE
) < 0)
669 dv_format_frame(c
, &c
->frame_buf
[0]);
678 void dv_delete_mux(DVMuxContext
*c
)
680 fifo_free(&c
->audio_data
);
683 DVDemuxContext
* dv_init_demux(AVFormatContext
*s
, int vid
, int aid
)
687 c
= av_mallocz(sizeof(DVDemuxContext
));
691 c
->vst
= (vid
< s
->nb_streams
) ? s
->streams
[vid
] : av_new_stream(s
, vid
);
692 c
->ast
= (aid
< s
->nb_streams
) ? s
->streams
[aid
] : av_new_stream(s
, aid
);
693 if (!c
->vst
|| !c
->ast
)
696 c
->vst
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
697 c
->vst
->codec
.codec_id
= CODEC_ID_DVVIDEO
;
698 c
->vst
->codec
.bit_rate
= 25000000;
700 c
->ast
->codec
.codec_type
= CODEC_TYPE_AUDIO
;
701 c
->ast
->codec
.codec_id
= CODEC_ID_PCM_S16LE
;
703 c
->audio_pkt
.size
= 0;
716 static void __destruct_pkt(struct AVPacket
*pkt
)
718 pkt
->data
= NULL
; pkt
->size
= 0;
722 int dv_get_packet(DVDemuxContext
*c
, AVPacket
*pkt
)
726 if (c
->audio_pkt
.size
) {
728 c
->audio_pkt
.size
= 0;
735 int dv_produce_packet(DVDemuxContext
*c
, AVPacket
*pkt
,
736 uint8_t* buf
, int buf_size
)
740 if (buf_size
< 4 || buf_size
< dv_frame_profile(buf
)->frame_size
)
741 return -1; /* Broken frame, or not enough data */
743 /* Queueing audio packet */
744 /* FIXME: in case of no audio/bad audio we have to do something */
745 size
= dv_extract_audio_info(buf
, &c
->ast
->codec
);
746 if (av_new_packet(&c
->audio_pkt
, size
) < 0)
747 return AVERROR_NOMEM
;
748 dv_extract_audio(buf
, c
->audio_pkt
.data
);
749 c
->audio_pkt
.size
= size
;
750 c
->audio_pkt
.stream_index
= c
->ast
->id
;
752 /* Now it's time to return video packet */
753 size
= dv_extract_video_info(buf
, &c
->vst
->codec
);
755 pkt
->destruct
= __destruct_pkt
;
758 pkt
->flags
|= PKT_FLAG_KEY
;
759 pkt
->stream_index
= c
->vst
->id
;
764 /************************************************************
765 * Implementation of the easiest DV storage of all -- raw DV.
766 ************************************************************/
768 typedef struct RawDVContext
{
773 static int dv_read_header(AVFormatContext
*s
,
774 AVFormatParameters
*ap
)
776 RawDVContext
*c
= s
->priv_data
;
777 c
->dv_demux
= dv_init_demux(s
, 0, 1);
779 return c
->dv_demux ?
0 : -1;
783 static int dv_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
786 RawDVContext
*c
= s
->priv_data
;
788 size
= dv_get_packet(c
->dv_demux
, pkt
);
791 if (get_buffer(&s
->pb
, c
->buf
, 4) <= 0)
794 size
= dv_frame_profile(c
->buf
)->frame_size
;
795 if (get_buffer(&s
->pb
, c
->buf
+ 4, size
- 4) <= 0)
798 size
= dv_produce_packet(c
->dv_demux
, pkt
, c
->buf
, size
);
804 static int dv_read_close(AVFormatContext
*s
)
806 RawDVContext
*c
= s
->priv_data
;
807 av_free(c
->dv_demux
);
811 static int dv_write_header(AVFormatContext
*s
)
813 s
->priv_data
= dv_init_mux(s
);
815 fprintf(stderr
, "Can't initialize DV format!\n"
816 "Make sure that you supply exactly two streams:\n"
817 " video: 25fps or 29.97fps, audio: 2ch/48Khz/PCM\n");
823 static int dv_write_packet(struct AVFormatContext
*s
,
825 const uint8_t *buf
, int size
, int64_t pts
)
830 fsize
= dv_assemble_frame((DVMuxContext
*)s
->priv_data
, s
->streams
[stream_index
],
833 put_buffer(&s
->pb
, frame
, fsize
);
834 put_flush_packet(&s
->pb
);
840 * We might end up with some extra A/V data without matching counterpart.
841 * E.g. video data without enough audio to write the complete frame.
842 * Currently we simply drop the last frame. I don't know whether this
843 * is the best strategy of all
845 static int dv_write_trailer(struct AVFormatContext
*s
)
847 dv_delete_mux((DVMuxContext
*)s
->priv_data
);
851 static AVInputFormat dv_iformat
= {
854 sizeof(RawDVContext
),
862 static AVOutputFormat dv_oformat
= {
867 sizeof(DVMuxContext
),
877 av_register_input_format(&dv_iformat
);
878 av_register_output_format(&dv_oformat
);