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
197197 int parsing_backward;
198198 int64_t last_forward_tell;
199199 int last_forward_partition;
200+ int current_edit_unit;
201+ int current_stream;
202+ int d10;
200203 } MXFContext;
201204
202205 enum MXFWrappingScheme {
@@ -372,7 +375,7 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv · 169 unmodified lines
372375 return 0;
373376 }
374377
375−static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
378+static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
376379 {
377380 KLVPacket klv;
378381
@@ -418,6 +421,65 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) · 39 unmodified lines
418421 return AVERROR_EOF;
419422 }
420423
424+static 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+
421483 static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
422484 {
423485 MXFContext *mxf = arg;
@@ -925,6 +987,8 @@ static const MXFCodecUL mxf_essence_container_uls[] = { · 501 unmodified lines
925987 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },
926988 };
927989
990+static UID mxf_d10_ul = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 };
991+
928992 static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
929993 {
930994 int i, j, nb_segments = 0;
@@ -1252,6 +1316,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) · 321 unmodified lines
12521316 }
12531317 }
12541318 }
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+
12551324 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
12561325 codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
12571326 st->codec->codec_id = codec_ul->id;
@@ -1291,8 +1360,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) · 33 unmodified lines
12911360 }
12921361 }
12931362 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");
1295− st->need_parsing = AVSTREAM_PARSE_FULL;
1363+ /* TODO: decode timestamps */
1364+ st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
12961365 }
12971366
12981367 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
16591728 {
16601729 AVStream *st = s->streams[stream_index];
16611730 int64_t seconds;
1731+ MXFContext* mxf = s->priv_data;
1732+ int64_t seekpos;
1733+ int index;
16621734
1735+ if (mxf->d10) {
16631736 if (!s->bit_rate)
16641737 return -1;
16651738 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
16681741 if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0)
16691742 return -1;
16701743 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+ }
16711765 return 0;
16721766 }
16731767
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
22 ret: 0 st:-1 flags:0 ts:-1.000000
33 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
44 ret: 0 st:-1 flags:1 ts: 1.894167
5−ret:-1
5+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
66 ret: 0 st: 0 flags:0 ts: 0.800000
7−ret:-1
7+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
88 ret: 0 st: 0 flags:1 ts:-0.320000
99 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
10−ret: 0 st: 1 flags:0 ts: 2.560000
11−ret:-1
10+ret:-1 st: 1 flags:0 ts: 2.560000
1211 ret: 0 st: 1 flags:1 ts: 1.480000
13−ret:-1
12+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
1413 ret: 0 st:-1 flags:0 ts: 0.365002
15−ret: 0 st: 0 flags:1 dts: 0.360000 pts: NOPTS pos: 6144 size: 24801
14+ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 211968 size: 24787
1615 ret: 0 st:-1 flags:1 ts:-0.740831
1716 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
18−ret: 0 st: 0 flags:0 ts: 2.160000
19−ret:-1
17+ret:-1 st: 0 flags:0 ts: 2.160000
2018 ret: 0 st: 0 flags:1 ts: 1.040000
21−ret:-1
19+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
2220 ret: 0 st: 1 flags:0 ts:-0.040000
2321 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
2422 ret: 0 st: 1 flags:1 ts: 2.840000
25−ret:-1
26−ret: 0 st:-1 flags:0 ts: 1.730004
27−ret:-1
23+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
24+ret:-1 st:-1 flags:0 ts: 1.730004
2825 ret: 0 st:-1 flags:1 ts: 0.624171
29−ret:-1
26+ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 211968 size: 24787
3027 ret: 0 st: 0 flags:0 ts:-0.480000
3128 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
3229 ret: 0 st: 0 flags:1 ts: 2.400000
33−ret:-1
34−ret: 0 st: 1 flags:0 ts: 1.320000
35−ret:-1
30+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
31+ret:-1 st: 1 flags:0 ts: 1.320000
3632 ret: 0 st: 1 flags:1 ts: 0.200000
37−ret: 0 st: 0 flags:1 dts: 0.200000 pts: NOPTS pos: 6144 size: 24801
33+ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
3834 ret: 0 st:-1 flags:0 ts:-0.904994
3935 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
4036 ret: 0 st:-1 flags:1 ts: 1.989173
41−ret:-1
37+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
4238 ret: 0 st: 0 flags:0 ts: 0.880000
43−ret:-1
39+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
4440 ret: 0 st: 0 flags:1 ts:-0.240000
4541 ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
46−ret: 0 st: 1 flags:0 ts: 2.680000
47−ret:-1
42+ret:-1 st: 1 flags:0 ts: 2.680000
4843 ret: 0 st: 1 flags:1 ts: 1.560000
49−ret:-1
44+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
5045 ret: 0 st:-1 flags:0 ts: 0.460008
51−ret: 0 st: 0 flags:1 dts: 0.480000 pts: NOPTS pos: 6144 size: 24801
46+ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
5247 ret: 0 st:-1 flags:1 ts:-0.645825
5348 ret: 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