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.RFFDenominator = CodecContext->time_base.num;
|
||||
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.TopFieldFirst = DecodeFrame->top_field_first;
|
||||
#ifdef FFMS_HAVE_FFMPEG_COLORSPACE_INFO
|
||||
|
@ -115,12 +121,18 @@ void FFLAVFVideo::DecodeNextFrame(int64_t *AStartTime) {
|
|||
if (*AStartTime < 0)
|
||||
*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);
|
||||
|
||||
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);
|
||||
|
@ -184,6 +196,7 @@ ReSeek:
|
|||
|
||||
if (HasSeeked) {
|
||||
HasSeeked = false;
|
||||
MPEG4Counter = 0;
|
||||
|
||||
// Is the seek destination time known? Does it belong to a frame?
|
||||
if (StartTime < 0 || (CurrentFrame = Frames.FrameFromPTS(StartTime)) < 0) {
|
||||
|
|
|
@ -98,6 +98,12 @@ FFMatroskaVideo::FFMatroskaVideo(const char *SourceFile, int Track,
|
|||
VP.FPSNumerator = 30;
|
||||
VP.RFFDenominator = CodecContext->time_base.num;
|
||||
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.TopFieldFirst = DecodeFrame->top_field_first;
|
||||
#ifdef FFMS_HAVE_FFMPEG_COLORSPACE_INFO
|
||||
|
@ -159,11 +165,18 @@ void FFMatroskaVideo::DecodeNextFrame() {
|
|||
|
||||
PacketNumber++;
|
||||
|
||||
if (CodecContext->codec_id == CODEC_ID_MPEG4 && IsNVOP(Packet))
|
||||
goto Done;
|
||||
|
||||
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)
|
||||
goto Done;
|
||||
}
|
||||
|
@ -190,6 +203,7 @@ FFMS_Frame *FFMatroskaVideo::GetFrame(int n) {
|
|||
|
||||
int ClosestKF = Frames.FindClosestVideoKeyFrame(n);
|
||||
if (CurrentFrame > n || ClosestKF > CurrentFrame + 10) {
|
||||
MPEG4Counter = 0;
|
||||
PacketNumber = ClosestKF;
|
||||
CurrentFrame = ClosestKF;
|
||||
avcodec_flush_buffers(CodecContext);
|
||||
|
|
|
@ -202,8 +202,17 @@ void InitNullPacket(AVPacket &pkt) {
|
|||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ FFMS_TrackType HaaliTrackTypeToFFTrackType(int TT);
|
|||
void ReadFrame(uint64_t FilePos, unsigned int &FrameSize, CompressedStream *CS, MatroskaReaderContext &Context);
|
||||
bool AudioFMTIsFloat(SampleFormat FMT);
|
||||
void InitNullPacket(AVPacket &pkt);
|
||||
bool IsPackedFrame(AVPacket &pkt);
|
||||
bool IsNVOP(AVPacket &pkt);
|
||||
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
|
||||
#ifdef HAALISOURCE
|
||||
|
|
|
@ -162,6 +162,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, in
|
|||
SWS = NULL;
|
||||
LastFrameNum = 0;
|
||||
CurrentFrame = 1;
|
||||
MPEG4Counter = 0;
|
||||
CodecContext = NULL;
|
||||
LastFrameHeight = -1;
|
||||
LastFrameWidth = -1;
|
||||
|
|
|
@ -73,6 +73,7 @@ protected:
|
|||
FFMS_Track Frames;
|
||||
int VideoTrack;
|
||||
int CurrentFrame;
|
||||
int MPEG4Counter;
|
||||
AVCodecContext *CodecContext;
|
||||
|
||||
FFMS_VideoSource(const char *SourceFile, FFMS_Index *Index, int Track);
|
||||
|
|
Loading…
Reference in a new issue