Ocean
Loading...
Searching...
No Matches
VideoDecoder.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_MEDIA_ANDROID_VIDEO_DECODER_H
9#define META_OCEAN_MEDIA_ANDROID_VIDEO_DECODER_H
10
11#if defined(__ANDROID_API__) && __ANDROID_API__ >= 24
12
13#ifndef OCEAN_MEDIA_ANDROID_VIDEODECODER_AVAILABLE
14 #define OCEAN_MEDIA_ANDROID_VIDEODECODER_AVAILABLE
15#endif
16
19
20#include "ocean/base/Frame.h"
21#include "ocean/base/Lock.h"
22
23namespace Ocean
24{
25
26namespace Media
27{
28
29namespace Android
30{
31
32/**
33 * This class implements a simple video decoder for Android using encoded media samples from memory as input.
34 *
35 * Usage:
36 * @code
37 * // a function which is e.g., running in a separate thread
38 * void threadRun()
39 * {
40 * VideoDecoder videoDecoder;
41 *
42 * // initializing the decoder with the input format of the media samples
43 * if (!videoDecoder.initialize("video/avc", 1920u, 1080u))
44 * {
45 * // handle error
46 * }
47 *
48 * if (!videoDecoder.start())
49 * {
50 * // handle error
51 * }
52 *
53 * unsigned int frameIndex = 0u;
54 * double frameRate = 30.0;
55 *
56 * while (true)
57 * {
58 * void* sampleData = nullptr;
59 * size_t sampleSize = 0;
60 *
61 * // external function: function needs to provide the new media samples from an external source - e.g., from an external webcam, a video stream, etc.
62 * if (doesNewInputSampleExist(sampleData, &sampleSize))
63 * {
64 * // presentation time in microseconds
65 * uint64_t presentationTime = uint64_t(1.0e6 * double(frameIndex) / frameRate);
66 *
67 * // we forward the media sample to the decoder, eventually it will be decoded and will be available through decodedFrame()
68 * if (!videoDecoder.pushSample(sampleData, sampleSize, presentationTime))
69 * {
70 * // handle error
71 * }
72 *
73 * ++frameIndex;
74 * }
75 *
76 * // we simply check whether another frame has been decoded (there may be a delay between
77 * Frame newFrame = videoDecoder.popFrame();
78 *
79 * if (newFrame.isValid())
80 * {
81 * // external function: receiving new frames and processes the frames
82 * sendFrameToReceiver(std::move(newFrame));
83 * }
84 * }
85 * }
86 * @endcode
87 * @ingroup mediaandroid
88 */
90{
91 public:
92
93 /**
94 * Default constructor creating an un-initialized decoder.
95 */
97
98 /**
99 * Move constructor.
100 * @param videoDecoder The decoder to be moved
101 */
102 inline VideoDecoder(VideoDecoder&& videoDecoder) noexcept;
103
104 /**
105 * Destructs the video decoder and releases all associated resources.
106 */
108
109 /**
110 * @param mime The MIME type (Multipurpose Internet Mail Extensions) of the video to be decoded, e.g., "video/avc", "video/hevc", ...
111 * @param width The width of the video to be decoded, in pixel, with range [1, infinity)
112 * @param height The height of the video to be decoded, in pixel, with range [1, infinity)
113 * @return True, if succeeded
114 * @see isInitialized().
115 */
116 bool initialize(const std::string& mime, const unsigned int width, const unsigned int height);
117
118 /**
119 * Starts the video decoder.
120 * @return True, if succeeded
121 * @see isStarted().
122 */
123 bool start();
124
125 /**
126 * Stops the video decoder.
127 * @return True, if succeeded
128 */
129 bool stop();
130
131 /**
132 * Adds a new media sample which needs to be decoded to the video decoder.
133 * The decoder needs to be initialized and started.<br>
134 * The presentation time is mainly intended to allow associating the provided encoded media sample with the resulting decoded frame when calling popFrame().<br>
135 * However, it's recommended to define a reasonable presentation time for each sample (e.g., let the first sample start at 0 and increment the time by 1^6/fps for each following sample.
136 * @param data The data of the encoded media sample, must be valid
137 * @param size The size of the encoded media sample, in bytes, with range [1, infinity)
138 * @param presentationTime The presentation time of the sample, in microseconds, with range [0, infinity)
139 * @return True, if succeeded
140 * @see start(), isInitialized(), isStarted().
141 */
142 bool pushSample(const void* data, const size_t size, const uint64_t presentationTime);
143
144 /**
145 * Optional the frame's presentation time will be returned, this is the presentation time which was used when the corresponding sample was provided in decodedSample().
146 * @param presentationTime Optional resulting presentation time in micro seconds, with range (-infinity, infinity)
147 * @return The resulting frame, invalid if currently no decoded frame is available
148 * @see pushSample().
149 */
150 Frame popFrame(int64_t* presentationTime = nullptr);
151
152 /**
153 * Returns whether this decode is initialized.
154 * @return True, if so
155 * @see initialize().
156 */
157 inline bool isInitialized() const;
158
159 /**
160 * Returns whether this decoder is currently running.
161 * @return True, if so
162 * @see start().
163 */
164 inline bool isStarted() const;
165
166 /**
167 * Explicitly releases this video encoder.
168 * If the encoder is still running, the encoder will be stopped as well.
169 */
170 void release();
171
172 /**
173 * Move operator.
174 * @param videoDecoder The video decoder to be moved
175 * @return Reference to this object
176 */
177 inline VideoDecoder& operator=(VideoDecoder&& videoDecoder) noexcept;
178
179 /**
180 * Extracts the video frame from an output buffer of a video codec.
181 * @param mediaCodec The media codec to which the output buffer belongs, must be valid
182 * @param presentationTime Optional resulting presentation time in micro seconds, with range (-infinity, infinity)
183 * @return The resulting extracted frame, invalid if the frame could not be extracted
184 */
185 static Frame extractVideoFrameFromCodecOutputBuffer(AMediaCodec* const mediaCodec, int64_t* presentationTime = nullptr);
186
187 protected:
188
189 /**
190 * Disabled copy constructor.
191 */
192 VideoDecoder(const VideoDecoder&) = delete;
193
194 /**
195 * Disabled copy operator.
196 * @return Reference to this object
197 */
199
200 protected:
201
202 /// The subscription for the native media library.
204
205 /// The Android media decoder used to decode the video.
207
208 /// True, if the decoder is currently started.
209 bool isStarted_ = false;
210
211 /// The decoder's lock.
212 mutable Lock lock_;
213};
214
215inline VideoDecoder::VideoDecoder(VideoDecoder&& videoDecoder) noexcept
216{
217 *this = std::move(videoDecoder);
218}
219
221{
222 const ScopedLock scopedLock(lock_);
223
224 return decoder_.isValid();
225}
226
227inline bool VideoDecoder::isStarted() const
228{
229 const ScopedLock scopedLock(lock_);
230
231 ocean_assert(!isStarted_ || isInitialized());
232
233 return isStarted_;
234}
235
236inline VideoDecoder& VideoDecoder::operator=(VideoDecoder&& videoDecoder) noexcept
237{
238 if (this != &videoDecoder)
239 {
240 release();
241
242 decoder_ = std::move(videoDecoder.decoder_);
243
244 isStarted_ = videoDecoder.isStarted_;
245 videoDecoder.isStarted_ = false;
246 }
247
248 return *this;
249}
250
251}
252
253}
254
255}
256
257#endif // defined(__ANDROID_API__) && __ANDROID_API__ >= 24
258
259#endif // META_OCEAN_MEDIA_ANDROID_VIDEO_DECODER_H
This class implements Ocean's image class.
Definition Frame.h:1808
This class implements a recursive lock object.
Definition Lock.h:31
Definition of a scoped object for AMediaCodec objects.
Definition NativeMediaLibrary.h:79
This class implements a simple video decoder for Android using encoded media samples from memory as i...
Definition VideoDecoder.h:90
bool initialize(const std::string &mime, const unsigned int width, const unsigned int height)
VideoDecoder(const VideoDecoder &)=delete
Disabled copy constructor.
static Frame extractVideoFrameFromCodecOutputBuffer(AMediaCodec *const mediaCodec, int64_t *presentationTime=nullptr)
Extracts the video frame from an output buffer of a video codec.
NativeMediaLibrary::ScopedAMediaCodec decoder_
The Android media decoder used to decode the video.
Definition VideoDecoder.h:206
VideoDecoder & operator=(VideoDecoder &&videoDecoder) noexcept
Move operator.
Definition VideoDecoder.h:236
void release()
Explicitly releases this video encoder.
VideoDecoder()
Default constructor creating an un-initialized decoder.
Lock lock_
The decoder's lock.
Definition VideoDecoder.h:212
~VideoDecoder()
Destructs the video decoder and releases all associated resources.
bool isStarted_
True, if the decoder is currently started.
Definition VideoDecoder.h:209
NativeMediaLibrary::ScopedSubscription nativeMediaLibrarySubscription_
The subscription for the native media library.
Definition VideoDecoder.h:203
bool isInitialized() const
Returns whether this decode is initialized.
Definition VideoDecoder.h:220
bool isStarted() const
Returns whether this decoder is currently running.
Definition VideoDecoder.h:227
bool stop()
Stops the video decoder.
bool pushSample(const void *data, const size_t size, const uint64_t presentationTime)
Adds a new media sample which needs to be decoded to the video decoder.
Frame popFrame(int64_t *presentationTime=nullptr)
Optional the frame's presentation time will be returned, this is the presentation time which was used...
bool start()
Starts the video decoder.
VideoDecoder & operator=(const VideoDecoder &)=delete
Disabled copy operator.
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:135
bool isValid() const
Returns whether this scoped object holds a valid release function (which will be invoked once the obj...
Definition ScopedObject.h:351
The namespace covering the entire Ocean framework.
Definition Accessor.h:15