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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
1 /*
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
2 * GXF demuxer.
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
3 * Copyright (c) 2006 Reimar Doeffinger.
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
15 * Lesser General Public License for more details.
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
16 *
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
20 */
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
23
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
24 typedef enum {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
25 PKT_MAP = 0xbc,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
26 PKT_MEDIA = 0xbf,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
27 PKT_EOS = 0xfb,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
28 PKT_FLT = 0xfc,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
29 PKT_UMF = 0xfd
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
30 } pkt_type_t;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
58 /**
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
59 * \brief parses a packet header, extracting type and length
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
60 * \param pb ByteIOContext to read header from
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
61 * \param type detected packet type is stored here
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
62 * \param length detected packet length, excluding header is stored here
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
63 * \return 0 if header not found or contains invalid data, 1 otherwise
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
64 */
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
65 static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
66 if (get_be32(pb))
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
67 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
68 if (get_byte(pb) != 1)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
69 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
70 *type = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
71 *length = get_be32(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
72 if ((*length >> 24) || *length < 16)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
73 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
74 *length -= 16;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
75 if (get_be32(pb))
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
76 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
77 if (get_byte(pb) != 0xe1)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
78 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
79 if (get_byte(pb) != 0xe2)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
80 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
81 return 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
82 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
83
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
84 /**
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
85 * \brief check if file starts with a PKT_MAP header
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
86 */
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
87 static int gxf_probe(AVProbeData *p) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
88 static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
89 static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2};
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
90 if (!memcmp(p->buf, startcode, sizeof(startcode)) &&
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
91 !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
92 return AVPROBE_SCORE_MAX;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
93 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
94 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
95
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
96 /**
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
97 * \brief gets the stream index for the track with the specified id, creates new
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
98 * stream if not found
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
99 * \param stream id of stream to find / add
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
100 * \param format stream format identifier
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
101 */
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
102 static int get_sindex(AVFormatContext *s, int id, int format) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
103 int i;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
104 AVStream *st = NULL;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
105 for (i = 0; i < s->nb_streams; i++) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
106 if (s->streams[i]->id == id)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
107 return i;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
108 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
109 st = av_new_stream(s, id);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
110 switch (format) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
111 case 3:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
112 case 4:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
113 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
114 st->codec->codec_id = CODEC_ID_MJPEG;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
115 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
116 case 13:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
117 case 15:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
118 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
119 st->codec->codec_id = CODEC_ID_DVVIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
120 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
121 case 14:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
122 case 16:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
123 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
124 st->codec->codec_id = CODEC_ID_DVVIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
125 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
126 case 11:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
127 case 12:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
128 case 20:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
129 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
130 st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
2023
a3e79d6e4e3c add an enum for need_parsing
aurel
parents: 2001
diff changeset
131 st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
132 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
133 case 22:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
134 case 23:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
135 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
136 st->codec->codec_id = CODEC_ID_MPEG1VIDEO;
2023
a3e79d6e4e3c add an enum for need_parsing
aurel
parents: 2001
diff changeset
137 st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
138 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
139 case 9:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
140 st->codec->codec_type = CODEC_TYPE_AUDIO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
141 st->codec->codec_id = CODEC_ID_PCM_S24LE;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
142 st->codec->channels = 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
143 st->codec->sample_rate = 48000;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
144 st->codec->bit_rate = 3 * 1 * 48000 * 8;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
145 st->codec->block_align = 3 * 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
146 st->codec->bits_per_sample = 24;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
147 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
148 case 10:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
149 st->codec->codec_type = CODEC_TYPE_AUDIO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
150 st->codec->codec_id = CODEC_ID_PCM_S16LE;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
151 st->codec->channels = 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
152 st->codec->sample_rate = 48000;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
153 st->codec->bit_rate = 2 * 1 * 48000 * 8;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
154 st->codec->block_align = 2 * 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
155 st->codec->bits_per_sample = 16;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
156 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
157 case 17:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
158 st->codec->codec_type = CODEC_TYPE_AUDIO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
159 st->codec->codec_id = CODEC_ID_AC3;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
160 st->codec->channels = 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
161 st->codec->sample_rate = 48000;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
162 break;
1539
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
163 // timecode tracks:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
164 case 7:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
165 case 8:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
166 case 24:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
167 st->codec->codec_type = CODEC_TYPE_DATA;
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
168 st->codec->codec_id = CODEC_ID_NONE;
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
169 break;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
170 default:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
171 st->codec->codec_type = CODEC_TYPE_UNKNOWN;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
172 st->codec->codec_id = CODEC_ID_NONE;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
173 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
174 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
175 return s->nb_streams - 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
176 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
280 static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
281 ByteIOContext *pb = &s->pb;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
282 pkt_type_t pkt_type;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
283 int map_len;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
288 if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
289 av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
290 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
291 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
292 map_len -= 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
293 if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
294 av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
295 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
296 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
297 map_len -= 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
298 len = get_be16(pb); // length of material data section
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
299 if (len > map_len) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
300 av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
301 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
302 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
305 url_fskip(pb, len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
306 map_len -= 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
307 len = get_be16(pb); // length of track description
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
308 if (len > map_len) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
309 av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
310 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
311 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
312 map_len -= len;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
313 while (len > 0) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
317 len -= 4;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
318 track_type = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
319 track_id = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
320 track_len = get_be16(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
323 url_fskip(pb, track_len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
324 if (!(track_type & 0x80)) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
325 av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
326 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
327 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
328 track_type &= 0x7f;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
329 if ((track_id & 0xc0) != 0xc0) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
330 av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
331 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
332 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
344 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
345 if (len < 0)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
346 av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
347 if (map_len)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
383 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
384 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
ad456312dd5e Minor resync optimization
reimar
parents: 1219
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
436 static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
437 ByteIOContext *pb = &s->pb;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
438 pkt_type_t pkt_type;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
439 int pkt_len;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
440 while (!url_feof(pb)) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
443 if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
444 if (!url_feof(pb))
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
445 av_log(s, AV_LOG_ERROR, "GXF: sync lost\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
446 return -1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
452 if (pkt_type != PKT_MEDIA) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
453 url_fskip(pb, pkt_len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
454 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
455 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
456 if (pkt_len < 16) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
457 av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
458 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
459 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
460 pkt_len -= 16;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
461 track_type = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
464 get_be32(pb); // field information
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
465 get_be32(pb); // "timeline" field number
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
466 get_byte(pb); // flags
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
467 get_byte(pb); // reserved
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
468 // NOTE: there is also data length information in the
1207
633aaf52d0c2 Fix typo in comment
reimar
parents: 1172
diff changeset
469 // field information, it might be better to take this into account
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
470 // as well.
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
471 ret = av_get_packet(pb, pkt, pkt_len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
474 return ret;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
475 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
476 return AVERROR_IO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
477 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
4146500158b5 Rename ABS macro to FFABS.
diego
parents: 1358
diff changeset
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
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
512 AVInputFormat gxf_demuxer = {
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
513 "gxf",
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
514 "GXF format",
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
515 0,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
516 gxf_probe,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
517 gxf_header,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
518 gxf_packet,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
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
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
522 };