image.png

ManageFrame

image.png

ManageFrameInternal

image.png

  1. enum VideoCodecType {
  2. // There are various memset(..., 0, ...) calls in the code that rely on
  3. // kVideoCodecGeneric being zero.
  4. kVideoCodecGeneric = 0,
  5. kVideoCodecVP8,
  6. kVideoCodecVP9,
  7. kVideoCodecAV1,
  8. kVideoCodecH264,
  9. kVideoCodecMultiplex,
  10. };
  11. RtpFrameReferenceFinder::ReturnVector RtpFrameReferenceFinderImpl::ManageFrame(
  12. std::unique_ptr<RtpFrameObject> frame) {
  13. const RTPVideoHeader& video_header = frame->GetRtpVideoHeader();
  14. if (video_header.generic.has_value()) {
  15. return GetRefFinderAs<RtpGenericFrameRefFinder>().ManageFrame(
  16. std::move(frame), *video_header.generic);
  17. }
  18. switch (frame->codec_type()) {
  19. case kVideoCodecVP8: {
  20. const RTPVideoHeaderVP8& vp8_header =
  21. absl::get<RTPVideoHeaderVP8>(video_header.video_type_header);
  22. if (vp8_header.temporalIdx == kNoTemporalIdx ||
  23. vp8_header.tl0PicIdx == kNoTl0PicIdx) {
  24. if (vp8_header.pictureId == kNoPictureId) {
  25. return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
  26. std::move(frame));
  27. }
  28. return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
  29. std::move(frame), vp8_header.pictureId);
  30. }
  31. return GetRefFinderAs<RtpVp8RefFinder>().ManageFrame(std::move(frame));
  32. }
  33. case kVideoCodecVP9: {
  34. const RTPVideoHeaderVP9& vp9_header =
  35. absl::get<RTPVideoHeaderVP9>(video_header.video_type_header);
  36. if (vp9_header.temporal_idx == kNoTemporalIdx) {
  37. if (vp9_header.picture_id == kNoPictureId) {
  38. return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
  39. std::move(frame));
  40. }
  41. return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
  42. std::move(frame), vp9_header.picture_id);
  43. }
  44. return GetRefFinderAs<RtpVp9RefFinder>().ManageFrame(std::move(frame));
  45. }
  46. case kVideoCodecGeneric: {
  47. if (auto* generic_header = absl::get_if<RTPVideoHeaderLegacyGeneric>(
  48. &video_header.video_type_header)) {
  49. return GetRefFinderAs<RtpFrameIdOnlyRefFinder>().ManageFrame(
  50. std::move(frame), generic_header->picture_id);
  51. }
  52. return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
  53. std::move(frame));
  54. }
  55. default: {
  56. return GetRefFinderAs<RtpSeqNumOnlyRefFinder>().ManageFrame(
  57. std::move(frame));
  58. }
  59. }
  60. }

可见H264编码方式的话会跑到default项。。

ManageFrameVp8

image.png
temporalIdx SVC分层的时域 的索引值
il0PicIdx : 时域层的第0层的pictureId索引值
如果不开启vp8的svc分层,则il0PicIdx 不存在。默认不开启。

ManageFramePidOrSeqNum

image.png
正常,获取到vp8的参考帧。 kHandOff代表找到了参考帧。

再看ManageFrame

image.png
RetryStashedFrames 判断缓存的stashedframe是否有某个帧找到了参考帧。

  1. RtpFrameReferenceFinder::ReturnVector RtpSeqNumOnlyRefFinder::ManageFrame(
  2. std::unique_ptr<RtpFrameObject> frame) {
  3. FrameDecision decision = ManageFrameInternal(frame.get());
  4. RtpFrameReferenceFinder::ReturnVector res;
  5. switch (decision) {
  6. case kStash:
  7. if (stashed_frames_.size() > kMaxStashedFrames)
  8. stashed_frames_.pop_back();
  9. stashed_frames_.push_front(std::move(frame));
  10. return res;
  11. case kHandOff:
  12. res.push_back(std::move(frame));
  13. RetryStashedFrames(res);
  14. return res;
  15. case kDrop:
  16. return res;
  17. }
  18. return res;
  19. }
  20. void RtpSeqNumOnlyRefFinder::RetryStashedFrames(
  21. RtpFrameReferenceFinder::ReturnVector& res) {
  22. bool complete_frame = false;
  23. do {
  24. complete_frame = false;
  25. for (auto frame_it = stashed_frames_.begin();
  26. frame_it != stashed_frames_.end();) {
  27. FrameDecision decision = ManageFrameInternal(frame_it->get());
  28. switch (decision) {
  29. case kStash:
  30. ++frame_it;
  31. break;
  32. case kHandOff:
  33. complete_frame = true;
  34. res.push_back(std::move(*frame_it));
  35. ABSL_FALLTHROUGH_INTENDED;
  36. case kDrop:
  37. frame_it = stashed_frames_.erase(frame_it);
  38. }
  39. }
  40. } while (complete_frame);
  41. }