1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
media / gpu / android / android_video_encode_accelerator.h [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_ANDROID_ANDROID_VIDEO_ENCODE_ACCELERATOR_H_
#define MEDIA_GPU_ANDROID_ANDROID_VIDEO_ENCODE_ACCELERATOR_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <tuple>
#include <vector>
#include "base/containers/queue.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "media/base/android/media_codec_bridge_impl.h"
#include "media/base/bitrate.h"
#include "media/gpu/media_gpu_export.h"
#include "media/video/video_encode_accelerator.h"
namespace media {
class BitstreamBuffer;
// Android-specific implementation of VideoEncodeAccelerator, enabling
// hardware-acceleration of video encoding, based on Android's MediaCodec class
// (http://developer.android.com/reference/android/media/MediaCodec.html). This
// class expects to live and be called on a single thread (the GPU process'
// ChildThread).
class MEDIA_GPU_EXPORT AndroidVideoEncodeAccelerator
: public VideoEncodeAccelerator {
public:
AndroidVideoEncodeAccelerator();
AndroidVideoEncodeAccelerator(const AndroidVideoEncodeAccelerator&) = delete;
AndroidVideoEncodeAccelerator& operator=(
const AndroidVideoEncodeAccelerator&) = delete;
~AndroidVideoEncodeAccelerator() override;
// VideoEncodeAccelerator implementation.
VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() override;
bool Initialize(const Config& config,
Client* client,
std::unique_ptr<MediaLog> media_log) override;
void Encode(scoped_refptr<VideoFrame> frame, bool force_keyframe) override;
void UseOutputBitstreamBuffer(BitstreamBuffer buffer) override;
void RequestEncodingParametersChange(
const Bitrate& bitrate,
uint32_t framerate,
const std::optional<gfx::Size>& size) override;
void Destroy() override;
private:
enum {
// Arbitrary choice.
INITIAL_FRAMERATE = 30,
// Default I-Frame interval in seconds.
IFRAME_INTERVAL_H264 = 20,
IFRAME_INTERVAL_VPX = 100,
IFRAME_INTERVAL = INT32_MAX,
};
// Impedance-mismatch fixers: MediaCodec is a poll-based API but VEA is a
// push-based API; these methods turn the crank to make the two work together.
void DoIOTask();
void QueueInput();
void DequeueOutput();
// Start & stop |io_timer_| if the time seems right.
void MaybeStartIOTimer();
void MaybeStopIOTimer();
// Ask MediaCodec what input buffer layout it prefers and set values of
// |input_buffer_stride_| and |input_buffer_yplane_height_|. If the codec
// does not provide these values, sets up |aligned_size_| such that encoded
// frames are cropped to the nearest 16x16 alignment.
bool SetInputBufferLayout();
void NotifyErrorStatus(EncoderStatus status);
// Used to DCHECK that we are called on the correct sequence.
SEQUENCE_CHECKER(sequence_checker_);
// VideoDecodeAccelerator::Client callbacks go here. Invalidated once any
// error triggers.
std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_;
std::unique_ptr<MediaLog> log_;
std::unique_ptr<MediaCodecBridge> media_codec_;
// Bitstream buffers waiting to be populated & returned to the client.
std::vector<BitstreamBuffer> available_bitstream_buffers_;
// Frames waiting to be passed to the codec, queued until an input buffer is
// available. Each element is a tuple of <Frame, key_frame, enqueue_time>.
using PendingFrames =
base::queue<std::tuple<scoped_refptr<VideoFrame>, bool, base::Time>>;
PendingFrames pending_frames_;
// Repeating timer responsible for draining pending IO to the codec.
base::RepeatingTimer io_timer_;
// The difference between number of buffers queued & dequeued at the codec.
int32_t num_buffers_at_codec_ = 0;
// A monotonically-growing value.
base::TimeDelta presentation_timestamp_;
std::map<base::TimeDelta /* presentation_timestamp */,
base::TimeDelta /* frame_timestamp */>
frame_timestamp_map_;
// Resolution of input stream. Set once in initialization and not allowed to
// change after.
gfx::Size frame_size_;
// Y and UV plane strides in the encoder's input buffer
int input_buffer_stride_ = 0;
// Y-plane height in the encoder's input
int input_buffer_yplane_height_ = 0;
uint32_t last_set_bitrate_ = 0; // In bps.
// True if there is encoder error.
bool error_occurred_ = false;
// Required for encoders which are missing stride information.
std::optional<gfx::Size> aligned_size_;
};
} // namespace media
#endif // MEDIA_GPU_ANDROID_ANDROID_VIDEO_ENCODE_ACCELERATOR_H_