/*
 *  Copyright 2013 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;

/**
 * Java wrapper of native AndroidVideoTrackSource.
 */
public class VideoSource extends MediaSource {
  /** Simple aspect ratio clas for use in constraining output format. */
  public static class AspectRatio {
    public static final AspectRatio UNDEFINED = new AspectRatio(/* width= */ 0, /* height= */ 0);

    public final int width;
    public final int height;

    public AspectRatio(int width, int height) {
      this.width = width;
      this.height = height;
    }
  }

  private final NativeAndroidVideoTrackSource nativeAndroidVideoTrackSource;
  private final Object videoProcessorLock = new Object();
  @Nullable private VideoProcessor videoProcessor;
  private boolean isCapturerRunning;

  private final CapturerObserver capturerObserver = new CapturerObserver() {
    @Override
    public void onCapturerStarted(boolean success) {
      nativeAndroidVideoTrackSource.setState(success);
      synchronized (videoProcessorLock) {
        isCapturerRunning = success;
        if (videoProcessor != null) {
          videoProcessor.onCapturerStarted(success);
        }
      }
    }

    @Override
    public void onCapturerStopped() {
      nativeAndroidVideoTrackSource.setState(/* isLive= */ false);
      synchronized (videoProcessorLock) {
        isCapturerRunning = false;
        if (videoProcessor != null) {
          videoProcessor.onCapturerStopped();
        }
      }
    }

    @Override
    public void onFrameCaptured(VideoFrame frame) {
      final VideoProcessor.FrameAdaptationParameters parameters =
          nativeAndroidVideoTrackSource.adaptFrame(frame);
      synchronized (videoProcessorLock) {
        if (videoProcessor != null) {
          videoProcessor.onFrameCaptured(frame, parameters);
          return;
        }
      }

      VideoFrame adaptedFrame = VideoProcessor.applyFrameAdaptationParameters(frame, parameters);
      if (adaptedFrame != null) {
        nativeAndroidVideoTrackSource.onFrameCaptured(adaptedFrame);
        adaptedFrame.release();
      }
    }
  };

  public VideoSource(long nativeSource) {
    super(nativeSource);
    this.nativeAndroidVideoTrackSource = new NativeAndroidVideoTrackSource(nativeSource);
  }

  /**
   * Calling this function will cause frames to be scaled down to the requested resolution. Also,
   * frames will be cropped to match the requested aspect ratio, and frames will be dropped to match
   * the requested fps. The requested aspect ratio is orientation agnostic and will be adjusted to
   * maintain the input orientation, so it doesn't matter if e.g. 1280x720 or 720x1280 is requested.
   */
  public void adaptOutputFormat(int width, int height, int fps) {
    final int maxSide = Math.max(width, height);
    final int minSide = Math.min(width, height);
    adaptOutputFormat(maxSide, minSide, minSide, maxSide, fps);
  }

  /**
   * Same as above, but allows setting two different target resolutions depending on incoming
   * frame orientation. This gives more fine-grained control and can e.g. be used to force landscape
   * video to be cropped to portrait video.
   */
  public void adaptOutputFormat(
      int landscapeWidth, int landscapeHeight, int portraitWidth, int portraitHeight, int fps) {
    adaptOutputFormat(new AspectRatio(landscapeWidth, landscapeHeight),
        /* maxLandscapePixelCount= */ landscapeWidth * landscapeHeight,
        new AspectRatio(portraitWidth, portraitHeight),
        /* maxPortraitPixelCount= */ portraitWidth * portraitHeight, fps);
  }

  /** Same as above, with even more control as each constraint is optional. */
  public void adaptOutputFormat(AspectRatio targetLandscapeAspectRatio,
      @Nullable Integer maxLandscapePixelCount, AspectRatio targetPortraitAspectRatio,
      @Nullable Integer maxPortraitPixelCount, @Nullable Integer maxFps) {
    nativeAndroidVideoTrackSource.adaptOutputFormat(targetLandscapeAspectRatio,
        maxLandscapePixelCount, targetPortraitAspectRatio, maxPortraitPixelCount, maxFps);
  }

  public void setIsScreencast(boolean isScreencast) {
    nativeAndroidVideoTrackSource.setIsScreencast(isScreencast);
  }

  /**
   * Hook for injecting a custom video processor before frames are passed onto WebRTC. The frames
   * will be cropped and scaled depending on CPU and network conditions before they are passed to
   * the video processor. Frames will be delivered to the video processor on the same thread they
   * are passed to this object. The video processor is allowed to deliver the processed frames
   * back on any thread.
   */
  public void setVideoProcessor(@Nullable VideoProcessor newVideoProcessor) {
    synchronized (videoProcessorLock) {
      if (videoProcessor != null) {
        videoProcessor.setSink(/* sink= */ null);
        if (isCapturerRunning) {
          videoProcessor.onCapturerStopped();
        }
      }
      videoProcessor = newVideoProcessor;
      if (newVideoProcessor != null) {
        newVideoProcessor.setSink(
            (frame)
                -> runWithReference(() -> nativeAndroidVideoTrackSource.onFrameCaptured(frame)));
        if (isCapturerRunning) {
          newVideoProcessor.onCapturerStarted(/* success= */ true);
        }
      }
    }
  }

  public CapturerObserver getCapturerObserver() {
    return capturerObserver;
  }

  /** Returns a pointer to webrtc::VideoTrackSourceInterface. */
  long getNativeVideoTrackSource() {
    return getNativeMediaSource();
  }

  @Override
  public void dispose() {
    setVideoProcessor(/* newVideoProcessor= */ null);
    super.dispose();
  }
}
