/*
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "media/filters/shell_raw_video_decoder_linux.h"

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/video_util.h"
#include "media/filters/shell_ffmpeg.h"

namespace media {

using base::TimeDelta;
typedef ShellVideoDataAllocator::FrameBuffer FrameBuffer;
typedef ShellVideoDataAllocator::YV12Param YV12Param;

namespace {

// FFmpeg requires its decoding buffers to align with platform alignment.  It
// mentions inside
// http://ffmpeg.org/doxygen/trunk/structAVFrame.html#aa52bfc6605f6a3059a0c3226cc0f6567
// that the alignment on most modern desktop systems are 16 or 32.  We use 64 to
// be safe.
const int kPlatformAlignment = 32;

size_t AlignUp(size_t size, int alignment) {
  DCHECK_EQ(alignment & (alignment - 1), 0);
  return (size + alignment - 1) & ~(alignment - 1);
}

size_t GetYV12SizeInBytes(int32 width, int32 height) {
  return width * height * 3 / 2;
}

VideoFrame::Format PixelFormatToVideoFormat(PixelFormat pixel_format) {
  switch (pixel_format) {
    case PIX_FMT_YUV420P:
      return VideoFrame::YV12;
    case PIX_FMT_YUVJ420P:
      return VideoFrame::YV12;
    default:
      DLOG(ERROR) << "Unsupported PixelFormat: " << pixel_format;
  }
  return VideoFrame::INVALID;
}

int VideoCodecProfileToProfileID(VideoCodecProfile profile) {
  switch (profile) {
    case H264PROFILE_BASELINE:
      return FF_PROFILE_H264_BASELINE;
    case H264PROFILE_MAIN:
      return FF_PROFILE_H264_MAIN;
    case H264PROFILE_EXTENDED:
      return FF_PROFILE_H264_EXTENDED;
    case H264PROFILE_HIGH:
      return FF_PROFILE_H264_HIGH;
    case H264PROFILE_HIGH10PROFILE:
      return FF_PROFILE_H264_HIGH_10;
    case H264PROFILE_HIGH422PROFILE:
      return FF_PROFILE_H264_HIGH_422;
    case H264PROFILE_HIGH444PREDICTIVEPROFILE:
      return FF_PROFILE_H264_HIGH_444_PREDICTIVE;
    default:
      DLOG(ERROR) << "Unknown VideoCodecProfile: " << profile;
  }
  return FF_PROFILE_UNKNOWN;
}

PixelFormat VideoFormatToPixelFormat(VideoFrame::Format video_format) {
  switch (video_format) {
    case VideoFrame::YV12:
      return PIX_FMT_YUV420P;
    default:
      DLOG(ERROR) << "Unsupported VideoFrame::Format: " << video_format;
  }
  return PIX_FMT_NONE;
}

void CopyColorPlane(const uint8* src,
                    int32 width_in_bytes,
                    int32 pitch,
                    int32 height,
                    uint8* dest) {
  while (height > 0) {
    memcpy(dest, src, width_in_bytes);
    src += pitch;
    dest += width_in_bytes;
    --height;
  }
}

// Convert a frame buffer whose pitch might be different than its width to a
// frame buffer whose pitch is the same as its width.  This involves line by
// line copy of all three color planes.
scoped_refptr<FrameBuffer> ConvertFrameBuffer(
    const scoped_refptr<FrameBuffer>& src,
    int32 width,
    int32 height) {
  DCHECK(width % 2 == 0) << "Invalid width " << width;
  DCHECK(height % 2 == 0) << "Invalid height " << height;

  ShellVideoDataAllocator* allocator =
      ShellMediaPlatform::Instance()->GetVideoDataAllocator();
  DCHECK(allocator);
  size_t yv12_frame_size = GetYV12SizeInBytes(width, height);
  scoped_refptr<FrameBuffer> dest =
      allocator->AllocateFrameBuffer(yv12_frame_size, kPlatformAlignment);

  // Get the src pitch and height as what we did in GetVideoBuffer().
  int32 src_pitch = AlignUp(width, kPlatformAlignment * 2);
  int32 src_height = AlignUp(height, kPlatformAlignment * 2);
  DCHECK_LE(GetYV12SizeInBytes(src_pitch, src_height), src->size());
  DCHECK_LE(GetYV12SizeInBytes(width, height), dest->size());

  uint8* src_data = src->data();
  uint8* dest_data = dest->data();
  CopyColorPlane(src_data, width, src_pitch, height, dest_data);
  src_data += src_pitch * src_height;
  dest_data += width * height;
  CopyColorPlane(src_data, width / 2, src_pitch / 2, height / 2, dest_data);
  src_data += src_pitch / 2 * src_height / 2;
  dest_data += width / 2 * height / 2;
  CopyColorPlane(src_data, width / 2, src_pitch / 2, height / 2, dest_data);
  return dest;
}

// TODO: Make this decoder handle decoder errors. Now it assumes
// that the input stream is always correct.
class ShellRawVideoDecoderLinux : public ShellRawVideoDecoder {
 public:
  explicit ShellRawVideoDecoderLinux(ShellVideoDataAllocator* allocator);
  ~ShellRawVideoDecoderLinux();

  virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
                      const DecodeCB& decode_cb) OVERRIDE;
  virtual bool Flush() OVERRIDE;
  virtual bool UpdateConfig(const VideoDecoderConfig& config) OVERRIDE;

 private:
  void ReleaseResource();
  static int GetVideoBuffer(AVCodecContext* codec_context, AVFrame* frame);
  static void ReleaseVideoBuffer(AVCodecContext*, AVFrame* frame);

  ShellVideoDataAllocator* allocator_;
  AVCodecContext* codec_context_;
  AVFrame* av_frame_;
  gfx::Size natural_size_;

  DISALLOW_COPY_AND_ASSIGN(ShellRawVideoDecoderLinux);
};

ShellRawVideoDecoderLinux::ShellRawVideoDecoderLinux(
    ShellVideoDataAllocator* allocator)
    : allocator_(allocator), codec_context_(NULL), av_frame_(NULL) {
  EnsureFfmpegInitialized();
}

ShellRawVideoDecoderLinux::~ShellRawVideoDecoderLinux() {
  ReleaseResource();
}

void ShellRawVideoDecoderLinux::Decode(
    const scoped_refptr<DecoderBuffer>& buffer,
    const DecodeCB& decode_cb) {
  DCHECK(buffer);
  DCHECK(!decode_cb.is_null());

  AVPacket packet;
  av_init_packet(&packet);
  avcodec_get_frame_defaults(av_frame_);
  packet.data = buffer->GetWritableData();
  packet.size = buffer->GetDataSize();
  packet.pts = buffer->GetTimestamp().InMilliseconds();

  int frame_decoded = 0;
  int result =
      avcodec_decode_video2(codec_context_, av_frame_, &frame_decoded, &packet);
  DCHECK_GE(result, 0);
  if (frame_decoded == 0) {
    decode_cb.Run(NEED_MORE_DATA, NULL);
    return;
  }

  // TODO(fbarchard): Work around for FFmpeg http://crbug.com/27675
  // The decoder is in a bad state and not decoding correctly.
  // Checking for NULL avoids a crash in CopyPlane().
  if (!av_frame_->data[VideoFrame::kYPlane] ||
      !av_frame_->data[VideoFrame::kUPlane] ||
      !av_frame_->data[VideoFrame::kVPlane]) {
    DLOG(ERROR) << "Video frame was produced yet has invalid frame data.";
    decode_cb.Run(FATAL_ERROR, NULL);
    return;
  }

  if (!av_frame_->opaque) {
    DLOG(ERROR) << "VideoFrame object associated with frame data not set.";
    decode_cb.Run(FATAL_ERROR, NULL);
    return;
  }

  scoped_refptr<FrameBuffer> frame_buffer =
      static_cast<FrameBuffer*>(av_frame_->opaque);
  DCHECK(frame_buffer);

  TimeDelta timestamp = TimeDelta::FromMilliseconds(av_frame_->pkt_pts);
  // TODO: Currently the Linux egl backend doesn't support texture
  // with pitch different than its width.  So we create a new video frame whose
  // visible size is the same as its coded size to ensure that the underlying
  // texture has the same pitch as its width.  This makes code complex, though
  // it doesn't necessary mean that the new code is slower as we have to make a
  // copy anyway to avoid using the frame buffer while Ffmpeg is still using it.
  // It is worth revisiting if we are going to release Linux as a production
  // platform.
  YV12Param param(av_frame_->width, av_frame_->height,
                  gfx::Rect(av_frame_->width, av_frame_->height));
  // We have to make a copy of the frame buffer as the frame buffer retrieved
  // from |av_frame_->opaque| may still be used by Ffmpeg.
  size_t yv12_frame_size =
      GetYV12SizeInBytes(av_frame_->width, av_frame_->height);
  scoped_refptr<FrameBuffer> converted_frame_buffer =
      ConvertFrameBuffer(frame_buffer, av_frame_->width, av_frame_->height);
  scoped_refptr<VideoFrame> frame =
      allocator_->CreateYV12Frame(converted_frame_buffer, param, timestamp);

  decode_cb.Run(FRAME_DECODED, frame);
}

bool ShellRawVideoDecoderLinux::Flush() {
  avcodec_flush_buffers(codec_context_);

  return true;
}

bool ShellRawVideoDecoderLinux::UpdateConfig(const VideoDecoderConfig& config) {
  ReleaseResource();

  natural_size_ = config.natural_size();

  codec_context_ = avcodec_alloc_context3(NULL);
  DCHECK(codec_context_);
  codec_context_->codec_type = AVMEDIA_TYPE_VIDEO;
  codec_context_->codec_id = CODEC_ID_H264;
  codec_context_->profile = VideoCodecProfileToProfileID(config.profile());
  codec_context_->coded_width = config.coded_size().width();
  codec_context_->coded_height = config.coded_size().height();
  codec_context_->pix_fmt = VideoFormatToPixelFormat(config.format());

  codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
  codec_context_->thread_count = 2;
  codec_context_->opaque = this;
  codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
  codec_context_->get_buffer = GetVideoBuffer;
  codec_context_->release_buffer = ReleaseVideoBuffer;

  if (config.extra_data()) {
    codec_context_->extradata_size = config.extra_data_size();
    codec_context_->extradata = reinterpret_cast<uint8_t*>(
        av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
    memcpy(codec_context_->extradata, config.extra_data(),
           config.extra_data_size());
    memset(codec_context_->extradata + config.extra_data_size(), '\0',
           FF_INPUT_BUFFER_PADDING_SIZE);
  } else {
    codec_context_->extradata = NULL;
    codec_context_->extradata_size = 0;
  }

  AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
  DCHECK(codec);
  int rv = avcodec_open2(codec_context_, codec, NULL);
  DCHECK_GE(rv, 0);
  if (rv < 0) {
    DLOG(ERROR) << "Unable to open codec, result = " << rv;
    return false;
  }

  av_frame_ = avcodec_alloc_frame();
  DCHECK(av_frame_);

  return true;
}

void ShellRawVideoDecoderLinux::ReleaseResource() {
  if (codec_context_) {
    av_free(codec_context_->extradata);
    avcodec_close(codec_context_);
    av_free(codec_context_);
    codec_context_ = NULL;
  }
  if (av_frame_) {
    av_free(av_frame_);
    av_frame_ = NULL;
  }
}

int ShellRawVideoDecoderLinux::GetVideoBuffer(AVCodecContext* codec_context,
                                              AVFrame* frame) {
  VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
  if (format == VideoFrame::INVALID)
    return AVERROR(EINVAL);
  DCHECK_EQ(format, VideoFrame::YV12);

  gfx::Size size(codec_context->width, codec_context->height);
  int ret = av_image_check_size(size.width(), size.height(), 0, NULL);
  if (ret < 0) {
    return ret;
  }

  if (!VideoFrame::IsValidConfig(format, size, gfx::Rect(size), size)) {
    return AVERROR(EINVAL);
  }

  // Align to kPlatformAlignment * 2 as we will divide the y_stride by 2 for u
  // and v planes.
  size_t y_stride = AlignUp(size.width(), kPlatformAlignment * 2);
  size_t uv_stride = y_stride / 2;
  size_t aligned_height = AlignUp(size.height(), kPlatformAlignment * 2);
  scoped_refptr<FrameBuffer> frame_buffer = allocator_->AllocateFrameBuffer(
      GetYV12SizeInBytes(y_stride, aligned_height), kPlatformAlignment);

  // y plane
  frame->base[0] = frame_buffer->data();
  frame->data[0] = frame->base[0];
  frame->linesize[0] = y_stride;
  // u plane
  frame->base[1] = frame->base[0] + y_stride * aligned_height;
  frame->data[1] = frame->base[1];
  memset(frame->data[1], 0, uv_stride * (aligned_height / 2));
  frame->linesize[1] = uv_stride;
  // v plane
  frame->base[2] = frame->base[1] + uv_stride * aligned_height / 2;
  frame->data[2] = frame->base[2];
  memset(frame->data[2], 0, uv_stride * (aligned_height / 2));
  frame->linesize[2] = uv_stride;

  frame->opaque = NULL;
  frame_buffer.swap(reinterpret_cast<FrameBuffer**>(&frame->opaque));
  frame->type = FF_BUFFER_TYPE_USER;
  frame->pkt_pts =
      codec_context->pkt ? codec_context->pkt->pts : AV_NOPTS_VALUE;
  frame->width = codec_context->width;
  frame->height = codec_context->height;
  frame->format = codec_context->pix_fmt;

  return 0;
}

void ShellRawVideoDecoderLinux::ReleaseVideoBuffer(AVCodecContext*,
                                                   AVFrame* frame) {
  scoped_refptr<FrameBuffer> frame_buffer;
  frame_buffer.swap(reinterpret_cast<FrameBuffer**>(&frame->opaque));

  // The FFmpeg API expects us to zero the data pointers in
  // this callback
  memset(frame->data, 0, sizeof(frame->data));
  frame->opaque = NULL;
}

}  // namespace

scoped_ptr<ShellRawVideoDecoder> CreateShellRawVideoDecoderLinux(
    ShellVideoDataAllocator* allocator,
    const VideoDecoderConfig& config,
    Decryptor* decryptor,
    bool was_encrypted) {
  DCHECK(allocator);
  DCHECK_EQ(config.codec(), kCodecH264) << "Video codec " << config.codec()
                                        << " is not supported.";
  scoped_ptr<ShellRawVideoDecoder> decoder(
      new ShellRawVideoDecoderLinux(allocator));
  if (decoder->UpdateConfig(config))
    return decoder.Pass();
  return scoped_ptr<ShellRawVideoDecoder>();
}

}  // namespace media
