Home | History | Annotate | Download | only in source
      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/main/interface/video_coding_defines.h"
     12 #include "webrtc/modules/video_coding/main/source/encoded_frame.h"
     13 #include "webrtc/modules/video_coding/main/source/generic_encoder.h"
     14 #include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h"
     15 
     16 namespace webrtc {
     17 
     18 VCMEncodedFrame::VCMEncodedFrame()
     19 :
     20 webrtc::EncodedImage(),
     21 _renderTimeMs(-1),
     22 _payloadType(0),
     23 _missingFrame(false),
     24 _codec(kVideoCodecUnknown),
     25 _fragmentation()
     26 {
     27     _codecSpecificInfo.codecType = kVideoCodecUnknown;
     28 }
     29 
     30 VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
     31 :
     32 webrtc::EncodedImage(rhs),
     33 _renderTimeMs(-1),
     34 _payloadType(0),
     35 _missingFrame(false),
     36 _codec(kVideoCodecUnknown),
     37 _fragmentation()
     38 {
     39     _codecSpecificInfo.codecType = kVideoCodecUnknown;
     40     _buffer = NULL;
     41     _size = 0;
     42     _length = 0;
     43     if (rhs._buffer != NULL)
     44     {
     45         VerifyAndAllocate(rhs._length);
     46         memcpy(_buffer, rhs._buffer, rhs._length);
     47     }
     48 }
     49 
     50 VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
     51   :
     52     webrtc::EncodedImage(rhs),
     53     _renderTimeMs(rhs._renderTimeMs),
     54     _payloadType(rhs._payloadType),
     55     _missingFrame(rhs._missingFrame),
     56     _codecSpecificInfo(rhs._codecSpecificInfo),
     57     _codec(rhs._codec),
     58     _fragmentation() {
     59   _buffer = NULL;
     60   _size = 0;
     61   _length = 0;
     62   if (rhs._buffer != NULL)
     63   {
     64       VerifyAndAllocate(rhs._length);
     65       memcpy(_buffer, rhs._buffer, rhs._length);
     66       _length = rhs._length;
     67   }
     68   _fragmentation.CopyFrom(rhs._fragmentation);
     69 }
     70 
     71 VCMEncodedFrame::~VCMEncodedFrame()
     72 {
     73     Free();
     74 }
     75 
     76 void VCMEncodedFrame::Free()
     77 {
     78     Reset();
     79     if (_buffer != NULL)
     80     {
     81         delete [] _buffer;
     82         _buffer = NULL;
     83     }
     84 }
     85 
     86 void VCMEncodedFrame::Reset()
     87 {
     88     _renderTimeMs = -1;
     89     _timeStamp = 0;
     90     _payloadType = 0;
     91     _frameType = kDeltaFrame;
     92     _encodedWidth = 0;
     93     _encodedHeight = 0;
     94     _completeFrame = false;
     95     _missingFrame = false;
     96     _length = 0;
     97     _codecSpecificInfo.codecType = kVideoCodecUnknown;
     98     _codec = kVideoCodecUnknown;
     99 }
    100 
    101 void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header)
    102 {
    103     if (header)
    104     {
    105         switch (header->codec)
    106         {
    107             case kRtpVideoVp8:
    108             {
    109                 if (_codecSpecificInfo.codecType != kVideoCodecVP8)
    110                 {
    111                     // This is the first packet for this frame.
    112                     _codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
    113                     _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
    114                     _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
    115                     _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
    116                     _codecSpecificInfo.codecType = kVideoCodecVP8;
    117                 }
    118                 _codecSpecificInfo.codecSpecific.VP8.nonReference =
    119                     header->codecHeader.VP8.nonReference;
    120                 if (header->codecHeader.VP8.pictureId != kNoPictureId)
    121                 {
    122                     _codecSpecificInfo.codecSpecific.VP8.pictureId =
    123                         header->codecHeader.VP8.pictureId;
    124                 }
    125                 if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx)
    126                 {
    127                     _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
    128                         header->codecHeader.VP8.temporalIdx;
    129                     _codecSpecificInfo.codecSpecific.VP8.layerSync =
    130                         header->codecHeader.VP8.layerSync;
    131                 }
    132                 if (header->codecHeader.VP8.keyIdx != kNoKeyIdx)
    133                 {
    134                     _codecSpecificInfo.codecSpecific.VP8.keyIdx =
    135                         header->codecHeader.VP8.keyIdx;
    136                 }
    137                 break;
    138             }
    139             default:
    140             {
    141                 _codecSpecificInfo.codecType = kVideoCodecUnknown;
    142                 break;
    143             }
    144         }
    145     }
    146 }
    147 
    148 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
    149   return &_fragmentation;
    150 }
    151 
    152 void VCMEncodedFrame::VerifyAndAllocate(const uint32_t minimumSize)
    153 {
    154     if(minimumSize > _size)
    155     {
    156         // create buffer of sufficient size
    157         uint8_t* newBuffer = new uint8_t[minimumSize];
    158         if(_buffer)
    159         {
    160             // copy old data
    161             memcpy(newBuffer, _buffer, _size);
    162             delete [] _buffer;
    163         }
    164         _buffer = newBuffer;
    165         _size = minimumSize;
    166     }
    167 }
    168 
    169 webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
    170 {
    171   switch(frameType) {
    172     case kKeyFrame:
    173       return  kVideoFrameKey;
    174     case kDeltaFrame:
    175       return kVideoFrameDelta;
    176     case kSkipFrame:
    177       return kFrameEmpty;
    178     default:
    179       return kVideoFrameDelta;
    180   }
    181 }
    182 
    183 VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frame_type) {
    184   switch (frame_type) {
    185     case kVideoFrameKey:
    186       return kKeyFrame;
    187     case kVideoFrameDelta:
    188       return kDeltaFrame;
    189     default:
    190       assert(false);
    191       return kDeltaFrame;
    192   }
    193 }
    194 
    195 void VCMEncodedFrame::ConvertFrameTypes(
    196     const std::vector<webrtc::FrameType>& frame_types,
    197     std::vector<VideoFrameType>* video_frame_types) {
    198   assert(video_frame_types);
    199   video_frame_types->reserve(frame_types.size());
    200   for (size_t i = 0; i < frame_types.size(); ++i) {
    201     (*video_frame_types)[i] = ConvertFrameType(frame_types[i]);
    202   }
    203 }
    204 
    205 }
    206