NdkMediaCodec.cpp revision 3425fd5a55dd31e261d2f2a9590c762d6d0a6b79
10c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen/*
20c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * Copyright (C) 2014 The Android Open Source Project
30c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *
40c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
50c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * you may not use this file except in compliance with the License.
60c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * You may obtain a copy of the License at
70c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *
80c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
90c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen *
100c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * Unless required by applicable law or agreed to in writing, software
110c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
120c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * See the License for the specific language governing permissions and
140c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen * limitations under the License.
150c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen */
160c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
170c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#define LOG_NDEBUG 0
180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#define LOG_TAG "NdkMediaCodec"
190c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
200c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include "NdkMediaCodec.h"
21050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen#include "NdkMediaError.h"
22050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen#include "NdkMediaCryptoPriv.h"
230c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include "NdkMediaFormatPriv.h"
240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <utils/Log.h>
260c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <utils/StrongPointer.h>
270c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <gui/Surface.h>
280c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
290c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/foundation/ALooper.h>
300c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/foundation/AMessage.h>
310c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/foundation/ABuffer.h>
320c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
330c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/MediaCodec.h>
340c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen#include <media/stagefright/MediaErrors.h>
350c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
360c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenusing namespace android;
370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenstatic int translate_error(status_t err) {
400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (err == OK) {
410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return OK;
420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    } else if (err == -EAGAIN) {
430c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return AMEDIACODEC_INFO_TRY_AGAIN_LATER;
440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
450c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("sf error code: %d", err);
46050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return AMEDIAERROR_GENERIC;
470c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
49cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenenum {
50cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    kWhatActivityNotify,
51cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    kWhatRequestActivityNotifications,
52cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    kWhatStopActivityNotifications,
53cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen};
54cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
550c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
560c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenclass CodecHandler: public AHandler {
57cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenprivate:
58cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    AMediaCodec* mCodec;
590c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenpublic:
60cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    CodecHandler(AMediaCodec *codec);
610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    virtual void onMessageReceived(const sp<AMessage> &msg);
620c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen};
630c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
64cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenstruct AMediaCodec {
65cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<android::MediaCodec> mCodec;
66cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<ALooper> mLooper;
67cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<CodecHandler> mHandler;
68cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<AMessage> mActivityNotification;
69cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    int32_t mGeneration;
70cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    bool mRequestedActivityNotification;
71cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    OnCodecEvent mCallback;
72cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    void *mCallbackUserData;
73cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen};
740c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
75cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco NelissenCodecHandler::CodecHandler(AMediaCodec *codec) {
76cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mCodec = codec;
770c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
780c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
790c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenvoid CodecHandler::onMessageReceived(const sp<AMessage> &msg) {
80cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
81cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    switch (msg->what()) {
82cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        case kWhatRequestActivityNotifications:
83cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        {
84cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            if (mCodec->mRequestedActivityNotification) {
85cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                break;
86cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            }
87cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
88cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mCodec->requestActivityNotification(mCodec->mActivityNotification);
89cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mRequestedActivityNotification = true;
90cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
91cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        }
92cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
93cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        case kWhatActivityNotify:
94cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        {
95cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            {
96cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                int32_t generation;
97cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                msg->findInt32("generation", &generation);
98cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
99cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                if (generation != mCodec->mGeneration) {
100cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                    // stale
101cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                    break;
102cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                }
103cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
104cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                mCodec->mRequestedActivityNotification = false;
105cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            }
106cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
107cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            if (mCodec->mCallback) {
108cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                mCodec->mCallback(mCodec, mCodec->mCallbackUserData);
109cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            }
110cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
111cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        }
112cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
113cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        case kWhatStopActivityNotifications:
114cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        {
115cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            uint32_t replyID;
116cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            msg->senderAwaitsResponse(&replyID);
117cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
118cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mGeneration++;
119cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mRequestedActivityNotification = false;
120cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
121cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            sp<AMessage> response = new AMessage;
122cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            response->postReply(replyID);
123cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
124cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        }
125cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
126cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        default:
127cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            ALOGE("shouldn't be here");
128cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
129cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    }
130cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
1310c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1320c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
133cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
134cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenstatic void requestActivityNotification(AMediaCodec *codec) {
135cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    (new AMessage(kWhatRequestActivityNotifications, codec->mHandler->id()))->post();
136cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen}
1370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenextern "C" {
1390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenstatic AMediaCodec * createAMediaCodec(const char *name, bool name_is_type, bool encoder) {
1410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AMediaCodec *mData = new AMediaCodec();
1420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mLooper = new ALooper;
1430c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mLooper->setName("NDK MediaCodec_looper");
1440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mLooper->start(
1450c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            false,      // runOnCallingThread
1460c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            true,       // canCallJava XXX
1470c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            PRIORITY_FOREGROUND);
1480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (name_is_type) {
1490c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec = android::MediaCodec::CreateByType(mData->mLooper, name, encoder);
1500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    } else {
1510c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec = android::MediaCodec::CreateByComponentName(mData->mLooper, name);
1520c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
153cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mHandler = new CodecHandler(mData);
1540c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mLooper->registerHandler(mData->mHandler);
155cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mGeneration = 1;
156cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mRequestedActivityNotification = false;
157cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mCallback = NULL;
158cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
1590c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return mData;
1600c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1623425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
16386aa02ce274826dc80ffa00766b16172c47503fdMarco NelissenAMediaCodec* AMediaCodec_createCodecByName(const char *name) {
1640c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return createAMediaCodec(name, false, false);
1650c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1660c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1673425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
16886aa02ce274826dc80ffa00766b16172c47503fdMarco NelissenAMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type) {
1690c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return createAMediaCodec(mime_type, true, false);
1700c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1710c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1723425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
17386aa02ce274826dc80ffa00766b16172c47503fdMarco NelissenAMediaCodec* AMediaCodec_createEncoderByType(const char *name) {
17486aa02ce274826dc80ffa00766b16172c47503fdMarco Nelissen    return createAMediaCodec(name, true, true);
1750c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1760c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1773425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
1780c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaCodec_delete(AMediaCodec *mData) {
1790c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mCodec != NULL) {
1800c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec->release();
1810c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec.clear();
1820c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1830c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1840c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mLooper != NULL) {
1850c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mLooper->unregisterHandler(mData->mHandler->id());
1860c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mLooper->stop();
1870c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mLooper.clear();
1880c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1890c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    delete mData;
1900c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return OK;
1910c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1920c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1933425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
19486aa02ce274826dc80ffa00766b16172c47503fdMarco Nelissenint AMediaCodec_configure(
195050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCodec *mData,
196050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        const AMediaFormat* format,
197050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        ANativeWindow* window,
198050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCrypto *crypto,
199050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t flags) {
2000c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<AMessage> nativeFormat;
2010c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AMediaFormat_getFormat(format, &nativeFormat);
2020c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGV("configure with format: %s", nativeFormat->debugString(0).c_str());
2030c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<Surface> surface = NULL;
2040c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (window != NULL) {
2050c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        surface = (Surface*) window;
2060c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2070c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
208050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return translate_error(mData->mCodec->configure(nativeFormat, surface,
209050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto ? crypto->mCrypto : NULL, flags));
2100c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2110c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2123425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaCodec_start(AMediaCodec *mData) {
214cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    status_t ret =  mData->mCodec->start();
215cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    if (ret != OK) {
216cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        return translate_error(ret);
217cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    }
218cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mActivityNotification = new AMessage(kWhatActivityNotify, mData->mHandler->id());
219cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mActivityNotification->setInt32("generation", mData->mGeneration);
220cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    requestActivityNotification(mData);
221cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    return OK;
2220c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2230c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2243425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaCodec_stop(AMediaCodec *mData) {
226cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    int ret = translate_error(mData->mCodec->stop());
227cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
228cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, mData->mHandler->id());
229cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<AMessage> response;
230cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    msg->postAndAwaitResponse(&response);
231cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mActivityNotification.clear();
232cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
233cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    return ret;
2340c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2350c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2363425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaCodec_flush(AMediaCodec *mData) {
2380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(mData->mCodec->flush());
2390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2413425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec *mData, int64_t timeoutUs) {
2430c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t idx;
2440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mCodec->dequeueInputBuffer(&idx, timeoutUs);
245cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    requestActivityNotification(mData);
2460c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (ret == OK) {
2470c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return idx;
2480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2490c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(ret);
2500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2510c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2523425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2530c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenuint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
2540c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    android::Vector<android::sp<android::ABuffer> > abufs;
2550c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mCodec->getInputBuffers(&abufs) == 0) {
2560c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        size_t n = abufs.size();
2570c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (idx >= n) {
2580c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            ALOGE("buffer index %d out of range", idx);
2590c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return NULL;
2600c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (out_size != NULL) {
2620c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            *out_size = abufs[idx]->capacity();
2630c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2640c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return abufs[idx]->data();
2650c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2660c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("couldn't get input buffers");
2670c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return NULL;
2680c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2690c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2703425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2710c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenuint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
2720c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    android::Vector<android::sp<android::ABuffer> > abufs;
2730c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mCodec->getOutputBuffers(&abufs) == 0) {
2740c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        size_t n = abufs.size();
2750c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (idx >= n) {
2760c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            ALOGE("buffer index %d out of range", idx);
2770c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return NULL;
2780c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2790c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (out_size != NULL) {
2800c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            *out_size = abufs[idx]->capacity();
2810c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2820c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return abufs[idx]->data();
2830c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2840c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("couldn't get output buffers");
2850c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return NULL;
2860c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2870c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2883425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2890c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaCodec_queueInputBuffer(AMediaCodec *mData,
2900c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags) {
2910c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2920c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AString errorMsg;
2930c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mCodec->queueInputBuffer(idx, offset, size, time, flags, &errorMsg);
2940c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(ret);
2950c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2960c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2973425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2980c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec *mData,
2990c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        AMediaCodecBufferInfo *info, int64_t timeoutUs) {
3000c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t idx;
3010c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t offset;
3020c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t size;
3030c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    uint32_t flags;
3040c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    int64_t presentationTimeUs;
3050c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mCodec->dequeueOutputBuffer(&idx, &offset, &size, &presentationTimeUs,
3060c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            &flags, timeoutUs);
307cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    requestActivityNotification(mData);
3080c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    switch (ret) {
3090c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case OK:
3100c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->offset = offset;
3110c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->size = size;
3120c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->flags = flags;
3130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->presentationTimeUs = presentationTimeUs;
3140c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return idx;
3150c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case -EAGAIN:
3160c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return AMEDIACODEC_INFO_TRY_AGAIN_LATER;
3170c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case android::INFO_FORMAT_CHANGED:
3180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED;
3190c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case INFO_OUTPUT_BUFFERS_CHANGED:
3200c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED;
3210c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        default:
3220c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            break;
3230c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
3240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(ret);
3250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
3260c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
3273425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
3280c3be875376adaee8d8e8dd917c64926e1513b29Marco NelissenAMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec *mData) {
3290c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<AMessage> format;
3300c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mCodec->getOutputFormat(&format);
3310c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return AMediaFormat_fromMsg(&format);
3320c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
3330c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
3343425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
3350c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenint AMediaCodec_releaseOutputBuffer(AMediaCodec *mData, size_t idx, bool render) {
3360c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (render) {
3370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx));
3380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    } else {
3390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return translate_error(mData->mCodec->releaseOutputBuffer(idx));
3400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
3410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
3420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
3433425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
344cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenint AMediaCodec_setNotificationCallback(AMediaCodec *mData, OnCodecEvent callback, void *userdata) {
345cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mCallback = callback;
346cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mCallbackUserData = userdata;
347cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    return OK;
348cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen}
349cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
350050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissentypedef struct AMediaCodecCryptoInfo {
351050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        int numsubsamples;
352050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t key[16];
353050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t iv[16];
354050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t mode;
355050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *clearbytes;
356050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *encryptedbytes;
357050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen} AMediaCodecCryptoInfo;
358050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
3593425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
360050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenint AMediaCodec_queueSecureInputBuffer(
361050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCodec* codec,
362050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t idx,
363050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        off_t offset,
364050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCodecCryptoInfo* crypto,
365050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint64_t time,
366050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t flags) {
367050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
368050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    CryptoPlugin::SubSample *subSamples = new CryptoPlugin::SubSample[crypto->numsubsamples];
369050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    for (int i = 0; i < crypto->numsubsamples; i++) {
370050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        subSamples[i].mNumBytesOfClearData = crypto->clearbytes[i];
371050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        subSamples[i].mNumBytesOfEncryptedData = crypto->encryptedbytes[i];
372050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
373050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
374050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    AString errormsg;
375050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    status_t err  = codec->mCodec->queueSecureInputBuffer(idx,
376050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            offset,
377050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            subSamples,
378050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto->numsubsamples,
379050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto->key,
380050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto->iv,
381050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            (CryptoPlugin::Mode) crypto->mode,
382050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            time,
383050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            flags,
384050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            &errormsg);
385050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (err != 0) {
386050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        ALOGE("queSecureInputBuffer: %s", errormsg.c_str());
387050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
388829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    delete [] subSamples;
389050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return translate_error(err);
390050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
391050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
392050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
393050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
3943425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
395050eb3280d7305b84f723d515be2dc9606dc39d1Marco NelissenAMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
396050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        int numsubsamples,
397050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t key[16],
398050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t iv[16],
399050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t mode,
400050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *clearbytes,
401050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *encryptedbytes) {
402050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
403050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // size needed to store all the crypto data
404050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t cryptosize = sizeof(AMediaCodecCryptoInfo) + sizeof(size_t) * numsubsamples * 2;
405050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    AMediaCodecCryptoInfo *ret = (AMediaCodecCryptoInfo*) malloc(cryptosize);
406050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!ret) {
407050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        ALOGE("couldn't allocate %d bytes", cryptosize);
408050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return NULL;
409050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
410050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ret->numsubsamples = numsubsamples;
411050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(ret->key, key, 16);
412050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(ret->iv, iv, 16);
413050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ret->mode = mode;
414050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
415050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // clearbytes and encryptedbytes point at the actual data, which follows
416829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    ret->clearbytes = (size_t*) (ret + 1); // point immediately after the struct
417829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    ret->encryptedbytes = ret->clearbytes + numsubsamples; // point after the clear sizes
418050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
419829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    memcpy(ret->clearbytes, clearbytes, numsubsamples * sizeof(size_t));
420829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    memcpy(ret->encryptedbytes, encryptedbytes, numsubsamples * sizeof(size_t));
421050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
422050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return ret;
423050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
424050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
425050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4263425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
427050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenint AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo* info) {
428050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    free(info);
429050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return OK;
430050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
431050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4323425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
433050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissensize_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo* ci) {
434050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return ci->numsubsamples;
435050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
436050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4373425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
438050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenint AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo* ci, uint8_t *dst) {
439050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!dst || !ci) {
440050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return AMEDIAERROR_UNSUPPORTED;
441050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
442050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->key, 16);
443050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return OK;
444050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
445050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4463425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
447050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenint AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo* ci, uint8_t *dst) {
448050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!dst || !ci) {
449050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return AMEDIAERROR_UNSUPPORTED;
450050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
451050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->iv, 16);
452050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return OK;
453050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
454050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4553425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
456050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenuint32_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo* ci) {
457050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!ci) {
458050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return AMEDIAERROR_UNSUPPORTED;
459050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
460050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return ci->mode;
461050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
462050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4633425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
464050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenint AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo* ci, size_t *dst) {
465050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!dst || !ci) {
466050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return AMEDIAERROR_UNSUPPORTED;
467050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
468050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->clearbytes, sizeof(size_t) * ci->numsubsamples);
469050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return OK;
470050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
471050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4723425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
473050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissenint AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo* ci, size_t *dst) {
474050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!dst || !ci) {
475050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return AMEDIAERROR_UNSUPPORTED;
476050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
477050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->encryptedbytes, sizeof(size_t) * ci->numsubsamples);
478050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return OK;
479050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
480cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
4810c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen} // extern "C"
4820c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
483