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_TRANSCODER_WRAPPER_H 18 #define ANDROID_TRANSCODER_WRAPPER_H 19 20 #include <media/NdkMediaError.h> 21 #include <media/NdkMediaFormat.h> 22 #include <media/TranscoderInterface.h> 23 #include <media/TranscodingLogger.h> 24 25 #include <chrono> 26 #include <list> 27 #include <map> 28 #include <mutex> 29 30 namespace android { 31 32 class MediaTranscoder; 33 class Parcelable; 34 35 /* 36 * Wrapper class around MediaTranscoder. 37 * Implements TranscoderInterface for TranscodingSessionController to use. 38 */ 39 class TranscoderWrapper : public TranscoderInterface, 40 public std::enable_shared_from_this<TranscoderWrapper> { 41 public: 42 TranscoderWrapper(const std::shared_ptr<TranscoderCallbackInterface>& cb, 43 const std::shared_ptr<TranscodingLogger>& logger, 44 int64_t heartBeatIntervalUs); 45 ~TranscoderWrapper(); 46 47 // TranscoderInterface 48 void start(ClientIdType clientId, SessionIdType sessionId, 49 const TranscodingRequestParcel& request, uid_t callingUid, 50 const std::shared_ptr<ITranscodingClientCallback>& clientCallback) override; 51 void pause(ClientIdType clientId, SessionIdType sessionId) override; 52 void resume(ClientIdType clientId, SessionIdType sessionId, 53 const TranscodingRequestParcel& request, uid_t callingUid, 54 const std::shared_ptr<ITranscodingClientCallback>& clientCallback) override; 55 void stop(ClientIdType clientId, SessionIdType sessionId, bool abandon = false) override; 56 // ~TranscoderInterface 57 58 private: 59 class CallbackImpl; 60 struct Event { 61 enum Type { 62 NoEvent, 63 Start, 64 Pause, 65 Resume, 66 Stop, 67 Finish, 68 Error, 69 Progress, 70 HeartBeat, 71 Abandon 72 } type; 73 ClientIdType clientId; 74 SessionIdType sessionId; 75 std::function<void()> runnable; 76 int32_t arg; 77 }; 78 using SessionKeyType = std::pair<ClientIdType, SessionIdType>; 79 80 std::shared_ptr<CallbackImpl> mTranscoderCb; 81 std::shared_ptr<MediaTranscoder> mTranscoder; 82 std::weak_ptr<TranscoderCallbackInterface> mCallback; 83 std::shared_ptr<TranscodingLogger> mLogger; 84 std::shared_ptr<AMediaFormat> mSrcFormat; 85 std::shared_ptr<AMediaFormat> mDstFormat; 86 int64_t mHeartBeatIntervalUs; 87 std::mutex mLock; 88 std::condition_variable mCondition; 89 std::list<Event> mQueue; // GUARDED_BY(mLock); 90 std::map<SessionKeyType, std::shared_ptr<ndk::ScopedAParcel>> mPausedStateMap; 91 ClientIdType mCurrentClientId; 92 SessionIdType mCurrentSessionId; 93 uid_t mCurrentCallingUid; 94 std::chrono::steady_clock::time_point mTranscodeStartTime; 95 96 // Whether the looper has been created. 97 bool mLooperReady; 98 99 static std::string toString(const Event& event); 100 void onFinish(ClientIdType clientId, SessionIdType sessionId); 101 void onError(ClientIdType clientId, SessionIdType sessionId, media_status_t status); 102 void onProgress(ClientIdType clientId, SessionIdType sessionId, int32_t progress); 103 void onHeartBeat(ClientIdType clientId, SessionIdType sessionId); 104 105 media_status_t handleStart(ClientIdType clientId, SessionIdType sessionId, 106 const TranscodingRequestParcel& request, uid_t callingUid, 107 const std::shared_ptr<ITranscodingClientCallback>& callback); 108 media_status_t handlePause(ClientIdType clientId, SessionIdType sessionId); 109 media_status_t handleResume(ClientIdType clientId, SessionIdType sessionId, 110 const TranscodingRequestParcel& request, uid_t callingUid, 111 const std::shared_ptr<ITranscodingClientCallback>& callback); 112 media_status_t setupTranscoder( 113 ClientIdType clientId, SessionIdType sessionId, const TranscodingRequestParcel& request, 114 uid_t callingUid, const std::shared_ptr<ITranscodingClientCallback>& callback, 115 TranscodingLogger::SessionEndedReason* failureReason /* nonnull */, 116 const std::shared_ptr<ndk::ScopedAParcel>& pausedState = nullptr); 117 118 void cleanup(); 119 void logSessionEnded(const TranscodingLogger::SessionEndedReason& reason, int error); 120 void reportError(ClientIdType clientId, SessionIdType sessionId, media_status_t err); 121 void queueEvent(Event::Type type, ClientIdType clientId, SessionIdType sessionId, 122 const std::function<void()> runnable, int32_t arg = 0); 123 void threadLoop(); 124 }; 125 126 } // namespace android 127 #endif // ANDROID_TRANSCODER_WRAPPER_H 128