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     switch (header->codec) {
    105       case kRtpVideoVp8: {
    106         if (_codecSpecificInfo.codecType != kVideoCodecVP8) {
    107           // This is the first packet for this frame.
    108           _codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
    109           _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
    110           _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
    111           _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
    112           _codecSpecificInfo.codecType = kVideoCodecVP8;
    113         }
    114         _codecSpecificInfo.codecSpecific.VP8.nonReference =
    115             header->codecHeader.VP8.nonReference;
    116         if (header->codecHeader.VP8.pictureId != kNoPictureId) {
    117           _codecSpecificInfo.codecSpecific.VP8.pictureId =
    118               header->codecHeader.VP8.pictureId;
    119         }
    120         if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx) {
    121           _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
    122               header->codecHeader.VP8.temporalIdx;
    123           _codecSpecificInfo.codecSpecific.VP8.layerSync =
    124               header->codecHeader.VP8.layerSync;
    125         }
    126         if (header->codecHeader.VP8.keyIdx != kNoKeyIdx) {
    127           _codecSpecificInfo.codecSpecific.VP8.keyIdx =
    128               header->codecHeader.VP8.keyIdx;
    129         }
    130         break;
    131       }
    132       case kRtpVideoH264: {
    133         _codecSpecificInfo.codecType = kVideoCodecH264;
    134         break;
    135       }
    136       default: {
    137         _codecSpecificInfo.codecType = kVideoCodecUnknown;
    138         break;
    139       }
    140     }
    141   }
    142 }
    143 
    144 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
    145   return &_fragmentation;
    146 }
    147 
    148 void VCMEncodedFrame::VerifyAndAllocate(const uint32_t minimumSize)
    149 {
    150     if(minimumSize > _size)
    151     {
    152         // create buffer of sufficient size
    153         uint8_t* newBuffer = new uint8_t[minimumSize];
    154         if(_buffer)
    155         {
    156             // copy old data
    157             memcpy(newBuffer, _buffer, _size);
    158             delete [] _buffer;
    159         }
    160         _buffer = newBuffer;
    161         _size = minimumSize;
    162     }
    163 }
    164 
    165 webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
    166 {
    167   switch(frameType) {
    168     case kKeyFrame:
    169       return  kVideoFrameKey;
    170     case kDeltaFrame:
    171       return kVideoFrameDelta;
    172     case kSkipFrame:
    173       return kFrameEmpty;
    174     default:
    175       return kVideoFrameDelta;
    176   }
    177 }
    178 
    179 VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frame_type) {
    180   switch (frame_type) {
    181     case kVideoFrameKey:
    182       return kKeyFrame;
    183     case kVideoFrameDelta:
    184       return kDeltaFrame;
    185     default:
    186       assert(false);
    187       return kDeltaFrame;
    188   }
    189 }
    190 
    191 void VCMEncodedFrame::ConvertFrameTypes(
    192     const std::vector<webrtc::FrameType>& frame_types,
    193     std::vector<VideoFrameType>* video_frame_types) {
    194   assert(video_frame_types);
    195   video_frame_types->reserve(frame_types.size());
    196   for (size_t i = 0; i < frame_types.size(); ++i) {
    197     (*video_frame_types)[i] = ConvertFrameType(frame_types[i]);
    198   }
    199 }
    200 
    201 }
    202