Mercurial > libavformat.hg
annotate gxf.c @ 2136:b53a19eed95d libavformat
remove duplicate PAT scaning code and actual PAT scan
also disabling the nonsense 3yr old rawts change (it would after the
above chage totally break the demuxer if its left enabled)
author | michael |
---|---|
date | Mon, 04 Jun 2007 14:44:52 +0000 |
parents | a3e79d6e4e3c |
children | b21c2af60bc9 |
rev | line source |
---|---|
1145 | 1 /* |
2 * GXF demuxer. | |
3 * Copyright (c) 2006 Reimar Doeffinger. | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1243
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1243
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1243
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1145 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * 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:
1243
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1145 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1243
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1145 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * 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:
1243
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
1145 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | |
21 #include "avformat.h" | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
22 #include "common.h" |
1145 | 23 |
24 typedef enum { | |
25 PKT_MAP = 0xbc, | |
26 PKT_MEDIA = 0xbf, | |
27 PKT_EOS = 0xfb, | |
28 PKT_FLT = 0xfc, | |
29 PKT_UMF = 0xfd | |
30 } pkt_type_t; | |
31 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
32 typedef enum { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
33 MAT_NAME = 0x40, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
34 MAT_FIRST_FIELD = 0x41, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
35 MAT_LAST_FIELD = 0x42, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
36 MAT_MARK_IN = 0x43, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
37 MAT_MARK_OUT = 0x44, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
38 MAT_SIZE = 0x45 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
39 } mat_tag_t; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
40 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
41 typedef enum { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
42 TRACK_NAME = 0x4c, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
43 TRACK_AUX = 0x4d, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
44 TRACK_VER = 0x4e, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
45 TRACK_MPG_AUX = 0x4f, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
46 TRACK_FPS = 0x50, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
47 TRACK_LINES = 0x51, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
48 TRACK_FPF = 0x52 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
49 } track_tag_t; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
50 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
51 typedef struct { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
52 int64_t first_field; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
53 int64_t last_field; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
54 AVRational frames_per_second; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
55 int32_t fields_per_frame; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
56 } st_info_t; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
57 |
1145 | 58 /** |
59 * \brief parses a packet header, extracting type and length | |
60 * \param pb ByteIOContext to read header from | |
61 * \param type detected packet type is stored here | |
62 * \param length detected packet length, excluding header is stored here | |
63 * \return 0 if header not found or contains invalid data, 1 otherwise | |
64 */ | |
65 static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) { | |
66 if (get_be32(pb)) | |
67 return 0; | |
68 if (get_byte(pb) != 1) | |
69 return 0; | |
70 *type = get_byte(pb); | |
71 *length = get_be32(pb); | |
72 if ((*length >> 24) || *length < 16) | |
73 return 0; | |
74 *length -= 16; | |
75 if (get_be32(pb)) | |
76 return 0; | |
77 if (get_byte(pb) != 0xe1) | |
78 return 0; | |
79 if (get_byte(pb) != 0xe2) | |
80 return 0; | |
81 return 1; | |
82 } | |
83 | |
84 /** | |
85 * \brief check if file starts with a PKT_MAP header | |
86 */ | |
87 static int gxf_probe(AVProbeData *p) { | |
88 static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet | |
89 static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2}; | |
90 if (!memcmp(p->buf, startcode, sizeof(startcode)) && | |
91 !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode))) | |
92 return AVPROBE_SCORE_MAX; | |
93 return 0; | |
94 } | |
95 | |
96 /** | |
97 * \brief gets the stream index for the track with the specified id, creates new | |
98 * stream if not found | |
99 * \param stream id of stream to find / add | |
100 * \param format stream format identifier | |
101 */ | |
102 static int get_sindex(AVFormatContext *s, int id, int format) { | |
103 int i; | |
104 AVStream *st = NULL; | |
105 for (i = 0; i < s->nb_streams; i++) { | |
106 if (s->streams[i]->id == id) | |
107 return i; | |
108 } | |
109 st = av_new_stream(s, id); | |
110 switch (format) { | |
111 case 3: | |
112 case 4: | |
113 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
114 st->codec->codec_id = CODEC_ID_MJPEG; | |
115 break; | |
116 case 13: | |
117 case 15: | |
118 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
119 st->codec->codec_id = CODEC_ID_DVVIDEO; | |
120 break; | |
121 case 14: | |
122 case 16: | |
123 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
124 st->codec->codec_id = CODEC_ID_DVVIDEO; | |
125 break; | |
126 case 11: | |
127 case 12: | |
128 case 20: | |
129 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
130 st->codec->codec_id = CODEC_ID_MPEG2VIDEO; | |
2023 | 131 st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. |
1145 | 132 break; |
133 case 22: | |
134 case 23: | |
135 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
136 st->codec->codec_id = CODEC_ID_MPEG1VIDEO; | |
2023 | 137 st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. |
1145 | 138 break; |
139 case 9: | |
140 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
141 st->codec->codec_id = CODEC_ID_PCM_S24LE; | |
142 st->codec->channels = 1; | |
143 st->codec->sample_rate = 48000; | |
144 st->codec->bit_rate = 3 * 1 * 48000 * 8; | |
145 st->codec->block_align = 3 * 1; | |
146 st->codec->bits_per_sample = 24; | |
147 break; | |
148 case 10: | |
149 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
150 st->codec->codec_id = CODEC_ID_PCM_S16LE; | |
151 st->codec->channels = 1; | |
152 st->codec->sample_rate = 48000; | |
153 st->codec->bit_rate = 2 * 1 * 48000 * 8; | |
154 st->codec->block_align = 2 * 1; | |
155 st->codec->bits_per_sample = 16; | |
156 break; | |
157 case 17: | |
158 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
159 st->codec->codec_id = CODEC_ID_AC3; | |
160 st->codec->channels = 2; | |
161 st->codec->sample_rate = 48000; | |
162 break; | |
1539 | 163 // timecode tracks: |
164 case 7: | |
165 case 8: | |
166 case 24: | |
167 st->codec->codec_type = CODEC_TYPE_DATA; | |
168 st->codec->codec_id = CODEC_ID_NONE; | |
169 break; | |
1145 | 170 default: |
171 st->codec->codec_type = CODEC_TYPE_UNKNOWN; | |
172 st->codec->codec_id = CODEC_ID_NONE; | |
173 break; | |
174 } | |
175 return s->nb_streams - 1; | |
176 } | |
177 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
178 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
179 * \brief filters out interesting tags from material information. |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
180 * \param len lenght of tag section, will be adjusted to contain remaining bytes |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
181 * \param si struct to store collected information into |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
182 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
183 static void gxf_material_tags(ByteIOContext *pb, int *len, st_info_t *si) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
184 si->first_field = AV_NOPTS_VALUE; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
185 si->last_field = AV_NOPTS_VALUE; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
186 while (*len >= 2) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
187 mat_tag_t tag = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
188 int tlen = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
189 *len -= 2; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
190 if (tlen > *len) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
191 return; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
192 *len -= tlen; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
193 if (tlen == 4) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
194 uint32_t value = get_be32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
195 if (tag == MAT_FIRST_FIELD) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
196 si->first_field = value; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
197 else if (tag == MAT_LAST_FIELD) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
198 si->last_field = value; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
199 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
200 url_fskip(pb, tlen); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
201 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
202 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
203 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
204 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
205 * \brief convert fps tag value to AVRational fps |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
206 * \param fps fps value from tag |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
207 * \return fps as AVRational, or 0 / 0 if unknown |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
208 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
209 static AVRational fps_tag2avr(int32_t fps) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
210 extern const AVRational ff_frame_rate_tab[]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
211 if (fps < 1 || fps > 9) fps = 9; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
212 return ff_frame_rate_tab[9 - fps]; // values have opposite order |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
213 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
214 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
215 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
216 * \brief convert UMF attributes flags to AVRational fps |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
217 * \param fps fps value from flags |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
218 * \return fps as AVRational, or 0 / 0 if unknown |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
219 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
220 static AVRational fps_umf2avr(uint32_t flags) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
221 static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1}, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
222 {25, 1}, {30000, 1001}}; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
223 int idx = av_log2((flags & 0x7c0) >> 6); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
224 return map[idx]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
225 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
226 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
227 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
228 * \brief filters out interesting tags from track information. |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
229 * \param len length of tag section, will be adjusted to contain remaining bytes |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
230 * \param si struct to store collected information into |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
231 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
232 static void gxf_track_tags(ByteIOContext *pb, int *len, st_info_t *si) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
233 si->frames_per_second = (AVRational){0, 0}; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
234 si->fields_per_frame = 0; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
235 while (*len >= 2) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
236 track_tag_t tag = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
237 int tlen = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
238 *len -= 2; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
239 if (tlen > *len) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
240 return; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
241 *len -= tlen; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
242 if (tlen == 4) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
243 uint32_t value = get_be32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
244 if (tag == TRACK_FPS) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
245 si->frames_per_second = fps_tag2avr(value); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
246 else if (tag == TRACK_FPF && (value == 1 || value == 2)) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
247 si->fields_per_frame = value; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
248 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
249 url_fskip(pb, tlen); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
250 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
251 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
252 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
253 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
254 * \brief read index from FLT packet into stream 0 av_index |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
255 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
256 static void gxf_read_index(AVFormatContext *s, int pkt_len) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
257 ByteIOContext *pb = &s->pb; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
258 AVStream *st = s->streams[0]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
259 uint32_t fields_per_map = get_le32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
260 uint32_t map_cnt = get_le32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
261 int i; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
262 pkt_len -= 8; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
263 if (map_cnt > 1000) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
264 av_log(s, AV_LOG_ERROR, "GXF: too many index entries %u (%x)\n", map_cnt, map_cnt); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
265 map_cnt = 1000; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
266 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
267 if (pkt_len < 4 * map_cnt) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
268 av_log(s, AV_LOG_ERROR, "GXF: invalid index length\n"); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
269 url_fskip(pb, pkt_len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
270 return; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
271 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
272 pkt_len -= 4 * map_cnt; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
273 av_add_index_entry(st, 0, 0, 0, 0, 0); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
274 for (i = 0; i < map_cnt; i++) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
275 av_add_index_entry(st, (uint64_t)get_le32(pb) * 1024, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
276 i * (uint64_t)fields_per_map + 1, 0, 0, 0); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
277 url_fskip(pb, pkt_len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
278 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
279 |
1145 | 280 static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { |
281 ByteIOContext *pb = &s->pb; | |
282 pkt_type_t pkt_type; | |
283 int map_len; | |
284 int len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
285 AVRational main_timebase = {0, 0}; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
286 st_info_t si; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
287 int i; |
1145 | 288 if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) { |
289 av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n"); | |
290 return 0; | |
291 } | |
292 map_len -= 2; | |
293 if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) { | |
294 av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n"); | |
295 return 0; | |
296 } | |
297 map_len -= 2; | |
298 len = get_be16(pb); // length of material data section | |
299 if (len > map_len) { | |
300 av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n"); | |
301 return 0; | |
302 } | |
303 map_len -= len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
304 gxf_material_tags(pb, &len, &si); |
1145 | 305 url_fskip(pb, len); |
306 map_len -= 2; | |
307 len = get_be16(pb); // length of track description | |
308 if (len > map_len) { | |
309 av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n"); | |
310 return 0; | |
311 } | |
312 map_len -= len; | |
313 while (len > 0) { | |
314 int track_type, track_id, track_len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
315 AVStream *st; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
316 int idx; |
1145 | 317 len -= 4; |
318 track_type = get_byte(pb); | |
319 track_id = get_byte(pb); | |
320 track_len = get_be16(pb); | |
321 len -= track_len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
322 gxf_track_tags(pb, &track_len, &si); |
1145 | 323 url_fskip(pb, track_len); |
324 if (!(track_type & 0x80)) { | |
325 av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type); | |
326 continue; | |
327 } | |
328 track_type &= 0x7f; | |
329 if ((track_id & 0xc0) != 0xc0) { | |
330 av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id); | |
331 continue; | |
332 } | |
333 track_id &= 0x3f; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
334 idx = get_sindex(s, track_id, track_type); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
335 if (idx < 0) continue; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
336 st = s->streams[idx]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
337 if (!main_timebase.num || !main_timebase.den) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
338 main_timebase.num = si.frames_per_second.den; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
339 main_timebase.den = si.frames_per_second.num * si.fields_per_frame; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
340 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
341 st->start_time = si.first_field; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
342 if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
343 st->duration = si.last_field - si.first_field; |
1145 | 344 } |
345 if (len < 0) | |
346 av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n"); | |
347 if (map_len) | |
348 url_fskip(pb, map_len); | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
349 if (!parse_packet_header(pb, &pkt_type, &len)) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
350 av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n"); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
351 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
352 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
353 if (pkt_type == PKT_FLT) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
354 gxf_read_index(s, len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
355 if (!parse_packet_header(pb, &pkt_type, &len)) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
356 av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n"); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
357 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
358 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
359 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
360 if (pkt_type == PKT_UMF) { |
1763
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
361 if (len >= 0x39) { |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
362 AVRational fps; |
1763
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
363 len -= 0x39; |
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
364 url_fskip(pb, 5); // preamble |
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
365 url_fskip(pb, 0x30); // payload description |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
366 fps = fps_umf2avr(get_le32(pb)); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
367 if (!main_timebase.num || !main_timebase.den) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
368 // this may not always be correct, but simply the best we can get |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
369 main_timebase.num = fps.den; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
370 main_timebase.den = fps.num; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
371 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
372 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
373 av_log(s, AV_LOG_INFO, "GXF: UMF packet too short\n"); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
374 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
375 av_log(s, AV_LOG_INFO, "GXF: UMF packet missing\n"); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
376 url_fskip(pb, len); |
1767
f1186797fbf5
Use av_set_pts_info and set some arbitrary timebase fallback
reimar
parents:
1765
diff
changeset
|
377 if (!main_timebase.num || !main_timebase.den) |
f1186797fbf5
Use av_set_pts_info and set some arbitrary timebase fallback
reimar
parents:
1765
diff
changeset
|
378 main_timebase = (AVRational){1, 50}; // set some arbitrary fallback |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
379 for (i = 0; i < s->nb_streams; i++) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
380 AVStream *st = s->streams[i]; |
1767
f1186797fbf5
Use av_set_pts_info and set some arbitrary timebase fallback
reimar
parents:
1765
diff
changeset
|
381 av_set_pts_info(st, 32, main_timebase.num, main_timebase.den); |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
382 } |
1145 | 383 return 0; |
384 } | |
385 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
386 #define READ_ONE() \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
387 { \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
388 if (!max_interval-- || url_feof(pb)) \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
389 goto out; \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
390 tmp = tmp << 8 | get_byte(pb); \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
391 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
392 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
393 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
394 * \brief resync the stream on the next media packet with specified properties |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
395 * \param max_interval how many bytes to search for matching packet at most |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
396 * \param track track id the media packet must belong to, -1 for any |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
397 * \param timestamp minimum timestamp (== field number) the packet must have, -1 for any |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
398 * \return timestamp of packet found |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
399 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
400 static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
401 uint32_t tmp; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
402 uint64_t last_pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
403 uint64_t last_found_pos = 0; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
404 int cur_track; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
405 int64_t cur_timestamp = AV_NOPTS_VALUE; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
406 int len; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
407 ByteIOContext *pb = &s->pb; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
408 pkt_type_t type; |
1221 | 409 tmp = get_be32(pb); |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
410 start: |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
411 while (tmp) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
412 READ_ONE(); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
413 READ_ONE(); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
414 if (tmp != 1) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
415 goto start; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
416 last_pos = url_ftell(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
417 url_fseek(pb, -5, SEEK_CUR); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
418 if (!parse_packet_header(pb, &type, &len) || type != PKT_MEDIA) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
419 url_fseek(pb, last_pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
420 goto start; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
421 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
422 get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
423 cur_track = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
424 cur_timestamp = get_be32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
425 last_found_pos = url_ftell(pb) - 16 - 6; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
426 if ((track >= 0 && track != cur_track) || (timestamp >= 0 && timestamp > cur_timestamp)) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
427 url_fseek(pb, last_pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
428 goto start; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
429 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
430 out: |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
431 if (last_found_pos) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
432 url_fseek(pb, last_found_pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
433 return cur_timestamp; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
434 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
435 |
1145 | 436 static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { |
437 ByteIOContext *pb = &s->pb; | |
438 pkt_type_t pkt_type; | |
439 int pkt_len; | |
440 while (!url_feof(pb)) { | |
441 int track_type, track_id, ret; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
442 int field_nr; |
1145 | 443 if (!parse_packet_header(pb, &pkt_type, &pkt_len)) { |
444 if (!url_feof(pb)) | |
445 av_log(s, AV_LOG_ERROR, "GXF: sync lost\n"); | |
446 return -1; | |
447 } | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
448 if (pkt_type == PKT_FLT) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
449 gxf_read_index(s, pkt_len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
450 continue; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
451 } |
1145 | 452 if (pkt_type != PKT_MEDIA) { |
453 url_fskip(pb, pkt_len); | |
454 continue; | |
455 } | |
456 if (pkt_len < 16) { | |
457 av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n"); | |
458 continue; | |
459 } | |
460 pkt_len -= 16; | |
461 track_type = get_byte(pb); | |
462 track_id = get_byte(pb); | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
463 field_nr = get_be32(pb); |
1145 | 464 get_be32(pb); // field information |
465 get_be32(pb); // "timeline" field number | |
466 get_byte(pb); // flags | |
467 get_byte(pb); // reserved | |
468 // NOTE: there is also data length information in the | |
1207 | 469 // field information, it might be better to take this into account |
1145 | 470 // as well. |
471 ret = av_get_packet(pb, pkt, pkt_len); | |
472 pkt->stream_index = get_sindex(s, track_id, track_type); | |
1243
088e77e1d06f
both timestamps are dts, (checked trailer.gxf, spec is unclear)
michael
parents:
1222
diff
changeset
|
473 pkt->dts = field_nr; |
1145 | 474 return ret; |
475 } | |
476 return AVERROR_IO; | |
477 } | |
478 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
479 static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
480 uint64_t pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
481 uint64_t maxlen = 100 * 1024 * 1024; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
482 AVStream *st = s->streams[0]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
483 int64_t start_time = s->streams[stream_index]->start_time; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
484 int64_t found; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
485 int idx; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
486 if (timestamp < start_time) timestamp = start_time; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
487 idx = av_index_search_timestamp(st, timestamp - start_time, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
488 AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
489 if (idx < 0) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
490 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
491 pos = st->index_entries[idx].pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
492 if (idx < st->nb_index_entries - 2) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
493 maxlen = st->index_entries[idx + 2].pos - pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
494 maxlen = FFMAX(maxlen, 200 * 1024); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
495 url_fseek(&s->pb, pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
496 found = gxf_resync_media(s, maxlen, -1, timestamp); |
1379 | 497 if (FFABS(found - timestamp) > 4) |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
498 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
499 return 0; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
500 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
501 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
502 static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
503 int64_t *pos, int64_t pos_limit) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
504 ByteIOContext *pb = &s->pb; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
505 int64_t res; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
506 url_fseek(pb, *pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
507 res = gxf_resync_media(s, pos_limit - *pos, -1, -1); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
508 *pos = url_ftell(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
509 return res; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
510 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
511 |
1169 | 512 AVInputFormat gxf_demuxer = { |
1145 | 513 "gxf", |
514 "GXF format", | |
515 0, | |
516 gxf_probe, | |
517 gxf_header, | |
518 gxf_packet, | |
519 NULL, | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
520 gxf_seek, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
521 gxf_read_timestamp, |
1145 | 522 }; |