xref: /aosp_15_r20/frameworks/av/media/ndk/NdkMediaCodec.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #include <charconv>
18*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
19*ec779b8eSAndroid Build Coastguard Worker #include <mutex>
20*ec779b8eSAndroid Build Coastguard Worker #include <set>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
23*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "NdkMediaCodec"
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker #include <media/NdkMediaCodecPlatform.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <media/NdkMediaError.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/NdkMediaFormatPriv.h>
28*ec779b8eSAndroid Build Coastguard Worker #include "NdkMediaCryptoPriv.h"
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <gui/Surface.h>
33*ec779b8eSAndroid Build Coastguard Worker 
34*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ALooper.h>
35*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABuffer.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AMessage.h>
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/PersistentSurface.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaCodec.h>
40*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaErrors.h>
41*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaCodecBuffer.h>
42*ec779b8eSAndroid Build Coastguard Worker #include <android/native_window.h>
43*ec779b8eSAndroid Build Coastguard Worker 
44*ec779b8eSAndroid Build Coastguard Worker using namespace android;
45*ec779b8eSAndroid Build Coastguard Worker 
46*ec779b8eSAndroid Build Coastguard Worker 
translate_error(status_t err)47*ec779b8eSAndroid Build Coastguard Worker static media_status_t translate_error(status_t err) {
48*ec779b8eSAndroid Build Coastguard Worker 
49*ec779b8eSAndroid Build Coastguard Worker     if (err == OK) {
50*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_OK;
51*ec779b8eSAndroid Build Coastguard Worker     } else if (err == -EAGAIN) {
52*ec779b8eSAndroid Build Coastguard Worker         return (media_status_t) AMEDIACODEC_INFO_TRY_AGAIN_LATER;
53*ec779b8eSAndroid Build Coastguard Worker     } else if (err == NO_MEMORY) {
54*ec779b8eSAndroid Build Coastguard Worker         return AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE;
55*ec779b8eSAndroid Build Coastguard Worker     } else if (err == DEAD_OBJECT) {
56*ec779b8eSAndroid Build Coastguard Worker         return AMEDIACODEC_ERROR_RECLAIMED;
57*ec779b8eSAndroid Build Coastguard Worker     }
58*ec779b8eSAndroid Build Coastguard Worker 
59*ec779b8eSAndroid Build Coastguard Worker     {
60*ec779b8eSAndroid Build Coastguard Worker         // minimize log flooding. Some CTS behavior made this noisy and apps could do the same.
61*ec779b8eSAndroid Build Coastguard Worker         static std::set<status_t> untranslated;
62*ec779b8eSAndroid Build Coastguard Worker         static std::mutex mutex;
63*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard lg(mutex);
64*ec779b8eSAndroid Build Coastguard Worker 
65*ec779b8eSAndroid Build Coastguard Worker         if (untranslated.find(err) == untranslated.end()) {
66*ec779b8eSAndroid Build Coastguard Worker             ALOGE("untranslated sf error code: %d", err);
67*ec779b8eSAndroid Build Coastguard Worker             char err_as_string[32];
68*ec779b8eSAndroid Build Coastguard Worker             snprintf(err_as_string, sizeof(err_as_string), "%d", err);
69*ec779b8eSAndroid Build Coastguard Worker             android_errorWriteWithInfoLog(0x534e4554, "224869524", -1,
70*ec779b8eSAndroid Build Coastguard Worker                                           err_as_string, strlen(err_as_string));
71*ec779b8eSAndroid Build Coastguard Worker             untranslated.insert(err);
72*ec779b8eSAndroid Build Coastguard Worker         }
73*ec779b8eSAndroid Build Coastguard Worker     }
74*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_ERROR_UNKNOWN;
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker 
77*ec779b8eSAndroid Build Coastguard Worker enum {
78*ec779b8eSAndroid Build Coastguard Worker     kWhatActivityNotify,
79*ec779b8eSAndroid Build Coastguard Worker     kWhatAsyncNotify,
80*ec779b8eSAndroid Build Coastguard Worker     kWhatRequestActivityNotifications,
81*ec779b8eSAndroid Build Coastguard Worker     kWhatStopActivityNotifications,
82*ec779b8eSAndroid Build Coastguard Worker     kWhatFrameRenderedNotify,
83*ec779b8eSAndroid Build Coastguard Worker };
84*ec779b8eSAndroid Build Coastguard Worker 
85*ec779b8eSAndroid Build Coastguard Worker struct AMediaCodecPersistentSurface : public Surface {
86*ec779b8eSAndroid Build Coastguard Worker     sp<PersistentSurface> mPersistentSurface;
AMediaCodecPersistentSurfaceAMediaCodecPersistentSurface87*ec779b8eSAndroid Build Coastguard Worker     AMediaCodecPersistentSurface(
88*ec779b8eSAndroid Build Coastguard Worker             const sp<IGraphicBufferProducer>& igbp,
89*ec779b8eSAndroid Build Coastguard Worker             const sp<PersistentSurface>& ps)
90*ec779b8eSAndroid Build Coastguard Worker             : Surface(igbp) {
91*ec779b8eSAndroid Build Coastguard Worker         mPersistentSurface = ps;
92*ec779b8eSAndroid Build Coastguard Worker     }
~AMediaCodecPersistentSurfaceAMediaCodecPersistentSurface93*ec779b8eSAndroid Build Coastguard Worker     virtual ~AMediaCodecPersistentSurface() {
94*ec779b8eSAndroid Build Coastguard Worker         //mPersistentSurface ref will be let go off here
95*ec779b8eSAndroid Build Coastguard Worker     }
96*ec779b8eSAndroid Build Coastguard Worker };
97*ec779b8eSAndroid Build Coastguard Worker 
98*ec779b8eSAndroid Build Coastguard Worker class CodecHandler: public AHandler {
99*ec779b8eSAndroid Build Coastguard Worker private:
100*ec779b8eSAndroid Build Coastguard Worker     AMediaCodec* mCodec;
101*ec779b8eSAndroid Build Coastguard Worker public:
102*ec779b8eSAndroid Build Coastguard Worker     explicit CodecHandler(AMediaCodec *codec);
103*ec779b8eSAndroid Build Coastguard Worker     virtual void onMessageReceived(const sp<AMessage> &msg);
104*ec779b8eSAndroid Build Coastguard Worker };
105*ec779b8eSAndroid Build Coastguard Worker 
106*ec779b8eSAndroid Build Coastguard Worker typedef void (*OnCodecEvent)(AMediaCodec *codec, void *userdata);
107*ec779b8eSAndroid Build Coastguard Worker 
108*ec779b8eSAndroid Build Coastguard Worker struct AMediaCodec {
109*ec779b8eSAndroid Build Coastguard Worker     sp<android::MediaCodec> mCodec;
110*ec779b8eSAndroid Build Coastguard Worker     sp<ALooper> mLooper;
111*ec779b8eSAndroid Build Coastguard Worker     sp<CodecHandler> mHandler;
112*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> mActivityNotification;
113*ec779b8eSAndroid Build Coastguard Worker     int32_t mGeneration;
114*ec779b8eSAndroid Build Coastguard Worker     bool mRequestedActivityNotification;
115*ec779b8eSAndroid Build Coastguard Worker     OnCodecEvent mCallback;
116*ec779b8eSAndroid Build Coastguard Worker     void *mCallbackUserData;
117*ec779b8eSAndroid Build Coastguard Worker 
118*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> mAsyncNotify;
119*ec779b8eSAndroid Build Coastguard Worker     mutable Mutex mAsyncCallbackLock;
120*ec779b8eSAndroid Build Coastguard Worker     AMediaCodecOnAsyncNotifyCallback mAsyncCallback;
121*ec779b8eSAndroid Build Coastguard Worker     void *mAsyncCallbackUserData;
122*ec779b8eSAndroid Build Coastguard Worker 
123*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> mFrameRenderedNotify;
124*ec779b8eSAndroid Build Coastguard Worker     mutable Mutex mFrameRenderedCallbackLock;
125*ec779b8eSAndroid Build Coastguard Worker     AMediaCodecOnFrameRendered mFrameRenderedCallback;
126*ec779b8eSAndroid Build Coastguard Worker     void *mFrameRenderedCallbackUserData;
127*ec779b8eSAndroid Build Coastguard Worker };
128*ec779b8eSAndroid Build Coastguard Worker 
CodecHandler(AMediaCodec * codec)129*ec779b8eSAndroid Build Coastguard Worker CodecHandler::CodecHandler(AMediaCodec *codec) {
130*ec779b8eSAndroid Build Coastguard Worker     mCodec = codec;
131*ec779b8eSAndroid Build Coastguard Worker }
132*ec779b8eSAndroid Build Coastguard Worker 
onMessageReceived(const sp<AMessage> & msg)133*ec779b8eSAndroid Build Coastguard Worker void CodecHandler::onMessageReceived(const sp<AMessage> &msg) {
134*ec779b8eSAndroid Build Coastguard Worker 
135*ec779b8eSAndroid Build Coastguard Worker     switch (msg->what()) {
136*ec779b8eSAndroid Build Coastguard Worker         case kWhatRequestActivityNotifications:
137*ec779b8eSAndroid Build Coastguard Worker         {
138*ec779b8eSAndroid Build Coastguard Worker             if (mCodec->mRequestedActivityNotification) {
139*ec779b8eSAndroid Build Coastguard Worker                 break;
140*ec779b8eSAndroid Build Coastguard Worker             }
141*ec779b8eSAndroid Build Coastguard Worker 
142*ec779b8eSAndroid Build Coastguard Worker             mCodec->mCodec->requestActivityNotification(mCodec->mActivityNotification);
143*ec779b8eSAndroid Build Coastguard Worker             mCodec->mRequestedActivityNotification = true;
144*ec779b8eSAndroid Build Coastguard Worker             break;
145*ec779b8eSAndroid Build Coastguard Worker         }
146*ec779b8eSAndroid Build Coastguard Worker 
147*ec779b8eSAndroid Build Coastguard Worker         case kWhatActivityNotify:
148*ec779b8eSAndroid Build Coastguard Worker         {
149*ec779b8eSAndroid Build Coastguard Worker             {
150*ec779b8eSAndroid Build Coastguard Worker                 int32_t generation;
151*ec779b8eSAndroid Build Coastguard Worker                 msg->findInt32("generation", &generation);
152*ec779b8eSAndroid Build Coastguard Worker 
153*ec779b8eSAndroid Build Coastguard Worker                 if (generation != mCodec->mGeneration) {
154*ec779b8eSAndroid Build Coastguard Worker                     // stale
155*ec779b8eSAndroid Build Coastguard Worker                     break;
156*ec779b8eSAndroid Build Coastguard Worker                 }
157*ec779b8eSAndroid Build Coastguard Worker 
158*ec779b8eSAndroid Build Coastguard Worker                 mCodec->mRequestedActivityNotification = false;
159*ec779b8eSAndroid Build Coastguard Worker             }
160*ec779b8eSAndroid Build Coastguard Worker 
161*ec779b8eSAndroid Build Coastguard Worker             if (mCodec->mCallback) {
162*ec779b8eSAndroid Build Coastguard Worker                 mCodec->mCallback(mCodec, mCodec->mCallbackUserData);
163*ec779b8eSAndroid Build Coastguard Worker             }
164*ec779b8eSAndroid Build Coastguard Worker             break;
165*ec779b8eSAndroid Build Coastguard Worker         }
166*ec779b8eSAndroid Build Coastguard Worker 
167*ec779b8eSAndroid Build Coastguard Worker         case kWhatAsyncNotify:
168*ec779b8eSAndroid Build Coastguard Worker         {
169*ec779b8eSAndroid Build Coastguard Worker              int32_t cbID;
170*ec779b8eSAndroid Build Coastguard Worker              if (!msg->findInt32("callbackID", &cbID)) {
171*ec779b8eSAndroid Build Coastguard Worker                  ALOGE("kWhatAsyncNotify: callbackID is expected.");
172*ec779b8eSAndroid Build Coastguard Worker                  break;
173*ec779b8eSAndroid Build Coastguard Worker              }
174*ec779b8eSAndroid Build Coastguard Worker 
175*ec779b8eSAndroid Build Coastguard Worker              ALOGV("kWhatAsyncNotify: cbID = %d", cbID);
176*ec779b8eSAndroid Build Coastguard Worker 
177*ec779b8eSAndroid Build Coastguard Worker              switch (cbID) {
178*ec779b8eSAndroid Build Coastguard Worker                  case MediaCodec::CB_INPUT_AVAILABLE:
179*ec779b8eSAndroid Build Coastguard Worker                  {
180*ec779b8eSAndroid Build Coastguard Worker                      int32_t index;
181*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findInt32("index", &index)) {
182*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_INPUT_AVAILABLE: index is expected.");
183*ec779b8eSAndroid Build Coastguard Worker                          break;
184*ec779b8eSAndroid Build Coastguard Worker                      }
185*ec779b8eSAndroid Build Coastguard Worker 
186*ec779b8eSAndroid Build Coastguard Worker                      Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
187*ec779b8eSAndroid Build Coastguard Worker                      if (mCodec->mAsyncCallback.onAsyncInputAvailable != NULL) {
188*ec779b8eSAndroid Build Coastguard Worker                          mCodec->mAsyncCallback.onAsyncInputAvailable(
189*ec779b8eSAndroid Build Coastguard Worker                                  mCodec,
190*ec779b8eSAndroid Build Coastguard Worker                                  mCodec->mAsyncCallbackUserData,
191*ec779b8eSAndroid Build Coastguard Worker                                  index);
192*ec779b8eSAndroid Build Coastguard Worker                      }
193*ec779b8eSAndroid Build Coastguard Worker 
194*ec779b8eSAndroid Build Coastguard Worker                      break;
195*ec779b8eSAndroid Build Coastguard Worker                  }
196*ec779b8eSAndroid Build Coastguard Worker 
197*ec779b8eSAndroid Build Coastguard Worker                  case MediaCodec::CB_OUTPUT_AVAILABLE:
198*ec779b8eSAndroid Build Coastguard Worker                  {
199*ec779b8eSAndroid Build Coastguard Worker                      int32_t index;
200*ec779b8eSAndroid Build Coastguard Worker                      size_t offset;
201*ec779b8eSAndroid Build Coastguard Worker                      size_t size;
202*ec779b8eSAndroid Build Coastguard Worker                      int64_t timeUs;
203*ec779b8eSAndroid Build Coastguard Worker                      int32_t flags;
204*ec779b8eSAndroid Build Coastguard Worker 
205*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findInt32("index", &index)) {
206*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_OUTPUT_AVAILABLE: index is expected.");
207*ec779b8eSAndroid Build Coastguard Worker                          break;
208*ec779b8eSAndroid Build Coastguard Worker                      }
209*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findSize("offset", &offset)) {
210*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_OUTPUT_AVAILABLE: offset is expected.");
211*ec779b8eSAndroid Build Coastguard Worker                          break;
212*ec779b8eSAndroid Build Coastguard Worker                      }
213*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findSize("size", &size)) {
214*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_OUTPUT_AVAILABLE: size is expected.");
215*ec779b8eSAndroid Build Coastguard Worker                          break;
216*ec779b8eSAndroid Build Coastguard Worker                      }
217*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findInt64("timeUs", &timeUs)) {
218*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_OUTPUT_AVAILABLE: timeUs is expected.");
219*ec779b8eSAndroid Build Coastguard Worker                          break;
220*ec779b8eSAndroid Build Coastguard Worker                      }
221*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findInt32("flags", &flags)) {
222*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_OUTPUT_AVAILABLE: flags is expected.");
223*ec779b8eSAndroid Build Coastguard Worker                          break;
224*ec779b8eSAndroid Build Coastguard Worker                      }
225*ec779b8eSAndroid Build Coastguard Worker 
226*ec779b8eSAndroid Build Coastguard Worker                      AMediaCodecBufferInfo bufferInfo = {
227*ec779b8eSAndroid Build Coastguard Worker                          (int32_t)offset,
228*ec779b8eSAndroid Build Coastguard Worker                          (int32_t)size,
229*ec779b8eSAndroid Build Coastguard Worker                          timeUs,
230*ec779b8eSAndroid Build Coastguard Worker                          (uint32_t)flags};
231*ec779b8eSAndroid Build Coastguard Worker 
232*ec779b8eSAndroid Build Coastguard Worker                      Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
233*ec779b8eSAndroid Build Coastguard Worker                      if (mCodec->mAsyncCallback.onAsyncOutputAvailable != NULL) {
234*ec779b8eSAndroid Build Coastguard Worker                          mCodec->mAsyncCallback.onAsyncOutputAvailable(
235*ec779b8eSAndroid Build Coastguard Worker                                  mCodec,
236*ec779b8eSAndroid Build Coastguard Worker                                  mCodec->mAsyncCallbackUserData,
237*ec779b8eSAndroid Build Coastguard Worker                                  index,
238*ec779b8eSAndroid Build Coastguard Worker                                  &bufferInfo);
239*ec779b8eSAndroid Build Coastguard Worker                      }
240*ec779b8eSAndroid Build Coastguard Worker 
241*ec779b8eSAndroid Build Coastguard Worker                      break;
242*ec779b8eSAndroid Build Coastguard Worker                  }
243*ec779b8eSAndroid Build Coastguard Worker 
244*ec779b8eSAndroid Build Coastguard Worker                  case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
245*ec779b8eSAndroid Build Coastguard Worker                  {
246*ec779b8eSAndroid Build Coastguard Worker                      sp<AMessage> format;
247*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findMessage("format", &format)) {
248*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_OUTPUT_FORMAT_CHANGED: format is expected.");
249*ec779b8eSAndroid Build Coastguard Worker                          break;
250*ec779b8eSAndroid Build Coastguard Worker                      }
251*ec779b8eSAndroid Build Coastguard Worker 
252*ec779b8eSAndroid Build Coastguard Worker                      // Here format is MediaCodec's internal copy of output format.
253*ec779b8eSAndroid Build Coastguard Worker                      // Make a copy since the client might modify it.
254*ec779b8eSAndroid Build Coastguard Worker                      sp<AMessage> copy;
255*ec779b8eSAndroid Build Coastguard Worker                      if (format != nullptr) {
256*ec779b8eSAndroid Build Coastguard Worker                          copy = format->dup();
257*ec779b8eSAndroid Build Coastguard Worker                      }
258*ec779b8eSAndroid Build Coastguard Worker                      AMediaFormat *aMediaFormat = AMediaFormat_fromMsg(&copy);
259*ec779b8eSAndroid Build Coastguard Worker 
260*ec779b8eSAndroid Build Coastguard Worker                      Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
261*ec779b8eSAndroid Build Coastguard Worker                      if (mCodec->mAsyncCallback.onAsyncFormatChanged != NULL) {
262*ec779b8eSAndroid Build Coastguard Worker                          mCodec->mAsyncCallback.onAsyncFormatChanged(
263*ec779b8eSAndroid Build Coastguard Worker                                  mCodec,
264*ec779b8eSAndroid Build Coastguard Worker                                  mCodec->mAsyncCallbackUserData,
265*ec779b8eSAndroid Build Coastguard Worker                                  aMediaFormat);
266*ec779b8eSAndroid Build Coastguard Worker                      }
267*ec779b8eSAndroid Build Coastguard Worker 
268*ec779b8eSAndroid Build Coastguard Worker                      break;
269*ec779b8eSAndroid Build Coastguard Worker                  }
270*ec779b8eSAndroid Build Coastguard Worker 
271*ec779b8eSAndroid Build Coastguard Worker                  case MediaCodec::CB_ERROR:
272*ec779b8eSAndroid Build Coastguard Worker                  {
273*ec779b8eSAndroid Build Coastguard Worker                      status_t err;
274*ec779b8eSAndroid Build Coastguard Worker                      int32_t actionCode;
275*ec779b8eSAndroid Build Coastguard Worker                      AString detail;
276*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findInt32("err", &err)) {
277*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_ERROR: err is expected.");
278*ec779b8eSAndroid Build Coastguard Worker                          break;
279*ec779b8eSAndroid Build Coastguard Worker                      }
280*ec779b8eSAndroid Build Coastguard Worker                      if (!msg->findInt32("actionCode", &actionCode)) {
281*ec779b8eSAndroid Build Coastguard Worker                          ALOGE("CB_ERROR: actionCode is expected.");
282*ec779b8eSAndroid Build Coastguard Worker                          break;
283*ec779b8eSAndroid Build Coastguard Worker                      }
284*ec779b8eSAndroid Build Coastguard Worker                      msg->findString("detail", &detail);
285*ec779b8eSAndroid Build Coastguard Worker                      ALOGE("Codec reported error(0x%x/%s), actionCode(%d), detail(%s)",
286*ec779b8eSAndroid Build Coastguard Worker                            err, StrMediaError(err).c_str(), actionCode, detail.c_str());
287*ec779b8eSAndroid Build Coastguard Worker 
288*ec779b8eSAndroid Build Coastguard Worker                      Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
289*ec779b8eSAndroid Build Coastguard Worker                      if (mCodec->mAsyncCallback.onAsyncError != NULL) {
290*ec779b8eSAndroid Build Coastguard Worker                          mCodec->mAsyncCallback.onAsyncError(
291*ec779b8eSAndroid Build Coastguard Worker                                  mCodec,
292*ec779b8eSAndroid Build Coastguard Worker                                  mCodec->mAsyncCallbackUserData,
293*ec779b8eSAndroid Build Coastguard Worker                                  translate_error(err),
294*ec779b8eSAndroid Build Coastguard Worker                                  actionCode,
295*ec779b8eSAndroid Build Coastguard Worker                                  detail.c_str());
296*ec779b8eSAndroid Build Coastguard Worker                      }
297*ec779b8eSAndroid Build Coastguard Worker 
298*ec779b8eSAndroid Build Coastguard Worker                      break;
299*ec779b8eSAndroid Build Coastguard Worker                  }
300*ec779b8eSAndroid Build Coastguard Worker 
301*ec779b8eSAndroid Build Coastguard Worker                  default:
302*ec779b8eSAndroid Build Coastguard Worker                  {
303*ec779b8eSAndroid Build Coastguard Worker                      ALOGE("kWhatAsyncNotify: callbackID(%d) is unexpected.", cbID);
304*ec779b8eSAndroid Build Coastguard Worker                      break;
305*ec779b8eSAndroid Build Coastguard Worker                  }
306*ec779b8eSAndroid Build Coastguard Worker              }
307*ec779b8eSAndroid Build Coastguard Worker              break;
308*ec779b8eSAndroid Build Coastguard Worker         }
309*ec779b8eSAndroid Build Coastguard Worker 
310*ec779b8eSAndroid Build Coastguard Worker         case kWhatStopActivityNotifications:
311*ec779b8eSAndroid Build Coastguard Worker         {
312*ec779b8eSAndroid Build Coastguard Worker             sp<AReplyToken> replyID;
313*ec779b8eSAndroid Build Coastguard Worker             msg->senderAwaitsResponse(&replyID);
314*ec779b8eSAndroid Build Coastguard Worker 
315*ec779b8eSAndroid Build Coastguard Worker             mCodec->mGeneration++;
316*ec779b8eSAndroid Build Coastguard Worker             mCodec->mRequestedActivityNotification = false;
317*ec779b8eSAndroid Build Coastguard Worker 
318*ec779b8eSAndroid Build Coastguard Worker             sp<AMessage> response = new AMessage;
319*ec779b8eSAndroid Build Coastguard Worker             response->postReply(replyID);
320*ec779b8eSAndroid Build Coastguard Worker             break;
321*ec779b8eSAndroid Build Coastguard Worker         }
322*ec779b8eSAndroid Build Coastguard Worker 
323*ec779b8eSAndroid Build Coastguard Worker         case kWhatFrameRenderedNotify:
324*ec779b8eSAndroid Build Coastguard Worker         {
325*ec779b8eSAndroid Build Coastguard Worker             sp<AMessage> data;
326*ec779b8eSAndroid Build Coastguard Worker             if (!msg->findMessage("data", &data)) {
327*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("kWhatFrameRenderedNotify: data is expected.");
328*ec779b8eSAndroid Build Coastguard Worker                 break;
329*ec779b8eSAndroid Build Coastguard Worker             }
330*ec779b8eSAndroid Build Coastguard Worker 
331*ec779b8eSAndroid Build Coastguard Worker             AMessage::Type type;
332*ec779b8eSAndroid Build Coastguard Worker             size_t n = data->countEntries();
333*ec779b8eSAndroid Build Coastguard Worker 
334*ec779b8eSAndroid Build Coastguard Worker             thread_local std::vector<std::optional<int64_t>> mediaTimesInUs;
335*ec779b8eSAndroid Build Coastguard Worker             thread_local std::vector<std::optional<int64_t>> systemTimesInNs;
336*ec779b8eSAndroid Build Coastguard Worker             mediaTimesInUs.resize(n);
337*ec779b8eSAndroid Build Coastguard Worker             systemTimesInNs.resize(n);
338*ec779b8eSAndroid Build Coastguard Worker             std::fill_n(mediaTimesInUs.begin(), n, std::nullopt);
339*ec779b8eSAndroid Build Coastguard Worker             std::fill_n(systemTimesInNs.begin(), n, std::nullopt);
340*ec779b8eSAndroid Build Coastguard Worker             for (size_t i = 0; i < n; i++) {
341*ec779b8eSAndroid Build Coastguard Worker                 AString name = data->getEntryNameAt(i, &type);
342*ec779b8eSAndroid Build Coastguard Worker                 if (name.endsWith("-media-time-us")) {
343*ec779b8eSAndroid Build Coastguard Worker                     int64_t mediaTimeUs;
344*ec779b8eSAndroid Build Coastguard Worker                     AMessage::ItemData itemData = data->getEntryAt(i);
345*ec779b8eSAndroid Build Coastguard Worker                     itemData.find(&mediaTimeUs);
346*ec779b8eSAndroid Build Coastguard Worker 
347*ec779b8eSAndroid Build Coastguard Worker                     int index = -1;
348*ec779b8eSAndroid Build Coastguard Worker                     std::from_chars_result result = std::from_chars(
349*ec779b8eSAndroid Build Coastguard Worker                             name.c_str(), name.c_str() + name.find("-"), index);
350*ec779b8eSAndroid Build Coastguard Worker                     if (result.ec == std::errc() && 0 <= index && index < n) {
351*ec779b8eSAndroid Build Coastguard Worker                         mediaTimesInUs[index] = mediaTimeUs;
352*ec779b8eSAndroid Build Coastguard Worker                     } else {
353*ec779b8eSAndroid Build Coastguard Worker                         std::error_code ec = std::make_error_code(result.ec);
354*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("Unexpected media time index: #%d with value %lldus (err=%d %s)",
355*ec779b8eSAndroid Build Coastguard Worker                               index, (long long)mediaTimeUs, ec.value(), ec.message().c_str());
356*ec779b8eSAndroid Build Coastguard Worker                     }
357*ec779b8eSAndroid Build Coastguard Worker                 } else if (name.endsWith("-system-nano")) {
358*ec779b8eSAndroid Build Coastguard Worker                     int64_t systemNano;
359*ec779b8eSAndroid Build Coastguard Worker                     AMessage::ItemData itemData = data->getEntryAt(i);
360*ec779b8eSAndroid Build Coastguard Worker                     itemData.find(&systemNano);
361*ec779b8eSAndroid Build Coastguard Worker 
362*ec779b8eSAndroid Build Coastguard Worker                     int index = -1;
363*ec779b8eSAndroid Build Coastguard Worker                     std::from_chars_result result = std::from_chars(
364*ec779b8eSAndroid Build Coastguard Worker                             name.c_str(), name.c_str() + name.find("-"), index);
365*ec779b8eSAndroid Build Coastguard Worker                     if (result.ec == std::errc() && 0 <= index && index < n) {
366*ec779b8eSAndroid Build Coastguard Worker                         systemTimesInNs[index] = systemNano;
367*ec779b8eSAndroid Build Coastguard Worker                     } else {
368*ec779b8eSAndroid Build Coastguard Worker                         std::error_code ec = std::make_error_code(result.ec);
369*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("Unexpected system time index: #%d with value %lldns (err=%d %s)",
370*ec779b8eSAndroid Build Coastguard Worker                               index, (long long)systemNano, ec.value(), ec.message().c_str());
371*ec779b8eSAndroid Build Coastguard Worker                     }
372*ec779b8eSAndroid Build Coastguard Worker                 }
373*ec779b8eSAndroid Build Coastguard Worker             }
374*ec779b8eSAndroid Build Coastguard Worker 
375*ec779b8eSAndroid Build Coastguard Worker             Mutex::Autolock _l(mCodec->mFrameRenderedCallbackLock);
376*ec779b8eSAndroid Build Coastguard Worker             if (mCodec->mFrameRenderedCallback != NULL) {
377*ec779b8eSAndroid Build Coastguard Worker                 for (size_t i = 0; i < n; ++i) {
378*ec779b8eSAndroid Build Coastguard Worker                     if (mediaTimesInUs[i] && systemTimesInNs[i]) {
379*ec779b8eSAndroid Build Coastguard Worker                         mCodec->mFrameRenderedCallback(
380*ec779b8eSAndroid Build Coastguard Worker                                 mCodec,
381*ec779b8eSAndroid Build Coastguard Worker                                 mCodec->mFrameRenderedCallbackUserData,
382*ec779b8eSAndroid Build Coastguard Worker                                 mediaTimesInUs[i].value(),
383*ec779b8eSAndroid Build Coastguard Worker                                 systemTimesInNs[i].value());
384*ec779b8eSAndroid Build Coastguard Worker                     } else {
385*ec779b8eSAndroid Build Coastguard Worker                         break;
386*ec779b8eSAndroid Build Coastguard Worker                     }
387*ec779b8eSAndroid Build Coastguard Worker                 }
388*ec779b8eSAndroid Build Coastguard Worker             }
389*ec779b8eSAndroid Build Coastguard Worker             break;
390*ec779b8eSAndroid Build Coastguard Worker         }
391*ec779b8eSAndroid Build Coastguard Worker 
392*ec779b8eSAndroid Build Coastguard Worker         default:
393*ec779b8eSAndroid Build Coastguard Worker             ALOGE("shouldn't be here");
394*ec779b8eSAndroid Build Coastguard Worker             break;
395*ec779b8eSAndroid Build Coastguard Worker     }
396*ec779b8eSAndroid Build Coastguard Worker 
397*ec779b8eSAndroid Build Coastguard Worker }
398*ec779b8eSAndroid Build Coastguard Worker 
399*ec779b8eSAndroid Build Coastguard Worker 
requestActivityNotification(AMediaCodec * codec)400*ec779b8eSAndroid Build Coastguard Worker static void requestActivityNotification(AMediaCodec *codec) {
401*ec779b8eSAndroid Build Coastguard Worker     (new AMessage(kWhatRequestActivityNotifications, codec->mHandler))->post();
402*ec779b8eSAndroid Build Coastguard Worker }
403*ec779b8eSAndroid Build Coastguard Worker 
404*ec779b8eSAndroid Build Coastguard Worker extern "C" {
405*ec779b8eSAndroid Build Coastguard Worker 
createAMediaCodec(const char * name,bool name_is_type,bool encoder,pid_t pid=android::MediaCodec::kNoPid,uid_t uid=android::MediaCodec::kNoUid)406*ec779b8eSAndroid Build Coastguard Worker static AMediaCodec * createAMediaCodec(const char *name,
407*ec779b8eSAndroid Build Coastguard Worker                                        bool name_is_type,
408*ec779b8eSAndroid Build Coastguard Worker                                        bool encoder,
409*ec779b8eSAndroid Build Coastguard Worker                                        pid_t pid = android::MediaCodec::kNoPid,
410*ec779b8eSAndroid Build Coastguard Worker                                        uid_t uid = android::MediaCodec::kNoUid) {
411*ec779b8eSAndroid Build Coastguard Worker     AMediaCodec *mData = new AMediaCodec();
412*ec779b8eSAndroid Build Coastguard Worker     mData->mLooper = new ALooper;
413*ec779b8eSAndroid Build Coastguard Worker     mData->mLooper->setName("NDK MediaCodec_looper");
414*ec779b8eSAndroid Build Coastguard Worker     size_t res = mData->mLooper->start(
415*ec779b8eSAndroid Build Coastguard Worker             false,      // runOnCallingThread
416*ec779b8eSAndroid Build Coastguard Worker             true,       // canCallJava XXX
417*ec779b8eSAndroid Build Coastguard Worker             PRIORITY_AUDIO);
418*ec779b8eSAndroid Build Coastguard Worker     if (res != OK) {
419*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to start the looper");
420*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec_delete(mData);
421*ec779b8eSAndroid Build Coastguard Worker         return NULL;
422*ec779b8eSAndroid Build Coastguard Worker     }
423*ec779b8eSAndroid Build Coastguard Worker     if (name_is_type) {
424*ec779b8eSAndroid Build Coastguard Worker         mData->mCodec = android::MediaCodec::CreateByType(
425*ec779b8eSAndroid Build Coastguard Worker                 mData->mLooper,
426*ec779b8eSAndroid Build Coastguard Worker                 name,
427*ec779b8eSAndroid Build Coastguard Worker                 encoder,
428*ec779b8eSAndroid Build Coastguard Worker                 nullptr /* err */,
429*ec779b8eSAndroid Build Coastguard Worker                 pid,
430*ec779b8eSAndroid Build Coastguard Worker                 uid);
431*ec779b8eSAndroid Build Coastguard Worker     } else {
432*ec779b8eSAndroid Build Coastguard Worker         mData->mCodec = android::MediaCodec::CreateByComponentName(
433*ec779b8eSAndroid Build Coastguard Worker                 mData->mLooper,
434*ec779b8eSAndroid Build Coastguard Worker                 name,
435*ec779b8eSAndroid Build Coastguard Worker                 nullptr /* err */,
436*ec779b8eSAndroid Build Coastguard Worker                 pid,
437*ec779b8eSAndroid Build Coastguard Worker                 uid);
438*ec779b8eSAndroid Build Coastguard Worker     }
439*ec779b8eSAndroid Build Coastguard Worker     if (mData->mCodec == NULL) {  // failed to create codec
440*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec_delete(mData);
441*ec779b8eSAndroid Build Coastguard Worker         return NULL;
442*ec779b8eSAndroid Build Coastguard Worker     }
443*ec779b8eSAndroid Build Coastguard Worker     mData->mHandler = new CodecHandler(mData);
444*ec779b8eSAndroid Build Coastguard Worker     mData->mLooper->registerHandler(mData->mHandler);
445*ec779b8eSAndroid Build Coastguard Worker     mData->mGeneration = 1;
446*ec779b8eSAndroid Build Coastguard Worker     mData->mRequestedActivityNotification = false;
447*ec779b8eSAndroid Build Coastguard Worker     mData->mCallback = NULL;
448*ec779b8eSAndroid Build Coastguard Worker 
449*ec779b8eSAndroid Build Coastguard Worker     mData->mAsyncCallback = {};
450*ec779b8eSAndroid Build Coastguard Worker     mData->mAsyncCallbackUserData = NULL;
451*ec779b8eSAndroid Build Coastguard Worker 
452*ec779b8eSAndroid Build Coastguard Worker     return mData;
453*ec779b8eSAndroid Build Coastguard Worker }
454*ec779b8eSAndroid Build Coastguard Worker 
455*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createCodecByName(const char * name)456*ec779b8eSAndroid Build Coastguard Worker AMediaCodec* AMediaCodec_createCodecByName(const char *name) {
457*ec779b8eSAndroid Build Coastguard Worker     return createAMediaCodec(name, false /* name_is_type */, false /* encoder */);
458*ec779b8eSAndroid Build Coastguard Worker }
459*ec779b8eSAndroid Build Coastguard Worker 
460*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createDecoderByType(const char * mime_type)461*ec779b8eSAndroid Build Coastguard Worker AMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type) {
462*ec779b8eSAndroid Build Coastguard Worker     return createAMediaCodec(mime_type, true /* name_is_type */, false /* encoder */);
463*ec779b8eSAndroid Build Coastguard Worker }
464*ec779b8eSAndroid Build Coastguard Worker 
465*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createEncoderByType(const char * name)466*ec779b8eSAndroid Build Coastguard Worker AMediaCodec* AMediaCodec_createEncoderByType(const char *name) {
467*ec779b8eSAndroid Build Coastguard Worker     return createAMediaCodec(name, true /* name_is_type */, true /* encoder */);
468*ec779b8eSAndroid Build Coastguard Worker }
469*ec779b8eSAndroid Build Coastguard Worker 
470*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createCodecByNameForClient(const char * name,pid_t pid,uid_t uid)471*ec779b8eSAndroid Build Coastguard Worker AMediaCodec* AMediaCodec_createCodecByNameForClient(const char *name,
472*ec779b8eSAndroid Build Coastguard Worker                                                     pid_t pid,
473*ec779b8eSAndroid Build Coastguard Worker                                                     uid_t uid) {
474*ec779b8eSAndroid Build Coastguard Worker     return createAMediaCodec(name, false /* name_is_type */, false /* encoder */, pid, uid);
475*ec779b8eSAndroid Build Coastguard Worker }
476*ec779b8eSAndroid Build Coastguard Worker 
477*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createDecoderByTypeForClient(const char * mime_type,pid_t pid,uid_t uid)478*ec779b8eSAndroid Build Coastguard Worker AMediaCodec* AMediaCodec_createDecoderByTypeForClient(const char *mime_type,
479*ec779b8eSAndroid Build Coastguard Worker                                                       pid_t pid,
480*ec779b8eSAndroid Build Coastguard Worker                                                       uid_t uid) {
481*ec779b8eSAndroid Build Coastguard Worker     return createAMediaCodec(mime_type, true /* name_is_type */, false /* encoder */, pid, uid);
482*ec779b8eSAndroid Build Coastguard Worker }
483*ec779b8eSAndroid Build Coastguard Worker 
484*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createEncoderByTypeForClient(const char * name,pid_t pid,uid_t uid)485*ec779b8eSAndroid Build Coastguard Worker AMediaCodec* AMediaCodec_createEncoderByTypeForClient(const char *name,
486*ec779b8eSAndroid Build Coastguard Worker                                                       pid_t pid,
487*ec779b8eSAndroid Build Coastguard Worker                                                       uid_t uid) {
488*ec779b8eSAndroid Build Coastguard Worker     return createAMediaCodec(name, true /* name_is_type */, true /* encoder */, pid, uid);
489*ec779b8eSAndroid Build Coastguard Worker }
490*ec779b8eSAndroid Build Coastguard Worker 
491*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_delete(AMediaCodec * mData)492*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_delete(AMediaCodec *mData) {
493*ec779b8eSAndroid Build Coastguard Worker     if (mData != NULL) {
494*ec779b8eSAndroid Build Coastguard Worker         if (mData->mCodec != NULL) {
495*ec779b8eSAndroid Build Coastguard Worker             mData->mCodec->release();
496*ec779b8eSAndroid Build Coastguard Worker             mData->mCodec.clear();
497*ec779b8eSAndroid Build Coastguard Worker         }
498*ec779b8eSAndroid Build Coastguard Worker 
499*ec779b8eSAndroid Build Coastguard Worker         if (mData->mLooper != NULL) {
500*ec779b8eSAndroid Build Coastguard Worker             if (mData->mHandler != NULL) {
501*ec779b8eSAndroid Build Coastguard Worker                 mData->mLooper->unregisterHandler(mData->mHandler->id());
502*ec779b8eSAndroid Build Coastguard Worker             }
503*ec779b8eSAndroid Build Coastguard Worker             mData->mLooper->stop();
504*ec779b8eSAndroid Build Coastguard Worker             mData->mLooper.clear();
505*ec779b8eSAndroid Build Coastguard Worker         }
506*ec779b8eSAndroid Build Coastguard Worker         delete mData;
507*ec779b8eSAndroid Build Coastguard Worker     }
508*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
509*ec779b8eSAndroid Build Coastguard Worker }
510*ec779b8eSAndroid Build Coastguard Worker 
511*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_getName(AMediaCodec * mData,char ** out_name)512*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_getName(
513*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData,
514*ec779b8eSAndroid Build Coastguard Worker         char** out_name) {
515*ec779b8eSAndroid Build Coastguard Worker     if (out_name == NULL) {
516*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
517*ec779b8eSAndroid Build Coastguard Worker     }
518*ec779b8eSAndroid Build Coastguard Worker 
519*ec779b8eSAndroid Build Coastguard Worker     AString compName;
520*ec779b8eSAndroid Build Coastguard Worker     status_t err = mData->mCodec->getName(&compName);
521*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
522*ec779b8eSAndroid Build Coastguard Worker         return translate_error(err);
523*ec779b8eSAndroid Build Coastguard Worker     }
524*ec779b8eSAndroid Build Coastguard Worker     *out_name = strdup(compName.c_str());
525*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
526*ec779b8eSAndroid Build Coastguard Worker }
527*ec779b8eSAndroid Build Coastguard Worker 
528*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_releaseName(AMediaCodec *,char * name)529*ec779b8eSAndroid Build Coastguard Worker void AMediaCodec_releaseName(
530*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec * /* mData */,
531*ec779b8eSAndroid Build Coastguard Worker         char* name) {
532*ec779b8eSAndroid Build Coastguard Worker     if (name != NULL) {
533*ec779b8eSAndroid Build Coastguard Worker         free(name);
534*ec779b8eSAndroid Build Coastguard Worker     }
535*ec779b8eSAndroid Build Coastguard Worker }
536*ec779b8eSAndroid Build Coastguard Worker 
537*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_configure(AMediaCodec * mData,const AMediaFormat * format,ANativeWindow * window,AMediaCrypto * crypto,uint32_t flags)538*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_configure(
539*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData,
540*ec779b8eSAndroid Build Coastguard Worker         const AMediaFormat* format,
541*ec779b8eSAndroid Build Coastguard Worker         ANativeWindow* window,
542*ec779b8eSAndroid Build Coastguard Worker         AMediaCrypto *crypto,
543*ec779b8eSAndroid Build Coastguard Worker         uint32_t flags) {
544*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> nativeFormat;
545*ec779b8eSAndroid Build Coastguard Worker     AMediaFormat_getFormat(format, &nativeFormat);
546*ec779b8eSAndroid Build Coastguard Worker     // create our shallow copy, so we aren't victim to any later changes.
547*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> dupNativeFormat = nativeFormat->dup();
548*ec779b8eSAndroid Build Coastguard Worker     ALOGV("configure with format: %s", dupNativeFormat->debugString(0).c_str());
549*ec779b8eSAndroid Build Coastguard Worker     sp<Surface> surface = NULL;
550*ec779b8eSAndroid Build Coastguard Worker     if (window != NULL) {
551*ec779b8eSAndroid Build Coastguard Worker         surface = (Surface*) window;
552*ec779b8eSAndroid Build Coastguard Worker     }
553*ec779b8eSAndroid Build Coastguard Worker 
554*ec779b8eSAndroid Build Coastguard Worker     status_t err = mData->mCodec->configure(dupNativeFormat, surface,
555*ec779b8eSAndroid Build Coastguard Worker             crypto ? crypto->mCrypto : NULL, flags);
556*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
557*ec779b8eSAndroid Build Coastguard Worker         ALOGE("configure: err(%d), failed with format: %s",
558*ec779b8eSAndroid Build Coastguard Worker               err, dupNativeFormat->debugString(0).c_str());
559*ec779b8eSAndroid Build Coastguard Worker     }
560*ec779b8eSAndroid Build Coastguard Worker     return translate_error(err);
561*ec779b8eSAndroid Build Coastguard Worker }
562*ec779b8eSAndroid Build Coastguard Worker 
563*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_setAsyncNotifyCallback(AMediaCodec * mData,AMediaCodecOnAsyncNotifyCallback callback,void * userdata)564*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_setAsyncNotifyCallback(
565*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData,
566*ec779b8eSAndroid Build Coastguard Worker         AMediaCodecOnAsyncNotifyCallback callback,
567*ec779b8eSAndroid Build Coastguard Worker         void *userdata) {
568*ec779b8eSAndroid Build Coastguard Worker 
569*ec779b8eSAndroid Build Coastguard Worker     {
570*ec779b8eSAndroid Build Coastguard Worker         Mutex::Autolock _l(mData->mAsyncCallbackLock);
571*ec779b8eSAndroid Build Coastguard Worker         if (mData->mAsyncNotify == NULL) {
572*ec779b8eSAndroid Build Coastguard Worker             mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
573*ec779b8eSAndroid Build Coastguard Worker         }
574*ec779b8eSAndroid Build Coastguard Worker         // we set this ahead so that we can be ready
575*ec779b8eSAndroid Build Coastguard Worker         // to receive callbacks as soon as the next call is a
576*ec779b8eSAndroid Build Coastguard Worker         // success.
577*ec779b8eSAndroid Build Coastguard Worker         mData->mAsyncCallback = callback;
578*ec779b8eSAndroid Build Coastguard Worker         mData->mAsyncCallbackUserData = userdata;
579*ec779b8eSAndroid Build Coastguard Worker     }
580*ec779b8eSAndroid Build Coastguard Worker 
581*ec779b8eSAndroid Build Coastguard Worker     // always call, codec may have been reset/re-configured since last call.
582*ec779b8eSAndroid Build Coastguard Worker     status_t err = mData->mCodec->setCallback(mData->mAsyncNotify);
583*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
584*ec779b8eSAndroid Build Coastguard Worker         {
585*ec779b8eSAndroid Build Coastguard Worker             //The setup gone wrong. clean up the pointers.
586*ec779b8eSAndroid Build Coastguard Worker             Mutex::Autolock _l(mData->mAsyncCallbackLock);
587*ec779b8eSAndroid Build Coastguard Worker             mData->mAsyncCallback = {};
588*ec779b8eSAndroid Build Coastguard Worker             mData->mAsyncCallbackUserData = nullptr;
589*ec779b8eSAndroid Build Coastguard Worker         }
590*ec779b8eSAndroid Build Coastguard Worker         ALOGE("setAsyncNotifyCallback: err(%d), failed to set async callback", err);
591*ec779b8eSAndroid Build Coastguard Worker         return translate_error(err);
592*ec779b8eSAndroid Build Coastguard Worker     }
593*ec779b8eSAndroid Build Coastguard Worker 
594*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
595*ec779b8eSAndroid Build Coastguard Worker }
596*ec779b8eSAndroid Build Coastguard Worker 
597*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_setOnFrameRenderedCallback(AMediaCodec * mData,AMediaCodecOnFrameRendered callback,void * userdata)598*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_setOnFrameRenderedCallback(
599*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData,
600*ec779b8eSAndroid Build Coastguard Worker         AMediaCodecOnFrameRendered callback,
601*ec779b8eSAndroid Build Coastguard Worker         void *userdata) {
602*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mData->mFrameRenderedCallbackLock);
603*ec779b8eSAndroid Build Coastguard Worker     if (mData->mFrameRenderedNotify == NULL) {
604*ec779b8eSAndroid Build Coastguard Worker         mData->mFrameRenderedNotify = new AMessage(kWhatFrameRenderedNotify, mData->mHandler);
605*ec779b8eSAndroid Build Coastguard Worker     }
606*ec779b8eSAndroid Build Coastguard Worker     status_t err = mData->mCodec->setOnFrameRenderedNotification(mData->mFrameRenderedNotify);
607*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
608*ec779b8eSAndroid Build Coastguard Worker         ALOGE("setOnFrameRenderedNotifyCallback: err(%d), failed to set callback", err);
609*ec779b8eSAndroid Build Coastguard Worker         return translate_error(err);
610*ec779b8eSAndroid Build Coastguard Worker     }
611*ec779b8eSAndroid Build Coastguard Worker 
612*ec779b8eSAndroid Build Coastguard Worker     mData->mFrameRenderedCallback = callback;
613*ec779b8eSAndroid Build Coastguard Worker     mData->mFrameRenderedCallbackUserData = userdata;
614*ec779b8eSAndroid Build Coastguard Worker 
615*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
616*ec779b8eSAndroid Build Coastguard Worker }
617*ec779b8eSAndroid Build Coastguard Worker 
618*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_releaseCrypto(AMediaCodec * mData)619*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_releaseCrypto(AMediaCodec *mData) {
620*ec779b8eSAndroid Build Coastguard Worker     return translate_error(mData->mCodec->releaseCrypto());
621*ec779b8eSAndroid Build Coastguard Worker }
622*ec779b8eSAndroid Build Coastguard Worker 
623*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_start(AMediaCodec * mData)624*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_start(AMediaCodec *mData) {
625*ec779b8eSAndroid Build Coastguard Worker     status_t ret =  mData->mCodec->start();
626*ec779b8eSAndroid Build Coastguard Worker     if (ret != OK) {
627*ec779b8eSAndroid Build Coastguard Worker         return translate_error(ret);
628*ec779b8eSAndroid Build Coastguard Worker     }
629*ec779b8eSAndroid Build Coastguard Worker     mData->mActivityNotification = new AMessage(kWhatActivityNotify, mData->mHandler);
630*ec779b8eSAndroid Build Coastguard Worker     mData->mActivityNotification->setInt32("generation", mData->mGeneration);
631*ec779b8eSAndroid Build Coastguard Worker     requestActivityNotification(mData);
632*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
633*ec779b8eSAndroid Build Coastguard Worker }
634*ec779b8eSAndroid Build Coastguard Worker 
635*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_stop(AMediaCodec * mData)636*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_stop(AMediaCodec *mData) {
637*ec779b8eSAndroid Build Coastguard Worker     media_status_t ret = translate_error(mData->mCodec->stop());
638*ec779b8eSAndroid Build Coastguard Worker 
639*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, mData->mHandler);
640*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> response;
641*ec779b8eSAndroid Build Coastguard Worker     msg->postAndAwaitResponse(&response);
642*ec779b8eSAndroid Build Coastguard Worker     mData->mActivityNotification.clear();
643*ec779b8eSAndroid Build Coastguard Worker 
644*ec779b8eSAndroid Build Coastguard Worker     return ret;
645*ec779b8eSAndroid Build Coastguard Worker }
646*ec779b8eSAndroid Build Coastguard Worker 
647*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_flush(AMediaCodec * mData)648*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_flush(AMediaCodec *mData) {
649*ec779b8eSAndroid Build Coastguard Worker     return translate_error(mData->mCodec->flush());
650*ec779b8eSAndroid Build Coastguard Worker }
651*ec779b8eSAndroid Build Coastguard Worker 
652*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_dequeueInputBuffer(AMediaCodec * mData,int64_t timeoutUs)653*ec779b8eSAndroid Build Coastguard Worker ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec *mData, int64_t timeoutUs) {
654*ec779b8eSAndroid Build Coastguard Worker     size_t idx;
655*ec779b8eSAndroid Build Coastguard Worker     status_t ret = mData->mCodec->dequeueInputBuffer(&idx, timeoutUs);
656*ec779b8eSAndroid Build Coastguard Worker     requestActivityNotification(mData);
657*ec779b8eSAndroid Build Coastguard Worker     if (ret == OK) {
658*ec779b8eSAndroid Build Coastguard Worker         return idx;
659*ec779b8eSAndroid Build Coastguard Worker     }
660*ec779b8eSAndroid Build Coastguard Worker     return translate_error(ret);
661*ec779b8eSAndroid Build Coastguard Worker }
662*ec779b8eSAndroid Build Coastguard Worker 
663*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_getInputBuffer(AMediaCodec * mData,size_t idx,size_t * out_size)664*ec779b8eSAndroid Build Coastguard Worker uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
665*ec779b8eSAndroid Build Coastguard Worker     if (mData->mAsyncNotify != NULL) {
666*ec779b8eSAndroid Build Coastguard Worker         // Asynchronous mode
667*ec779b8eSAndroid Build Coastguard Worker         sp<MediaCodecBuffer> abuf;
668*ec779b8eSAndroid Build Coastguard Worker         if (mData->mCodec->getInputBuffer(idx, &abuf) != 0) {
669*ec779b8eSAndroid Build Coastguard Worker             return NULL;
670*ec779b8eSAndroid Build Coastguard Worker         }
671*ec779b8eSAndroid Build Coastguard Worker 
672*ec779b8eSAndroid Build Coastguard Worker         if (out_size != NULL) {
673*ec779b8eSAndroid Build Coastguard Worker             *out_size = abuf->capacity();
674*ec779b8eSAndroid Build Coastguard Worker         }
675*ec779b8eSAndroid Build Coastguard Worker         return abuf->data();
676*ec779b8eSAndroid Build Coastguard Worker     }
677*ec779b8eSAndroid Build Coastguard Worker 
678*ec779b8eSAndroid Build Coastguard Worker     android::Vector<android::sp<android::MediaCodecBuffer> > abufs;
679*ec779b8eSAndroid Build Coastguard Worker     if (mData->mCodec->getInputBuffers(&abufs) == 0) {
680*ec779b8eSAndroid Build Coastguard Worker         size_t n = abufs.size();
681*ec779b8eSAndroid Build Coastguard Worker         if (idx >= n) {
682*ec779b8eSAndroid Build Coastguard Worker             ALOGE("buffer index %zu out of range", idx);
683*ec779b8eSAndroid Build Coastguard Worker             return NULL;
684*ec779b8eSAndroid Build Coastguard Worker         }
685*ec779b8eSAndroid Build Coastguard Worker         if (abufs[idx] == NULL) {
686*ec779b8eSAndroid Build Coastguard Worker             ALOGE("buffer index %zu is NULL", idx);
687*ec779b8eSAndroid Build Coastguard Worker             return NULL;
688*ec779b8eSAndroid Build Coastguard Worker         }
689*ec779b8eSAndroid Build Coastguard Worker         if (out_size != NULL) {
690*ec779b8eSAndroid Build Coastguard Worker             *out_size = abufs[idx]->capacity();
691*ec779b8eSAndroid Build Coastguard Worker         }
692*ec779b8eSAndroid Build Coastguard Worker         return abufs[idx]->data();
693*ec779b8eSAndroid Build Coastguard Worker     }
694*ec779b8eSAndroid Build Coastguard Worker     ALOGE("couldn't get input buffers");
695*ec779b8eSAndroid Build Coastguard Worker     return NULL;
696*ec779b8eSAndroid Build Coastguard Worker }
697*ec779b8eSAndroid Build Coastguard Worker 
698*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_getOutputBuffer(AMediaCodec * mData,size_t idx,size_t * out_size)699*ec779b8eSAndroid Build Coastguard Worker uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
700*ec779b8eSAndroid Build Coastguard Worker     if (mData->mAsyncNotify != NULL) {
701*ec779b8eSAndroid Build Coastguard Worker         // Asynchronous mode
702*ec779b8eSAndroid Build Coastguard Worker         sp<MediaCodecBuffer> abuf;
703*ec779b8eSAndroid Build Coastguard Worker         if (mData->mCodec->getOutputBuffer(idx, &abuf) != 0) {
704*ec779b8eSAndroid Build Coastguard Worker             return NULL;
705*ec779b8eSAndroid Build Coastguard Worker         }
706*ec779b8eSAndroid Build Coastguard Worker 
707*ec779b8eSAndroid Build Coastguard Worker         if (out_size != NULL) {
708*ec779b8eSAndroid Build Coastguard Worker             *out_size = abuf->capacity();
709*ec779b8eSAndroid Build Coastguard Worker         }
710*ec779b8eSAndroid Build Coastguard Worker         return abuf->data();
711*ec779b8eSAndroid Build Coastguard Worker     }
712*ec779b8eSAndroid Build Coastguard Worker 
713*ec779b8eSAndroid Build Coastguard Worker     android::Vector<android::sp<android::MediaCodecBuffer> > abufs;
714*ec779b8eSAndroid Build Coastguard Worker     if (mData->mCodec->getOutputBuffers(&abufs) == 0) {
715*ec779b8eSAndroid Build Coastguard Worker         size_t n = abufs.size();
716*ec779b8eSAndroid Build Coastguard Worker         if (idx >= n) {
717*ec779b8eSAndroid Build Coastguard Worker             ALOGE("buffer index %zu out of range", idx);
718*ec779b8eSAndroid Build Coastguard Worker             return NULL;
719*ec779b8eSAndroid Build Coastguard Worker         }
720*ec779b8eSAndroid Build Coastguard Worker         if (out_size != NULL) {
721*ec779b8eSAndroid Build Coastguard Worker             *out_size = abufs[idx]->capacity();
722*ec779b8eSAndroid Build Coastguard Worker         }
723*ec779b8eSAndroid Build Coastguard Worker         return abufs[idx]->data();
724*ec779b8eSAndroid Build Coastguard Worker     }
725*ec779b8eSAndroid Build Coastguard Worker     ALOGE("couldn't get output buffers");
726*ec779b8eSAndroid Build Coastguard Worker     return NULL;
727*ec779b8eSAndroid Build Coastguard Worker }
728*ec779b8eSAndroid Build Coastguard Worker 
729*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_queueInputBuffer(AMediaCodec * mData,size_t idx,off_t offset,size_t size,uint64_t time,uint32_t flags)730*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_queueInputBuffer(AMediaCodec *mData,
731*ec779b8eSAndroid Build Coastguard Worker         size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags) {
732*ec779b8eSAndroid Build Coastguard Worker 
733*ec779b8eSAndroid Build Coastguard Worker     AString errorMsg;
734*ec779b8eSAndroid Build Coastguard Worker     status_t ret = mData->mCodec->queueInputBuffer(idx, offset, size, time, flags, &errorMsg);
735*ec779b8eSAndroid Build Coastguard Worker     return translate_error(ret);
736*ec779b8eSAndroid Build Coastguard Worker }
737*ec779b8eSAndroid Build Coastguard Worker 
738*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_dequeueOutputBuffer(AMediaCodec * mData,AMediaCodecBufferInfo * info,int64_t timeoutUs)739*ec779b8eSAndroid Build Coastguard Worker ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec *mData,
740*ec779b8eSAndroid Build Coastguard Worker         AMediaCodecBufferInfo *info, int64_t timeoutUs) {
741*ec779b8eSAndroid Build Coastguard Worker     size_t idx;
742*ec779b8eSAndroid Build Coastguard Worker     size_t offset;
743*ec779b8eSAndroid Build Coastguard Worker     size_t size;
744*ec779b8eSAndroid Build Coastguard Worker     uint32_t flags;
745*ec779b8eSAndroid Build Coastguard Worker     int64_t presentationTimeUs;
746*ec779b8eSAndroid Build Coastguard Worker     status_t ret = mData->mCodec->dequeueOutputBuffer(&idx, &offset, &size, &presentationTimeUs,
747*ec779b8eSAndroid Build Coastguard Worker             &flags, timeoutUs);
748*ec779b8eSAndroid Build Coastguard Worker     requestActivityNotification(mData);
749*ec779b8eSAndroid Build Coastguard Worker     switch (ret) {
750*ec779b8eSAndroid Build Coastguard Worker         case OK:
751*ec779b8eSAndroid Build Coastguard Worker             info->offset = offset;
752*ec779b8eSAndroid Build Coastguard Worker             info->size = size;
753*ec779b8eSAndroid Build Coastguard Worker             info->flags = flags;
754*ec779b8eSAndroid Build Coastguard Worker             info->presentationTimeUs = presentationTimeUs;
755*ec779b8eSAndroid Build Coastguard Worker             return idx;
756*ec779b8eSAndroid Build Coastguard Worker         case -EAGAIN:
757*ec779b8eSAndroid Build Coastguard Worker             return AMEDIACODEC_INFO_TRY_AGAIN_LATER;
758*ec779b8eSAndroid Build Coastguard Worker         case android::INFO_FORMAT_CHANGED:
759*ec779b8eSAndroid Build Coastguard Worker             return AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED;
760*ec779b8eSAndroid Build Coastguard Worker         case INFO_OUTPUT_BUFFERS_CHANGED:
761*ec779b8eSAndroid Build Coastguard Worker             return AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED;
762*ec779b8eSAndroid Build Coastguard Worker         default:
763*ec779b8eSAndroid Build Coastguard Worker             break;
764*ec779b8eSAndroid Build Coastguard Worker     }
765*ec779b8eSAndroid Build Coastguard Worker     return translate_error(ret);
766*ec779b8eSAndroid Build Coastguard Worker }
767*ec779b8eSAndroid Build Coastguard Worker 
768*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_getOutputFormat(AMediaCodec * mData)769*ec779b8eSAndroid Build Coastguard Worker AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec *mData) {
770*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> format;
771*ec779b8eSAndroid Build Coastguard Worker     mData->mCodec->getOutputFormat(&format);
772*ec779b8eSAndroid Build Coastguard Worker     return AMediaFormat_fromMsg(&format);
773*ec779b8eSAndroid Build Coastguard Worker }
774*ec779b8eSAndroid Build Coastguard Worker 
775*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_getInputFormat(AMediaCodec * mData)776*ec779b8eSAndroid Build Coastguard Worker AMediaFormat* AMediaCodec_getInputFormat(AMediaCodec *mData) {
777*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> format;
778*ec779b8eSAndroid Build Coastguard Worker     mData->mCodec->getInputFormat(&format);
779*ec779b8eSAndroid Build Coastguard Worker     return AMediaFormat_fromMsg(&format);
780*ec779b8eSAndroid Build Coastguard Worker }
781*ec779b8eSAndroid Build Coastguard Worker 
782*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_getBufferFormat(AMediaCodec * mData,size_t index)783*ec779b8eSAndroid Build Coastguard Worker AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec *mData, size_t index) {
784*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> format;
785*ec779b8eSAndroid Build Coastguard Worker     mData->mCodec->getOutputFormat(index, &format);
786*ec779b8eSAndroid Build Coastguard Worker     return AMediaFormat_fromMsg(&format);
787*ec779b8eSAndroid Build Coastguard Worker }
788*ec779b8eSAndroid Build Coastguard Worker 
789*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_releaseOutputBuffer(AMediaCodec * mData,size_t idx,bool render)790*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec *mData, size_t idx, bool render) {
791*ec779b8eSAndroid Build Coastguard Worker     if (render) {
792*ec779b8eSAndroid Build Coastguard Worker         return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx));
793*ec779b8eSAndroid Build Coastguard Worker     } else {
794*ec779b8eSAndroid Build Coastguard Worker         return translate_error(mData->mCodec->releaseOutputBuffer(idx));
795*ec779b8eSAndroid Build Coastguard Worker     }
796*ec779b8eSAndroid Build Coastguard Worker }
797*ec779b8eSAndroid Build Coastguard Worker 
798*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_releaseOutputBufferAtTime(AMediaCodec * mData,size_t idx,int64_t timestampNs)799*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_releaseOutputBufferAtTime(
800*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData, size_t idx, int64_t timestampNs) {
801*ec779b8eSAndroid Build Coastguard Worker     ALOGV("render @ %" PRId64, timestampNs);
802*ec779b8eSAndroid Build Coastguard Worker     return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx, timestampNs));
803*ec779b8eSAndroid Build Coastguard Worker }
804*ec779b8eSAndroid Build Coastguard Worker 
805*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_setOutputSurface(AMediaCodec * mData,ANativeWindow * window)806*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_setOutputSurface(AMediaCodec *mData, ANativeWindow* window) {
807*ec779b8eSAndroid Build Coastguard Worker     sp<Surface> surface = NULL;
808*ec779b8eSAndroid Build Coastguard Worker     if (window != NULL) {
809*ec779b8eSAndroid Build Coastguard Worker         surface = (Surface*) window;
810*ec779b8eSAndroid Build Coastguard Worker     }
811*ec779b8eSAndroid Build Coastguard Worker     return translate_error(mData->mCodec->setSurface(surface));
812*ec779b8eSAndroid Build Coastguard Worker }
813*ec779b8eSAndroid Build Coastguard Worker 
814*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createInputSurface(AMediaCodec * mData,ANativeWindow ** surface)815*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_createInputSurface(AMediaCodec *mData, ANativeWindow **surface) {
816*ec779b8eSAndroid Build Coastguard Worker     if (surface == NULL || mData == NULL) {
817*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
818*ec779b8eSAndroid Build Coastguard Worker     }
819*ec779b8eSAndroid Build Coastguard Worker     *surface = NULL;
820*ec779b8eSAndroid Build Coastguard Worker 
821*ec779b8eSAndroid Build Coastguard Worker     sp<IGraphicBufferProducer> igbp = NULL;
822*ec779b8eSAndroid Build Coastguard Worker     status_t err = mData->mCodec->createInputSurface(&igbp);
823*ec779b8eSAndroid Build Coastguard Worker     if (err != NO_ERROR) {
824*ec779b8eSAndroid Build Coastguard Worker         return translate_error(err);
825*ec779b8eSAndroid Build Coastguard Worker     }
826*ec779b8eSAndroid Build Coastguard Worker 
827*ec779b8eSAndroid Build Coastguard Worker     *surface = new Surface(igbp);
828*ec779b8eSAndroid Build Coastguard Worker     ANativeWindow_acquire(*surface);
829*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
830*ec779b8eSAndroid Build Coastguard Worker }
831*ec779b8eSAndroid Build Coastguard Worker 
832*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_createPersistentInputSurface(ANativeWindow ** surface)833*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_createPersistentInputSurface(ANativeWindow **surface) {
834*ec779b8eSAndroid Build Coastguard Worker     if (surface == NULL) {
835*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
836*ec779b8eSAndroid Build Coastguard Worker     }
837*ec779b8eSAndroid Build Coastguard Worker     *surface = NULL;
838*ec779b8eSAndroid Build Coastguard Worker 
839*ec779b8eSAndroid Build Coastguard Worker     sp<PersistentSurface> ps = MediaCodec::CreatePersistentInputSurface();
840*ec779b8eSAndroid Build Coastguard Worker     if (ps == NULL) {
841*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_UNKNOWN;
842*ec779b8eSAndroid Build Coastguard Worker     }
843*ec779b8eSAndroid Build Coastguard Worker 
844*ec779b8eSAndroid Build Coastguard Worker     sp<IGraphicBufferProducer> igbp = ps->getBufferProducer();
845*ec779b8eSAndroid Build Coastguard Worker     if (igbp == NULL) {
846*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_UNKNOWN;
847*ec779b8eSAndroid Build Coastguard Worker     }
848*ec779b8eSAndroid Build Coastguard Worker 
849*ec779b8eSAndroid Build Coastguard Worker     *surface = new AMediaCodecPersistentSurface(igbp, ps);
850*ec779b8eSAndroid Build Coastguard Worker     ANativeWindow_acquire(*surface);
851*ec779b8eSAndroid Build Coastguard Worker 
852*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
853*ec779b8eSAndroid Build Coastguard Worker }
854*ec779b8eSAndroid Build Coastguard Worker 
855*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_setInputSurface(AMediaCodec * mData,ANativeWindow * surface)856*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_setInputSurface(
857*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData, ANativeWindow *surface) {
858*ec779b8eSAndroid Build Coastguard Worker 
859*ec779b8eSAndroid Build Coastguard Worker     if (surface == NULL || mData == NULL) {
860*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
861*ec779b8eSAndroid Build Coastguard Worker     }
862*ec779b8eSAndroid Build Coastguard Worker 
863*ec779b8eSAndroid Build Coastguard Worker     AMediaCodecPersistentSurface *aMediaPersistentSurface =
864*ec779b8eSAndroid Build Coastguard Worker             static_cast<AMediaCodecPersistentSurface *>(surface);
865*ec779b8eSAndroid Build Coastguard Worker     if (aMediaPersistentSurface->mPersistentSurface == NULL) {
866*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
867*ec779b8eSAndroid Build Coastguard Worker     }
868*ec779b8eSAndroid Build Coastguard Worker 
869*ec779b8eSAndroid Build Coastguard Worker     return translate_error(mData->mCodec->setInputSurface(
870*ec779b8eSAndroid Build Coastguard Worker             aMediaPersistentSurface->mPersistentSurface));
871*ec779b8eSAndroid Build Coastguard Worker }
872*ec779b8eSAndroid Build Coastguard Worker 
873*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_setParameters(AMediaCodec * mData,const AMediaFormat * params)874*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_setParameters(
875*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec *mData, const AMediaFormat* params) {
876*ec779b8eSAndroid Build Coastguard Worker     if (params == NULL || mData == NULL) {
877*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
878*ec779b8eSAndroid Build Coastguard Worker     }
879*ec779b8eSAndroid Build Coastguard Worker     sp<AMessage> nativeParams;
880*ec779b8eSAndroid Build Coastguard Worker     AMediaFormat_getFormat(params, &nativeParams);
881*ec779b8eSAndroid Build Coastguard Worker     ALOGV("setParameters: %s", nativeParams->debugString(0).c_str());
882*ec779b8eSAndroid Build Coastguard Worker 
883*ec779b8eSAndroid Build Coastguard Worker     return translate_error(mData->mCodec->setParameters(nativeParams));
884*ec779b8eSAndroid Build Coastguard Worker }
885*ec779b8eSAndroid Build Coastguard Worker 
886*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_signalEndOfInputStream(AMediaCodec * mData)887*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_signalEndOfInputStream(AMediaCodec *mData) {
888*ec779b8eSAndroid Build Coastguard Worker 
889*ec779b8eSAndroid Build Coastguard Worker     if (mData == NULL) {
890*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
891*ec779b8eSAndroid Build Coastguard Worker     }
892*ec779b8eSAndroid Build Coastguard Worker 
893*ec779b8eSAndroid Build Coastguard Worker     status_t err = mData->mCodec->signalEndOfInputStream();
894*ec779b8eSAndroid Build Coastguard Worker     if (err == INVALID_OPERATION) {
895*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OPERATION;
896*ec779b8eSAndroid Build Coastguard Worker     }
897*ec779b8eSAndroid Build Coastguard Worker 
898*ec779b8eSAndroid Build Coastguard Worker     return translate_error(err);
899*ec779b8eSAndroid Build Coastguard Worker 
900*ec779b8eSAndroid Build Coastguard Worker }
901*ec779b8eSAndroid Build Coastguard Worker 
902*ec779b8eSAndroid Build Coastguard Worker //EXPORT
AMediaCodec_setNotificationCallback(AMediaCodec * mData,OnCodecEvent callback,void * userdata)903*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_setNotificationCallback(AMediaCodec *mData, OnCodecEvent callback,
904*ec779b8eSAndroid Build Coastguard Worker         void *userdata) {
905*ec779b8eSAndroid Build Coastguard Worker     mData->mCallback = callback;
906*ec779b8eSAndroid Build Coastguard Worker     mData->mCallbackUserData = userdata;
907*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
908*ec779b8eSAndroid Build Coastguard Worker }
909*ec779b8eSAndroid Build Coastguard Worker 
910*ec779b8eSAndroid Build Coastguard Worker typedef struct AMediaCodecCryptoInfo {
911*ec779b8eSAndroid Build Coastguard Worker         int numsubsamples;
912*ec779b8eSAndroid Build Coastguard Worker         uint8_t key[16];
913*ec779b8eSAndroid Build Coastguard Worker         uint8_t iv[16];
914*ec779b8eSAndroid Build Coastguard Worker         cryptoinfo_mode_t mode;
915*ec779b8eSAndroid Build Coastguard Worker         cryptoinfo_pattern_t pattern;
916*ec779b8eSAndroid Build Coastguard Worker         size_t *clearbytes;
917*ec779b8eSAndroid Build Coastguard Worker         size_t *encryptedbytes;
918*ec779b8eSAndroid Build Coastguard Worker } AMediaCodecCryptoInfo;
919*ec779b8eSAndroid Build Coastguard Worker 
920*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodec_queueSecureInputBuffer(AMediaCodec * codec,size_t idx,off_t offset,AMediaCodecCryptoInfo * crypto,uint64_t time,uint32_t flags)921*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodec_queueSecureInputBuffer(
922*ec779b8eSAndroid Build Coastguard Worker         AMediaCodec* codec,
923*ec779b8eSAndroid Build Coastguard Worker         size_t idx,
924*ec779b8eSAndroid Build Coastguard Worker         off_t offset,
925*ec779b8eSAndroid Build Coastguard Worker         AMediaCodecCryptoInfo* crypto,
926*ec779b8eSAndroid Build Coastguard Worker         uint64_t time,
927*ec779b8eSAndroid Build Coastguard Worker         uint32_t flags) {
928*ec779b8eSAndroid Build Coastguard Worker 
929*ec779b8eSAndroid Build Coastguard Worker     CryptoPlugin::SubSample *subSamples = new CryptoPlugin::SubSample[crypto->numsubsamples];
930*ec779b8eSAndroid Build Coastguard Worker     for (int i = 0; i < crypto->numsubsamples; i++) {
931*ec779b8eSAndroid Build Coastguard Worker         subSamples[i].mNumBytesOfClearData = crypto->clearbytes[i];
932*ec779b8eSAndroid Build Coastguard Worker         subSamples[i].mNumBytesOfEncryptedData = crypto->encryptedbytes[i];
933*ec779b8eSAndroid Build Coastguard Worker     }
934*ec779b8eSAndroid Build Coastguard Worker 
935*ec779b8eSAndroid Build Coastguard Worker     CryptoPlugin::Pattern pattern;
936*ec779b8eSAndroid Build Coastguard Worker     pattern.mEncryptBlocks = crypto->pattern.encryptBlocks;
937*ec779b8eSAndroid Build Coastguard Worker     pattern.mSkipBlocks = crypto->pattern.skipBlocks;
938*ec779b8eSAndroid Build Coastguard Worker 
939*ec779b8eSAndroid Build Coastguard Worker     AString errormsg;
940*ec779b8eSAndroid Build Coastguard Worker     status_t err  = codec->mCodec->queueSecureInputBuffer(idx,
941*ec779b8eSAndroid Build Coastguard Worker             offset,
942*ec779b8eSAndroid Build Coastguard Worker             subSamples,
943*ec779b8eSAndroid Build Coastguard Worker             crypto->numsubsamples,
944*ec779b8eSAndroid Build Coastguard Worker             crypto->key,
945*ec779b8eSAndroid Build Coastguard Worker             crypto->iv,
946*ec779b8eSAndroid Build Coastguard Worker             (CryptoPlugin::Mode)crypto->mode,
947*ec779b8eSAndroid Build Coastguard Worker             pattern,
948*ec779b8eSAndroid Build Coastguard Worker             time,
949*ec779b8eSAndroid Build Coastguard Worker             flags,
950*ec779b8eSAndroid Build Coastguard Worker             &errormsg);
951*ec779b8eSAndroid Build Coastguard Worker     if (err != 0) {
952*ec779b8eSAndroid Build Coastguard Worker         ALOGE("queSecureInputBuffer: %s", errormsg.c_str());
953*ec779b8eSAndroid Build Coastguard Worker     }
954*ec779b8eSAndroid Build Coastguard Worker     delete [] subSamples;
955*ec779b8eSAndroid Build Coastguard Worker     return translate_error(err);
956*ec779b8eSAndroid Build Coastguard Worker }
957*ec779b8eSAndroid Build Coastguard Worker 
958*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecActionCode_isRecoverable(int32_t actionCode)959*ec779b8eSAndroid Build Coastguard Worker bool AMediaCodecActionCode_isRecoverable(int32_t actionCode) {
960*ec779b8eSAndroid Build Coastguard Worker     return (actionCode == ACTION_CODE_RECOVERABLE);
961*ec779b8eSAndroid Build Coastguard Worker }
962*ec779b8eSAndroid Build Coastguard Worker 
963*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecActionCode_isTransient(int32_t actionCode)964*ec779b8eSAndroid Build Coastguard Worker bool AMediaCodecActionCode_isTransient(int32_t actionCode) {
965*ec779b8eSAndroid Build Coastguard Worker     return (actionCode == ACTION_CODE_TRANSIENT);
966*ec779b8eSAndroid Build Coastguard Worker }
967*ec779b8eSAndroid Build Coastguard Worker 
968*ec779b8eSAndroid Build Coastguard Worker 
969*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_setPattern(AMediaCodecCryptoInfo * info,cryptoinfo_pattern_t * pattern)970*ec779b8eSAndroid Build Coastguard Worker void AMediaCodecCryptoInfo_setPattern(AMediaCodecCryptoInfo *info,
971*ec779b8eSAndroid Build Coastguard Worker         cryptoinfo_pattern_t *pattern) {
972*ec779b8eSAndroid Build Coastguard Worker     info->pattern.encryptBlocks = pattern->encryptBlocks;
973*ec779b8eSAndroid Build Coastguard Worker     info->pattern.skipBlocks = pattern->skipBlocks;
974*ec779b8eSAndroid Build Coastguard Worker }
975*ec779b8eSAndroid Build Coastguard Worker 
976*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_new(int numsubsamples,uint8_t key[16],uint8_t iv[16],cryptoinfo_mode_t mode,size_t * clearbytes,size_t * encryptedbytes)977*ec779b8eSAndroid Build Coastguard Worker AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
978*ec779b8eSAndroid Build Coastguard Worker         int numsubsamples,
979*ec779b8eSAndroid Build Coastguard Worker         uint8_t key[16],
980*ec779b8eSAndroid Build Coastguard Worker         uint8_t iv[16],
981*ec779b8eSAndroid Build Coastguard Worker         cryptoinfo_mode_t mode,
982*ec779b8eSAndroid Build Coastguard Worker         size_t *clearbytes,
983*ec779b8eSAndroid Build Coastguard Worker         size_t *encryptedbytes) {
984*ec779b8eSAndroid Build Coastguard Worker 
985*ec779b8eSAndroid Build Coastguard Worker     // size needed to store all the crypto data
986*ec779b8eSAndroid Build Coastguard Worker     size_t cryptosize;
987*ec779b8eSAndroid Build Coastguard Worker     // = sizeof(AMediaCodecCryptoInfo) + sizeof(size_t) * numsubsamples * 2;
988*ec779b8eSAndroid Build Coastguard Worker     if (__builtin_mul_overflow(sizeof(size_t) * 2, numsubsamples, &cryptosize) ||
989*ec779b8eSAndroid Build Coastguard Worker             __builtin_add_overflow(cryptosize, sizeof(AMediaCodecCryptoInfo), &cryptosize)) {
990*ec779b8eSAndroid Build Coastguard Worker         ALOGE("crypto size overflow");
991*ec779b8eSAndroid Build Coastguard Worker         return NULL;
992*ec779b8eSAndroid Build Coastguard Worker     }
993*ec779b8eSAndroid Build Coastguard Worker     AMediaCodecCryptoInfo *ret = (AMediaCodecCryptoInfo*) malloc(cryptosize);
994*ec779b8eSAndroid Build Coastguard Worker     if (!ret) {
995*ec779b8eSAndroid Build Coastguard Worker         ALOGE("couldn't allocate %zu bytes", cryptosize);
996*ec779b8eSAndroid Build Coastguard Worker         return NULL;
997*ec779b8eSAndroid Build Coastguard Worker     }
998*ec779b8eSAndroid Build Coastguard Worker     ret->numsubsamples = numsubsamples;
999*ec779b8eSAndroid Build Coastguard Worker     memcpy(ret->key, key, 16);
1000*ec779b8eSAndroid Build Coastguard Worker     memcpy(ret->iv, iv, 16);
1001*ec779b8eSAndroid Build Coastguard Worker     ret->mode = mode;
1002*ec779b8eSAndroid Build Coastguard Worker     ret->pattern.encryptBlocks = 0;
1003*ec779b8eSAndroid Build Coastguard Worker     ret->pattern.skipBlocks = 0;
1004*ec779b8eSAndroid Build Coastguard Worker 
1005*ec779b8eSAndroid Build Coastguard Worker     // clearbytes and encryptedbytes point at the actual data, which follows
1006*ec779b8eSAndroid Build Coastguard Worker     ret->clearbytes = (size_t*) (ret + 1); // point immediately after the struct
1007*ec779b8eSAndroid Build Coastguard Worker     ret->encryptedbytes = ret->clearbytes + numsubsamples; // point after the clear sizes
1008*ec779b8eSAndroid Build Coastguard Worker 
1009*ec779b8eSAndroid Build Coastguard Worker     memcpy(ret->clearbytes, clearbytes, numsubsamples * sizeof(size_t));
1010*ec779b8eSAndroid Build Coastguard Worker     memcpy(ret->encryptedbytes, encryptedbytes, numsubsamples * sizeof(size_t));
1011*ec779b8eSAndroid Build Coastguard Worker 
1012*ec779b8eSAndroid Build Coastguard Worker     return ret;
1013*ec779b8eSAndroid Build Coastguard Worker }
1014*ec779b8eSAndroid Build Coastguard Worker 
1015*ec779b8eSAndroid Build Coastguard Worker 
1016*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo * info)1017*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo* info) {
1018*ec779b8eSAndroid Build Coastguard Worker     free(info);
1019*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
1020*ec779b8eSAndroid Build Coastguard Worker }
1021*ec779b8eSAndroid Build Coastguard Worker 
1022*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo * ci)1023*ec779b8eSAndroid Build Coastguard Worker size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo* ci) {
1024*ec779b8eSAndroid Build Coastguard Worker     return ci->numsubsamples;
1025*ec779b8eSAndroid Build Coastguard Worker }
1026*ec779b8eSAndroid Build Coastguard Worker 
1027*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo * ci,uint8_t * dst)1028*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo* ci, uint8_t *dst) {
1029*ec779b8eSAndroid Build Coastguard Worker     if (!ci) {
1030*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
1031*ec779b8eSAndroid Build Coastguard Worker     }
1032*ec779b8eSAndroid Build Coastguard Worker     if (!dst) {
1033*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
1034*ec779b8eSAndroid Build Coastguard Worker     }
1035*ec779b8eSAndroid Build Coastguard Worker     memcpy(dst, ci->key, 16);
1036*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
1037*ec779b8eSAndroid Build Coastguard Worker }
1038*ec779b8eSAndroid Build Coastguard Worker 
1039*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo * ci,uint8_t * dst)1040*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo* ci, uint8_t *dst) {
1041*ec779b8eSAndroid Build Coastguard Worker     if (!ci) {
1042*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
1043*ec779b8eSAndroid Build Coastguard Worker     }
1044*ec779b8eSAndroid Build Coastguard Worker     if (!dst) {
1045*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
1046*ec779b8eSAndroid Build Coastguard Worker     }
1047*ec779b8eSAndroid Build Coastguard Worker     memcpy(dst, ci->iv, 16);
1048*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
1049*ec779b8eSAndroid Build Coastguard Worker }
1050*ec779b8eSAndroid Build Coastguard Worker 
1051*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo * ci)1052*ec779b8eSAndroid Build Coastguard Worker cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo* ci) {
1053*ec779b8eSAndroid Build Coastguard Worker     if (!ci) {
1054*ec779b8eSAndroid Build Coastguard Worker         return (cryptoinfo_mode_t) AMEDIA_ERROR_INVALID_OBJECT;
1055*ec779b8eSAndroid Build Coastguard Worker     }
1056*ec779b8eSAndroid Build Coastguard Worker     return ci->mode;
1057*ec779b8eSAndroid Build Coastguard Worker }
1058*ec779b8eSAndroid Build Coastguard Worker 
1059*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo * ci,size_t * dst)1060*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo* ci, size_t *dst) {
1061*ec779b8eSAndroid Build Coastguard Worker     if (!ci) {
1062*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
1063*ec779b8eSAndroid Build Coastguard Worker     }
1064*ec779b8eSAndroid Build Coastguard Worker     if (!dst) {
1065*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
1066*ec779b8eSAndroid Build Coastguard Worker     }
1067*ec779b8eSAndroid Build Coastguard Worker     memcpy(dst, ci->clearbytes, sizeof(size_t) * ci->numsubsamples);
1068*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
1069*ec779b8eSAndroid Build Coastguard Worker }
1070*ec779b8eSAndroid Build Coastguard Worker 
1071*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo * ci,size_t * dst)1072*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo* ci, size_t *dst) {
1073*ec779b8eSAndroid Build Coastguard Worker     if (!ci) {
1074*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
1075*ec779b8eSAndroid Build Coastguard Worker     }
1076*ec779b8eSAndroid Build Coastguard Worker     if (!dst) {
1077*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
1078*ec779b8eSAndroid Build Coastguard Worker     }
1079*ec779b8eSAndroid Build Coastguard Worker     memcpy(dst, ci->encryptedbytes, sizeof(size_t) * ci->numsubsamples);
1080*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
1081*ec779b8eSAndroid Build Coastguard Worker }
1082*ec779b8eSAndroid Build Coastguard Worker 
1083*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_HDR10_PLUS_INFO = AMEDIAFORMAT_KEY_HDR10_PLUS_INFO;
1084*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_LOW_LATENCY = AMEDIAFORMAT_KEY_LOW_LATENCY;
1085*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_OFFSET_TIME = "time-offset-us";
1086*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_REQUEST_SYNC_FRAME = "request-sync";
1087*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_SUSPEND = "drop-input-frames";
1088*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_SUSPEND_TIME = "drop-start-time-us";
1089*ec779b8eSAndroid Build Coastguard Worker EXPORT const char* AMEDIACODEC_KEY_VIDEO_BITRATE = "video-bitrate";
1090*ec779b8eSAndroid Build Coastguard Worker 
1091*ec779b8eSAndroid Build Coastguard Worker } // extern "C"
1092*ec779b8eSAndroid Build Coastguard Worker 
1093