• 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_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