From 606742288d39b33aa3e458e418af4de14e86c5e4 Mon Sep 17 00:00:00 2001 From: Fredrik Mellbin Date: Thu, 7 Mar 2024 21:59:54 +0100 Subject: [PATCH] Store per frame field order in index --- include/ffms.h | 3 ++- src/core/indexing.cpp | 8 +++++--- src/core/indexing.h | 2 +- src/core/track.cpp | 8 +++++--- src/core/track.h | 3 ++- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/include/ffms.h b/include/ffms.h index 586cc4ff6f..749ea20969 100644 --- a/include/ffms.h +++ b/include/ffms.h @@ -22,7 +22,7 @@ #define FFMS_H // Version format: major - minor - micro - bump -#define FFMS_VERSION ((5 << 24) | (0 << 16) | (0 << 8) | 0) +#define FFMS_VERSION ((5 << 24) | (1 << 16) | (0 << 8) | 0) #include #include @@ -353,6 +353,7 @@ typedef struct FFMS_TrackTimeBase { typedef struct FFMS_FrameInfo { int64_t PTS; + int FieldOrder; int RepeatPict; int KeyFrame; int64_t OriginalPTS; diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp index 8c55a5790e..31cb48dc0a 100644 --- a/src/core/indexing.cpp +++ b/src/core/indexing.cpp @@ -359,7 +359,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) { } } -void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, +void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *FieldOrder, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) { if (VideoContext.Parser) { uint8_t *OB; @@ -388,6 +388,7 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt } } + *FieldOrder = VideoContext.Parser->field_order; *RepeatPict = VideoContext.Parser->repeat_pict; *FrameType = VideoContext.Parser->pict_type; *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD)); @@ -553,12 +554,13 @@ FFMS_Index *FFMS_Indexer::DoIndexing() { TrackInfo.HasTS = false; } + int FieldOrder = -1; int RepeatPict = -1; int FrameType = 0; bool Invisible = false; - ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct); + ParseVideoPacket(AVContexts[Track], Packet, &FieldOrder, &RepeatPict, &FrameType, &Invisible, &LastPicStruct); - TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame, + TrackInfo.AddVideoFrame(PTS, FieldOrder, RepeatPict, KeyFrame, FrameType, Packet->pos, Invisible); } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { // For video seeking timestamps are used only if all packets have diff --git a/src/core/indexing.h b/src/core/indexing.h index 2cd0039d4c..a849c42e59 100644 --- a/src/core/indexing.h +++ b/src/core/indexing.h @@ -85,7 +85,7 @@ struct FFMS_Indexer { void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS); void CheckAudioProperties(int Track, AVCodecContext *Context); uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices); - void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct); + void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *FieldOrder, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct); void Free(); public: FFMS_Indexer(const char *Filename, const FFMS_KeyValuePair *DemuxerOptions, int NumOptions); diff --git a/src/core/track.cpp b/src/core/track.cpp index 01c9e116f0..ce0a3a9d54 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -48,6 +48,7 @@ FrameInfo ReadFrame(ZipFile &stream, FrameInfo const& prev, const FFMS_TrackType f.SampleCount = stream.Read() + prev.SampleCount; } else if (TT == FFMS_TYPE_VIDEO) { f.OriginalPos = static_cast(stream.Read() + prev.OriginalPos + 1); + f.FieldOrder = stream.Read(); f.RepeatPict = stream.Read(); } return f; @@ -64,6 +65,7 @@ static void WriteFrame(ZipFile &stream, FrameInfo const& f, FrameInfo const& pre stream.Write(f.SampleCount - prev.SampleCount); else if (TT == FFMS_TYPE_VIDEO) { stream.Write(static_cast(f.OriginalPos) - prev.OriginalPos - 1); + stream.Write(f.FieldOrder); stream.Write(f.RepeatPict); } } @@ -127,8 +129,8 @@ void FFMS_Track::Write(ZipFile &stream) const { WriteFrame(stream, Frames[i], i == 0 ? temp : Frames[i - 1], TT); } -void FFMS_Track::AddVideoFrame(int64_t PTS, int RepeatPict, bool KeyFrame, int FrameType, int64_t FilePos, bool Hidden) { - Data->Frames.push_back({ PTS, 0, FilePos, 0, 0, 0, FrameType, RepeatPict, KeyFrame, Hidden }); +void FFMS_Track::AddVideoFrame(int64_t PTS, int FieldOrder, int RepeatPict, bool KeyFrame, int FrameType, int64_t FilePos, bool Hidden) { + Data->Frames.push_back({ PTS, 0, FilePos, 0, 0, 0, FrameType, FieldOrder, RepeatPict, KeyFrame, Hidden }); } void FFMS_Track::AddAudioFrame(int64_t PTS, int64_t SampleStart, uint32_t SampleCount, bool KeyFrame, int64_t FilePos, bool Hidden) { @@ -408,7 +410,7 @@ void FFMS_Track::GeneratePublicInfo() { continue; RealFrameNumbers.push_back(static_cast(i)); - FFMS_FrameInfo info = { Frames[i].PTS, Frames[i].RepeatPict, Frames[i].KeyFrame, Frames[i].OriginalPTS }; + FFMS_FrameInfo info = { Frames[i].PTS, Frames[i].FieldOrder, Frames[i].RepeatPict, Frames[i].KeyFrame, Frames[i].OriginalPTS }; PublicFrameInfo.push_back(info); } } diff --git a/src/core/track.h b/src/core/track.h index f6a9fbb2cf..1be67ff028 100644 --- a/src/core/track.h +++ b/src/core/track.h @@ -37,6 +37,7 @@ struct FrameInfo { uint32_t SampleCount; size_t OriginalPos; int FrameType; + int FieldOrder; int RepeatPict; bool KeyFrame; bool Hidden; @@ -66,7 +67,7 @@ struct FFMS_Track { int64_t LastDuration = 0; int SampleRate = 0; // not persisted - void AddVideoFrame(int64_t PTS, int RepeatPict, bool KeyFrame, int FrameType, int64_t FilePos = 0, bool Invisible = false); + void AddVideoFrame(int64_t PTS, int FieldOrder, int RepeatPict, bool KeyFrame, int FrameType, int64_t FilePos = 0, bool Invisible = false); void AddAudioFrame(int64_t PTS, int64_t SampleStart, uint32_t SampleCount, bool KeyFrame, int64_t FilePos = 0, bool Invisible = false); void MaybeHideFrames();