mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00

The packets belonging to a frame were kept in PacketBuffer until the frame was decoded. This CL clears the dependencies of an existing RtpFrameObject to PacketBuffer so that we can free up PacketBuffer as soon as the RtpFrameObject is created. Bug: none Change-Id: Ic939be91815519ae1d1c67ada82006417b2d26a3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/149818 Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Johannes Kron <kron@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28977}
190 lines
6.4 KiB
C++
190 lines
6.4 KiB
C++
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef MODULES_VIDEO_CODING_PACKET_BUFFER_H_
|
|
#define MODULES_VIDEO_CODING_PACKET_BUFFER_H_
|
|
|
|
#include <memory>
|
|
#include <queue>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
#include "api/scoped_refptr.h"
|
|
#include "modules/include/module_common_types.h"
|
|
#include "modules/video_coding/packet.h"
|
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
|
#include "rtc_base/critical_section.h"
|
|
#include "rtc_base/numerics/sequence_number_util.h"
|
|
#include "rtc_base/thread_annotations.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class Clock;
|
|
|
|
namespace video_coding {
|
|
|
|
class RtpFrameObject;
|
|
|
|
// A frame is assembled when all of its packets have been received.
|
|
class OnAssembledFrameCallback {
|
|
public:
|
|
virtual ~OnAssembledFrameCallback() {}
|
|
virtual void OnAssembledFrame(std::unique_ptr<RtpFrameObject> frame) = 0;
|
|
};
|
|
|
|
class PacketBuffer {
|
|
public:
|
|
static rtc::scoped_refptr<PacketBuffer> Create(
|
|
Clock* clock,
|
|
size_t start_buffer_size,
|
|
size_t max_buffer_size,
|
|
OnAssembledFrameCallback* frame_callback);
|
|
|
|
virtual ~PacketBuffer();
|
|
|
|
// Returns true unless the packet buffer is cleared, which means that a key
|
|
// frame request should be sent. The PacketBuffer will always take ownership
|
|
// of the |packet.dataPtr| when this function is called. Made virtual for
|
|
// testing.
|
|
virtual bool InsertPacket(VCMPacket* packet);
|
|
void ClearTo(uint16_t seq_num);
|
|
void Clear();
|
|
void PaddingReceived(uint16_t seq_num);
|
|
|
|
// Timestamp (not RTP timestamp) of the last received packet/keyframe packet.
|
|
absl::optional<int64_t> LastReceivedPacketMs() const;
|
|
absl::optional<int64_t> LastReceivedKeyframePacketMs() const;
|
|
|
|
// Returns number of different frames seen in the packet buffer
|
|
int GetUniqueFramesSeen() const;
|
|
|
|
int AddRef() const;
|
|
int Release() const;
|
|
|
|
protected:
|
|
// Both |start_buffer_size| and |max_buffer_size| must be a power of 2.
|
|
PacketBuffer(Clock* clock,
|
|
size_t start_buffer_size,
|
|
size_t max_buffer_size,
|
|
OnAssembledFrameCallback* frame_callback);
|
|
|
|
private:
|
|
friend RtpFrameObject;
|
|
// Since we want the packet buffer to be as packet type agnostic
|
|
// as possible we extract only the information needed in order
|
|
// to determine whether a sequence of packets is continuous or not.
|
|
struct ContinuityInfo {
|
|
// The sequence number of the packet.
|
|
uint16_t seq_num = 0;
|
|
|
|
// If this is the first packet of the frame.
|
|
bool frame_begin = false;
|
|
|
|
// If this is the last packet of the frame.
|
|
bool frame_end = false;
|
|
|
|
// If this slot is currently used.
|
|
bool used = false;
|
|
|
|
// If all its previous packets have been inserted into the packet buffer.
|
|
bool continuous = false;
|
|
|
|
// If this packet has been used to create a frame already.
|
|
bool frame_created = false;
|
|
};
|
|
|
|
Clock* const clock_;
|
|
|
|
// Tries to expand the buffer.
|
|
bool ExpandBufferSize() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
// Test if all previous packets has arrived for the given sequence number.
|
|
bool PotentialNewFrame(uint16_t seq_num) const
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
// Test if all packets of a frame has arrived, and if so, creates a frame.
|
|
// Returns a vector of received frames.
|
|
std::vector<std::unique_ptr<RtpFrameObject>> FindFrames(uint16_t seq_num)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
// Copy the bitstream for |frame| to |destination|.
|
|
// Virtual for testing.
|
|
virtual bool GetBitstream(const RtpFrameObject& frame, uint8_t* destination);
|
|
|
|
// Get the packet with sequence number |seq_num|.
|
|
// Virtual for testing.
|
|
virtual VCMPacket* GetPacket(uint16_t seq_num)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
// Clears the packet buffer from |start_seq_num| to |stop_seq_num| where the
|
|
// endpoints are inclusive.
|
|
void ClearInterval(uint16_t start_seq_num, uint16_t stop_seq_num)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
void UpdateMissingPackets(uint16_t seq_num)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
// Counts unique received timestamps and updates |unique_frames_seen_|.
|
|
void OnTimestampReceived(uint32_t rtp_timestamp)
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
|
|
|
rtc::CriticalSection crit_;
|
|
|
|
// Buffer size_ and max_size_ must always be a power of two.
|
|
size_t size_ RTC_GUARDED_BY(crit_);
|
|
const size_t max_size_;
|
|
|
|
// The fist sequence number currently in the buffer.
|
|
uint16_t first_seq_num_ RTC_GUARDED_BY(crit_);
|
|
|
|
// If the packet buffer has received its first packet.
|
|
bool first_packet_received_ RTC_GUARDED_BY(crit_);
|
|
|
|
// If the buffer is cleared to |first_seq_num_|.
|
|
bool is_cleared_to_first_seq_num_ RTC_GUARDED_BY(crit_);
|
|
|
|
// Buffer that holds the inserted packets.
|
|
std::vector<VCMPacket> data_buffer_ RTC_GUARDED_BY(crit_);
|
|
|
|
// Buffer that holds the information about which slot that is currently in use
|
|
// and information needed to determine the continuity between packets.
|
|
std::vector<ContinuityInfo> sequence_buffer_ RTC_GUARDED_BY(crit_);
|
|
|
|
// Called when all packets in a frame are received, allowing the frame
|
|
// to be assembled.
|
|
OnAssembledFrameCallback* const assembled_frame_callback_;
|
|
|
|
// Timestamp (not RTP timestamp) of the last received packet/keyframe packet.
|
|
absl::optional<int64_t> last_received_packet_ms_ RTC_GUARDED_BY(crit_);
|
|
absl::optional<int64_t> last_received_keyframe_packet_ms_
|
|
RTC_GUARDED_BY(crit_);
|
|
|
|
int unique_frames_seen_ RTC_GUARDED_BY(crit_);
|
|
|
|
absl::optional<uint16_t> newest_inserted_seq_num_ RTC_GUARDED_BY(crit_);
|
|
std::set<uint16_t, DescendingSeqNumComp<uint16_t>> missing_packets_
|
|
RTC_GUARDED_BY(crit_);
|
|
|
|
// Indicates if we should require SPS, PPS, and IDR for a particular
|
|
// RTP timestamp to treat the corresponding frame as a keyframe.
|
|
const bool sps_pps_idr_is_h264_keyframe_;
|
|
|
|
// Stores several last seen unique timestamps for quick search.
|
|
std::set<uint32_t> rtp_timestamps_history_set_ RTC_GUARDED_BY(crit_);
|
|
// Stores the same unique timestamps in the order of insertion.
|
|
std::queue<uint32_t> rtp_timestamps_history_queue_ RTC_GUARDED_BY(crit_);
|
|
|
|
mutable volatile int ref_count_ = 0;
|
|
};
|
|
|
|
} // namespace video_coding
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_VIDEO_CODING_PACKET_BUFFER_H_
|