annotate gxf.c @ 1680:9240521ca4fd libavformat

this is wrong but it was that way before the AVCodecTag change, only reason why it didnt broke regressions was that the table wasnt used
author michael
date Sun, 21 Jan 2007 12:30:44 +0000
parents bc94f4215dd0
children e77907af9057
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 (p->buf_size < 16)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
91 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
92 if (!memcmp(p->buf, startcode, sizeof(startcode)) &&
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
93 !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
94 return AVPROBE_SCORE_MAX;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
95 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
96 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
97
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
98 /**
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
99 * \brief gets the stream index for the track with the specified id, creates new
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
100 * stream if not found
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
101 * \param stream id of stream to find / add
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
102 * \param format stream format identifier
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
103 */
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
104 static int get_sindex(AVFormatContext *s, int id, int format) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
105 int i;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
106 AVStream *st = NULL;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
107 for (i = 0; i < s->nb_streams; i++) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
108 if (s->streams[i]->id == id)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
109 return i;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
110 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
111 st = av_new_stream(s, id);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
112 switch (format) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
113 case 3:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
114 case 4:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
115 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
116 st->codec->codec_id = CODEC_ID_MJPEG;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
117 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
118 case 13:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
119 case 15:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
120 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
121 st->codec->codec_id = CODEC_ID_DVVIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
122 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
123 case 14:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
124 case 16:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
125 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
126 st->codec->codec_id = CODEC_ID_DVVIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
127 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
128 case 11:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
129 case 12:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
130 case 20:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
131 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
132 st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
1538
a7413070347a Set st->need_parsing = 2 for MPEG-content.
reimar
parents: 1379
diff changeset
133 st->need_parsing = 2; // get keyframe flag etc.
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
134 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
135 case 22:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
136 case 23:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
137 st->codec->codec_type = CODEC_TYPE_VIDEO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
138 st->codec->codec_id = CODEC_ID_MPEG1VIDEO;
1538
a7413070347a Set st->need_parsing = 2 for MPEG-content.
reimar
parents: 1379
diff changeset
139 st->need_parsing = 2; // get keyframe flag etc.
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
140 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
141 case 9:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
142 st->codec->codec_type = CODEC_TYPE_AUDIO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
143 st->codec->codec_id = CODEC_ID_PCM_S24LE;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
144 st->codec->channels = 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
145 st->codec->sample_rate = 48000;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
146 st->codec->bit_rate = 3 * 1 * 48000 * 8;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
147 st->codec->block_align = 3 * 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
148 st->codec->bits_per_sample = 24;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
149 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
150 case 10:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
151 st->codec->codec_type = CODEC_TYPE_AUDIO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
152 st->codec->codec_id = CODEC_ID_PCM_S16LE;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
153 st->codec->channels = 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
154 st->codec->sample_rate = 48000;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
155 st->codec->bit_rate = 2 * 1 * 48000 * 8;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
156 st->codec->block_align = 2 * 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
157 st->codec->bits_per_sample = 16;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
158 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
159 case 17:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
160 st->codec->codec_type = CODEC_TYPE_AUDIO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
161 st->codec->codec_id = CODEC_ID_AC3;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
162 st->codec->channels = 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
163 st->codec->sample_rate = 48000;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
164 break;
1539
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
165 // timecode tracks:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
166 case 7:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
167 case 8:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
168 case 24:
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
169 st->codec->codec_type = CODEC_TYPE_DATA;
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
170 st->codec->codec_id = CODEC_ID_NONE;
bc94f4215dd0 Set CODEC_TYPE_DATA for timecode tracks.
reimar
parents: 1538
diff changeset
171 break;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
172 default:
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
173 st->codec->codec_type = CODEC_TYPE_UNKNOWN;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
174 st->codec->codec_id = CODEC_ID_NONE;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
175 break;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
176 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
177 return s->nb_streams - 1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
178 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
179
1214
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 * \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
182 * \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
183 * \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
184 */
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
185 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
186 si->first_field = AV_NOPTS_VALUE;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
187 si->last_field = AV_NOPTS_VALUE;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
188 while (*len >= 2) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
189 mat_tag_t tag = get_byte(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
190 int tlen = get_byte(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
191 *len -= 2;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
192 if (tlen > *len)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
193 return;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
194 *len -= tlen;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
195 if (tlen == 4) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
196 uint32_t value = get_be32(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
197 if (tag == MAT_FIRST_FIELD)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
198 si->first_field = value;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
199 else if (tag == MAT_LAST_FIELD)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
200 si->last_field = value;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
201 } else
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
202 url_fskip(pb, tlen);
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
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
206 /**
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
207 * \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
208 * \param fps fps value from tag
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
209 * \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
210 */
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
211 static AVRational fps_tag2avr(int32_t fps) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
212 extern const AVRational ff_frame_rate_tab[];
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
213 if (fps < 1 || fps > 9) fps = 9;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
214 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
215 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
216
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
217 /**
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
218 * \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
219 * \param fps fps value from flags
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
220 * \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
221 */
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
222 static AVRational fps_umf2avr(uint32_t flags) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
223 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
224 {25, 1}, {30000, 1001}};
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
225 int idx = av_log2((flags & 0x7c0) >> 6);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
226 return map[idx];
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 * \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
231 * \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
232 * \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
233 */
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
234 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
235 si->frames_per_second = (AVRational){0, 0};
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
236 si->fields_per_frame = 0;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
237 while (*len >= 2) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
238 track_tag_t tag = get_byte(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
239 int tlen = get_byte(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
240 *len -= 2;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
241 if (tlen > *len)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
242 return;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
243 *len -= tlen;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
244 if (tlen == 4) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
245 uint32_t value = get_be32(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
246 if (tag == TRACK_FPS)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
247 si->frames_per_second = fps_tag2avr(value);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
248 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
249 si->fields_per_frame = value;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
250 } else
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
251 url_fskip(pb, tlen);
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
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 * \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
257 */
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
258 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
259 ByteIOContext *pb = &s->pb;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
260 AVStream *st = s->streams[0];
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
261 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
262 uint32_t map_cnt = get_le32(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
263 int i;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
264 pkt_len -= 8;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
265 if (map_cnt > 1000) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
266 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
267 map_cnt = 1000;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
268 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
269 if (pkt_len < 4 * map_cnt) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
270 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
271 url_fskip(pb, pkt_len);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
272 return;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
273 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
274 pkt_len -= 4 * map_cnt;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
275 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
276 for (i = 0; i < map_cnt; i++)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
277 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
278 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
279 url_fskip(pb, pkt_len);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
280 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
281
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
282 static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
283 ByteIOContext *pb = &s->pb;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
284 pkt_type_t pkt_type;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
285 int map_len;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
286 int len;
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
287 AVRational main_timebase = {0, 0};
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
288 st_info_t si;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
289 int i;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
290 if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
291 av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
292 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
293 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
294 map_len -= 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
295 if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
296 av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
297 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
298 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
299 map_len -= 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
300 len = get_be16(pb); // length of material data section
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
301 if (len > map_len) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
302 av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
303 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
304 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
305 map_len -= len;
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
306 gxf_material_tags(pb, &len, &si);
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
307 url_fskip(pb, len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
308 map_len -= 2;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
309 len = get_be16(pb); // length of track description
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
310 if (len > map_len) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
311 av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
312 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
313 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
314 map_len -= len;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
315 while (len > 0) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
316 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
317 AVStream *st;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
318 int idx;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
319 len -= 4;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
320 track_type = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
321 track_id = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
322 track_len = get_be16(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
323 len -= track_len;
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
324 gxf_track_tags(pb, &track_len, &si);
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
325 url_fskip(pb, track_len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
326 if (!(track_type & 0x80)) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
327 av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
328 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
329 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
330 track_type &= 0x7f;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
331 if ((track_id & 0xc0) != 0xc0) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
332 av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
333 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
334 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
335 track_id &= 0x3f;
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
336 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
337 if (idx < 0) continue;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
338 st = s->streams[idx];
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
339 if (!main_timebase.num || !main_timebase.den) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
340 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
341 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
342 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
343 st->start_time = si.first_field;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
344 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
345 st->duration = si.last_field - si.first_field;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
346 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
347 if (len < 0)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
348 av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
349 if (map_len)
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
350 url_fskip(pb, map_len);
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
351 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
352 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
353 return -1;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
354 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
355 if (pkt_type == PKT_FLT) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
356 gxf_read_index(s, len);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
357 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
358 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
359 return -1;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
360 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
361 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
362 if (pkt_type == PKT_UMF) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
363 if (len >= 9) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
364 AVRational fps;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
365 len -= 9;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
366 url_fskip(pb, 5);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
367 fps = fps_umf2avr(get_le32(pb));
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
368 if (!main_timebase.num || !main_timebase.den) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
369 // 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
370 main_timebase.num = fps.den;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
371 main_timebase.den = fps.num;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
372 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
373 } else
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
374 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
375 } else
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
376 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
377 url_fskip(pb, len);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
378 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
379 AVStream *st = s->streams[i];
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
380 if (main_timebase.num && main_timebase.den)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
381 st->time_base = main_timebase;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
382 else {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
383 st->start_time = st->duration = AV_NOPTS_VALUE;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
384 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
385 }
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
386 return 0;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
387 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
388
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
389 #define READ_ONE() \
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
390 { \
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
391 if (!max_interval-- || url_feof(pb)) \
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
392 goto out; \
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
393 tmp = tmp << 8 | get_byte(pb); \
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
394 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
395
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
396 /**
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
397 * \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
398 * \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
399 * \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
400 * \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
401 * \return timestamp of packet found
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
402 */
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
403 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
404 uint32_t tmp;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
405 uint64_t last_pos;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
406 uint64_t last_found_pos = 0;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
407 int cur_track;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
408 int64_t cur_timestamp = AV_NOPTS_VALUE;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
409 int len;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
410 ByteIOContext *pb = &s->pb;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
411 pkt_type_t type;
1221
ad456312dd5e Minor resync optimization
reimar
parents: 1219
diff changeset
412 tmp = get_be32(pb);
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
413 start:
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
414 while (tmp)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
415 READ_ONE();
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
416 READ_ONE();
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
417 if (tmp != 1)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
418 goto start;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
419 last_pos = url_ftell(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
420 url_fseek(pb, -5, SEEK_CUR);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
421 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
422 url_fseek(pb, last_pos, SEEK_SET);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
423 goto start;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
424 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
425 get_byte(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
426 cur_track = get_byte(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
427 cur_timestamp = get_be32(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
428 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
429 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
430 url_fseek(pb, last_pos, SEEK_SET);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
431 goto start;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
432 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
433 out:
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
434 if (last_found_pos)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
435 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
436 return cur_timestamp;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
437 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
438
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
439 static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
440 ByteIOContext *pb = &s->pb;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
441 pkt_type_t pkt_type;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
442 int pkt_len;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
443 while (!url_feof(pb)) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
444 int track_type, track_id, ret;
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
445 int field_nr;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
446 if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
447 if (!url_feof(pb))
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
448 av_log(s, AV_LOG_ERROR, "GXF: sync lost\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
449 return -1;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
450 }
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
451 if (pkt_type == PKT_FLT) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
452 gxf_read_index(s, pkt_len);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
453 continue;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
454 }
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
455 if (pkt_type != PKT_MEDIA) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
456 url_fskip(pb, pkt_len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
457 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
458 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
459 if (pkt_len < 16) {
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
460 av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n");
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
461 continue;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
462 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
463 pkt_len -= 16;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
464 track_type = get_byte(pb);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
465 track_id = get_byte(pb);
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
466 field_nr = get_be32(pb);
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
467 get_be32(pb); // field information
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
468 get_be32(pb); // "timeline" field number
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
469 get_byte(pb); // flags
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
470 get_byte(pb); // reserved
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
471 // NOTE: there is also data length information in the
1207
633aaf52d0c2 Fix typo in comment
reimar
parents: 1172
diff changeset
472 // field information, it might be better to take this into account
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
473 // as well.
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
474 ret = av_get_packet(pb, pkt, pkt_len);
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
475 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
476 pkt->dts = field_nr;
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
477 return ret;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
478 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
479 return AVERROR_IO;
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
480 }
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
481
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
482 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
483 uint64_t pos;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
484 uint64_t maxlen = 100 * 1024 * 1024;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
485 AVStream *st = s->streams[0];
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
486 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
487 int64_t found;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
488 int idx;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
489 if (timestamp < start_time) timestamp = start_time;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
490 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
491 AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
492 if (idx < 0)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
493 return -1;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
494 pos = st->index_entries[idx].pos;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
495 if (idx < st->nb_index_entries - 2)
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
496 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
497 maxlen = FFMAX(maxlen, 200 * 1024);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
498 url_fseek(&s->pb, pos, SEEK_SET);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
499 found = gxf_resync_media(s, maxlen, -1, timestamp);
1379
4146500158b5 Rename ABS macro to FFABS.
diego
parents: 1358
diff changeset
500 if (FFABS(found - timestamp) > 4)
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
501 return -1;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
502 return 0;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
503 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
504
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
505 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
506 int64_t *pos, int64_t pos_limit) {
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
507 ByteIOContext *pb = &s->pb;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
508 int64_t res;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
509 url_fseek(pb, *pos, SEEK_SET);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
510 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
511 *pos = url_ftell(pb);
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
512 return res;
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
513 }
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
514
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
515 AVInputFormat gxf_demuxer = {
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
516 "gxf",
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
517 "GXF format",
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
518 0,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
519 gxf_probe,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
520 gxf_header,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
521 gxf_packet,
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
522 NULL,
1214
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
523 gxf_seek,
4dbf4b5e675d Support for seeking, both with and without index and correct timestamps
reimar
parents: 1207
diff changeset
524 gxf_read_timestamp,
1145
95054d76b7e6 add GXF demuxer
reimar
parents:
diff changeset
525 };