Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a53d0e5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "NdkMedia: add more API's in MediaCodec and MediaFormat"

parents c32ac6d9 00cc9920
Loading
Loading
Loading
Loading
+254 −3
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ static media_status_t translate_error(status_t err) {

enum {
    kWhatActivityNotify,
    kWhatAsyncNotify,
    kWhatRequestActivityNotifications,
    kWhatStopActivityNotifications,
};
@@ -88,6 +89,11 @@ struct AMediaCodec {
    bool mRequestedActivityNotification;
    OnCodecEvent mCallback;
    void *mCallbackUserData;

    sp<AMessage> mAsyncNotify;
    mutable Mutex mAsyncCallbackLock;
    AMediaCodecOnAsyncNotifyCallback mAsyncCallback;
    void *mAsyncCallbackUserData;
};

CodecHandler::CodecHandler(AMediaCodec *codec) {
@@ -128,6 +134,147 @@ void CodecHandler::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case kWhatAsyncNotify:
        {
             int32_t cbID;
             if (!msg->findInt32("callbackID", &cbID)) {
                 ALOGE("kWhatAsyncNotify: callbackID is expected.");
                 break;
             }

             ALOGV("kWhatAsyncNotify: cbID = %d", cbID);

             switch (cbID) {
                 case MediaCodec::CB_INPUT_AVAILABLE:
                 {
                     int32_t index;
                     if (!msg->findInt32("index", &index)) {
                         ALOGE("CB_INPUT_AVAILABLE: index is expected.");
                         break;
                     }

                     Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
                     if (mCodec->mAsyncCallbackUserData != NULL
                         || mCodec->mAsyncCallback.onAsyncInputAvailable != NULL) {
                         mCodec->mAsyncCallback.onAsyncInputAvailable(
                                 mCodec,
                                 mCodec->mAsyncCallbackUserData,
                                 index);
                     }

                     break;
                 }

                 case MediaCodec::CB_OUTPUT_AVAILABLE:
                 {
                     int32_t index;
                     size_t offset;
                     size_t size;
                     int64_t timeUs;
                     int32_t flags;

                     if (!msg->findInt32("index", &index)) {
                         ALOGE("CB_OUTPUT_AVAILABLE: index is expected.");
                         break;
                     }
                     if (!msg->findSize("offset", &offset)) {
                         ALOGE("CB_OUTPUT_AVAILABLE: offset is expected.");
                         break;
                     }
                     if (!msg->findSize("size", &size)) {
                         ALOGE("CB_OUTPUT_AVAILABLE: size is expected.");
                         break;
                     }
                     if (!msg->findInt64("timeUs", &timeUs)) {
                         ALOGE("CB_OUTPUT_AVAILABLE: timeUs is expected.");
                         break;
                     }
                     if (!msg->findInt32("flags", &flags)) {
                         ALOGE("CB_OUTPUT_AVAILABLE: flags is expected.");
                         break;
                     }

                     AMediaCodecBufferInfo bufferInfo = {
                         (int32_t)offset,
                         (int32_t)size,
                         timeUs,
                         (uint32_t)flags};

                     Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
                     if (mCodec->mAsyncCallbackUserData != NULL
                         || mCodec->mAsyncCallback.onAsyncOutputAvailable != NULL) {
                         mCodec->mAsyncCallback.onAsyncOutputAvailable(
                                 mCodec,
                                 mCodec->mAsyncCallbackUserData,
                                 index,
                                 &bufferInfo);
                     }

                     break;
                 }

                 case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
                 {
                     sp<AMessage> format;
                     if (!msg->findMessage("format", &format)) {
                         ALOGE("CB_OUTPUT_FORMAT_CHANGED: format is expected.");
                         break;
                     }

                     AMediaFormat *aMediaFormat = AMediaFormat_fromMsg(&format);

                     Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
                     if (mCodec->mAsyncCallbackUserData != NULL
                         || mCodec->mAsyncCallback.onAsyncFormatChanged != NULL) {
                         mCodec->mAsyncCallback.onAsyncFormatChanged(
                                 mCodec,
                                 mCodec->mAsyncCallbackUserData,
                                 aMediaFormat);
                     }

                     break;
                 }

                 case MediaCodec::CB_ERROR:
                 {
                     status_t err;
                     int32_t actionCode;
                     AString detail;
                     if (!msg->findInt32("err", &err)) {
                         ALOGE("CB_ERROR: err is expected.");
                         break;
                     }
                     if (!msg->findInt32("action", &actionCode)) {
                         ALOGE("CB_ERROR: action is expected.");
                         break;
                     }
                     msg->findString("detail", &detail);
                     ALOGE("Decoder reported error(0x%x), actionCode(%d), detail(%s)",
                           err, actionCode, detail.c_str());

                     Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
                     if (mCodec->mAsyncCallbackUserData != NULL
                         || mCodec->mAsyncCallback.onAsyncError != NULL) {
                         mCodec->mAsyncCallback.onAsyncError(
                                 mCodec,
                                 mCodec->mAsyncCallbackUserData,
                                 translate_error(err),
                                 actionCode,
                                 detail.c_str());
                     }

                     break;
                 }

                 default:
                 {
                     ALOGE("kWhatAsyncNotify: callbackID(%d) is unexpected.", cbID);
                     break;
                 }
             }
             break;
        }

        case kWhatStopActivityNotifications:
        {
            sp<AReplyToken> replyID;
@@ -162,7 +309,7 @@ static AMediaCodec * createAMediaCodec(const char *name, bool name_is_type, bool
    size_t res = mData->mLooper->start(
            false,      // runOnCallingThread
            true,       // canCallJava XXX
            PRIORITY_FOREGROUND);
            PRIORITY_AUDIO);
    if (res != OK) {
        ALOGE("Failed to start the looper");
        AMediaCodec_delete(mData);
@@ -183,6 +330,9 @@ static AMediaCodec * createAMediaCodec(const char *name, bool name_is_type, bool
    mData->mRequestedActivityNotification = false;
    mData->mCallback = NULL;

    mData->mAsyncCallback = {};
    mData->mAsyncCallbackUserData = NULL;

    return mData;
}

@@ -221,6 +371,32 @@ media_status_t AMediaCodec_delete(AMediaCodec *mData) {
    return AMEDIA_OK;
}

EXPORT
media_status_t AMediaCodec_getName(
        AMediaCodec *mData,
        char** out_name) {
    if (out_name == NULL) {
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    AString compName;
    status_t err = mData->mCodec->getName(&compName);
    if (err != OK) {
        return translate_error(err);
    }
    *out_name = strdup(compName.c_str());
    return AMEDIA_OK;
}

EXPORT
void AMediaCodec_releaseName(
        AMediaCodec * /* mData */,
        char* name) {
    if (name != NULL) {
        free(name);
    }
}

EXPORT
media_status_t AMediaCodec_configure(
        AMediaCodec *mData,
@@ -236,8 +412,40 @@ media_status_t AMediaCodec_configure(
        surface = (Surface*) window;
    }

    return translate_error(mData->mCodec->configure(nativeFormat, surface,
            crypto ? crypto->mCrypto : NULL, flags));
    status_t err = mData->mCodec->configure(nativeFormat, surface,
            crypto ? crypto->mCrypto : NULL, flags);
    if (err != OK) {
        ALOGE("configure: err(%d), failed with format: %s",
              err, nativeFormat->debugString(0).c_str());
    }
    return translate_error(err);
}

EXPORT
media_status_t AMediaCodec_setAsyncNotifyCallback(
        AMediaCodec *mData,
        AMediaCodecOnAsyncNotifyCallback callback,
        void *userdata) {
    if (mData->mAsyncNotify == NULL && userdata != NULL) {
        mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
        status_t err = mData->mCodec->setCallback(mData->mAsyncNotify);
        if (err != OK) {
            ALOGE("setAsyncNotifyCallback: err(%d), failed to set async callback", err);
            return translate_error(err);
        }
    }

    Mutex::Autolock _l(mData->mAsyncCallbackLock);
    mData->mAsyncCallback = callback;
    mData->mAsyncCallbackUserData = userdata;

    return AMEDIA_OK;
}


EXPORT
media_status_t AMediaCodec_releaseCrypto(AMediaCodec *mData) {
    return translate_error(mData->mCodec->releaseCrypto());
}

EXPORT
@@ -282,6 +490,19 @@ ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec *mData, int64_t timeoutUs) {

EXPORT
uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
    if (mData->mAsyncNotify != NULL) {
        // Asynchronous mode
        sp<MediaCodecBuffer> abuf;
        if (mData->mCodec->getInputBuffer(idx, &abuf) != 0) {
            return NULL;
        }

        if (out_size != NULL) {
            *out_size = abuf->capacity();
        }
        return abuf->data();
    }

    android::Vector<android::sp<android::MediaCodecBuffer> > abufs;
    if (mData->mCodec->getInputBuffers(&abufs) == 0) {
        size_t n = abufs.size();
@@ -304,6 +525,19 @@ uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *mData, size_t idx, size_t *out_

EXPORT
uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *mData, size_t idx, size_t *out_size) {
    if (mData->mAsyncNotify != NULL) {
        // Asynchronous mode
        sp<MediaCodecBuffer> abuf;
        if (mData->mCodec->getOutputBuffer(idx, &abuf) != 0) {
            return NULL;
        }

        if (out_size != NULL) {
            *out_size = abuf->capacity();
        }
        return abuf->data();
    }

    android::Vector<android::sp<android::MediaCodecBuffer> > abufs;
    if (mData->mCodec->getOutputBuffers(&abufs) == 0) {
        size_t n = abufs.size();
@@ -366,6 +600,13 @@ AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec *mData) {
    return AMediaFormat_fromMsg(&format);
}

EXPORT
AMediaFormat* AMediaCodec_getInputFormat(AMediaCodec *mData) {
    sp<AMessage> format;
    mData->mCodec->getInputFormat(&format);
    return AMediaFormat_fromMsg(&format);
}

EXPORT
AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec *mData, size_t index) {
    sp<AMessage> format;
@@ -542,6 +783,16 @@ media_status_t AMediaCodec_queueSecureInputBuffer(
    return translate_error(err);
}

EXPORT
bool AMediaCodecActionCode_isRecoverable(int32_t actionCode) {
    return (actionCode == ACTION_CODE_RECOVERABLE);
}

EXPORT
bool AMediaCodecActionCode_isTransient(int32_t actionCode) {
    return (actionCode == ACTION_CODE_TRANSIENT);
}


EXPORT
void AMediaCodecCryptoInfo_setPattern(AMediaCodecCryptoInfo *info,
+67 −1
Original line number Diff line number Diff line
@@ -125,6 +125,14 @@ const char* AMediaFormat_toString(AMediaFormat *mData) {
                ret.appendFormat("double(%f)", val);
                break;
            }
            case AMessage::kTypeRect:
            {
                int32_t left, top, right, bottom;
                f->findRect(name, &left, &top, &right, &bottom);
                ret.appendFormat("Rect(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")",
                                 left, top, right, bottom);
                break;
            }
            case AMessage::kTypeString:
            {
                AString val;
@@ -164,11 +172,22 @@ bool AMediaFormat_getFloat(AMediaFormat* format, const char *name, float *out) {
    return format->mFormat->findFloat(name, out);
}

EXPORT
bool AMediaFormat_getDouble(AMediaFormat* format, const char *name, double *out) {
    return format->mFormat->findDouble(name, out);
}

EXPORT
bool AMediaFormat_getSize(AMediaFormat* format, const char *name, size_t *out) {
    return format->mFormat->findSize(name, out);
}

EXPORT
bool AMediaFormat_getRect(AMediaFormat* format, const char *name,
                          int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) {
    return format->mFormat->findRect(name, left, top, right, bottom);
}

EXPORT
bool AMediaFormat_getBuffer(AMediaFormat* format, const char *name, void** data, size_t *outsize) {
    sp<ABuffer> buf;
@@ -215,6 +234,22 @@ void AMediaFormat_setFloat(AMediaFormat* format, const char* name, float value)
    format->mFormat->setFloat(name, value);
}

EXPORT
void AMediaFormat_setDouble(AMediaFormat* format, const char* name, double value) {
    format->mFormat->setDouble(name, value);
}

EXPORT
void AMediaFormat_setSize(AMediaFormat* format, const char* name, size_t value) {
    format->mFormat->setSize(name, value);
}

EXPORT
void AMediaFormat_setRect(AMediaFormat* format, const char *name,
                          int32_t left, int32_t top, int32_t right, int32_t bottom) {
    format->mFormat->setRect(name, left, top, right, bottom);
}

EXPORT
void AMediaFormat_setString(AMediaFormat* format, const char* name, const char* value) {
    // AMessage::setString() makes a copy of the string
@@ -233,30 +268,61 @@ void AMediaFormat_setBuffer(AMediaFormat* format, const char* name, void* data,
}


EXPORT const char* AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_PROFILE = "aac-profile";
EXPORT const char* AMEDIAFORMAT_KEY_AAC_SBR_MODE = "aac-sbr-mode";
EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_SESSION_ID = "audio-session-id";
EXPORT const char* AMEDIAFORMAT_KEY_BITRATE_MODE = "bitrate-mode";
EXPORT const char* AMEDIAFORMAT_KEY_BIT_RATE = "bitrate";
EXPORT const char* AMEDIAFORMAT_KEY_CAPTURE_RATE = "capture-rate";
EXPORT const char* AMEDIAFORMAT_KEY_CHANNEL_COUNT = "channel-count";
EXPORT const char* AMEDIAFORMAT_KEY_CHANNEL_MASK = "channel-mask";
EXPORT const char* AMEDIAFORMAT_KEY_COLOR_FORMAT = "color-format";
EXPORT const char* AMEDIAFORMAT_KEY_COLOR_RANGE = "color-range";
EXPORT const char* AMEDIAFORMAT_KEY_COLOR_STANDARD = "color-standard";
EXPORT const char* AMEDIAFORMAT_KEY_COLOR_TRANSFER = "color-transfer";
EXPORT const char* AMEDIAFORMAT_KEY_COMPLEXITY = "complexity";
EXPORT const char* AMEDIAFORMAT_KEY_DISPLAY_CROP = "crop";
EXPORT const char* AMEDIAFORMAT_KEY_DURATION = "durationUs";
EXPORT const char* AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
EXPORT const char* AMEDIAFORMAT_KEY_FRAME_RATE = "frame-rate";
EXPORT const char* AMEDIAFORMAT_KEY_GRID_COLS = "grid-cols";
EXPORT const char* AMEDIAFORMAT_KEY_GRID_HEIGHT = "grid-height";
EXPORT const char* AMEDIAFORMAT_KEY_GRID_ROWS = "grid-rows";
EXPORT const char* AMEDIAFORMAT_KEY_GRID_WIDTH = "grid-width";
EXPORT const char* AMEDIAFORMAT_KEY_HDR_STATIC_INFO = "hdr-static-info";
EXPORT const char* AMEDIAFORMAT_KEY_HEIGHT = "height";
EXPORT const char* AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
EXPORT const char* AMEDIAFORMAT_KEY_IS_ADTS = "is-adts";
EXPORT const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT = "is-autoselect";
EXPORT const char* AMEDIAFORMAT_KEY_IS_DEFAULT = "is-default";
EXPORT const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE = "is-forced-subtitle";
EXPORT const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL = "i-frame-interval";
EXPORT const char* AMEDIAFORMAT_KEY_LANGUAGE = "language";
EXPORT const char* AMEDIAFORMAT_KEY_LATENCY = "latency";
EXPORT const char* AMEDIAFORMAT_KEY_LEVEL = "level";
EXPORT const char* AMEDIAFORMAT_KEY_MAX_HEIGHT = "max-height";
EXPORT const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE = "max-input-size";
EXPORT const char* AMEDIAFORMAT_KEY_MAX_WIDTH = "max-width";
EXPORT const char* AMEDIAFORMAT_KEY_MIME = "mime";
EXPORT const char* AMEDIAFORMAT_KEY_OPERATING_RATE = "operating-rate";
EXPORT const char* AMEDIAFORMAT_KEY_PCM_ENCODING = "pcm-encoding";
EXPORT const char* AMEDIAFORMAT_KEY_PRIORITY = "priority";
EXPORT const char* AMEDIAFORMAT_KEY_PROFILE = "profile";
EXPORT const char* AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
EXPORT const char* AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER = "repeat-previous-frame-after";
EXPORT const char* AMEDIAFORMAT_KEY_ROTATION = "rotation-degrees";
EXPORT const char* AMEDIAFORMAT_KEY_SAMPLE_RATE = "sample-rate";
EXPORT const char* AMEDIAFORMAT_KEY_WIDTH = "width";
EXPORT const char* AMEDIAFORMAT_KEY_SLICE_HEIGHT = "slice-height";
EXPORT const char* AMEDIAFORMAT_KEY_STRIDE = "stride";
EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYERING = "ts-schema";
EXPORT const char* AMEDIAFORMAT_KEY_TRACK_ID = "track-id";
EXPORT const char* AMEDIAFORMAT_KEY_WIDTH = "width";


} // extern "C"
+118 −1
Original line number Diff line number Diff line
@@ -53,11 +53,63 @@ typedef struct AMediaCodecBufferInfo AMediaCodecBufferInfo;
typedef struct AMediaCodecCryptoInfo AMediaCodecCryptoInfo;

enum {
    AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG = 2,
    AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM = 4,
    AMEDIACODEC_BUFFER_FLAG_PARTIAL_FRAME = 8,

    AMEDIACODEC_CONFIGURE_FLAG_ENCODE = 1,
    AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED = -3,
    AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED = -2,
    AMEDIACODEC_INFO_TRY_AGAIN_LATER = -1
    AMEDIACODEC_INFO_TRY_AGAIN_LATER = -1,
};

/**
 * Called when an input buffer becomes available.
 * The specified index is the index of the available input buffer.
 */
typedef void (*AMediaCodecOnAsyncInputAvailable)(
        AMediaCodec *codec,
        void *userdata,
        int32_t index);
/**
 * Called when an output buffer becomes available.
 * The specified index is the index of the available output buffer.
 * The specified bufferInfo contains information regarding the available output buffer.
 */
typedef void (*AMediaCodecOnAsyncOutputAvailable)(
        AMediaCodec *codec,
        void *userdata,
        int32_t index,
        AMediaCodecBufferInfo *bufferInfo);
/**
 * Called when the output format has changed.
 * The specified format contains the new output format.
 */
typedef void (*AMediaCodecOnAsyncFormatChanged)(
        AMediaCodec *codec,
        void *userdata,
        AMediaFormat *format);
/**
 * Called when the MediaCodec encountered an error.
 * The specified actionCode indicates the possible actions that client can take,
 * and it can be checked by calling AMediaCodecActionCode_isRecoverable or
 * AMediaCodecActionCode_isTransient. If both AMediaCodecActionCode_isRecoverable()
 * and AMediaCodecActionCode_isTransient() return false, then the codec error is fatal
 * and the codec must be deleted.
 * The specified detail may contain more detailed messages about this error.
 */
typedef void (*AMediaCodecOnAsyncError)(
        AMediaCodec *codec,
        void *userdata,
        media_status_t error,
        int32_t actionCode,
        const char *detail);

struct AMediaCodecOnAsyncNotifyCallback {
      AMediaCodecOnAsyncInputAvailable  onAsyncInputAvailable;
      AMediaCodecOnAsyncOutputAvailable onAsyncOutputAvailable;
      AMediaCodecOnAsyncFormatChanged   onAsyncFormatChanged;
      AMediaCodecOnAsyncError           onAsyncError;
};

#if __ANDROID_API__ >= 21
@@ -289,6 +341,71 @@ media_status_t AMediaCodec_signalEndOfInputStream(AMediaCodec *mData);

#endif /* __ANDROID_API__ >= 26 */

#if __ANDROID_API__ >= 28

/**
 * Get the component name. If the codec was created by createDecoderByType
 * or createEncoderByType, what component is chosen is not known beforehand.
 * Caller shall call AMediaCodec_releaseName to free the returned pointer.
 */
media_status_t AMediaCodec_getName(AMediaCodec*, char** out_name);

/**
 * Free the memory pointed by name which is returned by AMediaCodec_getName.
 */
void AMediaCodec_releaseName(AMediaCodec*, char* name);

/**
 * Set an asynchronous callback for actionable AMediaCodec events.
 * When asynchronous callback is enabled, the client should not call
 * AMediaCodec_getInputBuffers(), AMediaCodec_getOutputBuffers(),
 * AMediaCodec_dequeueInputBuffer() or AMediaCodec_dequeueOutputBuffer().
 *
 * Also, AMediaCodec_flush() behaves differently in asynchronous mode.
 * After calling AMediaCodec_flush(), you must call AMediaCodec_start() to
 * "resume" receiving input buffers, even if an input surface was created.
 *
 * Refer to the definition of AMediaCodecOnAsyncNotifyCallback on how each
 * callback function is called and what are specified.
 * The specified userdata is the pointer used when those callback functions are
 * called.
 *
 * All callbacks are fired on one NDK internal thread.
 * AMediaCodec_setAsyncNotifyCallback should not be called on the callback thread.
 * No heavy duty task should be performed on callback thread.
 */
media_status_t AMediaCodec_setAsyncNotifyCallback(
        AMediaCodec*,
        AMediaCodecOnAsyncNotifyCallback callback,
        void *userdata);

/**
 * Release the crypto if applicable.
 */
media_status_t AMediaCodec_releaseCrypto(AMediaCodec*);

/**
 * Call this after AMediaCodec_configure() returns successfully to get the input
 * format accepted by the codec. Do this to determine what optional configuration
 * parameters were supported by the codec.
 */
AMediaFormat* AMediaCodec_getInputFormat(AMediaCodec*);

/**
 * Returns true if the codec cannot proceed further, but can be recovered by stopping,
 * configuring, and starting again.
 */
bool AMediaCodecActionCode_isRecoverable(int32_t actionCode);

/**
 * Returns true if the codec error is a transient issue, perhaps due to
 * resource constraints, and that the method (or encoding/decoding) may be
 * retried at a later time.
 */
bool AMediaCodecActionCode_isTransient(int32_t actionCode);

#endif /* __ANDROID_API__ >= 28 */

typedef enum {
    AMEDIACODECRYPTOINFO_MODE_CLEAR = 0,
    AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1,
+11 −0
Original line number Diff line number Diff line
@@ -35,6 +35,17 @@ __BEGIN_DECLS
typedef enum {
    AMEDIA_OK = 0,

    /**
     * This indicates required resource was not able to be allocated.
     */
    AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE = 1100,

    /**
     * This indicates the resource manager reclaimed the media resource used by the codec.
     * With this error, the codec must be released, as it has moved to terminal state.
     */
    AMEDIACODEC_ERROR_RECLAIMED             = 1101,

    AMEDIA_ERROR_BASE                  = -10000,
    AMEDIA_ERROR_UNKNOWN               = AMEDIA_ERROR_BASE,
    AMEDIA_ERROR_MALFORMED             = AMEDIA_ERROR_BASE - 1,
+44 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading