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