зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1131563 - Set the flag skipToNextKeyFrame to false if there is no keyframe behind. r=kinetik
--HG-- extra : rebase_source : e561bdfe1bddfc5073587056925248a4ba905977
This commit is contained in:
Родитель
f57b36ec5f
Коммит
6649eea3cd
|
@ -941,8 +941,108 @@ bool WebMReader::DecodeAudioData()
|
|||
return DecodeAudioPacket(holder->mPacket, holder->mOffset);
|
||||
}
|
||||
|
||||
bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput)
|
||||
{
|
||||
// Push the video frames to the aOutput which's timestamp is less
|
||||
// than aEndTime.
|
||||
while (true) {
|
||||
nsAutoRef<NesteggPacketHolder> holder(NextPacket(VIDEO));
|
||||
if (!holder) {
|
||||
break;
|
||||
}
|
||||
uint64_t tstamp = 0;
|
||||
int r = nestegg_packet_tstamp(holder->mPacket, &tstamp);
|
||||
if (r == -1) {
|
||||
break;
|
||||
}
|
||||
uint64_t tstamp_usecs = tstamp / NS_PER_USEC;
|
||||
if (tstamp_usecs >= (uint64_t)aEndTime) {
|
||||
PushVideoPacket(holder.disown());
|
||||
return true;
|
||||
} else {
|
||||
aOutput.PushFront(holder.disown());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
|
||||
{
|
||||
WebMPacketQueue skipPacketQueue;
|
||||
if (!FilterPacketByTime(aTimeThreshold, skipPacketQueue)) {
|
||||
// Restore the packets before we return -1.
|
||||
uint32_t size = skipPacketQueue.GetSize();
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
PushVideoPacket(skipPacketQueue.PopFront());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find keyframe.
|
||||
bool foundKeyframe = false;
|
||||
int64_t keyframeTime = -1;
|
||||
while (!foundKeyframe) {
|
||||
nsAutoRef<NesteggPacketHolder> holder(NextPacket(VIDEO));
|
||||
if (!holder) {
|
||||
break;
|
||||
}
|
||||
unsigned int count = 0;
|
||||
int r = nestegg_packet_count(holder->mPacket, &count);
|
||||
if (r == -1) {
|
||||
break;
|
||||
}
|
||||
uint64_t tstamp = 0;
|
||||
r = nestegg_packet_tstamp(holder->mPacket, &tstamp);
|
||||
if (r == -1) {
|
||||
break;
|
||||
}
|
||||
uint64_t tstamp_usecs = tstamp / NS_PER_USEC;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
unsigned char* data;
|
||||
size_t length;
|
||||
r = nestegg_packet_data(holder->mPacket, i, &data, &length);
|
||||
if (r == -1) {
|
||||
foundKeyframe = true;
|
||||
break;
|
||||
}
|
||||
vpx_codec_stream_info_t si;
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.sz = sizeof(si);
|
||||
if (mVideoCodec == NESTEGG_CODEC_VP8) {
|
||||
vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si);
|
||||
} else if (mVideoCodec == NESTEGG_CODEC_VP9) {
|
||||
vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si);
|
||||
}
|
||||
if (si.is_kf) {
|
||||
foundKeyframe = true;
|
||||
keyframeTime = tstamp_usecs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
skipPacketQueue.PushFront(holder.disown());
|
||||
}
|
||||
|
||||
uint32_t size = skipPacketQueue.GetSize();
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
PushVideoPacket(skipPacketQueue.PopFront());
|
||||
}
|
||||
|
||||
return keyframeTime;
|
||||
}
|
||||
|
||||
bool WebMReader::ShouldSkipVideoFrame(int64_t aTimeThreshold)
|
||||
{
|
||||
return GetNextKeyframeTime(aTimeThreshold) != -1;
|
||||
}
|
||||
|
||||
bool WebMReader::DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold)
|
||||
{
|
||||
if (!(aKeyframeSkip && ShouldSkipVideoFrame(aTimeThreshold))) {
|
||||
LOG(PR_LOG_DEBUG, ("Reader [%p]: set the aKeyframeSkip to false.",this));
|
||||
aKeyframeSkip = false;
|
||||
}
|
||||
return mVideoDecoder->DecodeVideoFrame(aKeyframeSkip, aTimeThreshold);
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,15 @@ protected:
|
|||
// Initializes mLayersBackendType if possible.
|
||||
void InitLayersBackendType();
|
||||
|
||||
bool ShouldSkipVideoFrame(int64_t aTimeThreshold);
|
||||
|
||||
private:
|
||||
// Get the timestamp of keyframe greater than aTimeThreshold.
|
||||
int64_t GetNextKeyframeTime(int64_t aTimeThreshold);
|
||||
// Push the packets into aOutput which's timestamp is less than aEndTime.
|
||||
// Return false if we reach the end of stream or something wrong.
|
||||
bool FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput);
|
||||
|
||||
// libnestegg context for webm container. Access on state machine thread
|
||||
// or decoder thread only.
|
||||
nestegg* mContext;
|
||||
|
|
Загрузка…
Ссылка в новой задаче