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