NdkMediaCodec.cpp revision c7a11b2208aa8f1e6a39eb70a136fbc0dafd3260
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
17c7a11b2208aa8f1e6a39eb70a136fbc0dafd3260Marco 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
39e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translate_error(status_t err) {
400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (err == OK) {
41e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_OK;
420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    } else if (err == -EAGAIN) {
43e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return (media_status_t) AMEDIACODEC_INFO_TRY_AGAIN_LATER;
440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
450c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("sf error code: %d", err);
46e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_ERROR_UNKNOWN;
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
64e22a64b6887240fc9910d6fc8afb0e6f81507047Marco Nelissentypedef void (*OnCodecEvent)(AMediaCodec *codec, void *userdata);
65e22a64b6887240fc9910d6fc8afb0e6f81507047Marco Nelissen
66cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenstruct AMediaCodec {
67cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<android::MediaCodec> mCodec;
68cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<ALooper> mLooper;
69cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<CodecHandler> mHandler;
70cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<AMessage> mActivityNotification;
71cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    int32_t mGeneration;
72cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    bool mRequestedActivityNotification;
73cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    OnCodecEvent mCallback;
74cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    void *mCallbackUserData;
75cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen};
760c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
77cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco NelissenCodecHandler::CodecHandler(AMediaCodec *codec) {
78cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mCodec = codec;
790c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
800c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
810c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenvoid CodecHandler::onMessageReceived(const sp<AMessage> &msg) {
82cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
83cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    switch (msg->what()) {
84cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        case kWhatRequestActivityNotifications:
85cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        {
86cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            if (mCodec->mRequestedActivityNotification) {
87cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                break;
88cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            }
89cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
90cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mCodec->requestActivityNotification(mCodec->mActivityNotification);
91cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mRequestedActivityNotification = true;
92cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
93cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        }
94cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
95cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        case kWhatActivityNotify:
96cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        {
97cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            {
98cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                int32_t generation;
99cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                msg->findInt32("generation", &generation);
100cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
101cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                if (generation != mCodec->mGeneration) {
102cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                    // stale
103cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                    break;
104cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                }
105cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
106cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                mCodec->mRequestedActivityNotification = false;
107cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            }
108cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
109cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            if (mCodec->mCallback) {
110cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen                mCodec->mCallback(mCodec, mCodec->mCallbackUserData);
111cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            }
112cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
113cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        }
114cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
115cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        case kWhatStopActivityNotifications:
116cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        {
117cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            uint32_t replyID;
118cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            msg->senderAwaitsResponse(&replyID);
119cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
120cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mGeneration++;
121cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            mCodec->mRequestedActivityNotification = false;
122cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
123cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            sp<AMessage> response = new AMessage;
124cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            response->postReply(replyID);
125cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
126cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        }
127cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
128cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        default:
129cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            ALOGE("shouldn't be here");
130cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen            break;
131cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    }
132cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
1330c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1340c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
135cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
136cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissenstatic void requestActivityNotification(AMediaCodec *codec) {
137cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    (new AMessage(kWhatRequestActivityNotifications, codec->mHandler->id()))->post();
138cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen}
1390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenextern "C" {
1410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenstatic AMediaCodec * createAMediaCodec(const char *name, bool name_is_type, bool encoder) {
1430c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AMediaCodec *mData = new AMediaCodec();
1440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mLooper = new ALooper;
1450c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mLooper->setName("NDK MediaCodec_looper");
1460c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mLooper->start(
1470c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            false,      // runOnCallingThread
1480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            true,       // canCallJava XXX
1490c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            PRIORITY_FOREGROUND);
1500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (name_is_type) {
1510c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec = android::MediaCodec::CreateByType(mData->mLooper, name, encoder);
1520c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    } else {
1530c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec = android::MediaCodec::CreateByComponentName(mData->mLooper, name);
1540c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
155cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mHandler = new CodecHandler(mData);
1560c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mLooper->registerHandler(mData->mHandler);
157cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mGeneration = 1;
158cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mRequestedActivityNotification = false;
159cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mCallback = NULL;
160cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
1610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return mData;
1620c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1630c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1643425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
16586aa02ce274826dc80ffa00766b16172c47503fdMarco NelissenAMediaCodec* AMediaCodec_createCodecByName(const char *name) {
1660c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return createAMediaCodec(name, false, false);
1670c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1680c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1693425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
17086aa02ce274826dc80ffa00766b16172c47503fdMarco NelissenAMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type) {
1710c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return createAMediaCodec(mime_type, true, false);
1720c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1730c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1743425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
17586aa02ce274826dc80ffa00766b16172c47503fdMarco NelissenAMediaCodec* AMediaCodec_createEncoderByType(const char *name) {
17686aa02ce274826dc80ffa00766b16172c47503fdMarco Nelissen    return createAMediaCodec(name, true, true);
1770c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1780c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1793425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
180e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_delete(AMediaCodec *mData) {
1810c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mCodec != NULL) {
1820c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec->release();
1830c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mCodec.clear();
1840c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1850c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1860c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mLooper != NULL) {
1870c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mLooper->unregisterHandler(mData->mHandler->id());
1880c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mLooper->stop();
1890c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        mData->mLooper.clear();
1900c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
1910c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    delete mData;
192e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
1930c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
1940c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
1953425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
196e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_configure(
197050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCodec *mData,
198050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        const AMediaFormat* format,
199050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        ANativeWindow* window,
200050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCrypto *crypto,
201050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t flags) {
2020c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<AMessage> nativeFormat;
2030c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AMediaFormat_getFormat(format, &nativeFormat);
2040c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGV("configure with format: %s", nativeFormat->debugString(0).c_str());
2050c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<Surface> surface = NULL;
2060c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (window != NULL) {
2070c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        surface = (Surface*) window;
2080c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2090c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
210050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return translate_error(mData->mCodec->configure(nativeFormat, surface,
211050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto ? crypto->mCrypto : NULL, flags));
2120c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2143425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
215e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_start(AMediaCodec *mData) {
216cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    status_t ret =  mData->mCodec->start();
217cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    if (ret != OK) {
218cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen        return translate_error(ret);
219cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    }
220cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mActivityNotification = new AMessage(kWhatActivityNotify, mData->mHandler->id());
221cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mActivityNotification->setInt32("generation", mData->mGeneration);
222cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    requestActivityNotification(mData);
223e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
2240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2263425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
227e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_stop(AMediaCodec *mData) {
228e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    media_status_t ret = translate_error(mData->mCodec->stop());
229cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
230cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, mData->mHandler->id());
231cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    sp<AMessage> response;
232cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    msg->postAndAwaitResponse(&response);
233cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mActivityNotification.clear();
234cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
235cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    return ret;
2360c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2370c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2383425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
239e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_flush(AMediaCodec *mData) {
2400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(mData->mCodec->flush());
2410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2433425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec *mData, int64_t timeoutUs) {
2450c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t idx;
2460c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mCodec->dequeueInputBuffer(&idx, timeoutUs);
247cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    requestActivityNotification(mData);
2480c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (ret == OK) {
2490c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return idx;
2500c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2510c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(ret);
2520c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2530c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2543425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2550c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenuint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
2560c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    android::Vector<android::sp<android::ABuffer> > abufs;
2570c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mCodec->getInputBuffers(&abufs) == 0) {
2580c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        size_t n = abufs.size();
2590c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (idx >= n) {
2600c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            ALOGE("buffer index %d out of range", idx);
2610c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return NULL;
2620c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2630c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (out_size != NULL) {
2640c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            *out_size = abufs[idx]->capacity();
2650c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2660c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return abufs[idx]->data();
2670c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2680c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("couldn't get input buffers");
2690c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return NULL;
2700c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2710c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2723425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
2730c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenuint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
2740c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    android::Vector<android::sp<android::ABuffer> > abufs;
2750c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (mData->mCodec->getOutputBuffers(&abufs) == 0) {
2760c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        size_t n = abufs.size();
2770c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (idx >= n) {
2780c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            ALOGE("buffer index %d out of range", idx);
2790c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return NULL;
2800c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2810c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        if (out_size != NULL) {
2820c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            *out_size = abufs[idx]->capacity();
2830c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        }
2840c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return abufs[idx]->data();
2850c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
2860c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    ALOGE("couldn't get output buffers");
2870c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return NULL;
2880c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2890c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2903425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
291e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_queueInputBuffer(AMediaCodec *mData,
2920c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags) {
2930c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2940c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    AString errorMsg;
2950c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mCodec->queueInputBuffer(idx, offset, size, time, flags, &errorMsg);
2960c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(ret);
2970c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
2980c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
2993425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
3000c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissenssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec *mData,
3010c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        AMediaCodecBufferInfo *info, int64_t timeoutUs) {
3020c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t idx;
3030c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t offset;
3040c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    size_t size;
3050c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    uint32_t flags;
3060c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    int64_t presentationTimeUs;
3070c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    status_t ret = mData->mCodec->dequeueOutputBuffer(&idx, &offset, &size, &presentationTimeUs,
3080c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            &flags, timeoutUs);
309cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    requestActivityNotification(mData);
3100c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    switch (ret) {
3110c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case OK:
3120c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->offset = offset;
3130c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->size = size;
3140c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->flags = flags;
3150c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            info->presentationTimeUs = presentationTimeUs;
3160c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return idx;
3170c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case -EAGAIN:
3180c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return AMEDIACODEC_INFO_TRY_AGAIN_LATER;
3190c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case android::INFO_FORMAT_CHANGED:
3200c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED;
3210c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        case INFO_OUTPUT_BUFFERS_CHANGED:
3220c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            return AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED;
3230c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        default:
3240c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen            break;
3250c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
3260c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return translate_error(ret);
3270c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
3280c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
3293425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
3300c3be875376adaee8d8e8dd917c64926e1513b29Marco NelissenAMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec *mData) {
3310c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    sp<AMessage> format;
3320c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    mData->mCodec->getOutputFormat(&format);
3330c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    return AMediaFormat_fromMsg(&format);
3340c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
3350c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
3363425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
337e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec *mData, size_t idx, bool render) {
3380c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    if (render) {
3390c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx));
3400c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    } else {
3410c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen        return translate_error(mData->mCodec->releaseOutputBuffer(idx));
3420c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen    }
3430c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen}
3440c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
3453425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
34679e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissenmedia_status_t AMediaCodec_releaseOutputBufferAtTime(
34779e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        AMediaCodec *mData, size_t idx, int64_t timestampNs) {
34879e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    ALOGV("render @ %lld", timestampNs);
34979e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen    return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx, timestampNs));
35079e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen}
35179e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen
352e22a64b6887240fc9910d6fc8afb0e6f81507047Marco Nelissen//EXPORT
353e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_setNotificationCallback(AMediaCodec *mData, OnCodecEvent callback, void *userdata) {
354cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mCallback = callback;
355cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen    mData->mCallbackUserData = userdata;
356e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
357cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen}
358cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
359050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissentypedef struct AMediaCodecCryptoInfo {
360050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        int numsubsamples;
361050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t key[16];
362050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t iv[16];
36379e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        cryptoinfo_mode_t mode;
364050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *clearbytes;
365050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *encryptedbytes;
366050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen} AMediaCodecCryptoInfo;
367050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
3683425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
369e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodec_queueSecureInputBuffer(
370050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCodec* codec,
371050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t idx,
372050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        off_t offset,
373050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        AMediaCodecCryptoInfo* crypto,
374050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint64_t time,
375050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint32_t flags) {
376050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
377050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    CryptoPlugin::SubSample *subSamples = new CryptoPlugin::SubSample[crypto->numsubsamples];
378050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    for (int i = 0; i < crypto->numsubsamples; i++) {
379050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        subSamples[i].mNumBytesOfClearData = crypto->clearbytes[i];
380050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        subSamples[i].mNumBytesOfEncryptedData = crypto->encryptedbytes[i];
381050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
382050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
383050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    AString errormsg;
384050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    status_t err  = codec->mCodec->queueSecureInputBuffer(idx,
385050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            offset,
386050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            subSamples,
387050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto->numsubsamples,
388050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto->key,
389050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            crypto->iv,
390050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            (CryptoPlugin::Mode) crypto->mode,
391050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            time,
392050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            flags,
393050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen            &errormsg);
394050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (err != 0) {
395050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        ALOGE("queSecureInputBuffer: %s", errormsg.c_str());
396050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
397829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    delete [] subSamples;
398050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return translate_error(err);
399050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
400050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
401050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
402050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4033425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
404050eb3280d7305b84f723d515be2dc9606dc39d1Marco NelissenAMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
405050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        int numsubsamples,
406050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t key[16],
407050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        uint8_t iv[16],
40879e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        cryptoinfo_mode_t mode,
409050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *clearbytes,
410050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        size_t *encryptedbytes) {
411050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
412050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // size needed to store all the crypto data
413050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    size_t cryptosize = sizeof(AMediaCodecCryptoInfo) + sizeof(size_t) * numsubsamples * 2;
414050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    AMediaCodecCryptoInfo *ret = (AMediaCodecCryptoInfo*) malloc(cryptosize);
415050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!ret) {
416050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        ALOGE("couldn't allocate %d bytes", cryptosize);
417050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen        return NULL;
418050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
419050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ret->numsubsamples = numsubsamples;
420050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(ret->key, key, 16);
421050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(ret->iv, iv, 16);
422050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    ret->mode = mode;
423050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
424050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    // clearbytes and encryptedbytes point at the actual data, which follows
425829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    ret->clearbytes = (size_t*) (ret + 1); // point immediately after the struct
426829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    ret->encryptedbytes = ret->clearbytes + numsubsamples; // point after the clear sizes
427050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
428829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    memcpy(ret->clearbytes, clearbytes, numsubsamples * sizeof(size_t));
429829e097f832b4c4c41733f9b77121888204d993eMarco Nelissen    memcpy(ret->encryptedbytes, encryptedbytes, numsubsamples * sizeof(size_t));
430050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
431050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return ret;
432050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
433050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
434050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4353425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
436e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo* info) {
437050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    free(info);
438e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
439050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
440050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4413425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
442050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissensize_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo* ci) {
443050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return ci->numsubsamples;
444050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
445050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4463425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
447e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo* ci, uint8_t *dst) {
448e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!ci) {
449e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
450e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    }
451e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!dst) {
452e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
453050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
454050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->key, 16);
455e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
456050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
457050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4583425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
459e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo* ci, uint8_t *dst) {
460e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!ci) {
461e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
462e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    }
463e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!dst) {
464e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
465050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
466050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->iv, 16);
467e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
468050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
469050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4703425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
47179e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissencryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo* ci) {
472050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    if (!ci) {
47379e2b622702fb148ccff12d6f38643466555c4ebMarco Nelissen        return (cryptoinfo_mode_t) AMEDIA_ERROR_INVALID_OBJECT;
474050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
475050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    return ci->mode;
476050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
477050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4783425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
479e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo* ci, size_t *dst) {
480e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!ci) {
481e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
482e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    }
483e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!dst) {
484e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
485050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
486050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->clearbytes, sizeof(size_t) * ci->numsubsamples);
487e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
488050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
489050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen
4903425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
491e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo* ci, size_t *dst) {
492e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!ci) {
493e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
494e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    }
495e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    if (!dst) {
496e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
497050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    }
498050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen    memcpy(dst, ci->encryptedbytes, sizeof(size_t) * ci->numsubsamples);
499e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
500050eb3280d7305b84f723d515be2dc9606dc39d1Marco Nelissen}
501cdb42cdc5ccb785edabe1ee6407134fbae5662a9Marco Nelissen
5020c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen} // extern "C"
5030c3be875376adaee8d8e8dd917c64926e1513b29Marco Nelissen
504