// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CDM_CDM_HELPERS_H_
#define MEDIA_CDM_CDM_HELPERS_H_

#include <stdint.h>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "media/cdm/api/content_decryption_module.h"

#if !defined(USE_PPAPI_CDM_ADAPTER)
#include "base/memory/ref_counted.h"
#include "media/base/media_export.h"
#include "ui/gfx/geometry/size.h"
#define MEDIA_CDM_EXPORT MEDIA_EXPORT
#else
#define MEDIA_CDM_EXPORT
#endif

namespace media {

class VideoFrame;

class DecryptedBlockImpl : public cdm::DecryptedBlock {
 public:
  DecryptedBlockImpl();
  ~DecryptedBlockImpl() final;

  // cdm::DecryptedBlock implementation.
  void SetDecryptedBuffer(cdm::Buffer* buffer) final;
  cdm::Buffer* DecryptedBuffer() final;
  void SetTimestamp(int64_t timestamp) final;
  int64_t Timestamp() const final;

 private:
  cdm::Buffer* buffer_;
  int64_t timestamp_;

  DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl);
};

class MEDIA_CDM_EXPORT VideoFrameImpl
    : NON_EXPORTED_BASE(public cdm::VideoFrame) {
 public:
  VideoFrameImpl();
  ~VideoFrameImpl() override;

  // cdm::VideoFrame implementation.
  void SetFormat(cdm::VideoFormat format) final;
  cdm::VideoFormat Format() const final;
  void SetSize(cdm::Size size) final;
  cdm::Size Size() const final;
  void SetFrameBuffer(cdm::Buffer* frame_buffer) final;
  cdm::Buffer* FrameBuffer() final;
  void SetPlaneOffset(cdm::VideoFrame::VideoPlane plane, uint32_t offset) final;
  uint32_t PlaneOffset(VideoPlane plane) final;
  void SetStride(VideoPlane plane, uint32_t stride) final;
  uint32_t Stride(VideoPlane plane) final;
  void SetTimestamp(int64_t timestamp) final;
  int64_t Timestamp() const final;

#if !defined(USE_PPAPI_CDM_ADAPTER)
  // Create a media::VideoFrame based on the data contained in this object.
  // |natural_size| is the visible portion of the video frame, and is
  // provided separately as it comes from the configuration, not the CDM.
  // The returned object will own |frame_buffer_| and will be responsible for
  // calling Destroy() on it when the data is no longer needed.
  // Preconditions:
  // - |this| needs to be properly initialized.
  // Postconditions:
  // - |frame_buffer_| will be NULL (now owned by returned media::VideoFrame).
  virtual scoped_refptr<media::VideoFrame> TransformToVideoFrame(
      gfx::Size natural_size) = 0;
#endif

 protected:
  // The video buffer format.
  cdm::VideoFormat format_;

  // Width and height of the video frame.
  cdm::Size size_;

  // The video frame buffer.
  cdm::Buffer* frame_buffer_;

  // Array of data pointers to each plane in the video frame buffer.
  uint32_t plane_offsets_[kMaxPlanes];

  // Array of strides for each plane, typically greater or equal to the width
  // of the surface divided by the horizontal sampling period.  Note that
  // strides can be negative.
  uint32_t strides_[kMaxPlanes];

  // Presentation timestamp in microseconds.
  int64_t timestamp_;

 private:
  DISALLOW_COPY_AND_ASSIGN(VideoFrameImpl);
};

class AudioFramesImpl : public cdm::AudioFrames {
 public:
  AudioFramesImpl();
  ~AudioFramesImpl() final;

  // cdm::AudioFrames implementation.
  void SetFrameBuffer(cdm::Buffer* buffer) final;
  cdm::Buffer* FrameBuffer() final;
  void SetFormat(cdm::AudioFormat format) final;
  cdm::AudioFormat Format() const final;

  cdm::Buffer* PassFrameBuffer();

 private:
  cdm::Buffer* buffer_;
  cdm::AudioFormat format_;

  DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl);
};

}  // namespace media

#endif  // MEDIA_CDM_CDM_HELPERS_H_
