00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avformat.h"
00022 #include "common.h"
00023 #include "gxf.h"
00024
00025 typedef struct {
00026 int64_t first_field;
00027 int64_t last_field;
00028 AVRational frames_per_second;
00029 int32_t fields_per_frame;
00030 } st_info_t;
00031
00039 static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) {
00040 if (get_be32(pb))
00041 return 0;
00042 if (get_byte(pb) != 1)
00043 return 0;
00044 *type = get_byte(pb);
00045 *length = get_be32(pb);
00046 if ((*length >> 24) || *length < 16)
00047 return 0;
00048 *length -= 16;
00049 if (get_be32(pb))
00050 return 0;
00051 if (get_byte(pb) != 0xe1)
00052 return 0;
00053 if (get_byte(pb) != 0xe2)
00054 return 0;
00055 return 1;
00056 }
00057
00061 static int gxf_probe(AVProbeData *p) {
00062 static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc};
00063 static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2};
00064 if (!memcmp(p->buf, startcode, sizeof(startcode)) &&
00065 !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))
00066 return AVPROBE_SCORE_MAX;
00067 return 0;
00068 }
00069
00076 static int get_sindex(AVFormatContext *s, int id, int format) {
00077 int i;
00078 AVStream *st = NULL;
00079 for (i = 0; i < s->nb_streams; i++) {
00080 if (s->streams[i]->id == id)
00081 return i;
00082 }
00083 st = av_new_stream(s, id);
00084 switch (format) {
00085 case 3:
00086 case 4:
00087 st->codec->codec_type = CODEC_TYPE_VIDEO;
00088 st->codec->codec_id = CODEC_ID_MJPEG;
00089 break;
00090 case 13:
00091 case 15:
00092 st->codec->codec_type = CODEC_TYPE_VIDEO;
00093 st->codec->codec_id = CODEC_ID_DVVIDEO;
00094 break;
00095 case 14:
00096 case 16:
00097 st->codec->codec_type = CODEC_TYPE_VIDEO;
00098 st->codec->codec_id = CODEC_ID_DVVIDEO;
00099 break;
00100 case 11:
00101 case 12:
00102 case 20:
00103 st->codec->codec_type = CODEC_TYPE_VIDEO;
00104 st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
00105 st->need_parsing = AVSTREAM_PARSE_HEADERS;
00106 break;
00107 case 22:
00108 case 23:
00109 st->codec->codec_type = CODEC_TYPE_VIDEO;
00110 st->codec->codec_id = CODEC_ID_MPEG1VIDEO;
00111 st->need_parsing = AVSTREAM_PARSE_HEADERS;
00112 break;
00113 case 9:
00114 st->codec->codec_type = CODEC_TYPE_AUDIO;
00115 st->codec->codec_id = CODEC_ID_PCM_S24LE;
00116 st->codec->channels = 1;
00117 st->codec->sample_rate = 48000;
00118 st->codec->bit_rate = 3 * 1 * 48000 * 8;
00119 st->codec->block_align = 3 * 1;
00120 st->codec->bits_per_sample = 24;
00121 break;
00122 case 10:
00123 st->codec->codec_type = CODEC_TYPE_AUDIO;
00124 st->codec->codec_id = CODEC_ID_PCM_S16LE;
00125 st->codec->channels = 1;
00126 st->codec->sample_rate = 48000;
00127 st->codec->bit_rate = 2 * 1 * 48000 * 8;
00128 st->codec->block_align = 2 * 1;
00129 st->codec->bits_per_sample = 16;
00130 break;
00131 case 17:
00132 st->codec->codec_type = CODEC_TYPE_AUDIO;
00133 st->codec->codec_id = CODEC_ID_AC3;
00134 st->codec->channels = 2;
00135 st->codec->sample_rate = 48000;
00136 break;
00137
00138 case 7:
00139 case 8:
00140 case 24:
00141 st->codec->codec_type = CODEC_TYPE_DATA;
00142 st->codec->codec_id = CODEC_ID_NONE;
00143 break;
00144 default:
00145 st->codec->codec_type = CODEC_TYPE_UNKNOWN;
00146 st->codec->codec_id = CODEC_ID_NONE;
00147 break;
00148 }
00149 return s->nb_streams - 1;
00150 }
00151
00157 static void gxf_material_tags(ByteIOContext *pb, int *len, st_info_t *si) {
00158 si->first_field = AV_NOPTS_VALUE;
00159 si->last_field = AV_NOPTS_VALUE;
00160 while (*len >= 2) {
00161 mat_tag_t tag = get_byte(pb);
00162 int tlen = get_byte(pb);
00163 *len -= 2;
00164 if (tlen > *len)
00165 return;
00166 *len -= tlen;
00167 if (tlen == 4) {
00168 uint32_t value = get_be32(pb);
00169 if (tag == MAT_FIRST_FIELD)
00170 si->first_field = value;
00171 else if (tag == MAT_LAST_FIELD)
00172 si->last_field = value;
00173 } else
00174 url_fskip(pb, tlen);
00175 }
00176 }
00177
00183 static AVRational fps_tag2avr(int32_t fps) {
00184 extern const AVRational ff_frame_rate_tab[];
00185 if (fps < 1 || fps > 9) fps = 9;
00186 return ff_frame_rate_tab[9 - fps];
00187 }
00188
00194 static AVRational fps_umf2avr(uint32_t flags) {
00195 static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1},
00196 {25, 1}, {30000, 1001}};
00197 int idx = av_log2((flags & 0x7c0) >> 6);
00198 return map[idx];
00199 }
00200
00206 static void gxf_track_tags(ByteIOContext *pb, int *len, st_info_t *si) {
00207 si->frames_per_second = (AVRational){0, 0};
00208 si->fields_per_frame = 0;
00209 while (*len >= 2) {
00210 track_tag_t tag = get_byte(pb);
00211 int tlen = get_byte(pb);
00212 *len -= 2;
00213 if (tlen > *len)
00214 return;
00215 *len -= tlen;
00216 if (tlen == 4) {
00217 uint32_t value = get_be32(pb);
00218 if (tag == TRACK_FPS)
00219 si->frames_per_second = fps_tag2avr(value);
00220 else if (tag == TRACK_FPF && (value == 1 || value == 2))
00221 si->fields_per_frame = value;
00222 } else
00223 url_fskip(pb, tlen);
00224 }
00225 }
00226
00230 static void gxf_read_index(AVFormatContext *s, int pkt_len) {
00231 ByteIOContext *pb = s->pb;
00232 AVStream *st = s->streams[0];
00233 uint32_t fields_per_map = get_le32(pb);
00234 uint32_t map_cnt = get_le32(pb);
00235 int i;
00236 pkt_len -= 8;
00237 if (map_cnt > 1000) {
00238 av_log(s, AV_LOG_ERROR, "GXF: too many index entries %u (%x)\n", map_cnt, map_cnt);
00239 map_cnt = 1000;
00240 }
00241 if (pkt_len < 4 * map_cnt) {
00242 av_log(s, AV_LOG_ERROR, "GXF: invalid index length\n");
00243 url_fskip(pb, pkt_len);
00244 return;
00245 }
00246 pkt_len -= 4 * map_cnt;
00247 av_add_index_entry(st, 0, 0, 0, 0, 0);
00248 for (i = 0; i < map_cnt; i++)
00249 av_add_index_entry(st, (uint64_t)get_le32(pb) * 1024,
00250 i * (uint64_t)fields_per_map + 1, 0, 0, 0);
00251 url_fskip(pb, pkt_len);
00252 }
00253
00254 static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
00255 ByteIOContext *pb = s->pb;
00256 pkt_type_t pkt_type;
00257 int map_len;
00258 int len;
00259 AVRational main_timebase = {0, 0};
00260 st_info_t si;
00261 int i;
00262 if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
00263 av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n");
00264 return 0;
00265 }
00266 map_len -= 2;
00267 if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) {
00268 av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n");
00269 return 0;
00270 }
00271 map_len -= 2;
00272 len = get_be16(pb);
00273 if (len > map_len) {
00274 av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n");
00275 return 0;
00276 }
00277 map_len -= len;
00278 gxf_material_tags(pb, &len, &si);
00279 url_fskip(pb, len);
00280 map_len -= 2;
00281 len = get_be16(pb);
00282 if (len > map_len) {
00283 av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n");
00284 return 0;
00285 }
00286 map_len -= len;
00287 while (len > 0) {
00288 int track_type, track_id, track_len;
00289 AVStream *st;
00290 int idx;
00291 len -= 4;
00292 track_type = get_byte(pb);
00293 track_id = get_byte(pb);
00294 track_len = get_be16(pb);
00295 len -= track_len;
00296 gxf_track_tags(pb, &track_len, &si);
00297 url_fskip(pb, track_len);
00298 if (!(track_type & 0x80)) {
00299 av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type);
00300 continue;
00301 }
00302 track_type &= 0x7f;
00303 if ((track_id & 0xc0) != 0xc0) {
00304 av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id);
00305 continue;
00306 }
00307 track_id &= 0x3f;
00308 idx = get_sindex(s, track_id, track_type);
00309 if (idx < 0) continue;
00310 st = s->streams[idx];
00311 if (!main_timebase.num || !main_timebase.den) {
00312 main_timebase.num = si.frames_per_second.den;
00313 main_timebase.den = si.frames_per_second.num * si.fields_per_frame;
00314 }
00315 st->start_time = si.first_field;
00316 if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE)
00317 st->duration = si.last_field - si.first_field;
00318 }
00319 if (len < 0)
00320 av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n");
00321 if (map_len)
00322 url_fskip(pb, map_len);
00323 if (!parse_packet_header(pb, &pkt_type, &len)) {
00324 av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n");
00325 return -1;
00326 }
00327 if (pkt_type == PKT_FLT) {
00328 gxf_read_index(s, len);
00329 if (!parse_packet_header(pb, &pkt_type, &len)) {
00330 av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n");
00331 return -1;
00332 }
00333 }
00334 if (pkt_type == PKT_UMF) {
00335 if (len >= 0x39) {
00336 AVRational fps;
00337 len -= 0x39;
00338 url_fskip(pb, 5);
00339 url_fskip(pb, 0x30);
00340 fps = fps_umf2avr(get_le32(pb));
00341 if (!main_timebase.num || !main_timebase.den) {
00342
00343 main_timebase.num = fps.den;
00344 main_timebase.den = fps.num;
00345 }
00346 } else
00347 av_log(s, AV_LOG_INFO, "GXF: UMF packet too short\n");
00348 } else
00349 av_log(s, AV_LOG_INFO, "GXF: UMF packet missing\n");
00350 url_fskip(pb, len);
00351 if (!main_timebase.num || !main_timebase.den)
00352 main_timebase = (AVRational){1, 50};
00353 for (i = 0; i < s->nb_streams; i++) {
00354 AVStream *st = s->streams[i];
00355 av_set_pts_info(st, 32, main_timebase.num, main_timebase.den);
00356 }
00357 return 0;
00358 }
00359
00360 #define READ_ONE() \
00361 { \
00362 if (!max_interval-- || url_feof(pb)) \
00363 goto out; \
00364 tmp = tmp << 8 | get_byte(pb); \
00365 }
00366
00374 static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) {
00375 uint32_t tmp;
00376 uint64_t last_pos;
00377 uint64_t last_found_pos = 0;
00378 int cur_track;
00379 int64_t cur_timestamp = AV_NOPTS_VALUE;
00380 int len;
00381 ByteIOContext *pb = s->pb;
00382 pkt_type_t type;
00383 tmp = get_be32(pb);
00384 start:
00385 while (tmp)
00386 READ_ONE();
00387 READ_ONE();
00388 if (tmp != 1)
00389 goto start;
00390 last_pos = url_ftell(pb);
00391 url_fseek(pb, -5, SEEK_CUR);
00392 if (!parse_packet_header(pb, &type, &len) || type != PKT_MEDIA) {
00393 url_fseek(pb, last_pos, SEEK_SET);
00394 goto start;
00395 }
00396 get_byte(pb);
00397 cur_track = get_byte(pb);
00398 cur_timestamp = get_be32(pb);
00399 last_found_pos = url_ftell(pb) - 16 - 6;
00400 if ((track >= 0 && track != cur_track) || (timestamp >= 0 && timestamp > cur_timestamp)) {
00401 url_fseek(pb, last_pos, SEEK_SET);
00402 goto start;
00403 }
00404 out:
00405 if (last_found_pos)
00406 url_fseek(pb, last_found_pos, SEEK_SET);
00407 return cur_timestamp;
00408 }
00409
00410 static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
00411 ByteIOContext *pb = s->pb;
00412 pkt_type_t pkt_type;
00413 int pkt_len;
00414 while (!url_feof(pb)) {
00415 int track_type, track_id, ret;
00416 int field_nr;
00417 if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
00418 if (!url_feof(pb))
00419 av_log(s, AV_LOG_ERROR, "GXF: sync lost\n");
00420 return -1;
00421 }
00422 if (pkt_type == PKT_FLT) {
00423 gxf_read_index(s, pkt_len);
00424 continue;
00425 }
00426 if (pkt_type != PKT_MEDIA) {
00427 url_fskip(pb, pkt_len);
00428 continue;
00429 }
00430 if (pkt_len < 16) {
00431 av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n");
00432 continue;
00433 }
00434 pkt_len -= 16;
00435 track_type = get_byte(pb);
00436 track_id = get_byte(pb);
00437 field_nr = get_be32(pb);
00438 get_be32(pb);
00439 get_be32(pb);
00440 get_byte(pb);
00441 get_byte(pb);
00442
00443
00444
00445 ret = av_get_packet(pb, pkt, pkt_len);
00446 pkt->stream_index = get_sindex(s, track_id, track_type);
00447 pkt->dts = field_nr;
00448 return ret;
00449 }
00450 return AVERROR(EIO);
00451 }
00452
00453 static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
00454 uint64_t pos;
00455 uint64_t maxlen = 100 * 1024 * 1024;
00456 AVStream *st = s->streams[0];
00457 int64_t start_time = s->streams[stream_index]->start_time;
00458 int64_t found;
00459 int idx;
00460 if (timestamp < start_time) timestamp = start_time;
00461 idx = av_index_search_timestamp(st, timestamp - start_time,
00462 AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
00463 if (idx < 0)
00464 return -1;
00465 pos = st->index_entries[idx].pos;
00466 if (idx < st->nb_index_entries - 2)
00467 maxlen = st->index_entries[idx + 2].pos - pos;
00468 maxlen = FFMAX(maxlen, 200 * 1024);
00469 url_fseek(s->pb, pos, SEEK_SET);
00470 found = gxf_resync_media(s, maxlen, -1, timestamp);
00471 if (FFABS(found - timestamp) > 4)
00472 return -1;
00473 return 0;
00474 }
00475
00476 static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index,
00477 int64_t *pos, int64_t pos_limit) {
00478 ByteIOContext *pb = s->pb;
00479 int64_t res;
00480 url_fseek(pb, *pos, SEEK_SET);
00481 res = gxf_resync_media(s, pos_limit - *pos, -1, -1);
00482 *pos = url_ftell(pb);
00483 return res;
00484 }
00485
00486 AVInputFormat gxf_demuxer = {
00487 "gxf",
00488 "GXF format",
00489 0,
00490 gxf_probe,
00491 gxf_header,
00492 gxf_packet,
00493 NULL,
00494 gxf_seek,
00495 gxf_read_timestamp,
00496 };