Use the generic descriptor information in the RtpFrameReferenceFinder.

Bug: webrtc:9361
Change-Id: I8d7e7ee1d3ca89283552c21c45950d4dba1c1927
Reviewed-on: https://webrtc-review.googlesource.com/100301
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24826}
This commit is contained in:
philipel
2018-09-25 12:54:37 +02:00
committed by Commit Bot
parent 8b7bc5d701
commit dabfcae2d9
4 changed files with 177 additions and 17 deletions

View File

@ -84,6 +84,14 @@ void RtpFrameReferenceFinder::RetryStashedFrames() {
RtpFrameReferenceFinder::FrameDecision
RtpFrameReferenceFinder::ManageFrameInternal(RtpFrameObject* frame) {
absl::optional<RTPVideoHeader> video_header = frame->GetRtpVideoHeader();
// TODO(bugs.webrtc.org/9772): Remove the spatial id check when the old
// generic format has been removed.
if (video_header && video_header->generic &&
video_header->generic->spatial_index != -1) {
return ManageFrameGeneric(frame, *video_header->generic);
}
switch (frame->codec_type()) {
case kVideoCodecVP8:
return ManageFrameVp8(frame);
@ -91,11 +99,11 @@ RtpFrameReferenceFinder::ManageFrameInternal(RtpFrameObject* frame) {
return ManageFrameVp9(frame);
default: {
// Use 15 first bits of frame ID as picture ID if available.
absl::optional<RTPVideoHeader> video_header = frame->GetRtpVideoHeader();
absl::optional<RTPVideoHeader::GenericDescriptorInfo> generic_info =
video_header ? video_header->generic : absl::nullopt;
return ManageFrameGeneric(
frame, generic_info ? generic_info->frame_id & 0x7fff : kNoPictureId);
int picture_id = kNoPictureId;
if (video_header && video_header->generic)
picture_id = video_header->generic->frame_id & 0x7fff;
return ManageFramePidOrSeqNum(frame, picture_id);
}
}
}
@ -161,8 +169,28 @@ void RtpFrameReferenceFinder::UpdateLastPictureIdWithPadding(uint16_t seq_num) {
}
RtpFrameReferenceFinder::FrameDecision
RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame,
int picture_id) {
RtpFrameReferenceFinder::ManageFrameGeneric(
RtpFrameObject* frame,
const RTPVideoHeader::GenericDescriptorInfo& descriptor) {
if (EncodedFrame::kMaxFrameReferences < descriptor.dependencies.size()) {
RTC_LOG(LS_WARNING) << "Too many dependencies in generic descriptor.";
return kDrop;
}
int64_t frame_id = generic_frame_id_unwrapper_.Unwrap(descriptor.frame_id);
frame->id.picture_id = frame_id;
frame->id.spatial_layer = descriptor.spatial_index;
frame->num_references = descriptor.dependencies.size();
for (size_t i = 0; i < descriptor.dependencies.size(); ++i)
frame->references[i] = frame_id - descriptor.dependencies[i];
return kHandOff;
}
RtpFrameReferenceFinder::FrameDecision
RtpFrameReferenceFinder::ManageFramePidOrSeqNum(RtpFrameObject* frame,
int picture_id) {
// If |picture_id| is specified then we use that to set the frame references,
// otherwise we use sequence number.
if (picture_id != kNoPictureId) {
@ -219,7 +247,7 @@ RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame,
// picture id according to some incrementing counter.
frame->id.picture_id = frame->last_seq_num();
frame->num_references = frame->frame_type() == kVideoFrameDelta;
frame->references[0] = generic_unwrapper_.Unwrap(last_picture_id_gop);
frame->references[0] = rtp_seq_num_unwrapper_.Unwrap(last_picture_id_gop);
if (AheadOf<uint16_t>(frame->id.picture_id, last_picture_id_gop)) {
seq_num_it->second.first = frame->id.picture_id;
seq_num_it->second.second = frame->id.picture_id;
@ -227,7 +255,7 @@ RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame,
last_picture_id_ = frame->id.picture_id;
UpdateLastPictureIdWithPadding(frame->id.picture_id);
frame->id.picture_id = generic_unwrapper_.Unwrap(frame->id.picture_id);
frame->id.picture_id = rtp_seq_num_unwrapper_.Unwrap(frame->id.picture_id);
return kHandOff;
}
@ -247,7 +275,7 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8(
if (codec_header.pictureId == kNoPictureId ||
codec_header.temporalIdx == kNoTemporalIdx ||
codec_header.tl0PicIdx == kNoTl0PicIdx) {
return ManageFrameGeneric(std::move(frame), codec_header.pictureId);
return ManageFramePidOrSeqNum(std::move(frame), codec_header.pictureId);
}
frame->id.picture_id = codec_header.pictureId % kPicIdLength;
@ -396,7 +424,7 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9(
if (codec_header.picture_id == kNoPictureId ||
codec_header.temporal_idx == kNoTemporalIdx) {
return ManageFrameGeneric(std::move(frame), codec_header.picture_id);
return ManageFramePidOrSeqNum(std::move(frame), codec_header.picture_id);
}
frame->id.spatial_layer = codec_header.spatial_idx;

View File

@ -88,10 +88,15 @@ class RtpFrameReferenceFinder {
FrameDecision ManageFrameInternal(RtpFrameObject* frame)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
// Find references for generic frames. If |picture_id| is unspecified
// then packet sequence numbers will be used to determine the references
// of the frames.
FrameDecision ManageFrameGeneric(RtpFrameObject* frame, int picture_id)
FrameDecision ManageFrameGeneric(
RtpFrameObject* frame,
const RTPVideoHeader::GenericDescriptorInfo& descriptor)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
// Find references for frames with no or very limited information in the
// descriptor. If |picture_id| is unspecified then packet sequence numbers
// will be used to determine the references of the frames.
FrameDecision ManageFramePidOrSeqNum(RtpFrameObject* frame, int picture_id)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
// Find references for Vp8 frames
@ -192,9 +197,11 @@ class RtpFrameReferenceFinder {
OnCompleteFrameCallback* frame_callback_;
SeqNumUnwrapper<uint16_t> generic_frame_id_unwrapper_ RTC_GUARDED_BY(crit_);
// Unwrapper used to unwrap generic RTP streams. In a generic stream we derive
// a picture id from the packet sequence number.
SeqNumUnwrapper<uint16_t> generic_unwrapper_ RTC_GUARDED_BY(crit_);
SeqNumUnwrapper<uint16_t> rtp_seq_num_unwrapper_ RTC_GUARDED_BY(crit_);
// Unwrapper used to unwrap VP8/VP9 streams which have their picture id
// specified.