forked from mia/Aegisub
Update ffms2 to r238. Fixes #1048. This version is API and ABI compatible with the previous one so no further modifications are necessary.
Originally committed to SVN as r3820.
This commit is contained in:
parent
e720bba41c
commit
b8561bf01d
6 changed files with 48 additions and 9 deletions
|
@ -67,6 +67,12 @@ FFLAVFVideo::FFLAVFVideo(const char *SourceFile, int Track, FFMS_Index *Index,
|
||||||
VP.FPSNumerator = FormatContext->streams[VideoTrack]->time_base.den;
|
VP.FPSNumerator = FormatContext->streams[VideoTrack]->time_base.den;
|
||||||
VP.RFFDenominator = CodecContext->time_base.num;
|
VP.RFFDenominator = CodecContext->time_base.num;
|
||||||
VP.RFFNumerator = CodecContext->time_base.den;
|
VP.RFFNumerator = CodecContext->time_base.den;
|
||||||
|
if (CodecContext->codec_id == CODEC_ID_H264) {
|
||||||
|
if (VP.RFFNumerator & 1)
|
||||||
|
VP.RFFDenominator *= 2;
|
||||||
|
else
|
||||||
|
VP.RFFNumerator /= 2;
|
||||||
|
}
|
||||||
VP.NumFrames = Frames.size();
|
VP.NumFrames = Frames.size();
|
||||||
VP.TopFieldFirst = DecodeFrame->top_field_first;
|
VP.TopFieldFirst = DecodeFrame->top_field_first;
|
||||||
#ifdef FFMS_HAVE_FFMPEG_COLORSPACE_INFO
|
#ifdef FFMS_HAVE_FFMPEG_COLORSPACE_INFO
|
||||||
|
@ -115,12 +121,18 @@ void FFLAVFVideo::DecodeNextFrame(int64_t *AStartTime) {
|
||||||
if (*AStartTime < 0)
|
if (*AStartTime < 0)
|
||||||
*AStartTime = Packet.dts;
|
*AStartTime = Packet.dts;
|
||||||
|
|
||||||
if (CodecContext->codec_id == CODEC_ID_MPEG4 && IsNVOP(Packet)) {
|
|
||||||
av_free_packet(&Packet);
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
avcodec_decode_video2(CodecContext, DecodeFrame, &FrameFinished, &Packet);
|
avcodec_decode_video2(CodecContext, DecodeFrame, &FrameFinished, &Packet);
|
||||||
|
|
||||||
|
if (CodecContext->codec_id == CODEC_ID_MPEG4) {
|
||||||
|
if (IsPackedFrame(Packet)) {
|
||||||
|
MPEG4Counter++;
|
||||||
|
} else if (IsNVOP(Packet) && MPEG4Counter && FrameFinished) {
|
||||||
|
MPEG4Counter--;
|
||||||
|
} else if (IsNVOP(Packet) && !MPEG4Counter && !FrameFinished) {
|
||||||
|
av_free_packet(&Packet);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
av_free_packet(&Packet);
|
av_free_packet(&Packet);
|
||||||
|
@ -184,6 +196,7 @@ ReSeek:
|
||||||
|
|
||||||
if (HasSeeked) {
|
if (HasSeeked) {
|
||||||
HasSeeked = false;
|
HasSeeked = false;
|
||||||
|
MPEG4Counter = 0;
|
||||||
|
|
||||||
// Is the seek destination time known? Does it belong to a frame?
|
// Is the seek destination time known? Does it belong to a frame?
|
||||||
if (StartTime < 0 || (CurrentFrame = Frames.FrameFromPTS(StartTime)) < 0) {
|
if (StartTime < 0 || (CurrentFrame = Frames.FrameFromPTS(StartTime)) < 0) {
|
||||||
|
|
|
@ -98,6 +98,12 @@ FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track,
|
||||||
VP.FPSNumerator = 30;
|
VP.FPSNumerator = 30;
|
||||||
VP.RFFDenominator = CodecContext->time_base.num;
|
VP.RFFDenominator = CodecContext->time_base.num;
|
||||||
VP.RFFNumerator = CodecContext->time_base.den;
|
VP.RFFNumerator = CodecContext->time_base.den;
|
||||||
|
if (CodecContext->codec_id == CODEC_ID_H264) {
|
||||||
|
if (VP.RFFNumerator & 1)
|
||||||
|
VP.RFFDenominator *= 2;
|
||||||
|
else
|
||||||
|
VP.RFFNumerator /= 2;
|
||||||
|
}
|
||||||
VP.NumFrames = Frames.size();
|
VP.NumFrames = Frames.size();
|
||||||
VP.TopFieldFirst = DecodeFrame->top_field_first;
|
VP.TopFieldFirst = DecodeFrame->top_field_first;
|
||||||
#ifdef FFMS_HAVE_FFMPEG_COLORSPACE_INFO
|
#ifdef FFMS_HAVE_FFMPEG_COLORSPACE_INFO
|
||||||
|
@ -159,11 +165,18 @@ void FFMatroskaVideo::DecodeNextFrame() {
|
||||||
|
|
||||||
PacketNumber++;
|
PacketNumber++;
|
||||||
|
|
||||||
if (CodecContext->codec_id == CODEC_ID_MPEG4 && IsNVOP(Packet))
|
|
||||||
goto Done;
|
|
||||||
|
|
||||||
avcodec_decode_video2(CodecContext, DecodeFrame, &FrameFinished, &Packet);
|
avcodec_decode_video2(CodecContext, DecodeFrame, &FrameFinished, &Packet);
|
||||||
|
|
||||||
|
if (CodecContext->codec_id == CODEC_ID_MPEG4) {
|
||||||
|
if (IsPackedFrame(Packet)) {
|
||||||
|
MPEG4Counter++;
|
||||||
|
} else if (IsNVOP(Packet) && MPEG4Counter && FrameFinished) {
|
||||||
|
MPEG4Counter--;
|
||||||
|
} else if (IsNVOP(Packet) && !MPEG4Counter && !FrameFinished) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FrameFinished)
|
if (FrameFinished)
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -190,6 +203,7 @@ FFMS_Frame *FFMatroskaVideo::GetFrame(int n) {
|
||||||
|
|
||||||
int ClosestKF = Frames.FindClosestVideoKeyFrame(n);
|
int ClosestKF = Frames.FindClosestVideoKeyFrame(n);
|
||||||
if (CurrentFrame > n || ClosestKF > CurrentFrame + 10) {
|
if (CurrentFrame > n || ClosestKF > CurrentFrame + 10) {
|
||||||
|
MPEG4Counter = 0;
|
||||||
PacketNumber = ClosestKF;
|
PacketNumber = ClosestKF;
|
||||||
CurrentFrame = ClosestKF;
|
CurrentFrame = ClosestKF;
|
||||||
avcodec_flush_buffers(CodecContext);
|
avcodec_flush_buffers(CodecContext);
|
||||||
|
|
|
@ -202,8 +202,17 @@ void InitNullPacket(AVPacket &pkt) {
|
||||||
pkt.size = 0;
|
pkt.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsPackedFrame(AVPacket &pkt) {
|
||||||
|
for (int i = 0; i < pkt.size - 5; i++)
|
||||||
|
if (pkt.data[i] == 0x00 && pkt.data[i + 1] == 0x00 && pkt.data[i + 2] == 0x01 && pkt.data[i + 3] == 0xB6 && (pkt.data[i + 4] & 0x40))
|
||||||
|
for (i = i + 5; i < pkt.size - 5; i++)
|
||||||
|
if (pkt.data[i] == 0x00 && pkt.data[i + 1] == 0x00 && pkt.data[i + 2] == 0x01 && pkt.data[i + 3] == 0xB6 && (pkt.data[i + 4] & 0xC0) == 0x80)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsNVOP(AVPacket &pkt) {
|
bool IsNVOP(AVPacket &pkt) {
|
||||||
const uint8_t MPEG4NVOP[] = { 0x00, 0x00, 0x01, 0xB6 };
|
static const uint8_t MPEG4NVOP[] = { 0x00, 0x00, 0x01, 0xB6 };
|
||||||
return (pkt.size >= 4 && pkt.size <= 8) && !memcmp(pkt.data, MPEG4NVOP, 4);
|
return (pkt.size >= 4 && pkt.size <= 8) && !memcmp(pkt.data, MPEG4NVOP, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ FFMS_TrackType HaaliTrackTypeToFFTrackType(int TT);
|
||||||
void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, MatroskaReaderContext &Context);
|
void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, MatroskaReaderContext &Context);
|
||||||
bool AudioFMTIsFloat(SampleFormat FMT);
|
bool AudioFMTIsFloat(SampleFormat FMT);
|
||||||
void InitNullPacket(AVPacket &pkt);
|
void InitNullPacket(AVPacket &pkt);
|
||||||
|
bool IsPackedFrame(AVPacket &pkt);
|
||||||
bool IsNVOP(AVPacket &pkt);
|
bool IsNVOP(AVPacket &pkt);
|
||||||
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
|
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
|
||||||
#ifdef HAALISOURCE
|
#ifdef HAALISOURCE
|
||||||
|
|
|
@ -162,6 +162,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, in
|
||||||
SWS = NULL;
|
SWS = NULL;
|
||||||
LastFrameNum = 0;
|
LastFrameNum = 0;
|
||||||
CurrentFrame = 1;
|
CurrentFrame = 1;
|
||||||
|
MPEG4Counter = 0;
|
||||||
CodecContext = NULL;
|
CodecContext = NULL;
|
||||||
LastFrameHeight = -1;
|
LastFrameHeight = -1;
|
||||||
LastFrameWidth = -1;
|
LastFrameWidth = -1;
|
||||||
|
|
|
@ -73,6 +73,7 @@ protected:
|
||||||
FFMS_Track Frames;
|
FFMS_Track Frames;
|
||||||
int VideoTrack;
|
int VideoTrack;
|
||||||
int CurrentFrame;
|
int CurrentFrame;
|
||||||
|
int MPEG4Counter;
|
||||||
AVCodecContext *CodecContext;
|
AVCodecContext *CodecContext;
|
||||||
|
|
||||||
FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, int Track);
|
FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, int Track);
|
||||||
|
|
Loading…
Reference in a new issue