From be06d26cdc70070654f1eedcd08c1c68cd587ad6 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 14 Aug 2009 14:37:10 -0700 Subject: Squashed commit of the following: commit 5bb012f0065f7ffaaeb4f569d71f0e3a8d6b19c3 Author: Andreas Huber Date: Fri Aug 14 10:40:08 2009 -0700 An attempt at fixing export using the qcom encoders. More quirks. commit 0690e76bfa48118a68287ccf1bbfa82febaa620c Author: Andreas Huber Date: Fri Aug 14 09:08:28 2009 -0700 Callbacks are now dispatched from a separate thread in OMX. commit c6571a039526df29b6343f9a1971dbc019088c61 Author: Andreas Huber Date: Thu Aug 13 15:42:25 2009 -0700 Massive API changes throughout stagefright, smart pointers everywhere. commit 900612af6a0555664d9ba195112cd859491265f4 Author: Andreas Huber Date: Thu Aug 13 13:33:12 2009 -0700 OMXCodecs now properly shutdown. commit 96732f05e1b0603dcd1b11f16a23512592eeb4f5 Author: Andreas Huber Date: Thu Aug 13 12:04:04 2009 -0700 More work on JPEG decoding using the hardware OMX component. commit 63839a073ac393e3a130434ba467969053b694ad Author: Andreas Huber Date: Wed Aug 12 13:13:31 2009 -0700 An attempt to drive the JPEG decoder OMX node. commit 3ac2fe5ab2926eda81b2123610b2434c645294ff Author: Andreas Huber Date: Tue Aug 11 16:38:21 2009 -0700 Renamed StateMachine to OMXCodec and put it in its proper place. commit 247da75a96bf8881956413023dd49a84d5b4f5b2 Author: Andreas Huber Date: Tue Aug 11 16:06:19 2009 -0700 Statemachine is now a full-fledged MediaSource. commit 045244f6771fa0b9b329495c953afda900a84b71 Author: Andreas Huber Date: Fri Aug 7 09:16:54 2009 -0700 Properly setup the input format when exporting to AMR audio. commit 271b984cb32c5cd9e46e3f90ae121f334e4b8da9 Author: Andreas Huber Date: Thu Aug 6 09:59:38 2009 -0700 Added some code to test audio encoding to the OMX harness. commit 79af4748e4af33bd66d3fbac606e332a69741cf4 Author: Andreas Huber Date: Wed Aug 5 14:36:22 2009 -0700 Merge the old OMXDecoder and the new, shiny, StateMachine code. commit 91cf5dd77a8762bc10a0b2ffce35e3bbeb262231 Author: Andreas Huber Date: Tue Aug 4 17:41:43 2009 -0700 A new harness to test OMX node compliance (and quirks). --- include/media/IOMX.h | 19 ++- include/media/stagefright/AudioPlayer.h | 6 +- include/media/stagefright/CachingDataSource.h | 10 +- include/media/stagefright/DataSource.h | 12 +- include/media/stagefright/MP3Extractor.h | 16 ++- include/media/stagefright/MPEG4Extractor.h | 19 +-- include/media/stagefright/MPEG4Writer.h | 8 +- include/media/stagefright/MediaBuffer.h | 4 +- include/media/stagefright/MediaDebug.h | 18 +++ include/media/stagefright/MediaExtractor.h | 14 +- include/media/stagefright/MediaPlayerImpl.h | 18 +-- include/media/stagefright/MediaSource.h | 6 +- include/media/stagefright/OMXCodec.h | 190 ++++++++++++++++++++++++++ include/media/stagefright/OMXDecoder.h | 18 +-- include/media/stagefright/SampleTable.h | 12 +- 15 files changed, 302 insertions(+), 68 deletions(-) create mode 100644 include/media/stagefright/MediaDebug.h create mode 100644 include/media/stagefright/OMXCodec.h (limited to 'include/media') diff --git a/include/media/IOMX.h b/include/media/IOMX.h index 7e5ff61..58a74c7 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -56,6 +56,14 @@ public: node_id node, OMX_INDEXTYPE index, const void *params, size_t size) = 0; + virtual status_t get_config( + node_id node, OMX_INDEXTYPE index, + void *params, size_t size) = 0; + + virtual status_t set_config( + node_id node, OMX_INDEXTYPE index, + const void *params, size_t size) = 0; + virtual status_t use_buffer( node_id node, OMX_U32 port_index, const sp ¶ms, buffer_id *buffer) = 0; @@ -82,6 +90,11 @@ public: OMX_U32 range_offset, OMX_U32 range_length, OMX_U32 flags, OMX_TICKS timestamp) = 0; + virtual status_t get_extension_index( + node_id node, + const char *parameter_name, + OMX_INDEXTYPE *index) = 0; + virtual sp createRenderer( const sp &surface, const char *componentName, @@ -114,10 +127,11 @@ struct omx_message { QUIT_OBSERVER, } type; + IOMX::node_id node; + union { // if type == EVENT struct { - IOMX::node_id node; OMX_EVENTTYPE event; OMX_U32 data1; OMX_U32 data2; @@ -126,13 +140,11 @@ struct omx_message { // if type == EMPTY_BUFFER_DONE || type == FILL_BUFFER // || type == INITIAL_FILL_BUFFER struct { - IOMX::node_id node; IOMX::buffer_id buffer; } buffer_data; // if type == EMPTY_BUFFER || type == FILL_BUFFER_DONE struct { - IOMX::node_id node; IOMX::buffer_id buffer; OMX_U32 range_offset; OMX_U32 range_length; @@ -143,7 +155,6 @@ struct omx_message { // if type == SEND_COMMAND struct { - IOMX::node_id node; OMX_COMMANDTYPE cmd; OMX_S32 param; } send_command_data; diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index 0f2e528..960eda3 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -31,10 +31,10 @@ class AudioTrack; class AudioPlayer : public TimeSource { public: AudioPlayer(const sp &audioSink); - ~AudioPlayer(); + virtual ~AudioPlayer(); // Caller retains ownership of "source". - void setSource(MediaSource *source); + void setSource(const sp &source); // Return time in us. virtual int64_t getRealTimeUs(); @@ -56,7 +56,7 @@ public: status_t seekTo(int64_t time_us); private: - MediaSource *mSource; + sp mSource; AudioTrack *mAudioTrack; MediaBuffer *mInputBuffer; diff --git a/include/media/stagefright/CachingDataSource.h b/include/media/stagefright/CachingDataSource.h index e275cb4..e35e19e 100644 --- a/include/media/stagefright/CachingDataSource.h +++ b/include/media/stagefright/CachingDataSource.h @@ -26,14 +26,16 @@ namespace android { class CachingDataSource : public DataSource { public: - // Assumes ownership of "source". - CachingDataSource(DataSource *source, size_t pageSize, int numPages); - virtual ~CachingDataSource(); + CachingDataSource( + const sp &source, size_t pageSize, int numPages); status_t InitCheck() const; virtual ssize_t read_at(off_t offset, void *data, size_t size); +protected: + virtual ~CachingDataSource(); + private: struct Page { Page *mPrev, *mNext; @@ -42,7 +44,7 @@ private: void *mData; }; - DataSource *mSource; + sp mSource; void *mData; size_t mPageSize; Page *mFirst, *mLast; diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 31eea27..f46f0af 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -22,19 +22,22 @@ #include #include +#include #include namespace android { class String8; -class DataSource { +class DataSource : public RefBase { public: DataSource() {} - virtual ~DataSource() {} virtual ssize_t read_at(off_t offset, void *data, size_t size) = 0; + // Convenience methods: + bool getUInt16(off_t offset, uint16_t *x); + // May return ERROR_UNSUPPORTED. virtual status_t getSize(off_t *size); @@ -43,11 +46,14 @@ public: bool sniff(String8 *mimeType, float *confidence); typedef bool (*SnifferFunc)( - DataSource *source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence); static void RegisterSniffer(SnifferFunc func); static void RegisterDefaultSniffers(); +protected: + virtual ~DataSource() {} + private: static Mutex gSnifferMutex; static List gSniffers; diff --git a/include/media/stagefright/MP3Extractor.h b/include/media/stagefright/MP3Extractor.h index 09cfb70..4e1f3c3 100644 --- a/include/media/stagefright/MP3Extractor.h +++ b/include/media/stagefright/MP3Extractor.h @@ -28,16 +28,17 @@ class String8; class MP3Extractor : public MediaExtractor { public: // Extractor assumes ownership of "source". - MP3Extractor(DataSource *source); + MP3Extractor(const sp &source); - ~MP3Extractor(); + size_t countTracks(); + sp getTrack(size_t index); + sp getTrackMetaData(size_t index); - status_t countTracks(int *num_tracks); - status_t getTrack(int index, MediaSource **source); - sp getTrackMetaData(int index); +protected: + virtual ~MP3Extractor(); private: - DataSource *mDataSource; + sp mDataSource; off_t mFirstFramePos; sp mMeta; uint32_t mFixedHeader; @@ -46,7 +47,8 @@ private: MP3Extractor &operator=(const MP3Extractor &); }; -bool SniffMP3(DataSource *source, String8 *mimeType, float *confidence); +bool SniffMP3( + const sp &source, String8 *mimeType, float *confidence); } // namespace android diff --git a/include/media/stagefright/MPEG4Extractor.h b/include/media/stagefright/MPEG4Extractor.h index 51a7e82..932e30f 100644 --- a/include/media/stagefright/MPEG4Extractor.h +++ b/include/media/stagefright/MPEG4Extractor.h @@ -29,22 +29,24 @@ class String8; class MPEG4Extractor : public MediaExtractor { public: // Extractor assumes ownership of "source". - MPEG4Extractor(DataSource *source); - ~MPEG4Extractor(); + MPEG4Extractor(const sp &source); - status_t countTracks(int *num_tracks); - status_t getTrack(int index, MediaSource **source); - sp getTrackMetaData(int index); + size_t countTracks(); + sp getTrack(size_t index); + sp getTrackMetaData(size_t index); + +protected: + virtual ~MPEG4Extractor(); private: struct Track { Track *next; sp meta; uint32_t timescale; - SampleTable *sampleTable; + sp sampleTable; }; - DataSource *mDataSource; + sp mDataSource; bool mHaveMetadata; Track *mFirstTrack, *mLastTrack; @@ -58,7 +60,8 @@ private: MPEG4Extractor &operator=(const MPEG4Extractor &); }; -bool SniffMPEG4(DataSource *source, String8 *mimeType, float *confidence); +bool SniffMPEG4( + const sp &source, String8 *mimeType, float *confidence); } // namespace android diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 40d6127..5147de9 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -30,13 +30,12 @@ class MediaBuffer; class MediaSource; class MetaData; -class MPEG4Writer { +class MPEG4Writer : public RefBase { public: MPEG4Writer(const char *filename); - ~MPEG4Writer(); // Caller retains ownership of both meta and source. - void addSource(const sp &meta, MediaSource *source); + void addSource(const sp &meta, const sp &source); void start(); void stop(); @@ -50,6 +49,9 @@ public: void write(const void *data, size_t size); void endBox(); +protected: + virtual ~MPEG4Writer(); + private: class Track; diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h index c72ed66..339e6fb 100644 --- a/include/media/stagefright/MediaBuffer.h +++ b/include/media/stagefright/MediaBuffer.h @@ -75,6 +75,8 @@ public: // MetaData. MediaBuffer *clone(); + int refcount() const; + protected: virtual ~MediaBuffer(); @@ -102,8 +104,6 @@ private: void setNextBuffer(MediaBuffer *buffer); MediaBuffer *nextBuffer(); - int refcount() const; - MediaBuffer(const MediaBuffer &); MediaBuffer &operator=(const MediaBuffer &); }; diff --git a/include/media/stagefright/MediaDebug.h b/include/media/stagefright/MediaDebug.h new file mode 100644 index 0000000..83acd77 --- /dev/null +++ b/include/media/stagefright/MediaDebug.h @@ -0,0 +1,18 @@ +#ifndef MEDIA_DEBUG_H_ + +#define MEDIA_DEBUG_H_ + +#define LITERAL_TO_STRING_INTERNAL(x) #x +#define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x) + +#define CHECK_EQ(x,y) \ + LOG_ALWAYS_FATAL_IF( \ + (x) != (y), \ + __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x " != " #y) + +#define CHECK(x) \ + LOG_ALWAYS_FATAL_IF( \ + !(x), \ + __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x) + +#endif // MEDIA_DEBUG_H_ diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index 38f8e5b..67e45bd 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -26,18 +26,18 @@ class DataSource; class MediaSource; class MetaData; -class MediaExtractor { +class MediaExtractor : public RefBase { public: - static MediaExtractor *Create(DataSource *source, const char *mime = NULL); + static sp Create( + const sp &source, const char *mime = NULL); - virtual ~MediaExtractor() {} - - virtual status_t countTracks(int *num_tracks) = 0; - virtual status_t getTrack(int index, MediaSource **source) = 0; - virtual sp getTrackMetaData(int index) = 0; + virtual size_t countTracks() = 0; + virtual sp getTrack(size_t index) = 0; + virtual sp getTrackMetaData(size_t index) = 0; protected: MediaExtractor() {} + virtual ~MediaExtractor() {} private: MediaExtractor(const MediaExtractor &); diff --git a/include/media/stagefright/MediaPlayerImpl.h b/include/media/stagefright/MediaPlayerImpl.h index e96e5e8..53a2088 100644 --- a/include/media/stagefright/MediaPlayerImpl.h +++ b/include/media/stagefright/MediaPlayerImpl.h @@ -35,7 +35,6 @@ class MediaBuffer; class MediaSource; class MemoryHeapPmem; class MetaData; -class OMXDecoder; class Surface; class TimeSource; @@ -71,16 +70,16 @@ private: OMXClient mClient; - MediaExtractor *mExtractor; + sp mExtractor; TimeSource *mTimeSource; - MediaSource *mAudioSource; - OMXDecoder *mAudioDecoder; + sp mAudioSource; + sp mAudioDecoder; AudioPlayer *mAudioPlayer; - MediaSource *mVideoSource; - MediaSource *mVideoDecoder; + sp mVideoSource; + sp mVideoDecoder; int32_t mVideoWidth, mVideoHeight; int64_t mVideoPosition; @@ -103,16 +102,13 @@ private: bool mSeeking; int64_t mSeekTimeUs; - size_t mFrameSize; - bool mUseSoftwareColorConversion; - void init(); static void *VideoWrapper(void *me); void videoEntry(); - void setAudioSource(MediaSource *source); - void setVideoSource(MediaSource *source); + void setAudioSource(const sp &source); + void setVideoSource(const sp &source); MediaSource *makeShoutcastSource(const char *path); diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h index eb07f68..d1fa114 100644 --- a/include/media/stagefright/MediaSource.h +++ b/include/media/stagefright/MediaSource.h @@ -27,9 +27,8 @@ namespace android { class MediaBuffer; class MetaData; -struct MediaSource { +struct MediaSource : public RefBase { MediaSource(); - virtual ~MediaSource(); // To be called before any other methods on this object, except // getFormat(). @@ -81,6 +80,9 @@ struct MediaSource { int64_t mLatenessUs; }; +protected: + virtual ~MediaSource(); + private: MediaSource(const MediaSource &); MediaSource &operator=(const MediaSource &); diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h new file mode 100644 index 0000000..d4ae349 --- /dev/null +++ b/include/media/stagefright/OMXCodec.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2009 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 OMX_CODEC_H_ + +#define OMX_CODEC_H_ + +#include +#include +#include +#include + +namespace android { + +class MemoryDealer; +struct OMXCodecObserver; + +struct OMXCodec : public MediaSource, + public MediaBufferObserver { + static sp Create( + const sp &omx, + const sp &meta, bool createEncoder, + const sp &source); + + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + + virtual sp getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + + void on_message(const omx_message &msg); + + // from MediaBufferObserver + virtual void signalBufferReturned(MediaBuffer *buffer); + +protected: + virtual ~OMXCodec(); + +private: + enum State { + DEAD, + LOADED, + LOADED_TO_IDLE, + IDLE_TO_EXECUTING, + EXECUTING, + EXECUTING_TO_IDLE, + IDLE_TO_LOADED, + RECONFIGURING, + ERROR + }; + + enum { + kPortIndexInput = 0, + kPortIndexOutput = 1 + }; + + enum PortStatus { + ENABLED, + DISABLING, + DISABLED, + ENABLING, + SHUTTING_DOWN, + }; + + enum Quirks { + kNeedsFlushBeforeDisable = 1, + kWantsRawNALFrames = 2, + kRequiresLoadedToIdleAfterAllocation = 4, + kRequiresAllocateBufferOnInputPorts = 8, + }; + + struct BufferInfo { + IOMX::buffer_id mBuffer; + bool mOwnedByComponent; + sp mMem; + MediaBuffer *mMediaBuffer; + }; + + struct CodecSpecificData { + size_t mSize; + uint8_t mData[1]; + }; + + sp mOMX; + IOMX::node_id mNode; + sp mObserver; + uint32_t mQuirks; + bool mIsEncoder; + char *mMIME; + char *mComponentName; + sp mOutputFormat; + sp mSource; + Vector mCodecSpecificData; + size_t mCodecSpecificDataIndex; + + sp mDealer; + + State mState; + Vector mPortBuffers[2]; + PortStatus mPortStatus[2]; + bool mSignalledEOS; + bool mNoMoreOutputData; + int64_t mSeekTimeUs; + + Mutex mLock; + Condition mAsyncCompletion; + + // A list of indices into mPortStatus[kPortIndexOutput] filled with data. + List mFilledBuffers; + Condition mBufferFilled; + + OMXCodec(const sp &omx, IOMX::node_id node, uint32_t quirks, + bool isEncoder, const char *mime, const char *componentName, + const sp &source); + + void addCodecSpecificData(const void *data, size_t size); + void clearCodecSpecificData(); + + void setAMRFormat(); + void setAACFormat(); + + status_t setVideoPortFormatType( + OMX_U32 portIndex, + OMX_VIDEO_CODINGTYPE compressionFormat, + OMX_COLOR_FORMATTYPE colorFormat); + + void setVideoInputFormat( + const char *mime, OMX_U32 width, OMX_U32 height); + + void setVideoOutputFormat( + const char *mime, OMX_U32 width, OMX_U32 height); + + void setImageOutputFormat( + OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height); + + status_t allocateBuffers(); + status_t allocateBuffersOnPort(OMX_U32 portIndex); + + status_t freeBuffersOnPort( + OMX_U32 portIndex, bool onlyThoseWeOwn = false); + + void drainInputBuffer(IOMX::buffer_id buffer); + void fillOutputBuffer(IOMX::buffer_id buffer); + void drainInputBuffer(BufferInfo *info); + void fillOutputBuffer(BufferInfo *info); + + void drainInputBuffers(); + void fillOutputBuffers(); + + void flushPortAsync(OMX_U32 portIndex); + void disablePortAsync(OMX_U32 portIndex); + void enablePortAsync(OMX_U32 portIndex); + + static size_t countBuffersWeOwn(const Vector &buffers); + static bool isIntermediateState(State state); + + void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); + void onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data); + void onStateChange(OMX_STATETYPE newState); + void onPortSettingsChanged(OMX_U32 portIndex); + + void setState(State newState); + + status_t init(); + void initOutputFormat(const sp &inputFormat); + + void dumpPortStatus(OMX_U32 portIndex); + + OMXCodec(const OMXCodec &); + OMXCodec &operator=(const OMXCodec &); +}; + +} // namespace android + +#endif // OMX_CODEC_H_ diff --git a/include/media/stagefright/OMXDecoder.h b/include/media/stagefright/OMXDecoder.h index c6b7cb3..0abc5a6 100644 --- a/include/media/stagefright/OMXDecoder.h +++ b/include/media/stagefright/OMXDecoder.h @@ -36,14 +36,10 @@ class OMXDecoder : public MediaSource, public OMXObserver, public MediaBufferObserver { public: - static OMXDecoder *Create( + static sp Create( OMXClient *client, const sp &data, - bool createEncoder = false); - - virtual ~OMXDecoder(); - - // Caller retains ownership of "source". - void setSource(MediaSource *source); + bool createEncoder, + const sp &source); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); @@ -61,6 +57,9 @@ public: // from MediaBufferObserver virtual void signalBufferReturned(MediaBuffer *buffer); +protected: + virtual ~OMXDecoder(); + private: enum { kPortIndexInput = 0, @@ -97,7 +96,7 @@ private: bool mIsEncoder; uint32_t mQuirks; - MediaSource *mSource; + sp mSource; sp mOutputFormat; Mutex mLock; @@ -135,7 +134,8 @@ private: OMXDecoder(OMXClient *client, IOMX::node_id node, const char *mime, const char *codec, bool is_encoder, - uint32_t quirks); + uint32_t quirks, + const sp &source); void setPortStatus(OMX_U32 port_index, PortStatus status); PortStatus getPortStatus(OMX_U32 port_index) const; diff --git a/include/media/stagefright/SampleTable.h b/include/media/stagefright/SampleTable.h index 712da10..808d142 100644 --- a/include/media/stagefright/SampleTable.h +++ b/include/media/stagefright/SampleTable.h @@ -22,17 +22,16 @@ #include #include +#include #include namespace android { class DataSource; -class SampleTable { +class SampleTable : public RefBase { public: - // Caller retains ownership of "source". - SampleTable(DataSource *source); - ~SampleTable(); + SampleTable(const sp &source); // type can be 'stco' or 'co64'. status_t setChunkOffsetParams( @@ -76,8 +75,11 @@ public: status_t findClosestSyncSample( uint32_t start_sample_index, uint32_t *sample_index); +protected: + ~SampleTable(); + private: - DataSource *mDataSource; + sp mDataSource; Mutex mLock; off_t mChunkOffsetOffset; -- cgit v1.1