/*
 *  Copyright (c) 2019 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 "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h"

#include <memory>
#include <vector>

#include "api/array_view.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

void VerifyHeader(const RTPVideoHeaderVP9& expected,
                  const RTPVideoHeaderVP9& actual) {
  EXPECT_EQ(expected.inter_layer_predicted, actual.inter_layer_predicted);
  EXPECT_EQ(expected.inter_pic_predicted, actual.inter_pic_predicted);
  EXPECT_EQ(expected.flexible_mode, actual.flexible_mode);
  EXPECT_EQ(expected.beginning_of_frame, actual.beginning_of_frame);
  EXPECT_EQ(expected.end_of_frame, actual.end_of_frame);
  EXPECT_EQ(expected.ss_data_available, actual.ss_data_available);
  EXPECT_EQ(expected.non_ref_for_inter_layer_pred,
            actual.non_ref_for_inter_layer_pred);
  EXPECT_EQ(expected.picture_id, actual.picture_id);
  EXPECT_EQ(expected.max_picture_id, actual.max_picture_id);
  EXPECT_EQ(expected.temporal_idx, actual.temporal_idx);
  EXPECT_EQ(expected.spatial_idx, actual.spatial_idx);
  EXPECT_EQ(expected.gof_idx, actual.gof_idx);
  EXPECT_EQ(expected.tl0_pic_idx, actual.tl0_pic_idx);
  EXPECT_EQ(expected.temporal_up_switch, actual.temporal_up_switch);

  EXPECT_EQ(expected.num_ref_pics, actual.num_ref_pics);
  for (uint8_t i = 0; i < expected.num_ref_pics; ++i) {
    EXPECT_EQ(expected.pid_diff[i], actual.pid_diff[i]);
    EXPECT_EQ(expected.ref_picture_id[i], actual.ref_picture_id[i]);
  }
  if (expected.ss_data_available) {
    EXPECT_EQ(expected.spatial_layer_resolution_present,
              actual.spatial_layer_resolution_present);
    EXPECT_EQ(expected.num_spatial_layers, actual.num_spatial_layers);
    if (expected.spatial_layer_resolution_present) {
      for (size_t i = 0; i < expected.num_spatial_layers; i++) {
        EXPECT_EQ(expected.width[i], actual.width[i]);
        EXPECT_EQ(expected.height[i], actual.height[i]);
      }
    }
    EXPECT_EQ(expected.gof.num_frames_in_gof, actual.gof.num_frames_in_gof);
    for (size_t i = 0; i < expected.gof.num_frames_in_gof; i++) {
      EXPECT_EQ(expected.gof.temporal_up_switch[i],
                actual.gof.temporal_up_switch[i]);
      EXPECT_EQ(expected.gof.temporal_idx[i], actual.gof.temporal_idx[i]);
      EXPECT_EQ(expected.gof.num_ref_pics[i], actual.gof.num_ref_pics[i]);
      for (uint8_t j = 0; j < expected.gof.num_ref_pics[i]; j++) {
        EXPECT_EQ(expected.gof.pid_diff[i][j], actual.gof.pid_diff[i][j]);
      }
    }
  }
}

TEST(VideoRtpDepacketizerVp9Test, ParseBasicHeader) {
  uint8_t packet[4] = {0};
  packet[0] = 0x0C;  // I:0 P:0 L:0 F:0 B:1 E:1 V:0 Z:0

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 1);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  expected.beginning_of_frame = true;
  expected.end_of_frame = true;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseOneBytePictureId) {
  uint8_t packet[10] = {0};
  packet[0] = 0x80;  // I:1 P:0 L:0 F:0 B:0 E:0 V:0 Z:0
  packet[1] = kMaxOneBytePictureId;

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 2);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  expected.picture_id = kMaxOneBytePictureId;
  expected.max_picture_id = kMaxOneBytePictureId;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseTwoBytePictureId) {
  uint8_t packet[10] = {0};
  packet[0] = 0x80;  // I:1 P:0 L:0 F:0 B:0 E:0 V:0 Z:0
  packet[1] = 0x80 | ((kMaxTwoBytePictureId >> 8) & 0x7F);
  packet[2] = kMaxTwoBytePictureId & 0xFF;

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 3);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  expected.picture_id = kMaxTwoBytePictureId;
  expected.max_picture_id = kMaxTwoBytePictureId;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseLayerInfoWithNonFlexibleMode) {
  const uint8_t kTemporalIdx = 2;
  const uint8_t kUbit = 1;
  const uint8_t kSpatialIdx = 1;
  const uint8_t kDbit = 1;
  const uint8_t kTl0PicIdx = 17;
  uint8_t packet[13] = {0};
  packet[0] = 0x20;  // I:0 P:0 L:1 F:0 B:0 E:0 V:0 Z:0
  packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit;
  packet[2] = kTl0PicIdx;

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 3);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  // T:2 U:1 S:1 D:1
  // TL0PICIDX:17
  expected.temporal_idx = kTemporalIdx;
  expected.temporal_up_switch = kUbit ? true : false;
  expected.spatial_idx = kSpatialIdx;
  expected.inter_layer_predicted = kDbit ? true : false;
  expected.tl0_pic_idx = kTl0PicIdx;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseLayerInfoWithFlexibleMode) {
  const uint8_t kTemporalIdx = 2;
  const uint8_t kUbit = 1;
  const uint8_t kSpatialIdx = 0;
  const uint8_t kDbit = 0;
  uint8_t packet[13] = {0};
  packet[0] = 0x38;  // I:0 P:0 L:1 F:1 B:1 E:0 V:0 Z:0
  packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit;

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 2);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  // I:0 P:0 L:1 F:1 B:1 E:0 V:0 Z:0
  // L:   T:2 U:1 S:0 D:0
  expected.beginning_of_frame = true;
  expected.flexible_mode = true;
  expected.temporal_idx = kTemporalIdx;
  expected.temporal_up_switch = kUbit ? true : false;
  expected.spatial_idx = kSpatialIdx;
  expected.inter_layer_predicted = kDbit ? true : false;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseRefIdx) {
  const int16_t kPictureId = 17;
  const uint8_t kPdiff1 = 17;
  const uint8_t kPdiff2 = 18;
  const uint8_t kPdiff3 = 127;
  uint8_t packet[13] = {0};
  packet[0] = 0xD8;  // I:1 P:1 L:0 F:1 B:1 E:0 V:0 Z:0
  packet[1] = 0x80 | ((kPictureId >> 8) & 0x7F);  // Two byte pictureID.
  packet[2] = kPictureId;
  packet[3] = (kPdiff1 << 1) | 1;  // P_DIFF N:1
  packet[4] = (kPdiff2 << 1) | 1;  // P_DIFF N:1
  packet[5] = (kPdiff3 << 1) | 0;  // P_DIFF N:0

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 6);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  // I:1 P:1 L:0 F:1 B:1 E:0 V:0 Z:0
  // I:    PICTURE ID:17
  // I:
  // P,F:  P_DIFF:17  N:1 => refPicId = 17 - 17 = 0
  // P,F:  P_DIFF:18  N:1 => refPicId = (kMaxPictureId + 1) + 17 - 18 = 0x7FFF
  // P,F:  P_DIFF:127 N:0 => refPicId = (kMaxPictureId + 1) + 17 - 127 = 32658
  expected.beginning_of_frame = true;
  expected.inter_pic_predicted = true;
  expected.flexible_mode = true;
  expected.picture_id = kPictureId;
  expected.num_ref_pics = 3;
  expected.pid_diff[0] = kPdiff1;
  expected.pid_diff[1] = kPdiff2;
  expected.pid_diff[2] = kPdiff3;
  expected.ref_picture_id[0] = 0;
  expected.ref_picture_id[1] = 0x7FFF;
  expected.ref_picture_id[2] = 32658;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseRefIdxFailsWithNoPictureId) {
  const uint8_t kPdiff = 3;
  uint8_t packet[13] = {0};
  packet[0] = 0x58;           // I:0 P:1 L:0 F:1 B:1 E:0 V:0 Z:0
  packet[1] = (kPdiff << 1);  // P,F:  P_DIFF:3 N:0

  RTPVideoHeader video_header;
  EXPECT_EQ(VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header), 0);
}

TEST(VideoRtpDepacketizerVp9Test, ParseRefIdxFailsWithTooManyRefPics) {
  const uint8_t kPdiff = 3;
  uint8_t packet[13] = {0};
  packet[0] = 0xD8;                  // I:1 P:1 L:0 F:1 B:1 E:0 V:0 Z:0
  packet[1] = kMaxOneBytePictureId;  // I:    PICTURE ID:127
  packet[2] = (kPdiff << 1) | 1;     // P,F:  P_DIFF:3 N:1
  packet[3] = (kPdiff << 1) | 1;     // P,F:  P_DIFF:3 N:1
  packet[4] = (kPdiff << 1) | 1;     // P,F:  P_DIFF:3 N:1
  packet[5] = (kPdiff << 1) | 0;     // P,F:  P_DIFF:3 N:0

  RTPVideoHeader video_header;
  EXPECT_EQ(VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header), 0);
}

TEST(VideoRtpDepacketizerVp9Test, ParseSsData) {
  const uint8_t kYbit = 0;
  const size_t kNs = 2;
  const size_t kNg = 2;
  uint8_t packet[23] = {0};
  packet[0] = 0x0A;  // I:0 P:0 L:0 F:0 B:1 E:0 V:1 Z:0
  packet[1] = ((kNs - 1) << 5) | (kYbit << 4) | (1 << 3);  // N_S Y G:1 -
  packet[2] = kNg;                                         // N_G
  packet[3] = (0 << 5) | (1 << 4) | (0 << 2) | 0;          // T:0 U:1 R:0 -
  packet[4] = (2 << 5) | (0 << 4) | (1 << 2) | 0;          // T:2 U:0 R:1 -
  packet[5] = 33;

  RTPVideoHeader video_header;
  int offset = VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(offset, 6);
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  expected.beginning_of_frame = true;
  expected.ss_data_available = true;
  expected.num_spatial_layers = kNs;
  expected.spatial_layer_resolution_present = kYbit ? true : false;
  expected.gof.num_frames_in_gof = kNg;
  expected.gof.temporal_idx[0] = 0;
  expected.gof.temporal_idx[1] = 2;
  expected.gof.temporal_up_switch[0] = true;
  expected.gof.temporal_up_switch[1] = false;
  expected.gof.num_ref_pics[0] = 0;
  expected.gof.num_ref_pics[1] = 1;
  expected.gof.pid_diff[1][0] = 33;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ParseFirstPacketInKeyFrame) {
  uint8_t packet[2] = {0};
  packet[0] = 0x08;  // I:0 P:0 L:0 F:0 B:1 E:0 V:0 Z:0

  RTPVideoHeader video_header;
  VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(video_header.frame_type, VideoFrameType::kVideoFrameKey);
  EXPECT_TRUE(video_header.is_first_packet_in_frame);
}

TEST(VideoRtpDepacketizerVp9Test, ParseLastPacketInDeltaFrame) {
  uint8_t packet[2] = {0};
  packet[0] = 0x44;  // I:0 P:1 L:0 F:0 B:0 E:1 V:0 Z:0

  RTPVideoHeader video_header;
  VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(video_header.frame_type, VideoFrameType::kVideoFrameDelta);
  EXPECT_FALSE(video_header.is_first_packet_in_frame);
}

TEST(VideoRtpDepacketizerVp9Test, ParseResolution) {
  const uint16_t kWidth[2] = {640, 1280};
  const uint16_t kHeight[2] = {360, 720};
  uint8_t packet[20] = {0};
  packet[0] = 0x0A;                     // I:0 P:0 L:0 F:0 B:1 E:0 V:1 Z:0
  packet[1] = (1 << 5) | (1 << 4) | 0;  // N_S:1 Y:1 G:0
  packet[2] = kWidth[0] >> 8;
  packet[3] = kWidth[0] & 0xFF;
  packet[4] = kHeight[0] >> 8;
  packet[5] = kHeight[0] & 0xFF;
  packet[6] = kWidth[1] >> 8;
  packet[7] = kWidth[1] & 0xFF;
  packet[8] = kHeight[1] >> 8;
  packet[9] = kHeight[1] & 0xFF;

  RTPVideoHeader video_header;
  VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  EXPECT_EQ(video_header.width, kWidth[0]);
  EXPECT_EQ(video_header.height, kHeight[0]);
}

TEST(VideoRtpDepacketizerVp9Test, ParseFailsForNoPayloadLength) {
  rtc::ArrayView<const uint8_t> empty;

  RTPVideoHeader video_header;
  EXPECT_EQ(VideoRtpDepacketizerVp9::ParseRtpPayload(empty, &video_header), 0);
}

TEST(VideoRtpDepacketizerVp9Test, ParseFailsForTooShortBufferToFitPayload) {
  uint8_t packet[] = {0};

  RTPVideoHeader video_header;
  EXPECT_EQ(VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header), 0);
}

TEST(VideoRtpDepacketizerVp9Test, ParseNonRefForInterLayerPred) {
  RTPVideoHeader video_header;
  RTPVideoHeaderVP9 expected;
  expected.InitRTPVideoHeaderVP9();
  uint8_t packet[2] = {0};

  packet[0] = 0x08;  // I:0 P:0 L:0 F:0 B:1 E:0 V:0 Z:0
  VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  expected.beginning_of_frame = true;
  expected.non_ref_for_inter_layer_pred = false;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));

  packet[0] = 0x05;  // I:0 P:0 L:0 F:0 B:0 E:1 V:0 Z:1
  VideoRtpDepacketizerVp9::ParseRtpPayload(packet, &video_header);

  expected.beginning_of_frame = false;
  expected.end_of_frame = true;
  expected.non_ref_for_inter_layer_pred = true;
  VerifyHeader(expected,
               absl::get<RTPVideoHeaderVP9>(video_header.video_type_header));
}

TEST(VideoRtpDepacketizerVp9Test, ReferencesInputCopyOnWriteBuffer) {
  constexpr size_t kHeaderSize = 1;
  uint8_t packet[4] = {0};
  packet[0] = 0x0C;  // I:0 P:0 L:0 F:0 B:1 E:1 V:0 Z:0

  rtc::CopyOnWriteBuffer rtp_payload(packet);
  VideoRtpDepacketizerVp9 depacketizer;
  absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
      depacketizer.Parse(rtp_payload);
  ASSERT_TRUE(parsed);

  EXPECT_EQ(parsed->video_payload.size(), rtp_payload.size() - kHeaderSize);
  // Compare pointers to check there was no copy on write buffer unsharing.
  EXPECT_EQ(parsed->video_payload.cdata(), rtp_payload.cdata() + kHeaderSize);
}
}  // namespace
}  // namespace webrtc
