From 0c3be875376adaee8d8e8dd917c64926e1513b29 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 1 May 2014 10:14:44 -0700 Subject: WIP: MediaCodec and friends NDK APIs, plain C version Change-Id: I9ed6b9c5afb026a1b5fe8b652e75635bbcc223df --- include/ndk/NdkMediaCodec.h | 143 ++++++++++++++++++++++++++++++++++++++++ include/ndk/NdkMediaExtractor.h | 125 +++++++++++++++++++++++++++++++++++ include/ndk/NdkMediaFormat.h | 89 +++++++++++++++++++++++++ 3 files changed, 357 insertions(+) create mode 100644 include/ndk/NdkMediaCodec.h create mode 100644 include/ndk/NdkMediaExtractor.h create mode 100644 include/ndk/NdkMediaFormat.h (limited to 'include') diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h new file mode 100644 index 0000000..5067073 --- /dev/null +++ b/include/ndk/NdkMediaCodec.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_CODEC_H +#define _NDK_MEDIA_CODEC_H + +#include + +#include "NdkMediaFormat.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +struct AMediaCodec; +typedef struct AMediaCodec AMediaCodec; + +struct AMediaCodecBufferInfo { + int32_t offset; + int32_t size; + int64_t presentationTimeUs; + uint32_t flags; +}; +typedef struct AMediaCodecBufferInfo AMediaCodecBufferInfo; + +enum { + AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM = 4, + AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED = -3, + AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED = -2, + AMEDIACODEC_INFO_TRY_AGAIN_LATER = -1 +}; + + +/** + * Create decoder by name. Use this if you know the exact codec you want to use. + */ +AMediaCodec* AMediaCodec_createByCodecName(const char *name); + +/** + * Create codec by mime type. Most applications will use this, specifying a + * mime type obtained from media extractor. + */ +AMediaCodec* AMediaCodec_createByCodecType(const char *mime_type); + +/** + * Create encoder by name. + */ +AMediaCodec* AMediaCodec_createEncoderByName(const char *name); + +/** + * delete the codec and free its resources + */ +int AMediaCodec_delete(AMediaCodec*); + +/** + * Configure the codec. For decoding you would typically get the format from an extractor. + */ +int AMediaCodec_configure(AMediaCodec*, AMediaFormat *format, ANativeWindow* surface); // TODO: other args + +/** + * Start the codec. A codec must be configured before it can be started, and must be started + * before buffers can be sent to it. + */ +int AMediaCodec_start(AMediaCodec*); + +/** + * Stop the codec. + */ +int AMediaCodec_stop(AMediaCodec*); + +/* + * Flush the codec's input and output. All indices previously returned from calls to + * AMediaCodec_dequeueInputBuffer and AMediaCodec_dequeueOutputBuffer become invalid. + */ +int AMediaCodec_flush(AMediaCodec*); + +/** + * Get an input buffer. The specified buffer index must have been previously obtained from + * dequeueInputBuffer, and not yet queued. + */ +uint8_t* AMediaCodec_getInputBuffer(AMediaCodec*, size_t idx, size_t *out_size); + +/** + * Get an output buffer. The specified buffer index must have been previously obtained from + * dequeueOutputBuffer, and not yet queued. + */ +uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec*, size_t idx, size_t *out_size); + +/** + * Get the index of the next available input buffer. An app will typically use this with + * getInputBuffer() to get a pointer to the buffer, then copy the data to be encoded or decoded + * into the buffer before passing it to the codec. + */ +ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec*, int64_t timeoutUs); + +/** + * Send the specified buffer to the codec for processing. + */ +int AMediaCodec_queueInputBuffer(AMediaCodec*, + size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags); + +/** + * Get the index of the next available buffer of processed data. + */ +ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info, int64_t timeoutUs); +AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*); + +/** + * Release and optionally render the specified buffer. + */ +int AMediaCodec_releaseOutputBuffer(AMediaCodec*, size_t idx, bool render); + + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //_NDK_MEDIA_CODEC_H diff --git a/include/ndk/NdkMediaExtractor.h b/include/ndk/NdkMediaExtractor.h new file mode 100644 index 0000000..a7c32c4 --- /dev/null +++ b/include/ndk/NdkMediaExtractor.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_EXTRACTOR_H +#define _NDK_MEDIA_EXTRACTOR_H + +#include + +#include "NdkMediaFormat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct AMediaExtractor; +typedef struct AMediaExtractor AMediaExtractor; + + +/** + * Create new media extractor + */ +AMediaExtractor* AMediaExtractor_new(); + +/** + * Delete a previously created media extractor + */ +int AMediaExtractor_delete(AMediaExtractor*); + +/** + * Set the file descriptor from which the extractor will read. + */ +int AMediaExtractor_setDataSourceFd(AMediaExtractor*, int fd, off64_t offset, off64_t length); + +/** + * Set the URI from which the extractor will read. + */ +int AMediaExtractor_setDataSource(AMediaExtractor*, const char *location); // TODO support headers + +/** + * Return the number of tracks in the previously specified media file + */ +int AMediaExtractor_getTrackCount(AMediaExtractor*); + +/** + * Return the format of the specified track. The caller must free the returned format + */ +AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor*, size_t idx); + +/** + * Select the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and + * getSampleTime only retrieve information for the subset of tracks selected. + * Selecting the same track multiple times has no effect, the track is + * only selected once. + */ +int AMediaExtractor_selectTrack(AMediaExtractor*, size_t idx); + +/** + * Unselect the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and + * getSampleTime only retrieve information for the subset of tracks selected.. + */ +int AMediaExtractor_unselectTrack(AMediaExtractor*, size_t idx); + +/** + * Read the current sample. + */ +int AMediaExtractor_readSampleData(AMediaExtractor*, uint8_t *buffer, size_t capacity); + +/** + * Read the current sample's flags. + */ +int AMediaExtractor_getSampleFlags(AMediaExtractor*); // see definitions below + +/** + * Returns the track index the current sample originates from (or -1 + * if no more samples are available) + */ +int AMediaExtractor_getSampleTrackIndex(AMediaExtractor*); + +/** + * Returns the current sample's presentation time in microseconds. + * or -1 if no more samples are available. + */ +int64_t AMediaExtractor_getSampletime(AMediaExtractor*); + +/** + * Advance to the next sample. Returns false if no more sample data + * is available (end of stream). + */ +bool AMediaExtractor_advance(AMediaExtractor*); + +enum { + AMEDIAEXTRACTOR_SAMPLE_FLAG_SYNC = 1, + AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED = 2, +}; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_EXTRACTOR_H diff --git a/include/ndk/NdkMediaFormat.h b/include/ndk/NdkMediaFormat.h new file mode 100644 index 0000000..16f4348 --- /dev/null +++ b/include/ndk/NdkMediaFormat.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_FORMAT_H +#define _NDK_MEDIA_FORMAT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct AMediaFormat; +typedef struct AMediaFormat AMediaFormat; + +AMediaFormat *AMediaFormat_new(); +int AMediaFormat_delete(AMediaFormat*); + +/** + * Debug string. Caller must free. + */ +const char* AMediaFormat_toString(AMediaFormat*); + +bool AMediaFormat_getInt32(AMediaFormat*, const char *name, int32_t *out); +bool AMediaFormat_getInt64(AMediaFormat*, const char *name, int64_t *out); +bool AMediaFormat_getFloat(AMediaFormat*, const char *name, float *out); +bool AMediaFormat_getDouble(AMediaFormat*, const char *name, double *out); +bool AMediaFormat_getSize(AMediaFormat*, const char *name, size_t *out); +/** + * Caller must free the returned string + */ +bool AMediaFormat_getString(AMediaFormat*, const char *name, const char **out); + +/** + * XXX should these be ints/enums that we look up in a table as needed? + */ +extern const char* AMEDIAFORMAT_KEY_AAC_PROFILE; +extern const char* AMEDIAFORMAT_KEY_BIT_RATE; +extern const char* AMEDIAFORMAT_KEY_CHANNEL_COUNT; +extern const char* AMEDIAFORMAT_KEY_CHANNEL_MASK; +extern const char* AMEDIAFORMAT_KEY_COLOR_FORMAT; +extern const char* AMEDIAFORMAT_KEY_DURATION; +extern const char* AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL; +extern const char* AMEDIAFORMAT_KEY_FRAME_RATE; +extern const char* AMEDIAFORMAT_KEY_HEIGHT; +extern const char* AMEDIAFORMAT_KEY_IS_ADTS; +extern const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT; +extern const char* AMEDIAFORMAT_KEY_IS_DEFAULT; +extern const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE; +extern const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL; +extern const char* AMEDIAFORMAT_KEY_LANGUAGE; +extern const char* AMEDIAFORMAT_KEY_MAX_HEIGHT; +extern const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE; +extern const char* AMEDIAFORMAT_KEY_MAX_WIDTH; +extern const char* AMEDIAFORMAT_KEY_MIME; +extern const char* AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP; +extern const char* AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER; +extern const char* AMEDIAFORMAT_KEY_SAMPLE_RATE; +extern const char* AMEDIAFORMAT_KEY_WIDTH; +extern const char* AMEDIAFORMAT_KEY_STRIDE; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_FORMAT_H -- cgit v1.1