blob: c9adee424263bacbdc7c7b38f88825733a394ad6 [file] [log] [blame]
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +02001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "test/fake_vp8_encoder.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <algorithm>
14
15#include "absl/types/optional.h"
Erik Språng4529fbc2018-10-12 10:30:31 +020016#include "api/video_codecs/vp8_temporal_layers.h"
Elad Aloncde8ab22019-03-20 11:56:20 +010017#include "api/video_codecs/vp8_temporal_layers_factory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "common_types.h" // NOLINT(build/include)
19#include "modules/video_coding/codecs/interface/common_constants.h"
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020020#include "modules/video_coding/include/video_codec_interface.h"
21#include "modules/video_coding/include/video_error_codes.h"
22#include "modules/video_coding/utility/simulcast_utility.h"
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020023
Per Kjellander841c9122018-10-04 18:40:28 +020024namespace {
25
26// Write width and height to the payload the same way as the real encoder does.
27// It requires that |payload| has a size of at least kMinPayLoadHeaderLength.
28void WriteFakeVp8(unsigned char* payload,
29 int width,
30 int height,
31 bool key_frame) {
32 payload[0] = key_frame ? 0 : 0x01;
33
34 if (key_frame) {
35 payload[9] = (height & 0x3F00) >> 8;
36 payload[8] = (height & 0x00FF);
37
38 payload[7] = (width & 0x3F00) >> 8;
39 payload[6] = (width & 0x00FF);
40 }
41}
42} // namespace
43
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020044namespace webrtc {
45
46namespace test {
47
Niels Möllerd7380712019-03-06 10:09:47 +010048FakeVP8Encoder::FakeVP8Encoder(Clock* clock) : FakeEncoder(clock) {
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020049 sequence_checker_.Detach();
50}
51
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020052int32_t FakeVP8Encoder::InitEncode(const VideoCodec* config,
53 int32_t number_of_cores,
54 size_t max_payload_size) {
55 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
56 auto result =
57 FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
58 if (result != WEBRTC_VIDEO_CODEC_OK) {
59 return result;
60 }
61
Elad Aloncde8ab22019-03-20 11:56:20 +010062 Vp8TemporalLayersFactory factory;
63 frame_buffer_controller_ = factory.Create(*config);
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020064
65 return WEBRTC_VIDEO_CODEC_OK;
66}
67
68int32_t FakeVP8Encoder::Release() {
69 auto result = FakeEncoder::Release();
70 sequence_checker_.Detach();
71 return result;
72}
73
Erik Språng59021ba2018-10-03 11:05:16 +020074void FakeVP8Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
75 size_t size_bytes,
Niels Möller87e2d782019-03-07 10:18:23 +010076 VideoFrameType frame_type,
Erik Språng59021ba2018-10-03 11:05:16 +020077 int stream_idx,
78 uint32_t timestamp) {
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020079 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
80 codec_specific->codecType = kVideoCodecVP8;
philipel9df33532019-03-04 16:37:50 +010081 codec_specific->codecSpecific.VP8.keyIdx = kNoKeyIdx;
82 codec_specific->codecSpecific.VP8.nonReference = false;
Elad Aloncde8ab22019-03-20 11:56:20 +010083 frame_buffer_controller_->OnEncodeDone(stream_idx, timestamp, size_bytes,
84 frame_type == kVideoFrameKey, -1,
85 codec_specific);
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020086}
87
Niels Möllerd7380712019-03-06 10:09:47 +010088std::unique_ptr<RTPFragmentationHeader> FakeVP8Encoder::EncodeHook(
89 EncodedImage* encoded_image,
90 CodecSpecificInfo* codec_specific) {
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020091 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
Niels Möllerd7380712019-03-06 10:09:47 +010092 uint8_t stream_idx = encoded_image->SpatialIndex().value_or(0);
Elad Aloncde8ab22019-03-20 11:56:20 +010093 frame_buffer_controller_->UpdateLayerConfig(stream_idx,
94 encoded_image->Timestamp());
Niels Möllerd7380712019-03-06 10:09:47 +010095 PopulateCodecSpecific(codec_specific, encoded_image->size(),
96 encoded_image->_frameType, stream_idx,
97 encoded_image->Timestamp());
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +020098
Per Kjellander841c9122018-10-04 18:40:28 +020099 // Write width and height to the payload the same way as the real encoder
100 // does.
Niels Möllerd7380712019-03-06 10:09:47 +0100101 WriteFakeVp8(encoded_image->data(), encoded_image->_encodedWidth,
102 encoded_image->_encodedHeight,
103 encoded_image->_frameType == kVideoFrameKey);
104 return nullptr;
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +0200105}
106
Erik Språng86336a52018-11-15 15:38:05 +0100107VideoEncoder::EncoderInfo FakeVP8Encoder::GetEncoderInfo() const {
108 EncoderInfo info;
109 info.implementation_name = "FakeVp8Encoder";
110 return info;
111}
112
Ilya Nikolaevskiyb0588e62018-08-27 14:12:27 +0200113} // namespace test
114} // namespace webrtc