xref: /aosp_15_r20/external/webrtc/test/fake_vp8_encoder.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "test/fake_vp8_encoder.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
16*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_encoder.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/vp8_temporal_layers.h"
18*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/vp8_temporal_layers_factory.h"
19*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/codecs/interface/common_constants.h"
20*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/include/video_codec_interface.h"
21*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/include/video_error_codes.h"
22*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/utility/simulcast_utility.h"
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker namespace {
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker // Write width and height to the payload the same way as the real encoder does.
27*d9f75844SAndroid Build Coastguard Worker // It requires that `payload` has a size of at least kMinPayLoadHeaderLength.
WriteFakeVp8(unsigned char * payload,int width,int height,bool key_frame)28*d9f75844SAndroid Build Coastguard Worker void WriteFakeVp8(unsigned char* payload,
29*d9f75844SAndroid Build Coastguard Worker                   int width,
30*d9f75844SAndroid Build Coastguard Worker                   int height,
31*d9f75844SAndroid Build Coastguard Worker                   bool key_frame) {
32*d9f75844SAndroid Build Coastguard Worker   payload[0] = key_frame ? 0 : 0x01;
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker   if (key_frame) {
35*d9f75844SAndroid Build Coastguard Worker     payload[9] = (height & 0x3F00) >> 8;
36*d9f75844SAndroid Build Coastguard Worker     payload[8] = (height & 0x00FF);
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker     payload[7] = (width & 0x3F00) >> 8;
39*d9f75844SAndroid Build Coastguard Worker     payload[6] = (width & 0x00FF);
40*d9f75844SAndroid Build Coastguard Worker   }
41*d9f75844SAndroid Build Coastguard Worker }
42*d9f75844SAndroid Build Coastguard Worker }  // namespace
43*d9f75844SAndroid Build Coastguard Worker 
44*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
45*d9f75844SAndroid Build Coastguard Worker 
46*d9f75844SAndroid Build Coastguard Worker namespace test {
47*d9f75844SAndroid Build Coastguard Worker 
FakeVp8Encoder(Clock * clock)48*d9f75844SAndroid Build Coastguard Worker FakeVp8Encoder::FakeVp8Encoder(Clock* clock) : FakeEncoder(clock) {
49*d9f75844SAndroid Build Coastguard Worker   sequence_checker_.Detach();
50*d9f75844SAndroid Build Coastguard Worker }
51*d9f75844SAndroid Build Coastguard Worker 
InitEncode(const VideoCodec * config,const Settings & settings)52*d9f75844SAndroid Build Coastguard Worker int32_t FakeVp8Encoder::InitEncode(const VideoCodec* config,
53*d9f75844SAndroid Build Coastguard Worker                                    const Settings& settings) {
54*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
55*d9f75844SAndroid Build Coastguard Worker   auto result = FakeEncoder::InitEncode(config, settings);
56*d9f75844SAndroid Build Coastguard Worker   if (result != WEBRTC_VIDEO_CODEC_OK) {
57*d9f75844SAndroid Build Coastguard Worker     return result;
58*d9f75844SAndroid Build Coastguard Worker   }
59*d9f75844SAndroid Build Coastguard Worker 
60*d9f75844SAndroid Build Coastguard Worker   Vp8TemporalLayersFactory factory;
61*d9f75844SAndroid Build Coastguard Worker   frame_buffer_controller_ =
62*d9f75844SAndroid Build Coastguard Worker       factory.Create(*config, settings, &fec_controller_override_);
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker   return WEBRTC_VIDEO_CODEC_OK;
65*d9f75844SAndroid Build Coastguard Worker }
66*d9f75844SAndroid Build Coastguard Worker 
Release()67*d9f75844SAndroid Build Coastguard Worker int32_t FakeVp8Encoder::Release() {
68*d9f75844SAndroid Build Coastguard Worker   auto result = FakeEncoder::Release();
69*d9f75844SAndroid Build Coastguard Worker   sequence_checker_.Detach();
70*d9f75844SAndroid Build Coastguard Worker   return result;
71*d9f75844SAndroid Build Coastguard Worker }
72*d9f75844SAndroid Build Coastguard Worker 
PopulateCodecSpecific(size_t size_bytes,VideoFrameType frame_type,int stream_idx,uint32_t timestamp)73*d9f75844SAndroid Build Coastguard Worker CodecSpecificInfo FakeVp8Encoder::PopulateCodecSpecific(
74*d9f75844SAndroid Build Coastguard Worker     size_t size_bytes,
75*d9f75844SAndroid Build Coastguard Worker     VideoFrameType frame_type,
76*d9f75844SAndroid Build Coastguard Worker     int stream_idx,
77*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp) {
78*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
79*d9f75844SAndroid Build Coastguard Worker   CodecSpecificInfo codec_specific;
80*d9f75844SAndroid Build Coastguard Worker   codec_specific.codecType = kVideoCodecVP8;
81*d9f75844SAndroid Build Coastguard Worker   codec_specific.codecSpecific.VP8.keyIdx = kNoKeyIdx;
82*d9f75844SAndroid Build Coastguard Worker   codec_specific.codecSpecific.VP8.nonReference = false;
83*d9f75844SAndroid Build Coastguard Worker   if (size_bytes > 0) {
84*d9f75844SAndroid Build Coastguard Worker     frame_buffer_controller_->OnEncodeDone(
85*d9f75844SAndroid Build Coastguard Worker         stream_idx, timestamp, size_bytes,
86*d9f75844SAndroid Build Coastguard Worker         frame_type == VideoFrameType::kVideoFrameKey, -1, &codec_specific);
87*d9f75844SAndroid Build Coastguard Worker   } else {
88*d9f75844SAndroid Build Coastguard Worker     frame_buffer_controller_->OnFrameDropped(stream_idx, timestamp);
89*d9f75844SAndroid Build Coastguard Worker   }
90*d9f75844SAndroid Build Coastguard Worker   return codec_specific;
91*d9f75844SAndroid Build Coastguard Worker }
92*d9f75844SAndroid Build Coastguard Worker 
EncodeHook(EncodedImage & encoded_image,rtc::scoped_refptr<EncodedImageBuffer> buffer)93*d9f75844SAndroid Build Coastguard Worker CodecSpecificInfo FakeVp8Encoder::EncodeHook(
94*d9f75844SAndroid Build Coastguard Worker     EncodedImage& encoded_image,
95*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<EncodedImageBuffer> buffer) {
96*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&sequence_checker_);
97*d9f75844SAndroid Build Coastguard Worker   uint8_t stream_idx = encoded_image.SpatialIndex().value_or(0);
98*d9f75844SAndroid Build Coastguard Worker   frame_buffer_controller_->NextFrameConfig(stream_idx,
99*d9f75844SAndroid Build Coastguard Worker                                             encoded_image.Timestamp());
100*d9f75844SAndroid Build Coastguard Worker   CodecSpecificInfo codec_specific =
101*d9f75844SAndroid Build Coastguard Worker       PopulateCodecSpecific(encoded_image.size(), encoded_image._frameType,
102*d9f75844SAndroid Build Coastguard Worker                             stream_idx, encoded_image.Timestamp());
103*d9f75844SAndroid Build Coastguard Worker 
104*d9f75844SAndroid Build Coastguard Worker   // Write width and height to the payload the same way as the real encoder
105*d9f75844SAndroid Build Coastguard Worker   // does.
106*d9f75844SAndroid Build Coastguard Worker   WriteFakeVp8(buffer->data(), encoded_image._encodedWidth,
107*d9f75844SAndroid Build Coastguard Worker                encoded_image._encodedHeight,
108*d9f75844SAndroid Build Coastguard Worker                encoded_image._frameType == VideoFrameType::kVideoFrameKey);
109*d9f75844SAndroid Build Coastguard Worker   return codec_specific;
110*d9f75844SAndroid Build Coastguard Worker }
111*d9f75844SAndroid Build Coastguard Worker 
GetEncoderInfo() const112*d9f75844SAndroid Build Coastguard Worker VideoEncoder::EncoderInfo FakeVp8Encoder::GetEncoderInfo() const {
113*d9f75844SAndroid Build Coastguard Worker   EncoderInfo info;
114*d9f75844SAndroid Build Coastguard Worker   info.implementation_name = "FakeVp8Encoder";
115*d9f75844SAndroid Build Coastguard Worker   MutexLock lock(&mutex_);
116*d9f75844SAndroid Build Coastguard Worker   for (int sid = 0; sid < config_.numberOfSimulcastStreams; ++sid) {
117*d9f75844SAndroid Build Coastguard Worker     int number_of_temporal_layers =
118*d9f75844SAndroid Build Coastguard Worker         config_.simulcastStream[sid].numberOfTemporalLayers;
119*d9f75844SAndroid Build Coastguard Worker     info.fps_allocation[sid].clear();
120*d9f75844SAndroid Build Coastguard Worker     for (int tid = 0; tid < number_of_temporal_layers; ++tid) {
121*d9f75844SAndroid Build Coastguard Worker       // {1/4, 1/2, 1} allocation for num layers = 3.
122*d9f75844SAndroid Build Coastguard Worker       info.fps_allocation[sid].push_back(255 /
123*d9f75844SAndroid Build Coastguard Worker                                          (number_of_temporal_layers - tid));
124*d9f75844SAndroid Build Coastguard Worker     }
125*d9f75844SAndroid Build Coastguard Worker   }
126*d9f75844SAndroid Build Coastguard Worker   return info;
127*d9f75844SAndroid Build Coastguard Worker }
128*d9f75844SAndroid Build Coastguard Worker 
129*d9f75844SAndroid Build Coastguard Worker }  // namespace test
130*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
131