diff options
Diffstat (limited to 'webrtc/modules/video_coding/session_info.h')
-rw-r--r-- | webrtc/modules/video_coding/session_info.h | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/webrtc/modules/video_coding/session_info.h b/webrtc/modules/video_coding/session_info.h new file mode 100644 index 0000000000..e9ff25166d --- /dev/null +++ b/webrtc/modules/video_coding/session_info.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2011 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 WEBRTC_MODULES_VIDEO_CODING_SESSION_INFO_H_ +#define WEBRTC_MODULES_VIDEO_CODING_SESSION_INFO_H_ + +#include <list> + +#include "webrtc/modules/include/module_common_types.h" +#include "webrtc/modules/video_coding/include/video_coding.h" +#include "webrtc/modules/video_coding/packet.h" +#include "webrtc/typedefs.h" + +namespace webrtc { +// Used to pass data from jitter buffer to session info. +// This data is then used in determining whether a frame is decodable. +struct FrameData { + int64_t rtt_ms; + float rolling_average_packets_per_frame; +}; + +class VCMSessionInfo { + public: + VCMSessionInfo(); + + void UpdateDataPointers(const uint8_t* old_base_ptr, + const uint8_t* new_base_ptr); + // NACK - Building the NACK lists. + // Build hard NACK list: Zero out all entries in list up to and including + // _lowSeqNum. + int BuildHardNackList(int* seq_num_list, + int seq_num_list_length, + int nack_seq_nums_index); + + // Build soft NACK list: Zero out only a subset of the packets, discard + // empty packets. + int BuildSoftNackList(int* seq_num_list, + int seq_num_list_length, + int nack_seq_nums_index, + int rtt_ms); + void Reset(); + int InsertPacket(const VCMPacket& packet, + uint8_t* frame_buffer, + VCMDecodeErrorMode enable_decodable_state, + const FrameData& frame_data); + bool complete() const; + bool decodable() const; + + // Builds fragmentation headers for VP8, each fragment being a decodable + // VP8 partition. Returns the total number of bytes which are decodable. Is + // used instead of MakeDecodable for VP8. + size_t BuildVP8FragmentationHeader(uint8_t* frame_buffer, + size_t frame_buffer_length, + RTPFragmentationHeader* fragmentation); + + // Makes the frame decodable. I.e., only contain decodable NALUs. All + // non-decodable NALUs will be deleted and packets will be moved to in + // memory to remove any empty space. + // Returns the number of bytes deleted from the session. + size_t MakeDecodable(); + + // Sets decodable_ to false. + // Used by the dual decoder. After the mode is changed to kNoErrors from + // kWithErrors or kSelective errors, any states that have been marked + // decodable and are not complete are marked as non-decodable. + void SetNotDecodableIfIncomplete(); + + size_t SessionLength() const; + int NumPackets() const; + bool HaveFirstPacket() const; + bool HaveLastPacket() const; + bool session_nack() const; + webrtc::FrameType FrameType() const { return frame_type_; } + int LowSequenceNumber() const; + + // Returns highest sequence number, media or empty. + int HighSequenceNumber() const; + int PictureId() const; + int TemporalId() const; + bool LayerSync() const; + int Tl0PicId() const; + bool NonReference() const; + + void SetGofInfo(const GofInfoVP9& gof_info, size_t idx); + + // The number of packets discarded because the decoder can't make use of + // them. + int packets_not_decodable() const; + + private: + enum { kMaxVP8Partitions = 9 }; + + typedef std::list<VCMPacket> PacketList; + typedef PacketList::iterator PacketIterator; + typedef PacketList::const_iterator PacketIteratorConst; + typedef PacketList::reverse_iterator ReversePacketIterator; + + void InformOfEmptyPacket(uint16_t seq_num); + + // Finds the packet of the beginning of the next VP8 partition. If + // none is found the returned iterator points to |packets_.end()|. + // |it| is expected to point to the last packet of the previous partition, + // or to the first packet of the frame. |packets_skipped| is incremented + // for each packet found which doesn't have the beginning bit set. + PacketIterator FindNextPartitionBeginning(PacketIterator it) const; + + // Returns an iterator pointing to the last packet of the partition pointed to + // by |it|. + PacketIterator FindPartitionEnd(PacketIterator it) const; + static bool InSequence(const PacketIterator& it, + const PacketIterator& prev_it); + size_t InsertBuffer(uint8_t* frame_buffer, PacketIterator packetIterator); + size_t Insert(const uint8_t* buffer, + size_t length, + bool insert_start_code, + uint8_t* frame_buffer); + void ShiftSubsequentPackets(PacketIterator it, int steps_to_shift); + PacketIterator FindNaluEnd(PacketIterator packet_iter) const; + // Deletes the data of all packets between |start| and |end|, inclusively. + // Note that this function doesn't delete the actual packets. + size_t DeletePacketData(PacketIterator start, PacketIterator end); + void UpdateCompleteSession(); + + // When enabled, determine if session is decodable, i.e. incomplete but + // would be sent to the decoder. + // Note: definition assumes random loss. + // A frame is defined to be decodable when: + // Round trip time is higher than threshold + // It is not a key frame + // It has the first packet: In VP8 the first packet contains all or part of + // the first partition, which consists of the most relevant information for + // decoding. + // Either more than the upper threshold of the average number of packets per + // frame is present + // or less than the lower threshold of the average number of packets per + // frame is present: suggests a small frame. Such a frame is unlikely + // to contain many motion vectors, so having the first packet will + // likely suffice. Once we have more than the lower threshold of the + // frame, we know that the frame is medium or large-sized. + void UpdateDecodableSession(const FrameData& frame_data); + + // If this session has been NACKed by the jitter buffer. + bool session_nack_; + bool complete_; + bool decodable_; + webrtc::FrameType frame_type_; + // Packets in this frame. + PacketList packets_; + int empty_seq_num_low_; + int empty_seq_num_high_; + + // The following two variables correspond to the first and last media packets + // in a session defined by the first packet flag and the marker bit. + // They are not necessarily equal to the front and back packets, as packets + // may enter out of order. + // TODO(mikhal): Refactor the list to use a map. + int first_packet_seq_num_; + int last_packet_seq_num_; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_VIDEO_CODING_SESSION_INFO_H_ |