mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-26 09:12:33 +00:00
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.
This commit is contained in:
parent
5e67e3eac2
commit
ddcf3e0535
@ -197,6 +197,9 @@ typedef struct {
|
||||
int parsing_backward;
|
||||
int64_t last_forward_tell;
|
||||
int last_forward_partition;
|
||||
int current_edit_unit;
|
||||
int current_stream;
|
||||
int d10;
|
||||
} MXFContext;
|
||||
|
||||
enum MXFWrappingScheme {
|
||||
@ -372,7 +375,7 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
KLVPacket klv;
|
||||
|
||||
@ -418,6 +421,65 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
return AVERROR_EOF;
|
||||
}
|
||||
|
||||
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
MXFContext *mxf = s->priv_data;
|
||||
AVIndexEntry *e;
|
||||
int ret;
|
||||
int64_t ret64;
|
||||
KLVPacket klv;
|
||||
AVStream *st;
|
||||
|
||||
/* TODO: better logic for this?
|
||||
* only files that lack all index segments prior to the essence need this */
|
||||
if (!s->pb->seekable && mxf->op != OPAtom || mxf->d10)
|
||||
return mxf_read_packet_old(s, pkt);
|
||||
|
||||
if (mxf->current_stream >= s->nb_streams) {
|
||||
mxf->current_edit_unit++;
|
||||
mxf->current_stream = 0;
|
||||
}
|
||||
|
||||
st = s->streams[mxf->current_stream];
|
||||
|
||||
if (mxf->current_edit_unit >= st->nb_index_entries)
|
||||
return AVERROR_EOF;
|
||||
|
||||
e = &st->index_entries[mxf->current_edit_unit];
|
||||
|
||||
if ((ret64 = avio_seek(s->pb, e->pos, SEEK_SET)) < 0)
|
||||
return ret64;
|
||||
|
||||
if (mxf->op == OPAtom) {
|
||||
/* OPAtom - no KL, just essence */
|
||||
if ((ret = av_get_packet(s->pb, pkt, e->size)) != e->size)
|
||||
return ret < 0 ? ret : AVERROR_EOF;
|
||||
} else {
|
||||
/* read KL, read L bytes of essence */
|
||||
if ((ret = klv_read_packet(&klv, s->pb)) < 0)
|
||||
return ret;
|
||||
|
||||
/* untested, but looks OK */
|
||||
if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
|
||||
int res = mxf_decrypt_triplet(s, pkt, &klv);
|
||||
if (res < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ret = av_get_packet(s->pb, pkt, klv.length)) != klv.length)
|
||||
return ret < 0 ? ret : AVERROR_EOF;
|
||||
|
||||
pkt->pos = e->pos;
|
||||
}
|
||||
|
||||
pkt->stream_index = mxf->current_stream++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
|
||||
{
|
||||
MXFContext *mxf = arg;
|
||||
@ -925,6 +987,8 @@ static const MXFCodecUL mxf_essence_container_uls[] = {
|
||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },
|
||||
};
|
||||
|
||||
static UID mxf_d10_ul = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 };
|
||||
|
||||
static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
|
||||
{
|
||||
int i, j, nb_segments = 0;
|
||||
@ -1252,6 +1316,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* HACK: revert to the old demuxing/seeking scode for D-10 for now */
|
||||
if (mxf_match_uid(essence_container_ul, mxf_d10_ul, 14))
|
||||
mxf->d10 = 1;
|
||||
|
||||
/* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
|
||||
codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
|
||||
st->codec->codec_id = codec_ul->id;
|
||||
@ -1291,8 +1360,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
|
||||
}
|
||||
}
|
||||
if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
|
||||
av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n");
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
/* TODO: decode timestamps */
|
||||
st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
AVStream *st = s->streams[stream_index];
|
||||
int64_t seconds;
|
||||
MXFContext* mxf = s->priv_data;
|
||||
int64_t seekpos;
|
||||
int index;
|
||||
|
||||
if (mxf->d10) {
|
||||
if (!s->bit_rate)
|
||||
return -1;
|
||||
if (sample_time < 0)
|
||||
@ -1668,6 +1741,27 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
|
||||
if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0)
|
||||
return -1;
|
||||
ff_update_cur_dts(s, st, sample_time);
|
||||
} else {
|
||||
if (st->nb_index_entries <= 0)
|
||||
return -1;
|
||||
|
||||
index = av_index_search_timestamp(st, sample_time, flags);
|
||||
|
||||
av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, sample_time, index);
|
||||
|
||||
if (index < 0) {
|
||||
if (sample_time < st->index_entries[0].timestamp)
|
||||
index = 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
seekpos = st->index_entries[index].pos;
|
||||
av_update_cur_dts(s, st, st->index_entries[index].timestamp);
|
||||
mxf->current_edit_unit = st->index_entries[index].timestamp;
|
||||
mxf->current_stream = 0;
|
||||
avio_seek(s->pb, seekpos, SEEK_SET);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,52 +2,47 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st: 0 flags:0 ts: 0.800000
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st: 0 flags:1 ts:-0.320000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 1 flags:0 ts: 2.560000
|
||||
ret:-1
|
||||
ret:-1 st: 1 flags:0 ts: 2.560000
|
||||
ret: 0 st: 1 flags:1 ts: 1.480000
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st:-1 flags:0 ts: 0.365002
|
||||
ret: 0 st: 0 flags:1 dts: 0.360000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 211968 size: 24787
|
||||
ret: 0 st:-1 flags:1 ts:-0.740831
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 0 flags:0 ts: 2.160000
|
||||
ret:-1
|
||||
ret:-1 st: 0 flags:0 ts: 2.160000
|
||||
ret: 0 st: 0 flags:1 ts: 1.040000
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st: 1 flags:0 ts:-0.040000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 1 flags:1 ts: 2.840000
|
||||
ret:-1
|
||||
ret: 0 st:-1 flags:0 ts: 1.730004
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret:-1 st:-1 flags:0 ts: 1.730004
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 211968 size: 24787
|
||||
ret: 0 st: 0 flags:0 ts:-0.480000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 0 flags:1 ts: 2.400000
|
||||
ret:-1
|
||||
ret: 0 st: 1 flags:0 ts: 1.320000
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret:-1 st: 1 flags:0 ts: 1.320000
|
||||
ret: 0 st: 1 flags:1 ts: 0.200000
|
||||
ret: 0 st: 0 flags:1 dts: 0.200000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st:-1 flags:0 ts:-0.904994
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st:-1 flags:1 ts: 1.989173
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st: 0 flags:0 ts: 0.880000
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st: 0 flags:1 ts:-0.240000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 1 flags:0 ts: 2.680000
|
||||
ret:-1
|
||||
ret:-1 st: 1 flags:0 ts: 2.680000
|
||||
ret: 0 st: 1 flags:1 ts: 1.560000
|
||||
ret:-1
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||
ret: 0 st: 0 flags:1 dts: 0.480000 pts: NOPTS pos: 6144 size: 24801
|
||||
ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 460800 size: 24712
|
||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 6144 size: 24801
|
||||
|
Loading…
Reference in New Issue
Block a user