LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/video_coding - frame_buffer.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 137 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/video_coding/frame_buffer.h"
      12             : 
      13             : #include <assert.h>
      14             : #include <string.h>
      15             : 
      16             : #include "webrtc/base/checks.h"
      17             : #include "webrtc/base/logging.h"
      18             : #include "webrtc/modules/video_coding/packet.h"
      19             : 
      20             : namespace webrtc {
      21             : 
      22           0 : VCMFrameBuffer::VCMFrameBuffer()
      23           0 :     : _state(kStateEmpty), _nackCount(0), _latestPacketTimeMs(-1) {}
      24             : 
      25           0 : VCMFrameBuffer::~VCMFrameBuffer() {}
      26             : 
      27           0 : VCMFrameBuffer::VCMFrameBuffer(const VCMFrameBuffer& rhs)
      28             :     : VCMEncodedFrame(rhs),
      29           0 :       _state(rhs._state),
      30             :       _sessionInfo(),
      31           0 :       _nackCount(rhs._nackCount),
      32           0 :       _latestPacketTimeMs(rhs._latestPacketTimeMs) {
      33           0 :   _sessionInfo = rhs._sessionInfo;
      34           0 :   _sessionInfo.UpdateDataPointers(rhs._buffer, _buffer);
      35           0 : }
      36             : 
      37           0 : webrtc::FrameType VCMFrameBuffer::FrameType() const {
      38           0 :   return _sessionInfo.FrameType();
      39             : }
      40             : 
      41           0 : int32_t VCMFrameBuffer::GetLowSeqNum() const {
      42           0 :   return _sessionInfo.LowSequenceNumber();
      43             : }
      44             : 
      45           0 : int32_t VCMFrameBuffer::GetHighSeqNum() const {
      46           0 :   return _sessionInfo.HighSequenceNumber();
      47             : }
      48             : 
      49           0 : int VCMFrameBuffer::PictureId() const {
      50           0 :   return _sessionInfo.PictureId();
      51             : }
      52             : 
      53           0 : int VCMFrameBuffer::TemporalId() const {
      54           0 :   return _sessionInfo.TemporalId();
      55             : }
      56             : 
      57           0 : bool VCMFrameBuffer::LayerSync() const {
      58           0 :   return _sessionInfo.LayerSync();
      59             : }
      60             : 
      61           0 : int VCMFrameBuffer::Tl0PicId() const {
      62           0 :   return _sessionInfo.Tl0PicId();
      63             : }
      64             : 
      65           0 : bool VCMFrameBuffer::NonReference() const {
      66           0 :   return _sessionInfo.NonReference();
      67             : }
      68             : 
      69           0 : std::vector<NaluInfo> VCMFrameBuffer::GetNaluInfos() const {
      70           0 :   return _sessionInfo.GetNaluInfos();
      71             : }
      72             : 
      73           0 : void VCMFrameBuffer::SetGofInfo(const GofInfoVP9& gof_info, size_t idx) {
      74           0 :   _sessionInfo.SetGofInfo(gof_info, idx);
      75             :   // TODO(asapersson): Consider adding hdr->VP9.ref_picture_id for testing.
      76           0 :   _codecSpecificInfo.codecSpecific.VP9.temporal_idx =
      77           0 :       gof_info.temporal_idx[idx];
      78           0 :   _codecSpecificInfo.codecSpecific.VP9.temporal_up_switch =
      79           0 :       gof_info.temporal_up_switch[idx];
      80           0 : }
      81             : 
      82           0 : bool VCMFrameBuffer::IsSessionComplete() const {
      83           0 :   return _sessionInfo.complete();
      84             : }
      85             : 
      86             : // Insert packet
      87           0 : VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(
      88             :     const VCMPacket& packet,
      89             :     int64_t timeInMs,
      90             :     VCMDecodeErrorMode decode_error_mode,
      91             :     const FrameData& frame_data) {
      92           0 :   assert(!(NULL == packet.dataPtr && packet.sizeBytes > 0));
      93           0 :   if (packet.dataPtr != NULL) {
      94           0 :     _payloadType = packet.payloadType;
      95             :   }
      96             : 
      97           0 :   if (kStateEmpty == _state) {
      98             :     // First packet (empty and/or media) inserted into this frame.
      99             :     // store some info and set some initial values.
     100           0 :     _timeStamp = packet.timestamp;
     101             :     // We only take the ntp timestamp of the first packet of a frame.
     102           0 :     ntp_time_ms_ = packet.ntp_time_ms_;
     103           0 :     _codec = packet.codec;
     104           0 :     if (packet.frameType != kEmptyFrame) {
     105             :       // first media packet
     106           0 :       SetState(kStateIncomplete);
     107             :     }
     108             :   }
     109             : 
     110             :   // add safety margin because STAP-A packets can cause it to expand by
     111             :   // ~two bytes per NAL
     112             :   uint32_t requiredSizeBytes =
     113           0 :       Length() + packet.sizeBytes +
     114           0 :       (packet.insertStartCode ? kH264StartCodeLengthBytes : 0) +
     115           0 :       kBufferSafetyMargin +
     116           0 :       EncodedImage::GetBufferPaddingBytes(packet.codec);
     117           0 :   if (requiredSizeBytes >= _size) {
     118           0 :     const uint8_t* prevBuffer = _buffer;
     119             :     const uint32_t increments =
     120           0 :         requiredSizeBytes / kBufferIncStepSizeBytes +
     121           0 :         (requiredSizeBytes % kBufferIncStepSizeBytes > 0);
     122           0 :     const uint32_t newSize = _size + increments * kBufferIncStepSizeBytes;
     123           0 :     if (newSize > kMaxJBFrameSizeBytes) {
     124           0 :       LOG(LS_ERROR) << "Failed to insert packet due to frame being too "
     125           0 :                        "big.";
     126           0 :       return kSizeError;
     127             :     }
     128           0 :     VerifyAndAllocate(newSize);
     129           0 :     _sessionInfo.UpdateDataPointers(prevBuffer, _buffer);
     130             :   }
     131             : 
     132           0 :   if (packet.width > 0 && packet.height > 0) {
     133           0 :     _encodedWidth = packet.width;
     134           0 :     _encodedHeight = packet.height;
     135             :   }
     136             : 
     137             :   // Don't copy payload specific data for empty packets (e.g padding packets).
     138           0 :   if (packet.sizeBytes > 0)
     139           0 :     CopyCodecSpecific(&packet.video_header);
     140             : 
     141             :   int retVal =
     142           0 :       _sessionInfo.InsertPacket(packet, _buffer, decode_error_mode, frame_data);
     143           0 :   if (retVal == -1) {
     144           0 :     return kSizeError;
     145           0 :   } else if (retVal == -2) {
     146           0 :     return kDuplicatePacket;
     147           0 :   } else if (retVal == -3) {
     148           0 :     return kOutOfBoundsPacket;
     149             :   }
     150             :   // update length
     151           0 :   _length = Length() + static_cast<uint32_t>(retVal);
     152             : 
     153           0 :   _latestPacketTimeMs = timeInMs;
     154             : 
     155             :   // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/
     156             :   // ts_126114v120700p.pdf Section 7.4.5.
     157             :   // The MTSI client shall add the payload bytes as defined in this clause
     158             :   // onto the last RTP packet in each group of packets which make up a key
     159             :   // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265
     160             :   // (HEVC)).
     161           0 :   if (packet.markerBit) {
     162             :     //RTC_DCHECK(!_rotation_set);
     163           0 :     rotation_ = packet.video_header.rotation;
     164           0 :     _rotation_set = true;
     165             :   }
     166             : 
     167           0 :   if (packet.is_first_packet_in_frame) {
     168           0 :     playout_delay_ = packet.video_header.playout_delay;
     169             :   }
     170             : 
     171           0 :   if (_sessionInfo.complete()) {
     172           0 :     SetState(kStateComplete);
     173           0 :     return kCompleteSession;
     174           0 :   } else if (_sessionInfo.decodable()) {
     175           0 :     SetState(kStateDecodable);
     176           0 :     return kDecodableSession;
     177             :   }
     178           0 :   return kIncomplete;
     179             : }
     180             : 
     181           0 : int64_t VCMFrameBuffer::LatestPacketTimeMs() const {
     182           0 :   return _latestPacketTimeMs;
     183             : }
     184             : 
     185           0 : void VCMFrameBuffer::IncrementNackCount() {
     186           0 :   _nackCount++;
     187           0 : }
     188             : 
     189           0 : int16_t VCMFrameBuffer::GetNackCount() const {
     190           0 :   return _nackCount;
     191             : }
     192             : 
     193           0 : bool VCMFrameBuffer::HaveFirstPacket() const {
     194           0 :   return _sessionInfo.HaveFirstPacket();
     195             : }
     196             : 
     197           0 : bool VCMFrameBuffer::HaveLastPacket() const {
     198           0 :   return _sessionInfo.HaveLastPacket();
     199             : }
     200             : 
     201           0 : int VCMFrameBuffer::NumPackets() const {
     202           0 :   return _sessionInfo.NumPackets();
     203             : }
     204             : 
     205           0 : void VCMFrameBuffer::Reset() {
     206           0 :   _length = 0;
     207           0 :   _timeStamp = 0;
     208           0 :   _sessionInfo.Reset();
     209           0 :   _payloadType = 0;
     210           0 :   _nackCount = 0;
     211           0 :   _latestPacketTimeMs = -1;
     212           0 :   _state = kStateEmpty;
     213           0 :   VCMEncodedFrame::Reset();
     214           0 : }
     215             : 
     216             : // Set state of frame
     217           0 : void VCMFrameBuffer::SetState(VCMFrameBufferStateEnum state) {
     218           0 :   if (_state == state) {
     219           0 :     return;
     220             :   }
     221           0 :   switch (state) {
     222             :     case kStateIncomplete:
     223             :       // we can go to this state from state kStateEmpty
     224           0 :       assert(_state == kStateEmpty);
     225             : 
     226             :       // Do nothing, we received a packet
     227           0 :       break;
     228             : 
     229             :     case kStateComplete:
     230           0 :       assert(_state == kStateEmpty || _state == kStateIncomplete ||
     231             :              _state == kStateDecodable);
     232             : 
     233           0 :       break;
     234             : 
     235             :     case kStateEmpty:
     236             :       // Should only be set to empty through Reset().
     237           0 :       assert(false);
     238             :       break;
     239             : 
     240             :     case kStateDecodable:
     241           0 :       assert(_state == kStateEmpty || _state == kStateIncomplete);
     242           0 :       break;
     243             :   }
     244           0 :   _state = state;
     245             : }
     246             : 
     247             : // Get current state of frame
     248           0 : VCMFrameBufferStateEnum VCMFrameBuffer::GetState() const {
     249           0 :   return _state;
     250             : }
     251             : 
     252             : // Get current state of frame
     253           0 : VCMFrameBufferStateEnum VCMFrameBuffer::GetState(uint32_t& timeStamp) const {
     254           0 :   timeStamp = TimeStamp();
     255           0 :   return GetState();
     256             : }
     257             : 
     258           0 : bool VCMFrameBuffer::IsRetransmitted() const {
     259           0 :   return _sessionInfo.session_nack();
     260             : }
     261             : 
     262           0 : void VCMFrameBuffer::PrepareForDecode(bool continuous) {
     263           0 :   size_t bytes_removed = _sessionInfo.MakeDecodable();
     264           0 :   _length -= bytes_removed;
     265             :   // Transfer frame information to EncodedFrame and create any codec
     266             :   // specific information.
     267           0 :   _frameType = _sessionInfo.FrameType();
     268           0 :   _completeFrame = _sessionInfo.complete();
     269           0 :   _missingFrame = !continuous;
     270           0 : }
     271             : 
     272             : }  // namespace webrtc

Generated by: LCOV version 1.13