/*
 *  Copyright 2017 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.
 */

package org.webrtc;

import android.support.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;

/**
 * An encoded frame from a video stream. Used as an input for decoders and as an output for
 * encoders.
 */
public class EncodedImage implements RefCounted {
  // Must be kept in sync with common_types.h FrameType.
  public enum FrameType {
    EmptyFrame(0),
    VideoFrameKey(3),
    VideoFrameDelta(4);

    private final int nativeIndex;

    private FrameType(int nativeIndex) {
      this.nativeIndex = nativeIndex;
    }

    public int getNative() {
      return nativeIndex;
    }

    @CalledByNative("FrameType")
    static FrameType fromNativeIndex(int nativeIndex) {
      for (FrameType type : FrameType.values()) {
        if (type.getNative() == nativeIndex) {
          return type;
        }
      }
      throw new IllegalArgumentException("Unknown native frame type: " + nativeIndex);
    }
  }

  private final RefCountDelegate refCountDelegate;
  public final ByteBuffer buffer;
  public final int encodedWidth;
  public final int encodedHeight;
  public final long captureTimeMs; // Deprecated
  public final long captureTimeNs;
  public final FrameType frameType;
  public final int rotation;
  public final boolean completeFrame;
  public final @Nullable Integer qp;

  // TODO(bugs.webrtc.org/9378): Use retain and release from jni code.
  @Override
  public void retain() {
    refCountDelegate.retain();
  }

  @Override
  public void release() {
    refCountDelegate.release();
  }

  @CalledByNative
  private EncodedImage(ByteBuffer buffer, @Nullable Runnable releaseCallback, int encodedWidth,
      int encodedHeight, long captureTimeNs, FrameType frameType, int rotation,
      boolean completeFrame, @Nullable Integer qp) {
    this.buffer = buffer;
    this.encodedWidth = encodedWidth;
    this.encodedHeight = encodedHeight;
    this.captureTimeMs = TimeUnit.NANOSECONDS.toMillis(captureTimeNs);
    this.captureTimeNs = captureTimeNs;
    this.frameType = frameType;
    this.rotation = rotation;
    this.completeFrame = completeFrame;
    this.qp = qp;
    this.refCountDelegate = new RefCountDelegate(releaseCallback);
  }

  @CalledByNative
  private ByteBuffer getBuffer() {
    return buffer;
  }

  @CalledByNative
  private int getEncodedWidth() {
    return encodedWidth;
  }

  @CalledByNative
  private int getEncodedHeight() {
    return encodedHeight;
  }

  @CalledByNative
  private long getCaptureTimeNs() {
    return captureTimeNs;
  }

  @CalledByNative
  private int getFrameType() {
    return frameType.getNative();
  }

  @CalledByNative
  private int getRotation() {
    return rotation;
  }

  @CalledByNative
  private boolean getCompleteFrame() {
    return completeFrame;
  }

  @CalledByNative
  private @Nullable Integer getQp() {
    return qp;
  }

  public static Builder builder() {
    return new Builder();
  }

  public static class Builder {
    private ByteBuffer buffer;
    private @Nullable Runnable releaseCallback;
    private int encodedWidth;
    private int encodedHeight;
    private long captureTimeNs;
    private EncodedImage.FrameType frameType;
    private int rotation;
    private boolean completeFrame;
    private @Nullable Integer qp;

    private Builder() {}

    public Builder setBuffer(ByteBuffer buffer, @Nullable Runnable releaseCallback) {
      this.buffer = buffer;
      this.releaseCallback = releaseCallback;
      return this;
    }

    public Builder setEncodedWidth(int encodedWidth) {
      this.encodedWidth = encodedWidth;
      return this;
    }

    public Builder setEncodedHeight(int encodedHeight) {
      this.encodedHeight = encodedHeight;
      return this;
    }

    @Deprecated
    public Builder setCaptureTimeMs(long captureTimeMs) {
      this.captureTimeNs = TimeUnit.MILLISECONDS.toNanos(captureTimeMs);
      return this;
    }

    public Builder setCaptureTimeNs(long captureTimeNs) {
      this.captureTimeNs = captureTimeNs;
      return this;
    }

    public Builder setFrameType(EncodedImage.FrameType frameType) {
      this.frameType = frameType;
      return this;
    }

    public Builder setRotation(int rotation) {
      this.rotation = rotation;
      return this;
    }

    public Builder setCompleteFrame(boolean completeFrame) {
      this.completeFrame = completeFrame;
      return this;
    }

    public Builder setQp(@Nullable Integer qp) {
      this.qp = qp;
      return this;
    }

    public EncodedImage createEncodedImage() {
      return new EncodedImage(buffer, releaseCallback, encodedWidth, encodedHeight, captureTimeNs,
          frameType, rotation, completeFrame, qp);
    }
  }
}
