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_PASSTHROUGH_TRACK_TRANSCODER_H 18 #define ANDROID_PASSTHROUGH_TRACK_TRANSCODER_H 19 20 #include <media/MediaTrackTranscoder.h> 21 #include <media/NdkMediaFormat.h> 22 23 #include <condition_variable> 24 #include <map> 25 #include <mutex> 26 #include <unordered_map> 27 28 namespace android { 29 30 /** 31 * Track transcoder for passthrough mode. Passthrough mode copies sample data from a track unchanged 32 * from source file to destination file. This track transcoder uses an internal pool of buffers. 33 * When the maximum number of buffers are allocated and all of them are waiting on the output queue 34 * the transcoder will stall until samples are dequeued from the output queue and released. 35 */ 36 class PassthroughTrackTranscoder : public MediaTrackTranscoder { 37 public: 38 /** Maximum number of buffers to be allocated at a given time. */ 39 static constexpr int kMaxBufferCountDefault = 16; 40 PassthroughTrackTranscoder(const std::weak_ptr<MediaTrackTranscoderCallback> & transcoderCallback)41 PassthroughTrackTranscoder( 42 const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback) 43 : MediaTrackTranscoder(transcoderCallback), 44 mBufferPool(std::make_shared<BufferPool>(kMaxBufferCountDefault)){}; 45 virtual ~PassthroughTrackTranscoder() override = default; 46 47 private: 48 friend class BufferPoolTests; 49 50 /** Class to pool and reuse buffers. */ 51 class BufferPool { 52 public: BufferPool(int maxBufferCount)53 explicit BufferPool(int maxBufferCount) : mMaxBufferCount(maxBufferCount){}; 54 ~BufferPool(); 55 56 /** 57 * Retrieve a buffer from the pool. Buffers are allocated on demand. This method will block 58 * if the maximum number of buffers is reached and there are no free buffers available. 59 * @param minimumBufferSize The minimum size of the buffer. 60 * @return The buffer or nullptr if allocation failed or the pool was aborted. 61 */ 62 uint8_t* getBufferWithSize(size_t minimumBufferSize); 63 64 /** 65 * Return a buffer to the pool. 66 * @param buffer The buffer to return. 67 */ 68 void returnBuffer(uint8_t* buffer); 69 70 /** Wakes up threads waiting on buffers and prevents new buffers from being returned. */ 71 void abort(); 72 73 private: 74 // Maximum number of active buffers at a time. 75 const int mMaxBufferCount; 76 77 // Map containing all tracked buffers. 78 std::unordered_map<uint8_t*, size_t> mAddressSizeMap GUARDED_BY(mMutex); 79 80 // Map containing the currently free buffers. 81 std::multimap<size_t, uint8_t*> mFreeBufferMap GUARDED_BY(mMutex); 82 83 std::mutex mMutex; 84 std::condition_variable mCondition; 85 bool mAborted GUARDED_BY(mMutex) = false; 86 }; 87 88 // MediaTrackTranscoder 89 media_status_t runTranscodeLoop(bool* stopped) override; 90 void abortTranscodeLoop() override; 91 media_status_t configureDestinationFormat( 92 const std::shared_ptr<AMediaFormat>& destinationFormat) override; 93 std::shared_ptr<AMediaFormat> getOutputFormat() const override; 94 // ~MediaTrackTranscoder 95 96 std::shared_ptr<BufferPool> mBufferPool; 97 }; 98 99 } // namespace android 100 #endif // ANDROID_PASSTHROUGH_TRACK_TRANSCODER_H 101