/*
 *  Copyright (c) 2012 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.
 */

#include "webrtc/modules/video_coding/include/video_coding_defines.h"
#include "webrtc/modules/video_coding/encoded_frame.h"
#include "webrtc/modules/video_coding/generic_encoder.h"
#include "webrtc/modules/video_coding/jitter_buffer_common.h"

namespace webrtc {

VCMEncodedFrame::VCMEncodedFrame()
    : webrtc::EncodedImage(),
      _renderTimeMs(-1),
      _payloadType(0),
      _missingFrame(false),
      _codec(kVideoCodecUnknown),
      _fragmentation(),
      _rotation_set(false) {
  _codecSpecificInfo.codecType = kVideoCodecUnknown;
}

VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
    : webrtc::EncodedImage(rhs),
      _renderTimeMs(-1),
      _payloadType(0),
      _missingFrame(false),
      _codec(kVideoCodecUnknown),
      _fragmentation(),
      _rotation_set(false) {
  _codecSpecificInfo.codecType = kVideoCodecUnknown;
  _buffer = NULL;
  _size = 0;
  _length = 0;
  if (rhs._buffer != NULL) {
    VerifyAndAllocate(rhs._length +
                      EncodedImage::GetBufferPaddingBytes(_codec));
    memcpy(_buffer, rhs._buffer, rhs._length);
  }
}

VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
    : webrtc::EncodedImage(rhs),
      _renderTimeMs(rhs._renderTimeMs),
      _payloadType(rhs._payloadType),
      _missingFrame(rhs._missingFrame),
      _codecSpecificInfo(rhs._codecSpecificInfo),
      _codec(rhs._codec),
      _fragmentation(),
      _rotation_set(rhs._rotation_set) {
  _buffer = NULL;
  _size = 0;
  _length = 0;
  if (rhs._buffer != NULL) {
    VerifyAndAllocate(rhs._length +
                      EncodedImage::GetBufferPaddingBytes(_codec));
    memcpy(_buffer, rhs._buffer, rhs._length);
    _length = rhs._length;
  }
  _fragmentation.CopyFrom(rhs._fragmentation);
}

VCMEncodedFrame::~VCMEncodedFrame() {
  Free();
}

void VCMEncodedFrame::Free() {
  Reset();
  if (_buffer != NULL) {
    delete[] _buffer;
    _buffer = NULL;
  }
}

void VCMEncodedFrame::Reset() {
  _renderTimeMs = -1;
  _timeStamp = 0;
  _payloadType = 0;
  _frameType = kVideoFrameDelta;
  _encodedWidth = 0;
  _encodedHeight = 0;
  _completeFrame = false;
  _missingFrame = false;
  _length = 0;
  _codecSpecificInfo.codecType = kVideoCodecUnknown;
  _codec = kVideoCodecUnknown;
  rotation_ = kVideoRotation_0;
  _rotation_set = false;
}

void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) {
  if (header) {
    switch (header->codec) {
      case kRtpVideoVp8: {
        if (_codecSpecificInfo.codecType != kVideoCodecVP8) {
          // This is the first packet for this frame.
          _codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
          _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
          _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
          _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
          _codecSpecificInfo.codecType = kVideoCodecVP8;
        }
        _codecSpecificInfo.codecSpecific.VP8.nonReference =
            header->codecHeader.VP8.nonReference;
        if (header->codecHeader.VP8.pictureId != kNoPictureId) {
          _codecSpecificInfo.codecSpecific.VP8.pictureId =
              header->codecHeader.VP8.pictureId;
        }
        if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx) {
          _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
              header->codecHeader.VP8.temporalIdx;
          _codecSpecificInfo.codecSpecific.VP8.layerSync =
              header->codecHeader.VP8.layerSync;
        }
        if (header->codecHeader.VP8.keyIdx != kNoKeyIdx) {
          _codecSpecificInfo.codecSpecific.VP8.keyIdx =
              header->codecHeader.VP8.keyIdx;
        }
        break;
      }
      case kRtpVideoVp9: {
        if (_codecSpecificInfo.codecType != kVideoCodecVP9) {
          // This is the first packet for this frame.
          _codecSpecificInfo.codecSpecific.VP9.picture_id = -1;
          _codecSpecificInfo.codecSpecific.VP9.temporal_idx = 0;
          _codecSpecificInfo.codecSpecific.VP9.spatial_idx = 0;
          _codecSpecificInfo.codecSpecific.VP9.gof_idx = 0;
          _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted = false;
          _codecSpecificInfo.codecSpecific.VP9.tl0_pic_idx = -1;
          _codecSpecificInfo.codecType = kVideoCodecVP9;
        }
        _codecSpecificInfo.codecSpecific.VP9.inter_pic_predicted =
            header->codecHeader.VP9.inter_pic_predicted;
        _codecSpecificInfo.codecSpecific.VP9.flexible_mode =
            header->codecHeader.VP9.flexible_mode;
        _codecSpecificInfo.codecSpecific.VP9.num_ref_pics =
            header->codecHeader.VP9.num_ref_pics;
        for (uint8_t r = 0; r < header->codecHeader.VP9.num_ref_pics; ++r) {
          _codecSpecificInfo.codecSpecific.VP9.p_diff[r] =
              header->codecHeader.VP9.pid_diff[r];
        }
        _codecSpecificInfo.codecSpecific.VP9.ss_data_available =
            header->codecHeader.VP9.ss_data_available;
        if (header->codecHeader.VP9.picture_id != kNoPictureId) {
          _codecSpecificInfo.codecSpecific.VP9.picture_id =
              header->codecHeader.VP9.picture_id;
        }
        if (header->codecHeader.VP9.tl0_pic_idx != kNoTl0PicIdx) {
          _codecSpecificInfo.codecSpecific.VP9.tl0_pic_idx =
              header->codecHeader.VP9.tl0_pic_idx;
        }
        if (header->codecHeader.VP9.temporal_idx != kNoTemporalIdx) {
          _codecSpecificInfo.codecSpecific.VP9.temporal_idx =
              header->codecHeader.VP9.temporal_idx;
          _codecSpecificInfo.codecSpecific.VP9.temporal_up_switch =
              header->codecHeader.VP9.temporal_up_switch;
        }
        if (header->codecHeader.VP9.spatial_idx != kNoSpatialIdx) {
          _codecSpecificInfo.codecSpecific.VP9.spatial_idx =
              header->codecHeader.VP9.spatial_idx;
          _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted =
              header->codecHeader.VP9.inter_layer_predicted;
        }
        if (header->codecHeader.VP9.gof_idx != kNoGofIdx) {
          _codecSpecificInfo.codecSpecific.VP9.gof_idx =
              header->codecHeader.VP9.gof_idx;
        }
        if (header->codecHeader.VP9.ss_data_available) {
          _codecSpecificInfo.codecSpecific.VP9.num_spatial_layers =
              header->codecHeader.VP9.num_spatial_layers;
          _codecSpecificInfo.codecSpecific.VP9
              .spatial_layer_resolution_present =
              header->codecHeader.VP9.spatial_layer_resolution_present;
          if (header->codecHeader.VP9.spatial_layer_resolution_present) {
            for (size_t i = 0; i < header->codecHeader.VP9.num_spatial_layers;
                 ++i) {
              _codecSpecificInfo.codecSpecific.VP9.width[i] =
                  header->codecHeader.VP9.width[i];
              _codecSpecificInfo.codecSpecific.VP9.height[i] =
                  header->codecHeader.VP9.height[i];
            }
          }
          _codecSpecificInfo.codecSpecific.VP9.gof.CopyGofInfoVP9(
              header->codecHeader.VP9.gof);
        }
        break;
      }
      case kRtpVideoH264: {
        _codecSpecificInfo.codecType = kVideoCodecH264;
        break;
      }
      default: {
        _codecSpecificInfo.codecType = kVideoCodecUnknown;
        break;
      }
    }
  }
}

const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
  return &_fragmentation;
}

void VCMEncodedFrame::VerifyAndAllocate(size_t minimumSize) {
  if (minimumSize > _size) {
    // create buffer of sufficient size
    uint8_t* newBuffer = new uint8_t[minimumSize];
    if (_buffer) {
      // copy old data
      memcpy(newBuffer, _buffer, _size);
      delete[] _buffer;
    }
    _buffer = newBuffer;
    _size = minimumSize;
  }
}

}  // namespace webrtc
