yading@11
|
1 /*
|
yading@11
|
2 * General DV muxer/demuxer
|
yading@11
|
3 * Copyright (c) 2003 Roman Shaposhnik
|
yading@11
|
4 *
|
yading@11
|
5 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
|
yading@11
|
6 * of DV technical info.
|
yading@11
|
7 *
|
yading@11
|
8 * Raw DV format
|
yading@11
|
9 * Copyright (c) 2002 Fabrice Bellard
|
yading@11
|
10 *
|
yading@11
|
11 * 50 Mbps (DVCPRO50) and 100 Mbps (DVCPRO HD) support
|
yading@11
|
12 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
|
yading@11
|
13 * Funded by BBC Research & Development
|
yading@11
|
14 *
|
yading@11
|
15 * This file is part of FFmpeg.
|
yading@11
|
16 *
|
yading@11
|
17 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
18 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
19 * License as published by the Free Software Foundation; either
|
yading@11
|
20 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
21 *
|
yading@11
|
22 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
25 * Lesser General Public License for more details.
|
yading@11
|
26 *
|
yading@11
|
27 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
28 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
30 */
|
yading@11
|
31 #include <time.h>
|
yading@11
|
32 #include "avformat.h"
|
yading@11
|
33 #include "internal.h"
|
yading@11
|
34 #include "libavcodec/dv_profile.h"
|
yading@11
|
35 #include "libavcodec/dvdata.h"
|
yading@11
|
36 #include "libavutil/channel_layout.h"
|
yading@11
|
37 #include "libavutil/intreadwrite.h"
|
yading@11
|
38 #include "libavutil/mathematics.h"
|
yading@11
|
39 #include "libavutil/timecode.h"
|
yading@11
|
40 #include "dv.h"
|
yading@11
|
41 #include "libavutil/avassert.h"
|
yading@11
|
42
|
yading@11
|
43 struct DVDemuxContext {
|
yading@11
|
44 const DVprofile* sys; /* Current DV profile. E.g.: 525/60, 625/50 */
|
yading@11
|
45 AVFormatContext* fctx;
|
yading@11
|
46 AVStream* vst;
|
yading@11
|
47 AVStream* ast[4];
|
yading@11
|
48 AVPacket audio_pkt[4];
|
yading@11
|
49 uint8_t audio_buf[4][8192];
|
yading@11
|
50 int ach;
|
yading@11
|
51 int frames;
|
yading@11
|
52 uint64_t abytes;
|
yading@11
|
53 };
|
yading@11
|
54
|
yading@11
|
55 static inline uint16_t dv_audio_12to16(uint16_t sample)
|
yading@11
|
56 {
|
yading@11
|
57 uint16_t shift, result;
|
yading@11
|
58
|
yading@11
|
59 sample = (sample < 0x800) ? sample : sample | 0xf000;
|
yading@11
|
60 shift = (sample & 0xf00) >> 8;
|
yading@11
|
61
|
yading@11
|
62 if (shift < 0x2 || shift > 0xd) {
|
yading@11
|
63 result = sample;
|
yading@11
|
64 } else if (shift < 0x8) {
|
yading@11
|
65 shift--;
|
yading@11
|
66 result = (sample - (256 * shift)) << shift;
|
yading@11
|
67 } else {
|
yading@11
|
68 shift = 0xe - shift;
|
yading@11
|
69 result = ((sample + ((256 * shift) + 1)) << shift) - 1;
|
yading@11
|
70 }
|
yading@11
|
71
|
yading@11
|
72 return result;
|
yading@11
|
73 }
|
yading@11
|
74
|
yading@11
|
75 /*
|
yading@11
|
76 * This is the dumbest implementation of all -- it simply looks at
|
yading@11
|
77 * a fixed offset and if pack isn't there -- fails. We might want
|
yading@11
|
78 * to have a fallback mechanism for complete search of missing packs.
|
yading@11
|
79 */
|
yading@11
|
80 static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
|
yading@11
|
81 {
|
yading@11
|
82 int offs;
|
yading@11
|
83
|
yading@11
|
84 switch (t) {
|
yading@11
|
85 case dv_audio_source:
|
yading@11
|
86 offs = (80*6 + 80*16*3 + 3);
|
yading@11
|
87 break;
|
yading@11
|
88 case dv_audio_control:
|
yading@11
|
89 offs = (80*6 + 80*16*4 + 3);
|
yading@11
|
90 break;
|
yading@11
|
91 case dv_video_control:
|
yading@11
|
92 offs = (80*5 + 48 + 5);
|
yading@11
|
93 break;
|
yading@11
|
94 case dv_timecode:
|
yading@11
|
95 offs = (80*1 + 3 + 3);
|
yading@11
|
96 break;
|
yading@11
|
97 default:
|
yading@11
|
98 return NULL;
|
yading@11
|
99 }
|
yading@11
|
100
|
yading@11
|
101 return frame[offs] == t ? &frame[offs] : NULL;
|
yading@11
|
102 }
|
yading@11
|
103
|
yading@11
|
104 static const int dv_audio_frequency[3] = {
|
yading@11
|
105 48000, 44100, 32000,
|
yading@11
|
106 };
|
yading@11
|
107
|
yading@11
|
108 /*
|
yading@11
|
109 * There's a couple of assumptions being made here:
|
yading@11
|
110 * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples.
|
yading@11
|
111 * We can pass them upwards when libavcodec will be ready to deal with them.
|
yading@11
|
112 * 2. We don't do software emphasis.
|
yading@11
|
113 * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
|
yading@11
|
114 * are converted into 16bit linear ones.
|
yading@11
|
115 */
|
yading@11
|
116 static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
|
yading@11
|
117 const DVprofile *sys)
|
yading@11
|
118 {
|
yading@11
|
119 int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
|
yading@11
|
120 uint16_t lc, rc;
|
yading@11
|
121 const uint8_t* as_pack;
|
yading@11
|
122 uint8_t *pcm, ipcm;
|
yading@11
|
123
|
yading@11
|
124 as_pack = dv_extract_pack(frame, dv_audio_source);
|
yading@11
|
125 if (!as_pack) /* No audio ? */
|
yading@11
|
126 return 0;
|
yading@11
|
127
|
yading@11
|
128 smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
|
yading@11
|
129 freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
|
yading@11
|
130 quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
|
yading@11
|
131
|
yading@11
|
132 if (quant > 1)
|
yading@11
|
133 return -1; /* unsupported quantization */
|
yading@11
|
134
|
yading@11
|
135 if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
|
yading@11
|
136 return AVERROR_INVALIDDATA;
|
yading@11
|
137
|
yading@11
|
138 size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
|
yading@11
|
139 half_ch = sys->difseg_size / 2;
|
yading@11
|
140
|
yading@11
|
141 /* We work with 720p frames split in half, thus even frames have
|
yading@11
|
142 * channels 0,1 and odd 2,3. */
|
yading@11
|
143 ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
|
yading@11
|
144
|
yading@11
|
145 if (ipcm + sys->n_difchan > (quant == 1 ? 2 : 4)) {
|
yading@11
|
146 av_log(NULL, AV_LOG_ERROR, "too many dv pcm frames\n");
|
yading@11
|
147 return AVERROR_INVALIDDATA;
|
yading@11
|
148 }
|
yading@11
|
149
|
yading@11
|
150 /* for each DIF channel */
|
yading@11
|
151 for (chan = 0; chan < sys->n_difchan; chan++) {
|
yading@11
|
152 av_assert0(ipcm<4);
|
yading@11
|
153 pcm = ppcm[ipcm++];
|
yading@11
|
154 if (!pcm)
|
yading@11
|
155 break;
|
yading@11
|
156
|
yading@11
|
157 /* for each DIF segment */
|
yading@11
|
158 for (i = 0; i < sys->difseg_size; i++) {
|
yading@11
|
159 frame += 6 * 80; /* skip DIF segment header */
|
yading@11
|
160 if (quant == 1 && i == half_ch) {
|
yading@11
|
161 /* next stereo channel (12bit mode only) */
|
yading@11
|
162 av_assert0(ipcm<4);
|
yading@11
|
163 pcm = ppcm[ipcm++];
|
yading@11
|
164 if (!pcm)
|
yading@11
|
165 break;
|
yading@11
|
166 }
|
yading@11
|
167
|
yading@11
|
168 /* for each AV sequence */
|
yading@11
|
169 for (j = 0; j < 9; j++) {
|
yading@11
|
170 for (d = 8; d < 80; d += 2) {
|
yading@11
|
171 if (quant == 0) { /* 16bit quantization */
|
yading@11
|
172 of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
|
yading@11
|
173 if (of*2 >= size)
|
yading@11
|
174 continue;
|
yading@11
|
175
|
yading@11
|
176 pcm[of*2] = frame[d+1]; // FIXME: maybe we have to admit
|
yading@11
|
177 pcm[of*2+1] = frame[d]; // that DV is a big-endian PCM
|
yading@11
|
178 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
|
yading@11
|
179 pcm[of*2+1] = 0;
|
yading@11
|
180 } else { /* 12bit quantization */
|
yading@11
|
181 lc = ((uint16_t)frame[d] << 4) |
|
yading@11
|
182 ((uint16_t)frame[d+2] >> 4);
|
yading@11
|
183 rc = ((uint16_t)frame[d+1] << 4) |
|
yading@11
|
184 ((uint16_t)frame[d+2] & 0x0f);
|
yading@11
|
185 lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
|
yading@11
|
186 rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
|
yading@11
|
187
|
yading@11
|
188 of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
|
yading@11
|
189 if (of*2 >= size)
|
yading@11
|
190 continue;
|
yading@11
|
191
|
yading@11
|
192 pcm[of*2] = lc & 0xff; // FIXME: maybe we have to admit
|
yading@11
|
193 pcm[of*2+1] = lc >> 8; // that DV is a big-endian PCM
|
yading@11
|
194 of = sys->audio_shuffle[i%half_ch+half_ch][j] +
|
yading@11
|
195 (d - 8) / 3 * sys->audio_stride;
|
yading@11
|
196 pcm[of*2] = rc & 0xff; // FIXME: maybe we have to admit
|
yading@11
|
197 pcm[of*2+1] = rc >> 8; // that DV is a big-endian PCM
|
yading@11
|
198 ++d;
|
yading@11
|
199 }
|
yading@11
|
200 }
|
yading@11
|
201
|
yading@11
|
202 frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
|
yading@11
|
203 }
|
yading@11
|
204 }
|
yading@11
|
205 }
|
yading@11
|
206
|
yading@11
|
207 return size;
|
yading@11
|
208 }
|
yading@11
|
209
|
yading@11
|
210 static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
|
yading@11
|
211 {
|
yading@11
|
212 const uint8_t* as_pack;
|
yading@11
|
213 int freq, stype, smpls, quant, i, ach;
|
yading@11
|
214
|
yading@11
|
215 as_pack = dv_extract_pack(frame, dv_audio_source);
|
yading@11
|
216 if (!as_pack || !c->sys) { /* No audio ? */
|
yading@11
|
217 c->ach = 0;
|
yading@11
|
218 return 0;
|
yading@11
|
219 }
|
yading@11
|
220
|
yading@11
|
221 smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
|
yading@11
|
222 freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
|
yading@11
|
223 stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
|
yading@11
|
224 quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
|
yading@11
|
225
|
yading@11
|
226 if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
|
yading@11
|
227 av_log(c->fctx, AV_LOG_ERROR,
|
yading@11
|
228 "Unrecognized audio sample rate index (%d)\n", freq);
|
yading@11
|
229 return 0;
|
yading@11
|
230 }
|
yading@11
|
231
|
yading@11
|
232 if (stype > 3) {
|
yading@11
|
233 av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype);
|
yading@11
|
234 c->ach = 0;
|
yading@11
|
235 return 0;
|
yading@11
|
236 }
|
yading@11
|
237
|
yading@11
|
238 /* note: ach counts PAIRS of channels (i.e. stereo channels) */
|
yading@11
|
239 ach = ((int[4]){ 1, 0, 2, 4})[stype];
|
yading@11
|
240 if (ach == 1 && quant && freq == 2)
|
yading@11
|
241 ach = 2;
|
yading@11
|
242
|
yading@11
|
243 /* Dynamic handling of the audio streams in DV */
|
yading@11
|
244 for (i = 0; i < ach; i++) {
|
yading@11
|
245 if (!c->ast[i]) {
|
yading@11
|
246 c->ast[i] = avformat_new_stream(c->fctx, NULL);
|
yading@11
|
247 if (!c->ast[i])
|
yading@11
|
248 break;
|
yading@11
|
249 avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
|
yading@11
|
250 c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
yading@11
|
251 c->ast[i]->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
|
yading@11
|
252
|
yading@11
|
253 av_init_packet(&c->audio_pkt[i]);
|
yading@11
|
254 c->audio_pkt[i].size = 0;
|
yading@11
|
255 c->audio_pkt[i].data = c->audio_buf[i];
|
yading@11
|
256 c->audio_pkt[i].stream_index = c->ast[i]->index;
|
yading@11
|
257 c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY;
|
yading@11
|
258 }
|
yading@11
|
259 c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
|
yading@11
|
260 c->ast[i]->codec->channels = 2;
|
yading@11
|
261 c->ast[i]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
|
yading@11
|
262 c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;
|
yading@11
|
263 c->ast[i]->start_time = 0;
|
yading@11
|
264 }
|
yading@11
|
265 c->ach = i;
|
yading@11
|
266
|
yading@11
|
267 return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */;
|
yading@11
|
268 }
|
yading@11
|
269
|
yading@11
|
270 static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
|
yading@11
|
271 {
|
yading@11
|
272 const uint8_t* vsc_pack;
|
yading@11
|
273 AVCodecContext* avctx;
|
yading@11
|
274 int apt, is16_9;
|
yading@11
|
275 int size = 0;
|
yading@11
|
276
|
yading@11
|
277 if (c->sys) {
|
yading@11
|
278 avctx = c->vst->codec;
|
yading@11
|
279
|
yading@11
|
280 avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
|
yading@11
|
281 c->sys->time_base.den);
|
yading@11
|
282 avctx->time_base= c->sys->time_base;
|
yading@11
|
283
|
yading@11
|
284 /* finding out SAR is a little bit messy */
|
yading@11
|
285 vsc_pack = dv_extract_pack(frame, dv_video_control);
|
yading@11
|
286 apt = frame[4] & 0x07;
|
yading@11
|
287 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
|
yading@11
|
288 (!apt && (vsc_pack[2] & 0x07) == 0x07)));
|
yading@11
|
289 c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
|
yading@11
|
290 avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
|
yading@11
|
291 c->sys->time_base);
|
yading@11
|
292 size = c->sys->frame_size;
|
yading@11
|
293 }
|
yading@11
|
294 return size;
|
yading@11
|
295 }
|
yading@11
|
296
|
yading@11
|
297 static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char *tc)
|
yading@11
|
298 {
|
yading@11
|
299 const uint8_t *tc_pack;
|
yading@11
|
300
|
yading@11
|
301 // For PAL systems, drop frame bit is replaced by an arbitrary
|
yading@11
|
302 // bit so its value should not be considered. Drop frame timecode
|
yading@11
|
303 // is only relevant for NTSC systems.
|
yading@11
|
304 int prevent_df = c->sys->ltc_divisor == 25 || c->sys->ltc_divisor == 50;
|
yading@11
|
305
|
yading@11
|
306 tc_pack = dv_extract_pack(frame, dv_timecode);
|
yading@11
|
307 if (!tc_pack)
|
yading@11
|
308 return 0;
|
yading@11
|
309 av_timecode_make_smpte_tc_string(tc, AV_RB32(tc_pack + 1), prevent_df);
|
yading@11
|
310 return 1;
|
yading@11
|
311 }
|
yading@11
|
312
|
yading@11
|
313 /*
|
yading@11
|
314 * The following 3 functions constitute our interface to the world
|
yading@11
|
315 */
|
yading@11
|
316
|
yading@11
|
317 DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
|
yading@11
|
318 {
|
yading@11
|
319 DVDemuxContext *c;
|
yading@11
|
320
|
yading@11
|
321 c = av_mallocz(sizeof(DVDemuxContext));
|
yading@11
|
322 if (!c)
|
yading@11
|
323 return NULL;
|
yading@11
|
324
|
yading@11
|
325 c->vst = avformat_new_stream(s, NULL);
|
yading@11
|
326 if (!c->vst) {
|
yading@11
|
327 av_free(c);
|
yading@11
|
328 return NULL;
|
yading@11
|
329 }
|
yading@11
|
330
|
yading@11
|
331 c->fctx = s;
|
yading@11
|
332 c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
yading@11
|
333 c->vst->codec->codec_id = AV_CODEC_ID_DVVIDEO;
|
yading@11
|
334 c->vst->codec->bit_rate = 25000000;
|
yading@11
|
335 c->vst->start_time = 0;
|
yading@11
|
336
|
yading@11
|
337 return c;
|
yading@11
|
338 }
|
yading@11
|
339
|
yading@11
|
340 int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
|
yading@11
|
341 {
|
yading@11
|
342 int size = -1;
|
yading@11
|
343 int i;
|
yading@11
|
344
|
yading@11
|
345 for (i = 0; i < c->ach; i++) {
|
yading@11
|
346 if (c->ast[i] && c->audio_pkt[i].size) {
|
yading@11
|
347 *pkt = c->audio_pkt[i];
|
yading@11
|
348 c->audio_pkt[i].size = 0;
|
yading@11
|
349 size = pkt->size;
|
yading@11
|
350 break;
|
yading@11
|
351 }
|
yading@11
|
352 }
|
yading@11
|
353
|
yading@11
|
354 return size;
|
yading@11
|
355 }
|
yading@11
|
356
|
yading@11
|
357 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
|
yading@11
|
358 uint8_t* buf, int buf_size, int64_t pos)
|
yading@11
|
359 {
|
yading@11
|
360 int size, i;
|
yading@11
|
361 uint8_t *ppcm[4] = {0};
|
yading@11
|
362
|
yading@11
|
363 if (buf_size < DV_PROFILE_BYTES ||
|
yading@11
|
364 !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
|
yading@11
|
365 buf_size < c->sys->frame_size) {
|
yading@11
|
366 return -1; /* Broken frame, or not enough data */
|
yading@11
|
367 }
|
yading@11
|
368
|
yading@11
|
369 /* Queueing audio packet */
|
yading@11
|
370 /* FIXME: in case of no audio/bad audio we have to do something */
|
yading@11
|
371 size = dv_extract_audio_info(c, buf);
|
yading@11
|
372 for (i = 0; i < c->ach; i++) {
|
yading@11
|
373 c->audio_pkt[i].pos = pos;
|
yading@11
|
374 c->audio_pkt[i].size = size;
|
yading@11
|
375 c->audio_pkt[i].pts = c->abytes * 30000 * 8 / c->ast[i]->codec->bit_rate;
|
yading@11
|
376 ppcm[i] = c->audio_buf[i];
|
yading@11
|
377 }
|
yading@11
|
378 if (c->ach)
|
yading@11
|
379 dv_extract_audio(buf, ppcm, c->sys);
|
yading@11
|
380
|
yading@11
|
381 /* We work with 720p frames split in half, thus even frames have
|
yading@11
|
382 * channels 0,1 and odd 2,3. */
|
yading@11
|
383 if (c->sys->height == 720) {
|
yading@11
|
384 if (buf[1] & 0x0C) {
|
yading@11
|
385 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
|
yading@11
|
386 } else {
|
yading@11
|
387 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
|
yading@11
|
388 c->abytes += size;
|
yading@11
|
389 }
|
yading@11
|
390 } else {
|
yading@11
|
391 c->abytes += size;
|
yading@11
|
392 }
|
yading@11
|
393
|
yading@11
|
394 /* Now it's time to return video packet */
|
yading@11
|
395 size = dv_extract_video_info(c, buf);
|
yading@11
|
396 av_init_packet(pkt);
|
yading@11
|
397 pkt->data = buf;
|
yading@11
|
398 pkt->pos = pos;
|
yading@11
|
399 pkt->size = size;
|
yading@11
|
400 pkt->flags |= AV_PKT_FLAG_KEY;
|
yading@11
|
401 pkt->stream_index = c->vst->index;
|
yading@11
|
402 pkt->pts = c->frames;
|
yading@11
|
403
|
yading@11
|
404 c->frames++;
|
yading@11
|
405
|
yading@11
|
406 return size;
|
yading@11
|
407 }
|
yading@11
|
408
|
yading@11
|
409 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
|
yading@11
|
410 int64_t timestamp, int flags)
|
yading@11
|
411 {
|
yading@11
|
412 // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
|
yading@11
|
413 const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
|
yading@11
|
414 int64_t offset;
|
yading@11
|
415 int64_t size = avio_size(s->pb) - s->data_offset;
|
yading@11
|
416 int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
|
yading@11
|
417
|
yading@11
|
418 offset = sys->frame_size * timestamp;
|
yading@11
|
419
|
yading@11
|
420 if (size >= 0 && offset > max_offset) offset = max_offset;
|
yading@11
|
421 else if (offset < 0) offset = 0;
|
yading@11
|
422
|
yading@11
|
423 return offset + s->data_offset;
|
yading@11
|
424 }
|
yading@11
|
425
|
yading@11
|
426 void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
|
yading@11
|
427 {
|
yading@11
|
428 c->frames= frame_offset;
|
yading@11
|
429 if (c->ach) {
|
yading@11
|
430 if (c->sys) {
|
yading@11
|
431 c->abytes= av_rescale_q(c->frames, c->sys->time_base,
|
yading@11
|
432 (AVRational){8, c->ast[0]->codec->bit_rate});
|
yading@11
|
433 }else
|
yading@11
|
434 av_log(c->fctx, AV_LOG_ERROR, "cannot adjust audio bytes\n");
|
yading@11
|
435 }
|
yading@11
|
436 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
|
yading@11
|
437 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
|
yading@11
|
438 }
|
yading@11
|
439
|
yading@11
|
440 /************************************************************
|
yading@11
|
441 * Implementation of the easiest DV storage of all -- raw DV.
|
yading@11
|
442 ************************************************************/
|
yading@11
|
443
|
yading@11
|
444 typedef struct RawDVContext {
|
yading@11
|
445 DVDemuxContext* dv_demux;
|
yading@11
|
446 uint8_t buf[DV_MAX_FRAME_SIZE];
|
yading@11
|
447 } RawDVContext;
|
yading@11
|
448
|
yading@11
|
449 static int dv_read_timecode(AVFormatContext *s) {
|
yading@11
|
450 int ret;
|
yading@11
|
451 char timecode[AV_TIMECODE_STR_SIZE];
|
yading@11
|
452 int64_t pos = avio_tell(s->pb);
|
yading@11
|
453
|
yading@11
|
454 // Read 3 DIF blocks: Header block and 2 Subcode blocks.
|
yading@11
|
455 int partial_frame_size = 3 * 80;
|
yading@11
|
456 uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) *
|
yading@11
|
457 partial_frame_size);
|
yading@11
|
458
|
yading@11
|
459 RawDVContext *c = s->priv_data;
|
yading@11
|
460 ret = avio_read(s->pb, partial_frame, partial_frame_size);
|
yading@11
|
461 if (ret < 0)
|
yading@11
|
462 goto finish;
|
yading@11
|
463
|
yading@11
|
464 if (ret < partial_frame_size) {
|
yading@11
|
465 ret = -1;
|
yading@11
|
466 goto finish;
|
yading@11
|
467 }
|
yading@11
|
468
|
yading@11
|
469 ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode);
|
yading@11
|
470 if (ret)
|
yading@11
|
471 av_dict_set(&s->metadata, "timecode", timecode, 0);
|
yading@11
|
472 else
|
yading@11
|
473 av_log(s, AV_LOG_ERROR, "Detected timecode is invalid\n");
|
yading@11
|
474
|
yading@11
|
475 finish:
|
yading@11
|
476 av_free(partial_frame);
|
yading@11
|
477 avio_seek(s->pb, pos, SEEK_SET);
|
yading@11
|
478 return ret;
|
yading@11
|
479 }
|
yading@11
|
480
|
yading@11
|
481 static int dv_read_header(AVFormatContext *s)
|
yading@11
|
482 {
|
yading@11
|
483 unsigned state, marker_pos = 0;
|
yading@11
|
484 RawDVContext *c = s->priv_data;
|
yading@11
|
485
|
yading@11
|
486 c->dv_demux = avpriv_dv_init_demux(s);
|
yading@11
|
487 if (!c->dv_demux)
|
yading@11
|
488 return -1;
|
yading@11
|
489
|
yading@11
|
490 state = avio_rb32(s->pb);
|
yading@11
|
491 while ((state & 0xffffff7f) != 0x1f07003f) {
|
yading@11
|
492 if (url_feof(s->pb)) {
|
yading@11
|
493 av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
|
yading@11
|
494 return -1;
|
yading@11
|
495 }
|
yading@11
|
496 if (state == 0x003f0700 || state == 0xff3f0700)
|
yading@11
|
497 marker_pos = avio_tell(s->pb);
|
yading@11
|
498 if (state == 0xff3f0701 && avio_tell(s->pb) - marker_pos == 80) {
|
yading@11
|
499 avio_seek(s->pb, -163, SEEK_CUR);
|
yading@11
|
500 state = avio_rb32(s->pb);
|
yading@11
|
501 break;
|
yading@11
|
502 }
|
yading@11
|
503 state = (state << 8) | avio_r8(s->pb);
|
yading@11
|
504 }
|
yading@11
|
505 AV_WB32(c->buf, state);
|
yading@11
|
506
|
yading@11
|
507 if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) != DV_PROFILE_BYTES - 4 ||
|
yading@11
|
508 avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
|
yading@11
|
509 return AVERROR(EIO);
|
yading@11
|
510
|
yading@11
|
511 c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
|
yading@11
|
512 if (!c->dv_demux->sys) {
|
yading@11
|
513 av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
|
yading@11
|
514 return -1;
|
yading@11
|
515 }
|
yading@11
|
516
|
yading@11
|
517 s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
|
yading@11
|
518 c->dv_demux->sys->time_base);
|
yading@11
|
519
|
yading@11
|
520 if (s->pb->seekable)
|
yading@11
|
521 dv_read_timecode(s);
|
yading@11
|
522
|
yading@11
|
523 return 0;
|
yading@11
|
524 }
|
yading@11
|
525
|
yading@11
|
526
|
yading@11
|
527 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
|
yading@11
|
528 {
|
yading@11
|
529 int size;
|
yading@11
|
530 RawDVContext *c = s->priv_data;
|
yading@11
|
531
|
yading@11
|
532 size = avpriv_dv_get_packet(c->dv_demux, pkt);
|
yading@11
|
533
|
yading@11
|
534 if (size < 0) {
|
yading@11
|
535 int64_t pos = avio_tell(s->pb);
|
yading@11
|
536 if (!c->dv_demux->sys)
|
yading@11
|
537 return AVERROR(EIO);
|
yading@11
|
538 size = c->dv_demux->sys->frame_size;
|
yading@11
|
539 if (avio_read(s->pb, c->buf, size) <= 0)
|
yading@11
|
540 return AVERROR(EIO);
|
yading@11
|
541
|
yading@11
|
542 size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
|
yading@11
|
543 }
|
yading@11
|
544
|
yading@11
|
545 return size;
|
yading@11
|
546 }
|
yading@11
|
547
|
yading@11
|
548 static int dv_read_seek(AVFormatContext *s, int stream_index,
|
yading@11
|
549 int64_t timestamp, int flags)
|
yading@11
|
550 {
|
yading@11
|
551 RawDVContext *r = s->priv_data;
|
yading@11
|
552 DVDemuxContext *c = r->dv_demux;
|
yading@11
|
553 int64_t offset = dv_frame_offset(s, c, timestamp, flags);
|
yading@11
|
554
|
yading@11
|
555 if (avio_seek(s->pb, offset, SEEK_SET) < 0)
|
yading@11
|
556 return -1;
|
yading@11
|
557
|
yading@11
|
558 ff_dv_offset_reset(c, offset / c->sys->frame_size);
|
yading@11
|
559 return 0;
|
yading@11
|
560 }
|
yading@11
|
561
|
yading@11
|
562 static int dv_read_close(AVFormatContext *s)
|
yading@11
|
563 {
|
yading@11
|
564 RawDVContext *c = s->priv_data;
|
yading@11
|
565 av_free(c->dv_demux);
|
yading@11
|
566 return 0;
|
yading@11
|
567 }
|
yading@11
|
568
|
yading@11
|
569 static int dv_probe(AVProbeData *p)
|
yading@11
|
570 {
|
yading@11
|
571 unsigned state, marker_pos = 0;
|
yading@11
|
572 int i;
|
yading@11
|
573 int matches = 0;
|
yading@11
|
574 int secondary_matches = 0;
|
yading@11
|
575
|
yading@11
|
576 if (p->buf_size < 5)
|
yading@11
|
577 return 0;
|
yading@11
|
578
|
yading@11
|
579 state = AV_RB32(p->buf);
|
yading@11
|
580 for (i = 4; i < p->buf_size; i++) {
|
yading@11
|
581 if ((state & 0xffffff7f) == 0x1f07003f)
|
yading@11
|
582 matches++;
|
yading@11
|
583 // any section header, also with seq/chan num != 0,
|
yading@11
|
584 // should appear around every 12000 bytes, at least 10 per frame
|
yading@11
|
585 if ((state & 0xff07ff7f) == 0x1f07003f)
|
yading@11
|
586 secondary_matches++;
|
yading@11
|
587 if (state == 0x003f0700 || state == 0xff3f0700)
|
yading@11
|
588 marker_pos = i;
|
yading@11
|
589 if (state == 0xff3f0701 && i - marker_pos == 80)
|
yading@11
|
590 matches++;
|
yading@11
|
591 state = (state << 8) | p->buf[i];
|
yading@11
|
592 }
|
yading@11
|
593
|
yading@11
|
594 if (matches && p->buf_size / matches < 1024*1024) {
|
yading@11
|
595 if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
|
yading@11
|
596 return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match
|
yading@11
|
597 return AVPROBE_SCORE_MAX/4;
|
yading@11
|
598 }
|
yading@11
|
599 return 0;
|
yading@11
|
600 }
|
yading@11
|
601
|
yading@11
|
602 #if CONFIG_DV_DEMUXER
|
yading@11
|
603 AVInputFormat ff_dv_demuxer = {
|
yading@11
|
604 .name = "dv",
|
yading@11
|
605 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
|
yading@11
|
606 .priv_data_size = sizeof(RawDVContext),
|
yading@11
|
607 .read_probe = dv_probe,
|
yading@11
|
608 .read_header = dv_read_header,
|
yading@11
|
609 .read_packet = dv_read_packet,
|
yading@11
|
610 .read_close = dv_read_close,
|
yading@11
|
611 .read_seek = dv_read_seek,
|
yading@11
|
612 .extensions = "dv,dif",
|
yading@11
|
613 };
|
yading@11
|
614 #endif
|