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