This adds OPAtom support and proper seeking. D-10 and non-seekable OP1a streams still use the old demuxing/seeking code.
Unified · Split
| @@ -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 | ||
| 202 | enum MXFWrappingScheme { | 205 | enum 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 | ||
| 375 | static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) | 378 | static 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 | ||
| 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 | |||
| 421 | static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) | 483 | static 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 | ||
| 990 | static UID mxf_d10_ul = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }; | ||
| 991 | |||
| 928 | static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments) | 992 | static 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 | ||
| @@ -2,52 +2,47 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 · 1 unmodified line | |||
| 2 | ret: 0 st:-1 flags:0 ts:-1.000000 | 2 | ret: 0 st:-1 flags:0 ts:-1.000000 |
| 3 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 3 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 |
| 4 | ret: 0 st:-1 flags:1 ts: 1.894167 | 4 | 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 |
| 6 | ret: 0 st: 0 flags:0 ts: 0.800000 | 6 | 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 |
| 8 | ret: 0 st: 0 flags:1 ts:-0.320000 | 8 | ret: 0 st: 0 flags:1 ts:-0.320000 |
| 9 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 9 | 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 | 10 | ret:-1 st: 1 flags:0 ts: 2.560000 |
| 11 | ret:-1 | ||
| 12 | ret: 0 st: 1 flags:1 ts: 1.480000 | 11 | 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 |
| 14 | ret: 0 st:-1 flags:0 ts: 0.365002 | 13 | 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 |
| 16 | ret: 0 st:-1 flags:1 ts:-0.740831 | 15 | ret: 0 st:-1 flags:1 ts:-0.740831 |
| 17 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 16 | 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 | 17 | ret:-1 st: 0 flags:0 ts: 2.160000 |
| 19 | ret:-1 | ||
| 20 | ret: 0 st: 0 flags:1 ts: 1.040000 | 18 | 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 |
| 22 | ret: 0 st: 1 flags:0 ts:-0.040000 | 20 | ret: 0 st: 1 flags:0 ts:-0.040000 |
| 23 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 21 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 |
| 24 | ret: 0 st: 1 flags:1 ts: 2.840000 | 22 | ret: 0 st: 1 flags:1 ts: 2.840000 |
| 25 | ret:-1 | 23 | ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712 |
| 26 | ret: 0 st:-1 flags:0 ts: 1.730004 | 24 | ret:-1 st:-1 flags:0 ts: 1.730004 |
| 27 | ret:-1 | ||
| 28 | ret: 0 st:-1 flags:1 ts: 0.624171 | 25 | 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 |
| 30 | ret: 0 st: 0 flags:0 ts:-0.480000 | 27 | ret: 0 st: 0 flags:0 ts:-0.480000 |
| 31 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 28 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 |
| 32 | ret: 0 st: 0 flags:1 ts: 2.400000 | 29 | ret: 0 st: 0 flags:1 ts: 2.400000 |
| 33 | ret:-1 | 30 | ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712 |
| 34 | ret: 0 st: 1 flags:0 ts: 1.320000 | 31 | ret:-1 st: 1 flags:0 ts: 1.320000 |
| 35 | ret:-1 | ||
| 36 | ret: 0 st: 1 flags:1 ts: 0.200000 | 32 | 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 |
| 38 | ret: 0 st:-1 flags:0 ts:-0.904994 | 34 | ret: 0 st:-1 flags:0 ts:-0.904994 |
| 39 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 35 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 |
| 40 | ret: 0 st:-1 flags:1 ts: 1.989173 | 36 | 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 |
| 42 | ret: 0 st: 0 flags:0 ts: 0.880000 | 38 | 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 |
| 44 | ret: 0 st: 0 flags:1 ts:-0.240000 | 40 | ret: 0 st: 0 flags:1 ts:-0.240000 |
| 45 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 41 | 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 | 42 | ret:-1 st: 1 flags:0 ts: 2.680000 |
| 47 | ret:-1 | ||
| 48 | ret: 0 st: 1 flags:1 ts: 1.560000 | 43 | 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 |
| 50 | ret: 0 st:-1 flags:0 ts: 0.460008 | 45 | 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 |
| 52 | ret: 0 st:-1 flags:1 ts:-0.645825 | 47 | ret: 0 st:-1 flags:1 ts:-0.645825 |
| 53 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 | 48 | ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801 |