• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_VIDEO_TRACK_TRANSCODER_H
18 #define ANDROID_VIDEO_TRACK_TRANSCODER_H
19 
20 #include <android/native_window.h>
21 #include <media/MediaTrackTranscoder.h>
22 #include <media/NdkMediaCodecPlatform.h>
23 #include <media/NdkMediaFormat.h>
24 
25 #include <condition_variable>
26 #include <deque>
27 #include <mutex>
28 
29 namespace android {
30 
31 /**
32  * Track transcoder for video tracks. VideoTrackTranscoder uses AMediaCodec from the Media NDK
33  * internally. The two media codecs are run in asynchronous mode and shares uncompressed buffers
34  * using a native surface (ANativeWindow). Codec callback events are placed on a message queue and
35  * serviced in order on the transcoding thread managed by MediaTrackTranscoder.
36  */
37 class VideoTrackTranscoder : public std::enable_shared_from_this<VideoTrackTranscoder>,
38                              public MediaTrackTranscoder {
39 public:
40     static std::shared_ptr<VideoTrackTranscoder> create(
41             const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback,
42             pid_t pid = AMEDIACODEC_CALLING_PID, uid_t uid = AMEDIACODEC_CALLING_UID);
43 
44     virtual ~VideoTrackTranscoder() override;
45 
46 private:
47     friend struct AsyncCodecCallbackDispatch;
48     friend class VideoTrackTranscoderTests;
49 
50     // Minimal blocking queue used as a message queue by VideoTrackTranscoder.
51     template <typename T>
52     class BlockingQueue {
53     public:
54         void push(T const& value, bool front = false);
55         T pop();
56         void abort();
57 
58     private:
59         std::mutex mMutex;
60         std::condition_variable mCondition;
61         std::deque<T> mQueue;
62         bool mAborted = false;
63     };
64     class CodecWrapper;
65 
VideoTrackTranscoder(const std::weak_ptr<MediaTrackTranscoderCallback> & transcoderCallback,pid_t pid,uid_t uid)66     VideoTrackTranscoder(const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback,
67                          pid_t pid, uid_t uid)
68           : MediaTrackTranscoder(transcoderCallback), mPid(pid), mUid(uid){};
69 
70     // MediaTrackTranscoder
71     media_status_t runTranscodeLoop(bool* stopped) override;
72     void abortTranscodeLoop() override;
73     media_status_t configureDestinationFormat(
74             const std::shared_ptr<AMediaFormat>& destinationFormat) override;
75     std::shared_ptr<AMediaFormat> getOutputFormat() const override;
76     // ~MediaTrackTranscoder
77 
78     // Enqueues an input sample with the decoder.
79     void enqueueInputSample(int32_t bufferIndex);
80 
81     // Moves a decoded buffer from the decoder's output to the encoder's input.
82     void transferBuffer(int32_t bufferIndex, AMediaCodecBufferInfo bufferInfo);
83 
84     // Dequeues an encoded buffer from the encoder and adds it to the output queue.
85     void dequeueOutputSample(int32_t bufferIndex, AMediaCodecBufferInfo bufferInfo);
86 
87     // Updates the video track's actual format based on encoder and decoder output format.
88     void updateTrackFormat(AMediaFormat* outputFormat, bool fromDecoder);
89 
90     AMediaCodec* mDecoder = nullptr;
91     std::shared_ptr<CodecWrapper> mEncoder;
92     ANativeWindow* mSurface = nullptr;
93     bool mEosFromSource = false;
94     bool mEosFromEncoder = false;
95     bool mLastSampleWasSync = false;
96     media_status_t mStatus = AMEDIA_OK;
97     MediaSampleInfo mSampleInfo;
98     BlockingQueue<std::function<void()>> mCodecMessageQueue;
99     std::shared_ptr<AMediaFormat> mDestinationFormat;
100     std::shared_ptr<AMediaFormat> mActualOutputFormat;
101     pid_t mPid;
102     uid_t mUid;
103     uint64_t mInputFrameCount = 0;
104     uint64_t mOutputFrameCount = 0;
105     int32_t mConfiguredBitrate = 0;
106 };
107 
108 }  // namespace android
109 #endif  // ANDROID_VIDEO_TRACK_TRANSCODER_H
110