History

mxfdec: Index table driven demuxing and seeking

This adds OPAtom support and proper seeking. D-10 and non-seekable OP1a streams still use the old demuxing/seeking code.

Tomas Härdin committed 14 years ago

Commit ddcf3e01 parent 5e67e3e2 files · +115 −26Browse files

Unified · Split

2 files
  1. libavformat/mxfdec.c +97 −3
  2. tests/ref/seek/lavf_mxf +18 −23
libavformat/mxfdec.c+97−3
@@ -197,6 +197,9 @@ typedef struct { · 196 unmodified lines
197 int parsing_backward;197 int parsing_backward;
198 int64_t last_forward_tell;198 int64_t last_forward_tell;
199 int last_forward_partition;199 int last_forward_partition;
200 int current_edit_unit;
201 int current_stream;
202 int d10;
200} MXFContext;203} MXFContext;
201 204
202enum MXFWrappingScheme {205enum MXFWrappingScheme {
@@ -372,7 +375,7 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv · 169 unmodified lines
372 return 0;375 return 0;
373}376}
374 377
375static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)378static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
376{379{
377 KLVPacket klv;380 KLVPacket klv;
378 381
@@ -418,6 +421,65 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) · 39 unmodified lines
418 return AVERROR_EOF;421 return AVERROR_EOF;
419}422}
420 423
424static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
425{
426 MXFContext *mxf = s->priv_data;
427 AVIndexEntry *e;
428 int ret;
429 int64_t ret64;
430 KLVPacket klv;
431 AVStream *st;
432
433 /* TODO: better logic for this?
434 * only files that lack all index segments prior to the essence need this */
435 if (!s->pb->seekable && mxf->op != OPAtom || mxf->d10)
436 return mxf_read_packet_old(s, pkt);
437
438 if (mxf->current_stream >= s->nb_streams) {
439 mxf->current_edit_unit++;
440 mxf->current_stream = 0;
441 }
442
443 st = s->streams[mxf->current_stream];
444
445 if (mxf->current_edit_unit >= st->nb_index_entries)
446 return AVERROR_EOF;
447
448 e = &st->index_entries[mxf->current_edit_unit];
449
450 if ((ret64 = avio_seek(s->pb, e->pos, SEEK_SET)) < 0)
451 return ret64;
452
453 if (mxf->op == OPAtom) {
454 /* OPAtom - no KL, just essence */
455 if ((ret = av_get_packet(s->pb, pkt, e->size)) != e->size)
456 return ret < 0 ? ret : AVERROR_EOF;
457 } else {
458 /* read KL, read L bytes of essence */
459 if ((ret = klv_read_packet(&klv, s->pb)) < 0)
460 return ret;
461
462 /* untested, but looks OK */
463 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
464 int res = mxf_decrypt_triplet(s, pkt, &klv);
465 if (res < 0) {
466 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
467 return -1;
468 }
469 return 0;
470 }
471
472 if ((ret = av_get_packet(s->pb, pkt, klv.length)) != klv.length)
473 return ret < 0 ? ret : AVERROR_EOF;
474
475 pkt->pos = e->pos;
476 }
477
478 pkt->stream_index = mxf->current_stream++;
479
480 return 0;
481}
482
421static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)483static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
422{484{
423 MXFContext *mxf = arg;485 MXFContext *mxf = arg;
@@ -925,6 +987,8 @@ static const MXFCodecUL mxf_essence_container_uls[] = { · 501 unmodified lines
925 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },987 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },
926};988};
927 989
990static UID mxf_d10_ul = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 };
991
928static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)992static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
929{993{
930 int i, j, nb_segments = 0;994 int i, j, nb_segments = 0;
@@ -1252,6 +1316,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) · 321 unmodified lines
1252 }1316 }
1253 }1317 }
1254 }1318 }
1319
1320 /* HACK: revert to the old demuxing/seeking scode for D-10 for now */
1321 if (mxf_match_uid(essence_container_ul, mxf_d10_ul, 14))
1322 mxf->d10 = 1;
1323
1255 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */1324 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
1256 codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);1325 codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
1257 st->codec->codec_id = codec_ul->id;1326 st->codec->codec_id = codec_ul->id;
@@ -1291,8 +1360,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) · 33 unmodified lines
1291 }1360 }
1292 }1361 }
1293 if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {1362 if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
1294 av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n");1363 /* TODO: decode timestamps */
1295 st->need_parsing = AVSTREAM_PARSE_FULL;1364 st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
1296 }1365 }
1297 1366
1298 if ((ret = mxf_parse_index(mxf, material_track->track_id, st)))1367 if ((ret = mxf_parse_index(mxf, material_track->track_id, st)))
@@ -1659,7 +1728,11 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti · 360 unmodified lines
1659{1728{
1660 AVStream *st = s->streams[stream_index];1729 AVStream *st = s->streams[stream_index];
1661 int64_t seconds;1730 int64_t seconds;
1731 MXFContext* mxf = s->priv_data;
1732 int64_t seekpos;
1733 int index;
1662 1734
1735 if (mxf->d10) {
1663 if (!s->bit_rate)1736 if (!s->bit_rate)
1664 return -1;1737 return -1;
1665 if (sample_time < 0)1738 if (sample_time < 0)
@@ -1668,6 +1741,27 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti · 2 unmodified lines
1668 if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0)1741 if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0)
1669 return -1;1742 return -1;
1670 ff_update_cur_dts(s, st, sample_time);1743 ff_update_cur_dts(s, st, sample_time);
1744 } else {
1745 if (st->nb_index_entries <= 0)
1746 return -1;
1747
1748 index = av_index_search_timestamp(st, sample_time, flags);
1749
1750 av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, sample_time, index);
1751
1752 if (index < 0) {
1753 if (sample_time < st->index_entries[0].timestamp)
1754 index = 0;
1755 else
1756 return -1;
1757 }
1758
1759 seekpos = st->index_entries[index].pos;
1760 av_update_cur_dts(s, st, st->index_entries[index].timestamp);
1761 mxf->current_edit_unit = st->index_entries[index].timestamp;
1762 mxf->current_stream = 0;
1763 avio_seek(s->pb, seekpos, SEEK_SET);
1764 }
1671 return 0;1765 return 0;
1672}1766}
1673 1767
tests/ref/seek/lavf_mxf+18−23
@@ -2,52 +2,47 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 · 1 unmodified line
2ret: 0 st:-1 flags:0 ts:-1.0000002ret: 0 st:-1 flags:0 ts:-1.000000
3ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 248013ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
4ret: 0 st:-1 flags:1 ts: 1.8941674ret: 0 st:-1 flags:1 ts: 1.894167
5ret:-15ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
6ret: 0 st: 0 flags:0 ts: 0.8000006ret: 0 st: 0 flags:0 ts: 0.800000
7ret:-17ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
8ret: 0 st: 0 flags:1 ts:-0.3200008ret: 0 st: 0 flags:1 ts:-0.320000
9ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 248019ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
10ret: 0 st: 1 flags:0 ts: 2.56000010ret:-1 st: 1 flags:0 ts: 2.560000
11ret:-1
12ret: 0 st: 1 flags:1 ts: 1.48000011ret: 0 st: 1 flags:1 ts: 1.480000
13ret:-112ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
14ret: 0 st:-1 flags:0 ts: 0.36500213ret: 0 st:-1 flags:0 ts: 0.365002
15ret: 0 st: 0 flags:1 dts: 0.360000 pts: NOPTS pos: 6144 size: 2480114ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 211968 size: 24787
16ret: 0 st:-1 flags:1 ts:-0.74083115ret: 0 st:-1 flags:1 ts:-0.740831
17ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 2480116ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
18ret: 0 st: 0 flags:0 ts: 2.16000017ret:-1 st: 0 flags:0 ts: 2.160000
19ret:-1
20ret: 0 st: 0 flags:1 ts: 1.04000018ret: 0 st: 0 flags:1 ts: 1.040000
21ret:-119ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
22ret: 0 st: 1 flags:0 ts:-0.04000020ret: 0 st: 1 flags:0 ts:-0.040000
23ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 2480121ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
24ret: 0 st: 1 flags:1 ts: 2.84000022ret: 0 st: 1 flags:1 ts: 2.840000
25ret:-123ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
26ret: 0 st:-1 flags:0 ts: 1.73000424ret:-1 st:-1 flags:0 ts: 1.730004
27ret:-1
28ret: 0 st:-1 flags:1 ts: 0.62417125ret: 0 st:-1 flags:1 ts: 0.624171
29ret:-126ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 211968 size: 24787
30ret: 0 st: 0 flags:0 ts:-0.48000027ret: 0 st: 0 flags:0 ts:-0.480000
31ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 2480128ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
32ret: 0 st: 0 flags:1 ts: 2.40000029ret: 0 st: 0 flags:1 ts: 2.400000
33ret:-130ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
34ret: 0 st: 1 flags:0 ts: 1.32000031ret:-1 st: 1 flags:0 ts: 1.320000
35ret:-1
36ret: 0 st: 1 flags:1 ts: 0.20000032ret: 0 st: 1 flags:1 ts: 0.200000
37ret: 0 st: 0 flags:1 dts: 0.200000 pts: NOPTS pos: 6144 size: 2480133ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
38ret: 0 st:-1 flags:0 ts:-0.90499434ret: 0 st:-1 flags:0 ts:-0.904994
39ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 2480135ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
40ret: 0 st:-1 flags:1 ts: 1.98917336ret: 0 st:-1 flags:1 ts: 1.989173
41ret:-137ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
42ret: 0 st: 0 flags:0 ts: 0.88000038ret: 0 st: 0 flags:0 ts: 0.880000
43ret:-139ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
44ret: 0 st: 0 flags:1 ts:-0.24000040ret: 0 st: 0 flags:1 ts:-0.240000
45ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 2480141ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
46ret: 0 st: 1 flags:0 ts: 2.68000042ret:-1 st: 1 flags:0 ts: 2.680000
47ret:-1
48ret: 0 st: 1 flags:1 ts: 1.56000043ret: 0 st: 1 flags:1 ts: 1.560000
49ret:-144ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
50ret: 0 st:-1 flags:0 ts: 0.46000845ret: 0 st:-1 flags:0 ts: 0.460008
51ret: 0 st: 0 flags:1 dts: 0.480000 pts: NOPTS pos: 6144 size: 2480146ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
52ret: 0 st:-1 flags:1 ts:-0.64582547ret: 0 st:-1 flags:1 ts:-0.645825
53ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 2480148ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t