blob: 72ac56abd32efe41336278f66f73059b75627e2d [file] [log] [blame]
/*
* Copyright 2012, 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.
*/
#ifndef MEDIA_CODEC_H_
#define MEDIA_CODEC_H_
#include <gui/ISurfaceTexture.h>
#include <media/stagefright/foundation/AHandler.h>
#include <utils/Vector.h>
namespace android {
struct ABuffer;
struct ACodec;
struct AMessage;
struct SoftwareRenderer;
struct SurfaceTextureClient;
struct MediaCodec : public AHandler {
enum ConfigureFlags {
CONFIGURE_FLAG_ENCODE = 1,
};
enum BufferFlags {
BUFFER_FLAG_SYNCFRAME = 1,
BUFFER_FLAG_CODECCONFIG = 2,
BUFFER_FLAG_EOS = 4,
};
static sp<MediaCodec> CreateByType(
const sp<ALooper> &looper, const char *mime, bool encoder);
static sp<MediaCodec> CreateByComponentName(
const sp<ALooper> &looper, const char *name);
status_t configure(
const sp<AMessage> &format,
const sp<SurfaceTextureClient> &nativeWindow,
uint32_t flags);
status_t start();
// Returns to a state in which the component remains allocated but
// unconfigured.
status_t stop();
// Client MUST call release before releasing final reference to this
// object.
status_t release();
status_t flush();
status_t queueInputBuffer(
size_t index,
size_t offset,
size_t size,
int64_t presentationTimeUs,
uint32_t flags);
status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
status_t dequeueOutputBuffer(
size_t *index,
size_t *offset,
size_t *size,
int64_t *presentationTimeUs,
uint32_t *flags,
int64_t timeoutUs = 0ll);
status_t renderOutputBufferAndRelease(size_t index);
status_t releaseOutputBuffer(size_t index);
status_t getOutputFormat(sp<AMessage> *format) const;
status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;
status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const;
protected:
virtual ~MediaCodec();
virtual void onMessageReceived(const sp<AMessage> &msg);
private:
enum State {
UNINITIALIZED,
INITIALIZING,
INITIALIZED,
CONFIGURING,
CONFIGURED,
STARTING,
STARTED,
FLUSHING,
STOPPING,
RELEASING,
};
enum {
kPortIndexInput = 0,
kPortIndexOutput = 1,
};
enum {
kWhatInit = 'init',
kWhatConfigure = 'conf',
kWhatStart = 'strt',
kWhatStop = 'stop',
kWhatRelease = 'rele',
kWhatDequeueInputBuffer = 'deqI',
kWhatQueueInputBuffer = 'queI',
kWhatDequeueOutputBuffer = 'deqO',
kWhatReleaseOutputBuffer = 'relO',
kWhatGetBuffers = 'getB',
kWhatFlush = 'flus',
kWhatGetOutputFormat = 'getO',
kWhatDequeueInputTimedOut = 'dITO',
kWhatDequeueOutputTimedOut = 'dOTO',
kWhatCodecNotify = 'codc',
};
enum {
kFlagIsSoftwareCodec = 1,
kFlagOutputFormatChanged = 2,
kFlagOutputBuffersChanged = 4,
kFlagStickyError = 8,
kFlagDequeueInputPending = 16,
kFlagDequeueOutputPending = 32,
};
struct BufferInfo {
void *mBufferID;
sp<ABuffer> mData;
sp<AMessage> mNotify;
bool mOwnedByClient;
};
State mState;
sp<ALooper> mLooper;
sp<ALooper> mCodecLooper;
sp<ACodec> mCodec;
uint32_t mReplyID;
uint32_t mFlags;
sp<SurfaceTextureClient> mNativeWindow;
SoftwareRenderer *mSoftRenderer;
sp<AMessage> mOutputFormat;
List<size_t> mAvailPortBuffers[2];
Vector<BufferInfo> mPortBuffers[2];
int32_t mDequeueInputTimeoutGeneration;
uint32_t mDequeueInputReplyID;
int32_t mDequeueOutputTimeoutGeneration;
uint32_t mDequeueOutputReplyID;
MediaCodec(const sp<ALooper> &looper);
static status_t PostAndAwaitResponse(
const sp<AMessage> &msg, sp<AMessage> *response);
status_t init(const char *name, bool nameIsType, bool encoder);
void setState(State newState);
void returnBuffersToCodec();
void returnBuffersToCodecOnPort(int32_t portIndex);
size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
status_t onQueueInputBuffer(const sp<AMessage> &msg);
status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
ssize_t dequeuePortBuffer(int32_t portIndex);
bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false);
bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false);
void cancelPendingDequeueOperations();
DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};
} // namespace android
#endif // MEDIA_CODEC_H_