Bug 1158226 - Eagerly compute keyframe-ness and stash it on the packet holder. r=kinetik

This commit is contained in:
Bobby Holley 2015-04-23 18:33:12 -07:00
parent 3ed8d105fc
commit 4f3c199145
2 changed files with 50 additions and 30 deletions

View File

@ -924,9 +924,46 @@ WebMReader::DemuxPacket()
return nullptr;
}
// Figure out if this is a keyframe.
//
// Doing this at packet-granularity is kind of the wrong level of
// abstraction, but timestamps are on the packet, so the only time
// we have multiple video frames in a packet is when we have "alternate
// reference frames", which are a compression detail and never displayed.
// So for our purposes, we can just take the union of the is_kf values for
// all the frames in the packet.
bool isKeyframe = false;
if (track == mAudioTrack) {
isKeyframe = true;
} else if (track == mVideoTrack) {
unsigned int count = 0;
r = nestegg_packet_count(packet, &count);
if (r == -1) {
return nullptr;
}
for (unsigned i = 0; i < count; ++i) {
unsigned char* data;
size_t length;
r = nestegg_packet_data(packet, i, &data, &length);
if (r == -1) {
return nullptr;
}
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);
}
isKeyframe = isKeyframe || si.is_kf;
}
}
int64_t offset = mDecoder->GetResource()->Tell();
nsRefPtr<NesteggPacketHolder> holder = new NesteggPacketHolder();
if (!holder->Init(packet, offset, track)) {
if (!holder->Init(packet, offset, track, isKeyframe)) {
return nullptr;
}
@ -986,34 +1023,12 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
if (!holder) {
break;
}
unsigned int count = 0;
int r = nestegg_packet_count(holder->Packet(), &count);
if (r == -1) {
break;
}
int64_t tstamp = holder->Timestamp();
for (uint32_t i = 0; i < count; ++i) {
unsigned char* data;
size_t length;
r = nestegg_packet_data(holder->Packet(), 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;
break;
}
if (holder->IsKeyframe()) {
foundKeyframe = true;
keyframeTime = holder->Timestamp();
}
skipPacketQueue.PushFront(holder.forget());
}

View File

@ -36,9 +36,9 @@ static const double NS_PER_S = 1e9;
class NesteggPacketHolder {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder)
NesteggPacketHolder() : mPacket(nullptr), mOffset(-1), mTimestamp(-1) {}
NesteggPacketHolder() : mPacket(nullptr), mOffset(-1), mTimestamp(-1), mIsKeyframe(false) {}
bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack)
bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, bool aIsKeyframe)
{
uint64_t timestamp_ns;
if (nestegg_packet_tstamp(aPacket, &timestamp_ns) == -1) {
@ -51,6 +51,7 @@ public:
mPacket = aPacket;
mOffset = aOffset;
mTrack = aTrack;
mIsKeyframe = aIsKeyframe;
return true;
}
@ -59,6 +60,7 @@ public:
int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; }
int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; }
unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; }
bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; }
private:
~NesteggPacketHolder()
@ -80,6 +82,9 @@ private:
// Track ID.
unsigned mTrack;
// Does this packet contain a keyframe?
bool mIsKeyframe;
// Copy constructor and assignment operator not implemented. Don't use them!
NesteggPacketHolder(const NesteggPacketHolder &aOther);
NesteggPacketHolder& operator= (NesteggPacketHolder const& aOther);