Mercurial > libavformat.hg
annotate gxf.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | 7a0230981402 |
children | 1d3d17de20ba |
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 */ | |
3286 | 21 |
22 #include "libavutil/common.h" | |
1145 | 23 #include "avformat.h" |
2282
47f5906c30cc
replaces hardcoded values by the equivalent enum definitions
aurel
parents:
2274
diff
changeset
|
24 #include "gxf.h" |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
25 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
26 typedef struct { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
27 int64_t first_field; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
28 int64_t last_field; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
29 AVRational frames_per_second; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
30 int32_t fields_per_frame; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
31 } st_info_t; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
32 |
1145 | 33 /** |
34 * \brief parses a packet header, extracting type and length | |
35 * \param pb ByteIOContext to read header from | |
36 * \param type detected packet type is stored here | |
37 * \param length detected packet length, excluding header is stored here | |
38 * \return 0 if header not found or contains invalid data, 1 otherwise | |
39 */ | |
40 static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) { | |
41 if (get_be32(pb)) | |
42 return 0; | |
43 if (get_byte(pb) != 1) | |
44 return 0; | |
45 *type = get_byte(pb); | |
46 *length = get_be32(pb); | |
47 if ((*length >> 24) || *length < 16) | |
48 return 0; | |
49 *length -= 16; | |
50 if (get_be32(pb)) | |
51 return 0; | |
52 if (get_byte(pb) != 0xe1) | |
53 return 0; | |
54 if (get_byte(pb) != 0xe2) | |
55 return 0; | |
56 return 1; | |
57 } | |
58 | |
59 /** | |
60 * \brief check if file starts with a PKT_MAP header | |
61 */ | |
62 static int gxf_probe(AVProbeData *p) { | |
63 static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet | |
64 static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2}; | |
65 if (!memcmp(p->buf, startcode, sizeof(startcode)) && | |
66 !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode))) | |
67 return AVPROBE_SCORE_MAX; | |
68 return 0; | |
69 } | |
70 | |
71 /** | |
72 * \brief gets the stream index for the track with the specified id, creates new | |
73 * stream if not found | |
74 * \param stream id of stream to find / add | |
75 * \param format stream format identifier | |
76 */ | |
77 static int get_sindex(AVFormatContext *s, int id, int format) { | |
78 int i; | |
79 AVStream *st = NULL; | |
80 for (i = 0; i < s->nb_streams; i++) { | |
81 if (s->streams[i]->id == id) | |
82 return i; | |
83 } | |
84 st = av_new_stream(s, id); | |
3400 | 85 if (!st) |
86 return AVERROR(ENOMEM); | |
1145 | 87 switch (format) { |
88 case 3: | |
89 case 4: | |
90 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
91 st->codec->codec_id = CODEC_ID_MJPEG; | |
92 break; | |
93 case 13: | |
94 case 15: | |
95 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
96 st->codec->codec_id = CODEC_ID_DVVIDEO; | |
97 break; | |
98 case 14: | |
99 case 16: | |
100 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
101 st->codec->codec_id = CODEC_ID_DVVIDEO; | |
102 break; | |
103 case 11: | |
104 case 12: | |
105 case 20: | |
106 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
107 st->codec->codec_id = CODEC_ID_MPEG2VIDEO; | |
2023 | 108 st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. |
1145 | 109 break; |
110 case 22: | |
111 case 23: | |
112 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
113 st->codec->codec_id = CODEC_ID_MPEG1VIDEO; | |
2023 | 114 st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. |
1145 | 115 break; |
116 case 9: | |
117 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
118 st->codec->codec_id = CODEC_ID_PCM_S24LE; | |
119 st->codec->channels = 1; | |
120 st->codec->sample_rate = 48000; | |
121 st->codec->bit_rate = 3 * 1 * 48000 * 8; | |
122 st->codec->block_align = 3 * 1; | |
123 st->codec->bits_per_sample = 24; | |
124 break; | |
125 case 10: | |
126 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
127 st->codec->codec_id = CODEC_ID_PCM_S16LE; | |
128 st->codec->channels = 1; | |
129 st->codec->sample_rate = 48000; | |
130 st->codec->bit_rate = 2 * 1 * 48000 * 8; | |
131 st->codec->block_align = 2 * 1; | |
132 st->codec->bits_per_sample = 16; | |
133 break; | |
134 case 17: | |
135 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
136 st->codec->codec_id = CODEC_ID_AC3; | |
137 st->codec->channels = 2; | |
138 st->codec->sample_rate = 48000; | |
139 break; | |
1539 | 140 // timecode tracks: |
141 case 7: | |
142 case 8: | |
143 case 24: | |
144 st->codec->codec_type = CODEC_TYPE_DATA; | |
145 st->codec->codec_id = CODEC_ID_NONE; | |
146 break; | |
1145 | 147 default: |
148 st->codec->codec_type = CODEC_TYPE_UNKNOWN; | |
149 st->codec->codec_id = CODEC_ID_NONE; | |
150 break; | |
151 } | |
152 return s->nb_streams - 1; | |
153 } | |
154 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
155 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
156 * \brief filters out interesting tags from material information. |
2560 | 157 * \param len length of tag section, will be adjusted to contain remaining bytes |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
158 * \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
|
159 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
160 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
|
161 si->first_field = AV_NOPTS_VALUE; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
162 si->last_field = AV_NOPTS_VALUE; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
163 while (*len >= 2) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
164 mat_tag_t tag = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
165 int tlen = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
166 *len -= 2; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
167 if (tlen > *len) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
168 return; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
169 *len -= tlen; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
170 if (tlen == 4) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
171 uint32_t value = get_be32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
172 if (tag == MAT_FIRST_FIELD) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
173 si->first_field = value; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
174 else if (tag == MAT_LAST_FIELD) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
175 si->last_field = value; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
176 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
177 url_fskip(pb, tlen); |
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 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
180 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
181 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
182 * \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
|
183 * \param fps fps value from tag |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
184 * \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
|
185 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
186 static AVRational fps_tag2avr(int32_t fps) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
187 extern const AVRational ff_frame_rate_tab[]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
188 if (fps < 1 || fps > 9) fps = 9; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
189 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
|
190 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
191 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
192 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
193 * \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
|
194 * \param fps fps value from flags |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
195 * \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
|
196 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
197 static AVRational fps_umf2avr(uint32_t flags) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
198 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
|
199 {25, 1}, {30000, 1001}}; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
200 int idx = av_log2((flags & 0x7c0) >> 6); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
201 return map[idx]; |
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 filters out interesting tags from track information. |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
206 * \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
|
207 * \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
|
208 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
209 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
|
210 si->frames_per_second = (AVRational){0, 0}; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
211 si->fields_per_frame = 0; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
212 while (*len >= 2) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
213 track_tag_t tag = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
214 int tlen = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
215 *len -= 2; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
216 if (tlen > *len) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
217 return; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
218 *len -= tlen; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
219 if (tlen == 4) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
220 uint32_t value = get_be32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
221 if (tag == TRACK_FPS) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
222 si->frames_per_second = fps_tag2avr(value); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
223 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
|
224 si->fields_per_frame = value; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
225 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
226 url_fskip(pb, tlen); |
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 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
229 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
230 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
231 * \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
|
232 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
233 static void gxf_read_index(AVFormatContext *s, int pkt_len) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2560
diff
changeset
|
234 ByteIOContext *pb = s->pb; |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
235 AVStream *st = s->streams[0]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
236 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
|
237 uint32_t map_cnt = get_le32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
238 int i; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
239 pkt_len -= 8; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
240 if (map_cnt > 1000) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
241 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
|
242 map_cnt = 1000; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
243 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
244 if (pkt_len < 4 * map_cnt) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
245 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
|
246 url_fskip(pb, pkt_len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
247 return; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
248 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
249 pkt_len -= 4 * map_cnt; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
250 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
|
251 for (i = 0; i < map_cnt; i++) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
252 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
|
253 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
|
254 url_fskip(pb, pkt_len); |
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 |
1145 | 257 static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2560
diff
changeset
|
258 ByteIOContext *pb = s->pb; |
1145 | 259 pkt_type_t pkt_type; |
260 int map_len; | |
261 int len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
262 AVRational main_timebase = {0, 0}; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
263 st_info_t si; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
264 int i; |
1145 | 265 if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) { |
266 av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n"); | |
267 return 0; | |
268 } | |
269 map_len -= 2; | |
270 if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) { | |
271 av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n"); | |
272 return 0; | |
273 } | |
274 map_len -= 2; | |
275 len = get_be16(pb); // length of material data section | |
276 if (len > map_len) { | |
277 av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n"); | |
278 return 0; | |
279 } | |
280 map_len -= len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
281 gxf_material_tags(pb, &len, &si); |
1145 | 282 url_fskip(pb, len); |
283 map_len -= 2; | |
284 len = get_be16(pb); // length of track description | |
285 if (len > map_len) { | |
286 av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n"); | |
287 return 0; | |
288 } | |
289 map_len -= len; | |
290 while (len > 0) { | |
291 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
|
292 AVStream *st; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
293 int idx; |
1145 | 294 len -= 4; |
295 track_type = get_byte(pb); | |
296 track_id = get_byte(pb); | |
297 track_len = get_be16(pb); | |
298 len -= track_len; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
299 gxf_track_tags(pb, &track_len, &si); |
1145 | 300 url_fskip(pb, track_len); |
301 if (!(track_type & 0x80)) { | |
302 av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type); | |
303 continue; | |
304 } | |
305 track_type &= 0x7f; | |
306 if ((track_id & 0xc0) != 0xc0) { | |
307 av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id); | |
308 continue; | |
309 } | |
310 track_id &= 0x3f; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
311 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
|
312 if (idx < 0) continue; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
313 st = s->streams[idx]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
314 if (!main_timebase.num || !main_timebase.den) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
315 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
|
316 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
|
317 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
318 st->start_time = si.first_field; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
319 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
|
320 st->duration = si.last_field - si.first_field; |
1145 | 321 } |
322 if (len < 0) | |
323 av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n"); | |
324 if (map_len) | |
325 url_fskip(pb, map_len); | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
326 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
|
327 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
|
328 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
329 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
330 if (pkt_type == PKT_FLT) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
331 gxf_read_index(s, len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
332 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
|
333 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
|
334 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
335 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
336 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
337 if (pkt_type == PKT_UMF) { |
1763
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
338 if (len >= 0x39) { |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
339 AVRational fps; |
1763
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
340 len -= 0x39; |
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
341 url_fskip(pb, 5); // preamble |
e77907af9057
10l, forgot to skip payload description in UMF packet parsing
reimar
parents:
1539
diff
changeset
|
342 url_fskip(pb, 0x30); // payload description |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
343 fps = fps_umf2avr(get_le32(pb)); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
344 if (!main_timebase.num || !main_timebase.den) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
345 // 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
|
346 main_timebase.num = fps.den; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
347 main_timebase.den = fps.num; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
348 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
349 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
350 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
|
351 } else |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
352 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
|
353 url_fskip(pb, len); |
1767
f1186797fbf5
Use av_set_pts_info and set some arbitrary timebase fallback
reimar
parents:
1765
diff
changeset
|
354 if (!main_timebase.num || !main_timebase.den) |
f1186797fbf5
Use av_set_pts_info and set some arbitrary timebase fallback
reimar
parents:
1765
diff
changeset
|
355 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
|
356 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
|
357 AVStream *st = s->streams[i]; |
1767
f1186797fbf5
Use av_set_pts_info and set some arbitrary timebase fallback
reimar
parents:
1765
diff
changeset
|
358 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
|
359 } |
1145 | 360 return 0; |
361 } | |
362 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
363 #define READ_ONE() \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
364 { \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
365 if (!max_interval-- || url_feof(pb)) \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
366 goto out; \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
367 tmp = tmp << 8 | get_byte(pb); \ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
368 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
369 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
370 /** |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
371 * \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
|
372 * \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
|
373 * \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
|
374 * \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
|
375 * \return timestamp of packet found |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
376 */ |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
377 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
|
378 uint32_t tmp; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
379 uint64_t last_pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
380 uint64_t last_found_pos = 0; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
381 int cur_track; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
382 int64_t cur_timestamp = AV_NOPTS_VALUE; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
383 int len; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2560
diff
changeset
|
384 ByteIOContext *pb = s->pb; |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
385 pkt_type_t type; |
1221 | 386 tmp = get_be32(pb); |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
387 start: |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
388 while (tmp) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
389 READ_ONE(); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
390 READ_ONE(); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
391 if (tmp != 1) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
392 goto start; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
393 last_pos = url_ftell(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
394 url_fseek(pb, -5, SEEK_CUR); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
395 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
|
396 url_fseek(pb, last_pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
397 goto start; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
398 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
399 get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
400 cur_track = get_byte(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
401 cur_timestamp = get_be32(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
402 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
|
403 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
|
404 url_fseek(pb, last_pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
405 goto start; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
406 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
407 out: |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
408 if (last_found_pos) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
409 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
|
410 return cur_timestamp; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
411 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
412 |
1145 | 413 static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2560
diff
changeset
|
414 ByteIOContext *pb = s->pb; |
1145 | 415 pkt_type_t pkt_type; |
416 int pkt_len; | |
417 while (!url_feof(pb)) { | |
418 int track_type, track_id, ret; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
419 int field_nr; |
3400 | 420 int stream_index; |
1145 | 421 if (!parse_packet_header(pb, &pkt_type, &pkt_len)) { |
422 if (!url_feof(pb)) | |
423 av_log(s, AV_LOG_ERROR, "GXF: sync lost\n"); | |
424 return -1; | |
425 } | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
426 if (pkt_type == PKT_FLT) { |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
427 gxf_read_index(s, pkt_len); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
428 continue; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
429 } |
1145 | 430 if (pkt_type != PKT_MEDIA) { |
431 url_fskip(pb, pkt_len); | |
432 continue; | |
433 } | |
434 if (pkt_len < 16) { | |
435 av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n"); | |
436 continue; | |
437 } | |
438 pkt_len -= 16; | |
439 track_type = get_byte(pb); | |
440 track_id = get_byte(pb); | |
3400 | 441 stream_index = get_sindex(s, track_id, track_type); |
442 if (stream_index < 0) | |
443 return stream_index; | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
444 field_nr = get_be32(pb); |
1145 | 445 get_be32(pb); // field information |
446 get_be32(pb); // "timeline" field number | |
447 get_byte(pb); // flags | |
448 get_byte(pb); // reserved | |
449 // NOTE: there is also data length information in the | |
1207 | 450 // field information, it might be better to take this into account |
1145 | 451 // as well. |
452 ret = av_get_packet(pb, pkt, pkt_len); | |
3400 | 453 pkt->stream_index = stream_index; |
1243
088e77e1d06f
both timestamps are dts, (checked trailer.gxf, spec is unclear)
michael
parents:
1222
diff
changeset
|
454 pkt->dts = field_nr; |
1145 | 455 return ret; |
456 } | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2023
diff
changeset
|
457 return AVERROR(EIO); |
1145 | 458 } |
459 | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
460 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
|
461 uint64_t pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
462 uint64_t maxlen = 100 * 1024 * 1024; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
463 AVStream *st = s->streams[0]; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
464 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
|
465 int64_t found; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
466 int idx; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
467 if (timestamp < start_time) timestamp = start_time; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
468 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
|
469 AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
470 if (idx < 0) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
471 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
472 pos = st->index_entries[idx].pos; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
473 if (idx < st->nb_index_entries - 2) |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
474 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
|
475 maxlen = FFMAX(maxlen, 200 * 1024); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2560
diff
changeset
|
476 url_fseek(s->pb, pos, SEEK_SET); |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
477 found = gxf_resync_media(s, maxlen, -1, timestamp); |
1379 | 478 if (FFABS(found - timestamp) > 4) |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
479 return -1; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
480 return 0; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
481 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
482 |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
483 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
|
484 int64_t *pos, int64_t pos_limit) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2560
diff
changeset
|
485 ByteIOContext *pb = s->pb; |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
486 int64_t res; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
487 url_fseek(pb, *pos, SEEK_SET); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
488 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
|
489 *pos = url_ftell(pb); |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
490 return res; |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
491 } |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
492 |
1169 | 493 AVInputFormat gxf_demuxer = { |
1145 | 494 "gxf", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3400
diff
changeset
|
495 NULL_IF_CONFIG_SMALL("GXF format"), |
1145 | 496 0, |
497 gxf_probe, | |
498 gxf_header, | |
499 gxf_packet, | |
500 NULL, | |
1214
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
501 gxf_seek, |
4dbf4b5e675d
Support for seeking, both with and without index and correct timestamps
reimar
parents:
1207
diff
changeset
|
502 gxf_read_timestamp, |
1145 | 503 }; |