2 * General DV muxer/demuxer
3 * Copyright (c) 2003 Roman Shaposhnik
5 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
6 * of DV technical info.
9 * Copyright (c) 2002 Fabrice Bellard
11 * 50 Mbps (DVCPRO50) and 100 Mbps (DVCPRO HD) support
12 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
13 * Funded by BBC Research & Development
15 * This file is part of FFmpeg.
17 * FFmpeg is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
22 * FFmpeg is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with FFmpeg; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "libavcodec/dvdata.h"
34 #include "libavutil/intreadwrite.h"
37 struct DVDemuxContext
{
38 const DVprofile
* sys
; /* Current DV profile. E.g.: 525/60, 625/50 */
39 AVFormatContext
* fctx
;
42 AVPacket audio_pkt
[4];
43 uint8_t audio_buf
[4][8192];
49 static inline uint16_t dv_audio_12to16(uint16_t sample
)
51 uint16_t shift
, result
;
53 sample
= (sample
< 0x800) ? sample
: sample
| 0xf000;
54 shift
= (sample
& 0xf00) >> 8;
56 if (shift
< 0x2 || shift
> 0xd) {
58 } else if (shift
< 0x8) {
60 result
= (sample
- (256 * shift
)) << shift
;
63 result
= ((sample
+ ((256 * shift
) + 1)) << shift
) - 1;
70 * This is the dumbest implementation of all -- it simply looks at
71 * a fixed offset and if pack isn't there -- fails. We might want
72 * to have a fallback mechanism for complete search of missing packs.
74 static const uint8_t* dv_extract_pack(uint8_t* frame
, enum dv_pack_type t
)
80 offs
= (80*6 + 80*16*3 + 3);
82 case dv_audio_control
:
83 offs
= (80*6 + 80*16*4 + 3);
85 case dv_video_control
:
86 offs
= (80*5 + 48 + 5);
92 return frame
[offs
] == t
? &frame
[offs
] : NULL
;
96 * There's a couple of assumptions being made here:
97 * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples.
98 * We can pass them upwards when ffmpeg will be ready to deal with them.
99 * 2. We don't do software emphasis.
100 * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
101 * are converted into 16bit linear ones.
103 static int dv_extract_audio(uint8_t* frame
, uint8_t* ppcm
[4],
104 const DVprofile
*sys
)
106 int size
, chan
, i
, j
, d
, of
, smpls
, freq
, quant
, half_ch
;
108 const uint8_t* as_pack
;
111 as_pack
= dv_extract_pack(frame
, dv_audio_source
);
112 if (!as_pack
) /* No audio ? */
115 smpls
= as_pack
[1] & 0x3f; /* samples in this frame - min. samples */
116 freq
= (as_pack
[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
117 quant
= as_pack
[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
120 return -1; /* unsupported quantization */
122 size
= (sys
->audio_min_samples
[freq
] + smpls
) * 4; /* 2ch, 2bytes */
123 half_ch
= sys
->difseg_size
/ 2;
125 /* We work with 720p frames split in half, thus even frames have
126 * channels 0,1 and odd 2,3. */
127 ipcm
= (sys
->height
== 720 && !(frame
[1] & 0x0C)) ? 2 : 0;
130 /* for each DIF channel */
131 for (chan
= 0; chan
< sys
->n_difchan
; chan
++) {
132 /* for each DIF segment */
133 for (i
= 0; i
< sys
->difseg_size
; i
++) {
134 frame
+= 6 * 80; /* skip DIF segment header */
135 if (quant
== 1 && i
== half_ch
) {
136 /* next stereo channel (12bit mode only) */
142 /* for each AV sequence */
143 for (j
= 0; j
< 9; j
++) {
144 for (d
= 8; d
< 80; d
+= 2) {
145 if (quant
== 0) { /* 16bit quantization */
146 of
= sys
->audio_shuffle
[i
][j
] + (d
- 8) / 2 * sys
->audio_stride
;
150 pcm
[of
*2] = frame
[d
+1]; // FIXME: maybe we have to admit
151 pcm
[of
*2+1] = frame
[d
]; // that DV is a big-endian PCM
152 if (pcm
[of
*2+1] == 0x80 && pcm
[of
*2] == 0x00)
154 } else { /* 12bit quantization */
155 lc
= ((uint16_t)frame
[d
] << 4) |
156 ((uint16_t)frame
[d
+2] >> 4);
157 rc
= ((uint16_t)frame
[d
+1] << 4) |
158 ((uint16_t)frame
[d
+2] & 0x0f);
159 lc
= (lc
== 0x800 ? 0 : dv_audio_12to16(lc
));
160 rc
= (rc
== 0x800 ? 0 : dv_audio_12to16(rc
));
162 of
= sys
->audio_shuffle
[i
%half_ch
][j
] + (d
- 8) / 3 * sys
->audio_stride
;
166 pcm
[of
*2] = lc
& 0xff; // FIXME: maybe we have to admit
167 pcm
[of
*2+1] = lc
>> 8; // that DV is a big-endian PCM
168 of
= sys
->audio_shuffle
[i
%half_ch
+half_ch
][j
] +
169 (d
- 8) / 3 * sys
->audio_stride
;
170 pcm
[of
*2] = rc
& 0xff; // FIXME: maybe we have to admit
171 pcm
[of
*2+1] = rc
>> 8; // that DV is a big-endian PCM
176 frame
+= 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
180 /* next stereo channel (50Mbps and 100Mbps only) */
189 static int dv_extract_audio_info(DVDemuxContext
* c
, uint8_t* frame
)
191 const uint8_t* as_pack
;
192 int freq
, stype
, smpls
, quant
, i
, ach
;
194 as_pack
= dv_extract_pack(frame
, dv_audio_source
);
195 if (!as_pack
|| !c
->sys
) { /* No audio ? */
200 smpls
= as_pack
[1] & 0x3f; /* samples in this frame - min. samples */
201 freq
= (as_pack
[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
202 stype
= (as_pack
[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
203 quant
= as_pack
[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
205 /* note: ach counts PAIRS of channels (i.e. stereo channels) */
206 ach
= ((int[4]){ 1, 0, 2, 4})[stype
];
207 if (ach
== 1 && quant
&& freq
== 2)
210 /* Dynamic handling of the audio streams in DV */
211 for (i
= 0; i
< ach
; i
++) {
213 c
->ast
[i
] = av_new_stream(c
->fctx
, 0);
216 av_set_pts_info(c
->ast
[i
], 64, 1, 30000);
217 c
->ast
[i
]->codec
->codec_type
= CODEC_TYPE_AUDIO
;
218 c
->ast
[i
]->codec
->codec_id
= CODEC_ID_PCM_S16LE
;
220 av_init_packet(&c
->audio_pkt
[i
]);
221 c
->audio_pkt
[i
].size
= 0;
222 c
->audio_pkt
[i
].data
= c
->audio_buf
[i
];
223 c
->audio_pkt
[i
].stream_index
= c
->ast
[i
]->index
;
224 c
->audio_pkt
[i
].flags
|= PKT_FLAG_KEY
;
226 c
->ast
[i
]->codec
->sample_rate
= dv_audio_frequency
[freq
];
227 c
->ast
[i
]->codec
->channels
= 2;
228 c
->ast
[i
]->codec
->bit_rate
= 2 * dv_audio_frequency
[freq
] * 16;
229 c
->ast
[i
]->start_time
= 0;
233 return (c
->sys
->audio_min_samples
[freq
] + smpls
) * 4; /* 2ch, 2bytes */;
236 static int dv_extract_video_info(DVDemuxContext
*c
, uint8_t* frame
)
238 const uint8_t* vsc_pack
;
239 AVCodecContext
* avctx
;
244 avctx
= c
->vst
->codec
;
246 av_set_pts_info(c
->vst
, 64, c
->sys
->time_base
.num
,
247 c
->sys
->time_base
.den
);
248 avctx
->time_base
= c
->sys
->time_base
;
250 avctx
->width
= c
->sys
->width
;
251 avctx
->height
= c
->sys
->height
;
253 avctx
->pix_fmt
= c
->sys
->pix_fmt
;
255 /* finding out SAR is a little bit messy */
256 vsc_pack
= dv_extract_pack(frame
, dv_video_control
);
257 apt
= frame
[4] & 0x07;
258 is16_9
= (vsc_pack
&& ((vsc_pack
[2] & 0x07) == 0x02 ||
259 (!apt
&& (vsc_pack
[2] & 0x07) == 0x07)));
260 c
->vst
->sample_aspect_ratio
= c
->sys
->sar
[is16_9
];
261 avctx
->bit_rate
= av_rescale_q(c
->sys
->frame_size
, (AVRational
){8,1},
263 size
= c
->sys
->frame_size
;
269 * The following 3 functions constitute our interface to the world
272 DVDemuxContext
* dv_init_demux(AVFormatContext
*s
)
276 c
= av_mallocz(sizeof(DVDemuxContext
));
280 c
->vst
= av_new_stream(s
, 0);
288 memset(c
->ast
, 0, sizeof(c
->ast
));
293 c
->vst
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
294 c
->vst
->codec
->codec_id
= CODEC_ID_DVVIDEO
;
295 c
->vst
->codec
->bit_rate
= 25000000;
296 c
->vst
->start_time
= 0;
301 int dv_get_packet(DVDemuxContext
*c
, AVPacket
*pkt
)
306 for (i
= 0; i
< c
->ach
; i
++) {
307 if (c
->ast
[i
] && c
->audio_pkt
[i
].size
) {
308 *pkt
= c
->audio_pkt
[i
];
309 c
->audio_pkt
[i
].size
= 0;
318 int dv_produce_packet(DVDemuxContext
*c
, AVPacket
*pkt
,
319 uint8_t* buf
, int buf_size
)
322 uint8_t *ppcm
[4] = {0};
324 if (buf_size
< DV_PROFILE_BYTES
||
325 !(c
->sys
= dv_frame_profile(buf
)) ||
326 buf_size
< c
->sys
->frame_size
) {
327 return -1; /* Broken frame, or not enough data */
330 /* Queueing audio packet */
331 /* FIXME: in case of no audio/bad audio we have to do something */
332 size
= dv_extract_audio_info(c
, buf
);
333 for (i
= 0; i
< c
->ach
; i
++) {
334 c
->audio_pkt
[i
].size
= size
;
335 c
->audio_pkt
[i
].pts
= c
->abytes
* 30000*8 / c
->ast
[i
]->codec
->bit_rate
;
336 ppcm
[i
] = c
->audio_buf
[i
];
338 dv_extract_audio(buf
, ppcm
, c
->sys
);
341 /* We work with 720p frames split in half, thus even frames have
342 * channels 0,1 and odd 2,3. */
343 if (c
->sys
->height
== 720) {
345 c
->audio_pkt
[2].size
= c
->audio_pkt
[3].size
= 0;
347 c
->audio_pkt
[0].size
= c
->audio_pkt
[1].size
= 0;
350 /* Now it's time to return video packet */
351 size
= dv_extract_video_info(c
, buf
);
355 pkt
->flags
|= PKT_FLAG_KEY
;
356 pkt
->stream_index
= c
->vst
->id
;
357 pkt
->pts
= c
->frames
;
364 static int64_t dv_frame_offset(AVFormatContext
*s
, DVDemuxContext
*c
,
365 int64_t timestamp
, int flags
)
367 // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
368 const DVprofile
* sys
= dv_codec_profile(c
->vst
->codec
);
370 int64_t size
= url_fsize(s
->pb
);
371 int64_t max_offset
= ((size
-1) / sys
->frame_size
) * sys
->frame_size
;
373 offset
= sys
->frame_size
* timestamp
;
375 if (offset
> max_offset
) offset
= max_offset
;
376 else if (offset
< 0) offset
= 0;
381 void dv_offset_reset(DVDemuxContext
*c
, int64_t frame_offset
)
383 c
->frames
= frame_offset
;
385 c
->abytes
= av_rescale_q(c
->frames
, c
->sys
->time_base
,
386 (AVRational
){8, c
->ast
[0]->codec
->bit_rate
});
387 c
->audio_pkt
[0].size
= c
->audio_pkt
[1].size
= 0;
388 c
->audio_pkt
[2].size
= c
->audio_pkt
[3].size
= 0;
391 /************************************************************
392 * Implementation of the easiest DV storage of all -- raw DV.
393 ************************************************************/
395 typedef struct RawDVContext
{
396 DVDemuxContext
* dv_demux
;
397 uint8_t buf
[DV_MAX_FRAME_SIZE
];
400 static int dv_read_header(AVFormatContext
*s
,
401 AVFormatParameters
*ap
)
404 RawDVContext
*c
= s
->priv_data
;
406 c
->dv_demux
= dv_init_demux(s
);
410 state
= get_be32(s
->pb
);
411 while ((state
& 0xffffff7f) != 0x1f07003f) {
412 if (url_feof(s
->pb
)) {
413 av_log(s
, AV_LOG_ERROR
, "Cannot find DV header.\n");
416 state
= (state
<< 8) | get_byte(s
->pb
);
418 AV_WB32(c
->buf
, state
);
420 if (get_buffer(s
->pb
, c
->buf
+ 4, DV_PROFILE_BYTES
- 4) <= 0 ||
421 url_fseek(s
->pb
, -DV_PROFILE_BYTES
, SEEK_CUR
) < 0)
424 c
->dv_demux
->sys
= dv_frame_profile(c
->buf
);
425 if (!c
->dv_demux
->sys
) {
426 av_log(s
, AV_LOG_ERROR
, "Can't determine profile of DV input stream.\n");
430 s
->bit_rate
= av_rescale_q(c
->dv_demux
->sys
->frame_size
, (AVRational
){8,1},
431 c
->dv_demux
->sys
->time_base
);
437 static int dv_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
440 RawDVContext
*c
= s
->priv_data
;
442 size
= dv_get_packet(c
->dv_demux
, pkt
);
445 if (!c
->dv_demux
->sys
)
447 size
= c
->dv_demux
->sys
->frame_size
;
448 if (get_buffer(s
->pb
, c
->buf
, size
) <= 0)
451 size
= dv_produce_packet(c
->dv_demux
, pkt
, c
->buf
, size
);
457 static int dv_read_seek(AVFormatContext
*s
, int stream_index
,
458 int64_t timestamp
, int flags
)
460 RawDVContext
*r
= s
->priv_data
;
461 DVDemuxContext
*c
= r
->dv_demux
;
462 int64_t offset
= dv_frame_offset(s
, c
, timestamp
, flags
);
464 dv_offset_reset(c
, offset
/ c
->sys
->frame_size
);
466 offset
= url_fseek(s
->pb
, offset
, SEEK_SET
);
467 return (offset
< 0) ? offset
: 0;
470 static int dv_read_close(AVFormatContext
*s
)
472 RawDVContext
*c
= s
->priv_data
;
473 av_free(c
->dv_demux
);
477 static int dv_probe(AVProbeData
*p
)
485 state
= AV_RB32(p
->buf
);
486 for (i
= 4; i
< p
->buf_size
; i
++) {
487 if ((state
& 0xffffff7f) == 0x1f07003f)
488 return AVPROBE_SCORE_MAX
*3/4; // not max to avoid dv in mov to match
489 state
= (state
<< 8) | p
->buf
[i
];
495 #if CONFIG_DV_DEMUXER
496 AVInputFormat dv_demuxer
= {
498 NULL_IF_CONFIG_SMALL("DV video format"),
499 sizeof(RawDVContext
),
505 .extensions
= "dv,dif",