/*
 *  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(kVideoRotation_0),
      _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(kVideoRotation_0),
      _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(rhs._rotation),
      _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
