Mercurial > libavformat.hg
annotate dv.c @ 5843:777a89fdb1c0 libavformat
RTSP: Synchronize the start time of the chained RTP muxers
This makes sure that the streams get correctly synchronized when viewed,
previously the streams were out of sync by as much time as it took
between the initialization of the individual muxers.
author | mstorsjo |
---|---|
date | Mon, 15 Mar 2010 14:20:07 +0000 |
parents | 15f34b5059ed |
children | cf5eee67f9eb |
rev | line source |
---|---|
885 | 1 /* |
2 * General DV muxer/demuxer | |
933 | 3 * Copyright (c) 2003 Roman Shaposhnik |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
4 * |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
5 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
6 * of DV technical info. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
7 * |
0 | 8 * Raw DV format |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4206
diff
changeset
|
9 * Copyright (c) 2002 Fabrice Bellard |
0 | 10 * |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
11 * 50 Mbps (DVCPRO50) and 100 Mbps (DVCPRO HD) support |
995 | 12 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com> |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
13 * Funded by BBC Research & Development |
995 | 14 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1317
diff
changeset
|
15 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1317
diff
changeset
|
16 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1317
diff
changeset
|
17 * FFmpeg is free software; you can redistribute it and/or |
0 | 18 * modify it under the terms of the GNU Lesser General Public |
19 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1317
diff
changeset
|
20 * version 2.1 of the License, or (at your option) any later version. |
0 | 21 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1317
diff
changeset
|
22 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1317
diff
changeset
|
28 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 30 */ |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
31 #include <time.h> |
0 | 32 #include "avformat.h" |
3286 | 33 #include "libavcodec/dvdata.h" |
4562
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
34 #include "libavutil/intreadwrite.h" |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
35 #include "dv.h" |
0 | 36 |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
37 struct DVDemuxContext { |
995 | 38 const DVprofile* sys; /* Current DV profile. E.g.: 525/60, 625/50 */ |
4008 | 39 AVFormatContext* fctx; |
40 AVStream* vst; | |
41 AVStream* ast[4]; | |
42 AVPacket audio_pkt[4]; | |
43 uint8_t audio_buf[4][8192]; | |
44 int ach; | |
45 int frames; | |
46 uint64_t abytes; | |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
47 }; |
0 | 48 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
49 static inline uint16_t dv_audio_12to16(uint16_t sample) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
50 { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
51 uint16_t shift, result; |
885 | 52 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
53 sample = (sample < 0x800) ? sample : sample | 0xf000; |
4008 | 54 shift = (sample & 0xf00) >> 8; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
55 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
56 if (shift < 0x2 || shift > 0xd) { |
887 | 57 result = sample; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
58 } else if (shift < 0x8) { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
59 shift--; |
887 | 60 result = (sample - (256 * shift)) << shift; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
61 } else { |
887 | 62 shift = 0xe - shift; |
63 result = ((sample + ((256 * shift) + 1)) << shift) - 1; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
64 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
65 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
66 return result; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
67 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
68 |
885 | 69 /* |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
70 * This is the dumbest implementation of all -- it simply looks at |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
71 * a fixed offset and if pack isn't there -- fails. We might want |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
72 * to have a fallback mechanism for complete search of missing packs. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
73 */ |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
74 static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
75 { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
76 int offs; |
885 | 77 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
78 switch (t) { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
79 case dv_audio_source: |
4008 | 80 offs = (80*6 + 80*16*3 + 3); |
81 break; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
82 case dv_audio_control: |
4008 | 83 offs = (80*6 + 80*16*4 + 3); |
84 break; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
85 case dv_video_control: |
4008 | 86 offs = (80*5 + 48 + 5); |
87 break; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
88 default: |
4008 | 89 return NULL; |
885 | 90 } |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
91 |
3278 | 92 return frame[offs] == t ? &frame[offs] : NULL; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
93 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
94 |
885 | 95 /* |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
96 * There's a couple of assumptions being made here: |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
97 * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
98 * We can pass them upwards when ffmpeg will be ready to deal with them. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
99 * 2. We don't do software emphasis. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
100 * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
101 * are converted into 16bit linear ones. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
102 */ |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
103 static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], |
995 | 104 const DVprofile *sys) |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
105 { |
995 | 106 int size, chan, i, j, d, of, smpls, freq, quant, half_ch; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
107 uint16_t lc, rc; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
108 const uint8_t* as_pack; |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
109 uint8_t *pcm, ipcm; |
885 | 110 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
111 as_pack = dv_extract_pack(frame, dv_audio_source); |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
112 if (!as_pack) /* No audio ? */ |
887 | 113 return 0; |
885 | 114 |
4008 | 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 */ | |
885 | 118 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
119 if (quant > 1) |
4007 | 120 return -1; /* unsupported quantization */ |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
121 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
122 size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ |
4008 | 123 half_ch = sys->difseg_size / 2; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
124 |
4007 | 125 /* We work with 720p frames split in half, thus even frames have |
4008 | 126 * channels 0,1 and odd 2,3. */ |
127 ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0; | |
128 pcm = ppcm[ipcm++]; | |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
129 |
995 | 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) */ | |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
137 pcm = ppcm[ipcm++]; |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
138 if (!pcm) |
995 | 139 break; |
140 } | |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
141 |
995 | 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 */ | |
4008 | 146 of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride; |
995 | 147 if (of*2 >= size) |
148 continue; | |
885 | 149 |
3968 | 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 | |
995 | 152 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00) |
153 pcm[of*2+1] = 0; | |
154 } else { /* 12bit quantization */ | |
4008 | 155 lc = ((uint16_t)frame[d] << 4) | |
995 | 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)); | |
161 | |
4008 | 162 of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride; |
995 | 163 if (of*2 >= size) |
164 continue; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
165 |
3968 | 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 | |
995 | 168 of = sys->audio_shuffle[i%half_ch+half_ch][j] + |
4008 | 169 (d - 8) / 3 * sys->audio_stride; |
3968 | 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 | |
995 | 172 ++d; |
173 } | |
174 } | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
175 |
995 | 176 frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ |
177 } | |
178 } | |
885 | 179 |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
180 /* next stereo channel (50Mbps and 100Mbps only) */ |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
181 pcm = ppcm[ipcm++]; |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
182 if (!pcm) |
995 | 183 break; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
184 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
185 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
186 return size; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
187 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
188 |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
189 static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
190 { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
191 const uint8_t* as_pack; |
995 | 192 int freq, stype, smpls, quant, i, ach; |
37 | 193 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
194 as_pack = dv_extract_pack(frame, dv_audio_source); |
995 | 195 if (!as_pack || !c->sys) { /* No audio ? */ |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
196 c->ach = 0; |
887 | 197 return 0; |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
198 } |
885 | 199 |
4008 | 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 */ | |
995 | 204 |
205 /* note: ach counts PAIRS of channels (i.e. stereo channels) */ | |
3993 | 206 ach = ((int[4]){ 1, 0, 2, 4})[stype]; |
3991 | 207 if (ach == 1 && quant && freq == 2) |
208 ach = 2; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
209 |
532
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
210 /* Dynamic handling of the audio streams in DV */ |
4008 | 211 for (i = 0; i < ach; i++) { |
532
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
212 if (!c->ast[i]) { |
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
213 c->ast[i] = av_new_stream(c->fctx, 0); |
887 | 214 if (!c->ast[i]) |
215 break; | |
216 av_set_pts_info(c->ast[i], 64, 1, 30000); | |
217 c->ast[i]->codec->codec_type = CODEC_TYPE_AUDIO; | |
4008 | 218 c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE; |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
219 |
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
220 av_init_packet(&c->audio_pkt[i]); |
4008 | 221 c->audio_pkt[i].size = 0; |
222 c->audio_pkt[i].data = c->audio_buf[i]; | |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
223 c->audio_pkt[i].stream_index = c->ast[i]->index; |
4008 | 224 c->audio_pkt[i].flags |= PKT_FLAG_KEY; |
532
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
225 } |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
764
diff
changeset
|
226 c->ast[i]->codec->sample_rate = dv_audio_frequency[freq]; |
4008 | 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; | |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
230 } |
532
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
231 c->ach = i; |
885 | 232 |
995 | 233 return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
234 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
235 |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
236 static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame) |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
237 { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
238 const uint8_t* vsc_pack; |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
239 AVCodecContext* avctx; |
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
240 int apt, is16_9; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
241 int size = 0; |
885 | 242 |
995 | 243 if (c->sys) { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
764
diff
changeset
|
244 avctx = c->vst->codec; |
885 | 245 |
4008 | 246 av_set_pts_info(c->vst, 64, c->sys->time_base.num, |
247 c->sys->time_base.den); | |
3992
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
248 avctx->time_base= c->sys->time_base; |
4008 | 249 if (!avctx->width){ |
995 | 250 avctx->width = c->sys->width; |
251 avctx->height = c->sys->height; | |
845 | 252 } |
995 | 253 avctx->pix_fmt = c->sys->pix_fmt; |
885 | 254 |
887 | 255 /* finding out SAR is a little bit messy */ |
256 vsc_pack = dv_extract_pack(frame, dv_video_control); | |
4008 | 257 apt = frame[4] & 0x07; |
258 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || | |
259 (!apt && (vsc_pack[2] & 0x07) == 0x07))); | |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3424
diff
changeset
|
260 c->vst->sample_aspect_ratio = c->sys->sar[is16_9]; |
3992
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
261 avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1}, |
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
262 c->sys->time_base); |
995 | 263 size = c->sys->frame_size; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
264 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
265 return size; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
266 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
267 |
885 | 268 /* |
1317
132206560fe6
Split the DV demuxer and muxer into separate files (as suggested by Diego
takis
parents:
1289
diff
changeset
|
269 * The following 3 functions constitute our interface to the world |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
270 */ |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
271 |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
272 DVDemuxContext* dv_init_demux(AVFormatContext *s) |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
273 { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
274 DVDemuxContext *c; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
275 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
276 c = av_mallocz(sizeof(DVDemuxContext)); |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
277 if (!c) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
278 return NULL; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
279 |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
280 c->vst = av_new_stream(s, 0); |
532
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
281 if (!c->vst) { |
885 | 282 av_free(c); |
532
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
283 return NULL; |
772247018ade
* experimental dynamic audio stream allocation for DV demuxer. This
romansh
parents:
531
diff
changeset
|
284 } |
462
b69898ffc92a
move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents:
460
diff
changeset
|
285 |
4008 | 286 c->sys = NULL; |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
287 c->fctx = s; |
3787
6f3cdf5fb948
Two cosmetic changes for improved readability and ease of HDVCPRO HD integration
romansh
parents:
3759
diff
changeset
|
288 memset(c->ast, 0, sizeof(c->ast)); |
4008 | 289 c->ach = 0; |
392 | 290 c->frames = 0; |
291 c->abytes = 0; | |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
292 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
764
diff
changeset
|
293 c->vst->codec->codec_type = CODEC_TYPE_VIDEO; |
4008 | 294 c->vst->codec->codec_id = CODEC_ID_DVVIDEO; |
295 c->vst->codec->bit_rate = 25000000; | |
296 c->vst->start_time = 0; | |
885 | 297 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
298 return c; |
0 | 299 } |
300 | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
301 int dv_get_packet(DVDemuxContext *c, AVPacket *pkt) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
302 { |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
303 int size = -1; |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
304 int i; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
305 |
4008 | 306 for (i = 0; i < c->ach; i++) { |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
307 if (c->ast[i] && c->audio_pkt[i].size) { |
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
308 *pkt = c->audio_pkt[i]; |
887 | 309 c->audio_pkt[i].size = 0; |
310 size = pkt->size; | |
311 break; | |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
312 } |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
313 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
314 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
315 return size; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
316 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
317 |
885 | 318 int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
319 uint8_t* buf, int buf_size) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
320 { |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
321 int size, i; |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
322 uint8_t *ppcm[4] = {0}; |
885 | 323 |
1048 | 324 if (buf_size < DV_PROFILE_BYTES || |
5288
15f34b5059ed
Split parts of dvdata.h into dvdata.c, this ensures that things like
reimar
parents:
5237
diff
changeset
|
325 !(c->sys = ff_dv_frame_profile(c->sys, buf, buf_size)) || |
1048 | 326 buf_size < c->sys->frame_size) { |
327 return -1; /* Broken frame, or not enough data */ | |
328 } | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
329 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
330 /* Queueing audio packet */ |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
331 /* FIXME: in case of no audio/bad audio we have to do something */ |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
332 size = dv_extract_audio_info(c, buf); |
4008 | 333 for (i = 0; i < c->ach; i++) { |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
334 c->audio_pkt[i].size = size; |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
764
diff
changeset
|
335 c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate; |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
336 ppcm[i] = c->audio_buf[i]; |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
337 } |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
338 dv_extract_audio(buf, ppcm, c->sys); |
885 | 339 |
4007 | 340 /* We work with 720p frames split in half, thus even frames have |
341 * channels 0,1 and odd 2,3. */ | |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
342 if (c->sys->height == 720) { |
5047
0a4137d6a7a5
fix dvcprohd 720p channels 3 and 4 audio timestamps, patch by Brian Brice, bbrice at gmail dot com
bcoudurier
parents:
5034
diff
changeset
|
343 if (buf[1] & 0x0C) { |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
344 c->audio_pkt[2].size = c->audio_pkt[3].size = 0; |
5047
0a4137d6a7a5
fix dvcprohd 720p channels 3 and 4 audio timestamps, patch by Brian Brice, bbrice at gmail dot com
bcoudurier
parents:
5034
diff
changeset
|
345 } else { |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
346 c->audio_pkt[0].size = c->audio_pkt[1].size = 0; |
5047
0a4137d6a7a5
fix dvcprohd 720p channels 3 and 4 audio timestamps, patch by Brian Brice, bbrice at gmail dot com
bcoudurier
parents:
5034
diff
changeset
|
347 c->abytes += size; |
0a4137d6a7a5
fix dvcprohd 720p channels 3 and 4 audio timestamps, patch by Brian Brice, bbrice at gmail dot com
bcoudurier
parents:
5034
diff
changeset
|
348 } |
0a4137d6a7a5
fix dvcprohd 720p channels 3 and 4 audio timestamps, patch by Brian Brice, bbrice at gmail dot com
bcoudurier
parents:
5034
diff
changeset
|
349 } else { |
0a4137d6a7a5
fix dvcprohd 720p channels 3 and 4 audio timestamps, patch by Brian Brice, bbrice at gmail dot com
bcoudurier
parents:
5034
diff
changeset
|
350 c->abytes += size; |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
351 } |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
352 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
353 /* Now it's time to return video packet */ |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
354 size = dv_extract_video_info(c, buf); |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
355 av_init_packet(pkt); |
4008 | 356 pkt->data = buf; |
357 pkt->size = size; | |
358 pkt->flags |= PKT_FLAG_KEY; | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
359 pkt->stream_index = c->vst->id; |
4008 | 360 pkt->pts = c->frames; |
885 | 361 |
392 | 362 c->frames++; |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
363 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
364 return size; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
365 } |
885 | 366 |
559
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
367 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c, |
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
368 int64_t timestamp, int flags) |
392 | 369 { |
523
d788959a01e2
* seek in raw DV patch by Nathan Kurz (nate at verse dot com)
romansh
parents:
515
diff
changeset
|
370 // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk) |
5288
15f34b5059ed
Split parts of dvdata.h into dvdata.c, this ensures that things like
reimar
parents:
5237
diff
changeset
|
371 const DVprofile* sys = ff_dv_codec_profile(c->vst->codec); |
741 | 372 int64_t offset; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
373 int64_t size = url_fsize(s->pb); |
559
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
374 int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size; |
392 | 375 |
741 | 376 offset = sys->frame_size * timestamp; |
885 | 377 |
559
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
378 if (offset > max_offset) offset = max_offset; |
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
379 else if (offset < 0) offset = 0; |
523
d788959a01e2
* seek in raw DV patch by Nathan Kurz (nate at verse dot com)
romansh
parents:
515
diff
changeset
|
380 |
d788959a01e2
* seek in raw DV patch by Nathan Kurz (nate at verse dot com)
romansh
parents:
515
diff
changeset
|
381 return offset; |
392 | 382 } |
383 | |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1358
diff
changeset
|
384 void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset) |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
385 { |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1358
diff
changeset
|
386 c->frames= frame_offset; |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1358
diff
changeset
|
387 if (c->ach) |
3992
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
388 c->abytes= av_rescale_q(c->frames, c->sys->time_base, |
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
389 (AVRational){8, c->ast[0]->codec->bit_rate}); |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
390 c->audio_pkt[0].size = c->audio_pkt[1].size = 0; |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
391 c->audio_pkt[2].size = c->audio_pkt[3].size = 0; |
562
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
392 } |
bf3231dd1d7c
* static allocation for audio packets. This will make it a little bit
romansh
parents:
560
diff
changeset
|
393 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
394 /************************************************************ |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
395 * Implementation of the easiest DV storage of all -- raw DV. |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
396 ************************************************************/ |
885 | 397 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
398 typedef struct RawDVContext { |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
399 DVDemuxContext* dv_demux; |
995 | 400 uint8_t buf[DV_MAX_FRAME_SIZE]; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
401 } RawDVContext; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
402 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
403 static int dv_read_header(AVFormatContext *s, |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
404 AVFormatParameters *ap) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
405 { |
5034
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
406 unsigned state, marker_pos = 0; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
407 RawDVContext *c = s->priv_data; |
995 | 408 |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
288
diff
changeset
|
409 c->dv_demux = dv_init_demux(s); |
524
0b9dfb0cddc8
* misc. fixes and hacks to improve timing detection in raw DV
romansh
parents:
523
diff
changeset
|
410 if (!c->dv_demux) |
0b9dfb0cddc8
* misc. fixes and hacks to improve timing detection in raw DV
romansh
parents:
523
diff
changeset
|
411 return -1; |
885 | 412 |
4562
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
413 state = get_be32(s->pb); |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
414 while ((state & 0xffffff7f) != 0x1f07003f) { |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
415 if (url_feof(s->pb)) { |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
416 av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n"); |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
417 return -1; |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
418 } |
5034
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
419 if (state == 0x003f0700 || state == 0xff3f0700) |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
420 marker_pos = url_ftell(s->pb); |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
421 if (state == 0xff3f0701 && url_ftell(s->pb) - marker_pos == 80) { |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
422 url_fseek(s->pb, -163, SEEK_CUR); |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
423 state = get_be32(s->pb); |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
424 break; |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
425 } |
4562
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
426 state = (state << 8) | get_byte(s->pb); |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
427 } |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
428 AV_WB32(c->buf, state); |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
429 |
69cb74b61706
Support playback of incorrectly cut DV files where the headers do not
reimar
parents:
4251
diff
changeset
|
430 if (get_buffer(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 || |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
431 url_fseek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2203
diff
changeset
|
432 return AVERROR(EIO); |
524
0b9dfb0cddc8
* misc. fixes and hacks to improve timing detection in raw DV
romansh
parents:
523
diff
changeset
|
433 |
5288
15f34b5059ed
Split parts of dvdata.h into dvdata.c, this ensures that things like
reimar
parents:
5237
diff
changeset
|
434 c->dv_demux->sys = ff_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES); |
3790
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
435 if (!c->dv_demux->sys) { |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
436 av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n"); |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
437 return -1; |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
438 } |
a8a70ae19206
Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as
romansh
parents:
3787
diff
changeset
|
439 |
3992
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
440 s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1}, |
36f92f77c85e
replacing frame_rate and frame_rate_base with an AVRational time_base
romansh
parents:
3991
diff
changeset
|
441 c->dv_demux->sys->time_base); |
885 | 442 |
524
0b9dfb0cddc8
* misc. fixes and hacks to improve timing detection in raw DV
romansh
parents:
523
diff
changeset
|
443 return 0; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
444 } |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
445 |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
446 |
0 | 447 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) |
448 { | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
449 int size; |
885 | 450 RawDVContext *c = s->priv_data; |
451 | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
452 size = dv_get_packet(c->dv_demux, pkt); |
885 | 453 |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
454 if (size < 0) { |
4155 | 455 if (!c->dv_demux->sys) |
456 return AVERROR(EIO); | |
995 | 457 size = c->dv_demux->sys->frame_size; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
458 if (get_buffer(s->pb, c->buf, size) <= 0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2203
diff
changeset
|
459 return AVERROR(EIO); |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
460 |
887 | 461 size = dv_produce_packet(c->dv_demux, pkt, c->buf, size); |
885 | 462 } |
463 | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
464 return size; |
0 | 465 } |
466 | |
885 | 467 static int dv_read_seek(AVFormatContext *s, int stream_index, |
559
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
468 int64_t timestamp, int flags) |
392 | 469 { |
4008 | 470 RawDVContext *r = s->priv_data; |
559
f5f85a07fafe
flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>)
michael
parents:
532
diff
changeset
|
471 DVDemuxContext *c = r->dv_demux; |
4008 | 472 int64_t offset = dv_frame_offset(s, c, timestamp, flags); |
392 | 473 |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1358
diff
changeset
|
474 dv_offset_reset(c, offset / c->sys->frame_size); |
885 | 475 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
476 offset = url_fseek(s->pb, offset, SEEK_SET); |
4008 | 477 return (offset < 0) ? offset : 0; |
392 | 478 } |
479 | |
0 | 480 static int dv_read_close(AVFormatContext *s) |
481 { | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
482 RawDVContext *c = s->priv_data; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
483 av_free(c->dv_demux); |
0 | 484 return 0; |
485 } | |
486 | |
4582 | 487 static int dv_probe(AVProbeData *p) |
488 { | |
5034
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
489 unsigned state, marker_pos = 0; |
4582 | 490 int i; |
5185 | 491 int matches = 0; |
5237
496723640f94
Extend DV autodetection to also reliably detect single-frame DVs with
reimar
parents:
5185
diff
changeset
|
492 int secondary_matches = 0; |
4582 | 493 |
494 if (p->buf_size < 5) | |
495 return 0; | |
496 | |
497 state = AV_RB32(p->buf); | |
498 for (i = 4; i < p->buf_size; i++) { | |
499 if ((state & 0xffffff7f) == 0x1f07003f) | |
5185 | 500 matches++; |
5237
496723640f94
Extend DV autodetection to also reliably detect single-frame DVs with
reimar
parents:
5185
diff
changeset
|
501 // any section header, also with seq/chan num != 0, |
496723640f94
Extend DV autodetection to also reliably detect single-frame DVs with
reimar
parents:
5185
diff
changeset
|
502 // should appear around every 12000 bytes, at least 10 per frame |
496723640f94
Extend DV autodetection to also reliably detect single-frame DVs with
reimar
parents:
5185
diff
changeset
|
503 if ((state & 0xff07ff7f) == 0x1f07003f) |
496723640f94
Extend DV autodetection to also reliably detect single-frame DVs with
reimar
parents:
5185
diff
changeset
|
504 secondary_matches++; |
5034
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
505 if (state == 0x003f0700 || state == 0xff3f0700) |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
506 marker_pos = i; |
b9f35b2c4859
fix probing and demuxing of pond.dv, issue #887
bcoudurier
parents:
5033
diff
changeset
|
507 if (state == 0xff3f0701 && i - marker_pos == 80) |
5185 | 508 matches++; |
4582 | 509 state = (state << 8) | p->buf[i]; |
510 } | |
511 | |
5185 | 512 if (matches && p->buf_size / matches < 1024*1024) { |
5237
496723640f94
Extend DV autodetection to also reliably detect single-frame DVs with
reimar
parents:
5185
diff
changeset
|
513 if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000)) |
5185 | 514 return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match |
515 return AVPROBE_SCORE_MAX/4; | |
516 } | |
4582 | 517 return 0; |
518 } | |
519 | |
4206 | 520 #if CONFIG_DV_DEMUXER |
1169 | 521 AVInputFormat dv_demuxer = { |
0 | 522 "dv", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
523 NULL_IF_CONFIG_SMALL("DV video format"), |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
241
diff
changeset
|
524 sizeof(RawDVContext), |
4582 | 525 dv_probe, |
0 | 526 dv_read_header, |
527 dv_read_packet, | |
528 dv_read_close, | |
392 | 529 dv_read_seek, |
393 | 530 .extensions = "dv,dif", |
0 | 531 }; |
1169 | 532 #endif |