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