ManageFrame
ManageFrameInternal
enum VideoCodecType {
// There are various memset(..., 0, ...) calls in the code that rely on
// kVideoCodecGeneric being zero.
kVideoCodecGeneric = 0,
kVideoCodecVP8,
kVideoCodecVP9,
kVideoCodecAV1,
kVideoCodecH264,
kVideoCodecMultiplex,
};
RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinderImpl::ManageFrame(
std::unique_ptr<RtpFrameObject> frame) {
const RTPVideoHeader& video_header = frame->GetRtpVideoHeader();
if (video_header.generic.has_value()) {
return GetRefFinderAs<RtpGenericFrameRefFinder>().ManageFrame(
std::move(frame), *video_header.generic);
}
switch (frame->codec_type()) {
case kVideoCodecVP8: {
const RTPVideoHeaderVP8& vp8_header =
absl::get<RTPVideoHeaderVP8>(video_header.video_type_header);
if (vp8_header.temporalIdx == kNoTemporalIdx ||
vp8_header.tl0PicIdx == kNoTl0PicIdx) {
if (vp8_header.pictureId == kNoPictureId) {
return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
std::move(frame));
}
return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
std::move(frame), vp8_header.pictureId);
}
return GetRefFinderAs<RtpVp8RefFinder>().ManageFrame(std::move(frame));
}
case kVideoCodecVP9: {
const RTPVideoHeaderVP9& vp9_header =
absl::get<RTPVideoHeaderVP9>(video_header.video_type_header);
if (vp9_header.temporal_idx == kNoTemporalIdx) {
if (vp9_header.picture_id == kNoPictureId) {
return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
std::move(frame));
}
return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
std::move(frame), vp9_header.picture_id);
}
return GetRefFinderAs<RtpVp9RefFinder>().ManageFrame(std::move(frame));
}
case kVideoCodecGeneric: {
if (auto* generic_header = absl::get_if<RTPVideoHeaderLegacyGeneric>(
&video_header.video_type_header)) {
return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
std::move(frame), generic_header->picture_id);
}
return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
std::move(frame));
}
default: {
return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
std::move(frame));
}
}
}
ManageFrameVp8
temporalIdx SVC分层的时域 的索引值
il0PicIdx : 时域层的第0层的pictureId索引值
如果不开启vp8的svc分层,则il0PicIdx 不存在。默认不开启。
ManageFramePidOrSeqNum
正常,获取到vp8的参考帧。 kHandOff代表找到了参考帧。
再看ManageFrame
RetryStashedFrames 判断缓存的stashedframe是否有某个帧找到了参考帧。
RtpFrameReferenceFinder::ReturnVector RtpSeqNumOnlyRefFinder::ManageFrame(
std::unique_ptr<RtpFrameObject> frame) {
FrameDecision decision = ManageFrameInternal(frame.get());
RtpFrameReferenceFinder::ReturnVector res;
switch (decision) {
case kStash:
if (stashed_frames_.size() > kMaxStashedFrames)
stashed_frames_.pop_back();
stashed_frames_.push_front(std::move(frame));
return res;
case kHandOff:
res.push_back(std::move(frame));
RetryStashedFrames(res);
return res;
case kDrop:
return res;
}
return res;
}
void RtpSeqNumOnlyRefFinder::RetryStashedFrames(
RtpFrameReferenceFinder::ReturnVector& res) {
bool complete_frame = false;
do {
complete_frame = false;
for (auto frame_it = stashed_frames_.begin();
frame_it != stashed_frames_.end();) {
FrameDecision decision = ManageFrameInternal(frame_it->get());
switch (decision) {
case kStash:
++frame_it;
break;
case kHandOff:
complete_frame = true;
res.push_back(std::move(*frame_it));
ABSL_FALLTHROUGH_INTENDED;
case kDrop:
frame_it = stashed_frames_.erase(frame_it);
}
}
} while (complete_frame);
}