diff options
Diffstat (limited to 'include/media/stagefright')
23 files changed, 575 insertions, 32 deletions
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 8b5b862..0ac13b9 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -28,6 +28,8 @@ #include <media/stagefright/SkipCutBuffer.h> #include <OMX_Audio.h> +#include <system/audio.h> + #define TRACK_BUFFER_TIMING 0 namespace android { @@ -93,8 +95,11 @@ struct ACodec : public AHierarchicalStateMachine, public CodecBase { protected: virtual ~ACodec(); + virtual status_t setupCustomCodec( + status_t err, const char *mime, const sp<AMessage> &msg); + virtual status_t GetVideoCodingTypeFromMime( + const char *mime, OMX_VIDEO_CODINGTYPE *codingType); -private: struct BaseState; struct UninitializedState; struct LoadedState; @@ -143,6 +148,7 @@ private: kFlagIsSecure = 1, kFlagPushBlankBuffersToNativeWindowOnShutdown = 2, kFlagIsGrallocUsageProtected = 4, + kFlagPushBlankBuffersToNativeWindowOnSwitch = 1 << 7, }; enum { @@ -152,6 +158,7 @@ private: }; struct BufferInfo { + BufferInfo() : mCustomData(-1) {} enum Status { OWNED_BY_US, OWNED_BY_COMPONENT, @@ -173,6 +180,7 @@ private: sp<GraphicBuffer> mGraphicBuffer; int mFenceFd; FrameRenderTracker::Info *mRenderInfo; + int mCustomData; // The following field and 4 methods are used for debugging only bool mIsReadFence; @@ -236,6 +244,8 @@ private: bool mSentFormat; bool mIsVideo; bool mIsEncoder; + bool mEncoderComponent; + bool mComponentAllocByName; bool mFatalError; bool mShutdownInProgress; bool mExplicitShutdown; @@ -271,7 +281,7 @@ private: status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode); status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t freeBuffersOnPort(OMX_U32 portIndex); - status_t freeBuffer(OMX_U32 portIndex, size_t i); + virtual status_t freeBuffer(OMX_U32 portIndex, size_t i); status_t handleSetSurface(const sp<Surface> &surface); status_t setupNativeWindowSizeFormatAndUsage( @@ -284,6 +294,9 @@ private: status_t submitOutputMetadataBuffer(); void signalSubmitOutputMetadataBufferIfEOS_workaround(); status_t allocateOutputBuffersFromNativeWindow(); +#ifdef USE_SAMSUNG_COLORFORMAT + void setNativeWindowColorFormat(OMX_COLOR_FORMATTYPE &eNativeColorFormat); +#endif status_t cancelBufferToNativeWindow(BufferInfo *info); status_t freeOutputBuffersNotOwnedByComponent(); BufferInfo *dequeueBufferFromNativeWindow(); @@ -300,8 +313,8 @@ private: uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index = NULL); - status_t setComponentRole(bool isEncoder, const char *mime); - status_t configureCodec(const char *mime, const sp<AMessage> &msg); + virtual status_t setComponentRole(bool isEncoder, const char *mime); + virtual status_t configureCodec(const char *mime, const sp<AMessage> &msg); status_t configureTunneledVideoPlayback(int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow); @@ -314,10 +327,10 @@ private: status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat); - status_t setupVideoDecoder( + virtual status_t setupVideoDecoder( const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers); - status_t setupVideoEncoder( + virtual status_t setupVideoEncoder( const char *mime, const sp<AMessage> &msg); status_t setVideoFormatOnPort( @@ -338,11 +351,13 @@ private: int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode, int32_t maxOutputChannelCount, const drcParams_t& drc, - int32_t pcmLimiterEnable); + int32_t pcmLimiterEnable, int32_t bitsPerSample = 16); - status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); + status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate, + int32_t bitsPerSample = 16); - status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); + status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate, + int32_t bitsPerSample = 16); status_t selectAudioPortFormat( OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat); @@ -372,7 +387,7 @@ private: status_t configureBitrate( int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode); - status_t setupErrorCorrectionParameters(); + virtual status_t setupErrorCorrectionParameters(); status_t initNativeWindow(); @@ -408,7 +423,7 @@ private: bool dropIncomplete = false, FrameRenderTracker::Info *until = NULL); void sendFormatChange(const sp<AMessage> &reply); - status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify); + virtual status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify); void signalError( OMX_ERRORTYPE error = OMX_ErrorUndefined, @@ -420,11 +435,40 @@ private: DescribeColorFormatParams &describeParams); status_t requestIDRFrame(); - status_t setParameters(const sp<AMessage> ¶ms); + virtual status_t setParameters(const sp<AMessage> ¶ms); // Send EOS on input stream. void onSignalEndOfInputStream(); + virtual void setBFrames(OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type) {} + virtual void setBFrames(OMX_VIDEO_PARAM_AVCTYPE *h264type, + const int32_t iFramesInterval, const int32_t frameRate) {} + + virtual status_t getVQZIPInfo(const sp<AMessage> &msg) { + return OK; + } + virtual bool canAllocateBuffer(OMX_U32 /* portIndex */) { + return false; + } + virtual void enableCustomAllocationMode(const sp<AMessage> &/* msg */) {} + virtual status_t allocateBuffer( + OMX_U32 portIndex, size_t bufSize, BufferInfo &info); + + virtual status_t setDSModeHint(sp<AMessage>& msg, + OMX_U32 flags, int64_t timeUs) { + return UNKNOWN_ERROR; + } + + virtual bool getDSModeHint(const sp<AMessage>& msg) { + return false; + } + + sp<IOMXObserver> createObserver(); + + status_t setupRawAudioFormatInternal( + OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, + int32_t bitsPerSample); + DISALLOW_EVIL_CONSTRUCTORS(ACodec); }; diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index e0cd965..edc9f25 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -103,6 +103,7 @@ private: int64_t mSeekTimeUs; bool mStarted; + bool mSourcePaused; bool mIsFirstBuffer; status_t mFirstBufferResult; @@ -115,6 +116,7 @@ private: bool mPlaying; int64_t mStartPosUs; const uint32_t mCreateFlags; + bool mPauseRequired; static void AudioCallback(int event, void *user, void *info); void AudioCallback(int event, void *info); diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h index 3074910..699b1b4 100644 --- a/include/media/stagefright/AudioSource.h +++ b/include/media/stagefright/AudioSource.h @@ -58,9 +58,11 @@ struct AudioSource : public MediaSource, public MediaBufferObserver { protected: virtual ~AudioSource(); -private: +protected: enum { - kMaxBufferSize = 2048, + //calculated for max duration 80 msec with 48K sampling rate. + kMaxBufferSize = 30720, + // After the initial mute, we raise the volume linearly // over kAutoRampDurationUs. @@ -68,7 +70,7 @@ private: // This is the initial mute duration to suppress // the video recording signal tone - kAutoRampStartUs = 0, + kAutoRampStartUs = 500000, }; Mutex mLock; @@ -90,6 +92,8 @@ private: int64_t mNumFramesReceived; int64_t mNumClientOwnedBuffers; + bool mRecPaused; + List<MediaBuffer * > mBuffersReceived; void trackMaxAmplitude(int16_t *data, int nSamples); @@ -100,13 +104,17 @@ private: int32_t startFrame, int32_t rampDurationFrames, uint8_t *data, size_t bytes); - void queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs); + virtual void queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs); void releaseQueuedFrames_l(); void waitOutstandingEncodingFrames_l(); - status_t reset(); + virtual status_t reset(); AudioSource(const AudioSource &); AudioSource &operator=(const AudioSource &); + +public: + virtual status_t pause(); + }; } // namespace android diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index 069e897..3dcfe4e 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -92,6 +92,8 @@ public: virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL); + virtual status_t pause(); + /** * Check whether a CameraSource object is properly initialized. * Must call this method before stop(). @@ -189,7 +191,7 @@ protected: void releaseCamera(); -private: +protected: friend struct CameraSourceListener; Mutex mLock; @@ -206,6 +208,11 @@ private: bool mCollectStats; bool mIsMetaDataStoredInVideoBuffers; + int64_t mPauseAdjTimeUs; + int64_t mPauseStartTimeUs; + int64_t mPauseEndTimeUs; + bool mRecPause; + void releaseQueuedFrames(); void releaseOneRecordingFrame(const sp<IMemory>& frame); @@ -236,6 +243,9 @@ private: status_t checkFrameRate(const CameraParameters& params, int32_t frameRate); + static void adjustIncomingANWBuffer(IMemory* data); + static void adjustOutgoingANWBuffer(IMemory* data); + void stopCameraRecording(); status_t reset(); diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h index 34213be..eeb453f 100644 --- a/include/media/stagefright/CameraSourceTimeLapse.h +++ b/include/media/stagefright/CameraSourceTimeLapse.h @@ -20,6 +20,7 @@ #include <pthread.h> +#include <media/stagefright/CameraSource.h> #include <utils/RefBase.h> #include <utils/threads.h> #include <utils/String16.h> @@ -56,7 +57,7 @@ public: // returning quickly. void startQuickReadReturns(); -private: +protected: // size of the encoded video. int32_t mVideoWidth; int32_t mVideoHeight; @@ -66,6 +67,9 @@ private: // Real timestamp of the last encoded time lapse frame int64_t mLastTimeLapseFrameRealTimestampUs; + // Adjusted continuous timestamp based on recording fps + // of the last encoded time lapse frame + int64_t mLastTimeLapseFrameTimeStampUs; // Variable set in dataCallbackTimestamp() to help skipCurrentFrame() // to know if current frame needs to be skipped. @@ -152,7 +156,7 @@ private: // the frame needs to be encoded, it returns false and also modifies // the time stamp to be one frame time ahead of the last encoded // frame's time stamp. - bool skipFrameAndModifyTimeStamp(int64_t *timestampUs); + virtual bool skipFrameAndModifyTimeStamp(int64_t *timestampUs); // Wrapper to enter threadTimeLapseEntry() static void *ThreadTimeLapseWrapper(void *me); diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 47c5c34..c8ad05e 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -27,10 +27,10 @@ #include <utils/RefBase.h> #include <utils/threads.h> #include <drm/DrmManagerClient.h> +#include <media/stagefright/foundation/AMessage.h> namespace android { -struct AMessage; struct AString; class IDataSource; struct IMediaHTTPService; @@ -51,12 +51,13 @@ public: const char *uri, const KeyedVector<String8, String8> *headers = NULL, String8 *contentType = NULL, - HTTPBase *httpSource = NULL); + HTTPBase *httpSource = NULL, + bool useExtendedCache = false); static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService); static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source); - DataSource() {} + DataSource() : mMeta(new AMessage) {} virtual status_t initCheck() const = 0; @@ -121,15 +122,21 @@ public: virtual String8 getMIMEType() const; + virtual sp<AMessage> meta() { return mMeta; } + protected: virtual ~DataSource() {} private: + sp<AMessage> mMeta; + static Mutex gSnifferMutex; static List<SnifferFunc> gSniffers; + static List<SnifferFunc> gExtraSniffers; static bool gSniffersRegistered; static void RegisterSniffer_l(SnifferFunc func); + static void RegisterSnifferPlugin(); DataSource(const DataSource &); DataSource &operator=(const DataSource &); diff --git a/include/media/stagefright/ExtendedMediaDefs.h b/include/media/stagefright/ExtendedMediaDefs.h new file mode 100644 index 0000000..18b5e9a --- /dev/null +++ b/include/media/stagefright/ExtendedMediaDefs.h @@ -0,0 +1,69 @@ +/*Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _EXTENDED_MEDIA_DEFS_H_ +#define _EXTENDED_MEDIA_DEFS_H_ + +namespace android { + +extern const char *MEDIA_MIMETYPE_AUDIO_EVRC; +extern const char *MEDIA_MIMETYPE_VIDEO_WMV; +extern const char *MEDIA_MIMETYPE_VIDEO_WMV_VC1; +extern const char *MEDIA_MIMETYPE_AUDIO_WMA; +extern const char *MEDIA_MIMETYPE_AUDIO_WMA_PRO; +extern const char *MEDIA_MIMETYPE_AUDIO_WMA_LOSSLESS; +extern const char *MEDIA_MIMETYPE_CONTAINER_ASF; +extern const char *MEDIA_MIMETYPE_VIDEO_DIVX; +extern const char *MEDIA_MIMETYPE_CONTAINER_AAC; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCP; +extern const char *MEDIA_MIMETYPE_VIDEO_DIVX311; +extern const char *MEDIA_MIMETYPE_VIDEO_DIVX4; +extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2; +extern const char *MEDIA_MIMETYPE_CONTAINER_3G2; +extern const char *MEDIA_MIMETYPE_AUDIO_DTS; +extern const char *MEDIA_MIMETYPE_AUDIO_DTS_LBR; +extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS; +extern const char *MEDIA_MIMETYPE_AUDIO_AIFF; +extern const char *MEDIA_MIMETYPE_AUDIO_ALAC; +extern const char *MEDIA_MIMETYPE_AUDIO_APE; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_NB; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_WB; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCWAV; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2TS; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2PS; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG4; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCMATROSKA; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCOGG; +extern const char *MEDIA_MIMETYPE_CONTAINER_QCFLV; +extern const char *MEDIA_MIMETYPE_VIDEO_VPX; +extern const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC; +extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4_DP; + +} // namespace android + +#endif // _EXTENDED_MEDIA_DEFS_H_ diff --git a/include/media/stagefright/FFMPEGSoftCodec.h b/include/media/stagefright/FFMPEGSoftCodec.h new file mode 100644 index 0000000..c6b6482 --- /dev/null +++ b/include/media/stagefright/FFMPEGSoftCodec.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2014 The CyanogenMod 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 FFMPEG_SOFT_CODEC_H_ +#define FFMPEG_SOFT_CODEC_H_ + +#include <media/IOMX.h> +#include <media/MediaCodecInfo.h> + +#include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AString.h> + +#include <media/stagefright/MetaData.h> + +#include <OMX_Audio.h> +#include <OMX_Video.h> + +namespace android { + +struct FFMPEGSoftCodec { + + enum { + kPortIndexInput = 0, + kPortIndexOutput = 1 + }; + + static void convertMessageToMetaDataFF( + const sp<AMessage> &msg, sp<MetaData> &meta); + + static void convertMetaDataToMessageFF( + const sp<MetaData> &meta, sp<AMessage> *format); + + static const char* overrideComponentName( + uint32_t quirks, const sp<MetaData> &meta, + const char *mime, bool isEncoder); + + static void overrideComponentName( + uint32_t quirks, const sp<AMessage> &msg, + AString* componentName, AString* mime, + int32_t isEncoder); + + static status_t setSupportedRole( + const sp<IOMX> &omx, IOMX::node_id node, + bool isEncoder, const char *mime); + + static status_t setAudioFormat( + const sp<AMessage> &msg, const char* mime, + sp<IOMX> OMXhandle, IOMX::node_id nodeID); + + static status_t setVideoFormat( + status_t status, + const sp<AMessage> &msg, const char* mime, + sp<IOMX> OMXhandle,IOMX::node_id nodeID, + bool isEncoder, OMX_VIDEO_CODINGTYPE *compressionFormat, + const char* componentName); + + static status_t getAudioPortFormat( + OMX_U32 portIndex, int coding, + sp<AMessage> ¬ify, sp<IOMX> OMXhandle, IOMX::node_id nodeID); + + static status_t getVideoPortFormat( + OMX_U32 portIndex, int coding, + sp<AMessage> ¬ify, sp<IOMX> OMXhandle, IOMX::node_id nodeID); + +private: + static const char* getMsgKey(int key); + + static status_t setWMVFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setRVFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setFFmpegVideoFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setRawAudioFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setWMAFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setVORBISFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setRAFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setFLACFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setMP2Format( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setAC3Format( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setAPEFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setDTSFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + + static status_t setFFmpegAudioFormat( + const sp<AMessage> &msg, sp<IOMX> OMXhandle, + IOMX::node_id nodeID); + +#ifdef QCOM_HARDWARE + static status_t setQCDIVXFormat( + const sp<AMessage> &msg, const char* mime, + sp<IOMX> OMXhandle, IOMX::node_id nodeID, int port_index); +#endif + +}; + +} +#endif diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h index a981d1c..f4f874f 100644 --- a/include/media/stagefright/FileSource.h +++ b/include/media/stagefright/FileSource.h @@ -43,11 +43,16 @@ public: virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client); + virtual String8 getUri() { + return mUri; + } + protected: virtual ~FileSource(); private: int mFd; + String8 mUri; int64_t mOffset; int64_t mLength; Mutex mLock; @@ -56,10 +61,11 @@ private: sp<DecryptHandle> mDecryptHandle; DrmManagerClient *mDrmManagerClient; int64_t mDrmBufOffset; - size_t mDrmBufSize; + ssize_t mDrmBufSize; unsigned char *mDrmBuf; ssize_t readAtDRM(off64_t offset, void *data, size_t size); + void fetchUriFromFd(int fd); FileSource(const FileSource &); FileSource &operator=(const FileSource &); diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index a195fe8..09a48f9 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -77,13 +77,17 @@ private: int mFd; status_t mInitCheck; bool mIsRealTimeRecording; +protected: bool mUse4ByteNalLength; +private: bool mUse32BitOffset; bool mIsFileSizeLimitExplicitlyRequested; bool mPaused; bool mStarted; // Writer thread + track threads started successfully bool mWriterThreadStarted; // Only writer thread started successfully +protected: off64_t mOffset; +private: off_t mMdatOffset; uint8_t *mMoovBoxBuffer; off64_t mMoovBoxBufferOffset; @@ -108,6 +112,8 @@ private: sp<AMessage> mMetaKeys; + bool mIsVideoHEVC; + void setStartTimestampUs(int64_t timeUs); int64_t getStartTimestampUs(); // Not const status_t startTracks(MetaData *params); @@ -181,13 +187,22 @@ private: // By default, real time recording is on. bool isRealTimeRecording() const; + // To use 3gp4 box for clips with AMR audio + bool mIsAudioAMR; + + // HFR scale + uint32_t mHFRRatio; + void lock(); void unlock(); // Acquire lock before calling these methods off64_t addSample_l(MediaBuffer *buffer); - off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); +protected: + static void StripStartcode(MediaBuffer *buffer); + virtual off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); +private: bool exceedsFileSizeLimit(); bool use32BitFileOffset() const; bool exceedsFileDurationLimit(); diff --git a/include/media/stagefright/MediaAdapter.h b/include/media/stagefright/MediaAdapter.h index 369fce6..8622546 100644 --- a/include/media/stagefright/MediaAdapter.h +++ b/include/media/stagefright/MediaAdapter.h @@ -56,6 +56,8 @@ public: // deep copy, such that after pushBuffer return, the buffer can be re-used. status_t pushBuffer(MediaBuffer *buffer); + virtual void notifyError(status_t err); + private: Mutex mAdapterLock; // Make sure the read() wait for the incoming buffer. @@ -68,6 +70,8 @@ private: bool mStarted; sp<MetaData> mOutputFormat; + status_t mStatus; + DISALLOW_EVIL_CONSTRUCTORS(MediaAdapter); }; diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h index c8a50e8..5ab266f 100644 --- a/include/media/stagefright/MediaBuffer.h +++ b/include/media/stagefright/MediaBuffer.h @@ -93,6 +93,7 @@ protected: private: friend class MediaBufferGroup; friend class OMXDecoder; + friend class MediaAdapter; // For use by OMXDecoder, reference count must be 1, drop reference // count to 0 without signalling the observer. diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index cdfa159..e2588a4 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -51,6 +51,8 @@ struct MediaCodec : public AHandler { BUFFER_FLAG_SYNCFRAME = 1, BUFFER_FLAG_CODECCONFIG = 2, BUFFER_FLAG_EOS = 4, + BUFFER_FLAG_EXTRADATA = 0x1000, + BUFFER_FLAG_DATACORRUPT = 0x2000, }; enum { diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h index 71f58a9..d41d87b 100644 --- a/include/media/stagefright/MediaCodecSource.h +++ b/include/media/stagefright/MediaCodecSource.h @@ -28,7 +28,7 @@ class AMessage; struct AReplyToken; class IGraphicBufferProducer; class IGraphicBufferConsumer; -class MediaCodec; +struct MediaCodec; class MetaData; struct MediaCodecSource : public MediaSource, diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index 21eb04a..ffbd20c 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -66,6 +66,43 @@ extern const char *MEDIA_MIMETYPE_TEXT_VTT; extern const char *MEDIA_MIMETYPE_TEXT_CEA_608; extern const char *MEDIA_MIMETYPE_DATA_TIMED_ID3; +extern const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC; +extern const char *MEDIA_MIMETYPE_AUDIO_EAC3; + +extern const char *MEDIA_MIMETYPE_VIDEO_FLV1; +extern const char *MEDIA_MIMETYPE_VIDEO_MJPEG; +extern const char *MEDIA_MIMETYPE_VIDEO_RV; +extern const char *MEDIA_MIMETYPE_VIDEO_VC1; +extern const char *MEDIA_MIMETYPE_VIDEO_WMV; +extern const char *MEDIA_MIMETYPE_VIDEO_HEVC; +extern const char *MEDIA_MIMETYPE_VIDEO_FFMPEG; + +extern const char *MEDIA_MIMETYPE_AUDIO_AC3; +extern const char *MEDIA_MIMETYPE_AUDIO_PCM; +extern const char *MEDIA_MIMETYPE_AUDIO_RA; +extern const char *MEDIA_MIMETYPE_AUDIO_WMA; +extern const char *MEDIA_MIMETYPE_AUDIO_FFMPEG; + +extern const char *MEDIA_MIMETYPE_CONTAINER_APE; +extern const char *MEDIA_MIMETYPE_CONTAINER_DIVX; +extern const char *MEDIA_MIMETYPE_CONTAINER_DTS; +extern const char *MEDIA_MIMETYPE_CONTAINER_FLAC; +extern const char *MEDIA_MIMETYPE_CONTAINER_FLV; +extern const char *MEDIA_MIMETYPE_CONTAINER_MOV; +extern const char *MEDIA_MIMETYPE_CONTAINER_MP2; +extern const char *MEDIA_MIMETYPE_CONTAINER_MPG; +extern const char *MEDIA_MIMETYPE_CONTAINER_RA; +extern const char *MEDIA_MIMETYPE_CONTAINER_RM; +extern const char *MEDIA_MIMETYPE_CONTAINER_TS; +extern const char *MEDIA_MIMETYPE_CONTAINER_WEBM; +extern const char *MEDIA_MIMETYPE_CONTAINER_VC1; +extern const char *MEDIA_MIMETYPE_CONTAINER_HEVC; +extern const char *MEDIA_MIMETYPE_CONTAINER_WMA; +extern const char *MEDIA_MIMETYPE_CONTAINER_WMV; +extern const char *MEDIA_MIMETYPE_CONTAINER_FFMPEG; + } // namespace android +#include <media/stagefright/ExtendedMediaDefs.h> + #endif // MEDIA_DEFS_H_ diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index 183933a..e83defa 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -19,17 +19,30 @@ #define MEDIA_EXTRACTOR_H_ #include <utils/RefBase.h> +#include <media/stagefright/DataSource.h> namespace android { -class DataSource; class MediaSource; class MetaData; class MediaExtractor : public RefBase { public: + typedef MediaExtractor *(*CreateFunc)(const sp<DataSource> &source, + const char *mime, const sp<AMessage> &meta); + + struct Plugin { + DataSource::SnifferFunc sniff; + CreateFunc create; + }; + + static Plugin *getPlugin() { + return &sPlugin; + } + static sp<MediaExtractor> Create( - const sp<DataSource> &source, const char *mime = NULL); + const sp<DataSource> &source, const char *mime = NULL, + const uint32_t flags = 0, const sp<AMessage> *meta = NULL); virtual size_t countTracks() = 0; virtual sp<MediaSource> getTrack(size_t index) = 0; @@ -67,6 +80,7 @@ public: } virtual void setUID(uid_t uid) { } + virtual void setExtraFlags(uint32_t flag) {} protected: MediaExtractor() : mIsDrm(false) {} @@ -74,6 +88,7 @@ protected: private: bool mIsDrm; + static Plugin sPlugin; MediaExtractor(const MediaExtractor &); MediaExtractor &operator=(const MediaExtractor &); diff --git a/include/media/stagefright/MediaHTTP.h b/include/media/stagefright/MediaHTTP.h index 006d8d8..88683bd 100644 --- a/include/media/stagefright/MediaHTTP.h +++ b/include/media/stagefright/MediaHTTP.h @@ -54,7 +54,7 @@ protected: virtual String8 getUri(); virtual String8 getMIMEType() const; -private: +protected: status_t mInitCheck; sp<IMediaHTTPConnection> mHTTPConnection; diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h index a653db9..7ab5f62 100644 --- a/include/media/stagefright/MediaSource.h +++ b/include/media/stagefright/MediaSource.h @@ -59,6 +59,7 @@ struct MediaSource : public virtual RefBase { virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL) = 0; + virtual void notifyError(status_t) {} // Options that modify read() behaviour. The default is to // a) not request a seek // b) not be late, i.e. lateness_us = 0 diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index 8d4e15a..66e7d63 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -50,6 +50,10 @@ enum { kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz) kKeyFrameRate = 'frmR', // int32_t (video frame rate fps) kKeyBitRate = 'brte', // int32_t (bps) + kKeyCodecId = 'cdid', // int32_t + kKeyBitsPerSample = 'sbit', // int32_t (DUPE of kKeySampleBits) + kKeyCodedSampleBits = 'cosb', // int32_t + kKeySampleFormat = 'sfmt', // int32_t kKeyESDS = 'esds', // raw data kKeyAACProfile = 'aacp', // int32_t kKeyAVCC = 'avcc', // raw data @@ -64,6 +68,7 @@ enum { kKeyIsSyncFrame = 'sync', // int32_t (bool) kKeyIsCodecConfig = 'conf', // int32_t (bool) kKeyTime = 'time', // int64_t (usecs) + kKeyTimeBoot = 'timb', // int64_t (usecs) kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs) kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) kKeyTargetTime = 'tarT', // int64_t (usecs) @@ -131,6 +136,23 @@ enum { kKeyIsUnreadable = 'unre', // bool (int32_t) + kKeyRawCodecSpecificData = 'rcsd', // raw data - added to support mmParser + kKeyDivXVersion = 'DivX', // int32_t + kKeyDivXDrm = 'QDrm', // void * + kKeyWMAEncodeOpt = 'eopt', // int32_t + kKeyWMABlockAlign = 'blka', // int32_t + kKeyWMAVersion = 'wmav', // int32_t + kKeyWMAAdvEncOpt1 = 'ade1', // int16_t + kKeyWMAAdvEncOpt2 = 'ade2', // int32_t + kKeyWMAFormatTag = 'fmtt', // int64_t + kKeyWMABitspersample = 'bsps', // int64_t + kKeyWMAVirPktSize = 'vpks', // int64_t + kKeyWMVProfile = 'wmvp', // int32_t + + kKeyWMVVersion = 'wmvv', // int32_t + kKeyRVVersion = '#rvv', // int32_t + kKeyBlockAlign = 'ablk', // int32_t , should be different from kKeyWMABlockAlign + // An indication that a video buffer has been rendered. kKeyRendered = 'rend', // bool (int32_t) @@ -181,6 +203,13 @@ enum { // H264 supplemental enhancement information offsets/sizes kKeySEI = 'sei ', // raw data + + kKeyPCMFormat = 'pfmt', + kKeyArbitraryMode = 'ArbM', + + // Indicate if it is OK to hold on to the MediaBuffer and not + // release it immediately + kKeyCanDeferRelease = 'drel', // bool (int32_t) }; enum { @@ -190,6 +219,32 @@ enum { kTypeD263 = 'd263', }; +enum { + kTypeDivXVer_3_11, + kTypeDivXVer_4, + kTypeDivXVer_5, + kTypeDivXVer_6, +}; + +enum { + kTypeWMA, + kTypeWMAPro, + kTypeWMALossLess, +}; + +enum { + kTypeWMVVer_7, // WMV1 + kTypeWMVVer_8, // WMV2 + kTypeWMVVer_9, // WMV3 +}; + +// http://en.wikipedia.org/wiki/RealVideo +enum { + kTypeRVVer_G2, // rv20: RealVideo G2 + kTypeRVVer_8, // rv30: RealVideo 8 + kTypeRVVer_9, // rv40: RealVideo 9 +}; + class MetaData : public RefBase { public: MetaData(); diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index b0404aa..2f73de8 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -135,6 +135,9 @@ private: EXECUTING_TO_IDLE, IDLE_TO_LOADED, RECONFIGURING, + PAUSING, + FLUSHING, + PAUSED, ERROR }; @@ -344,6 +347,7 @@ private: status_t waitForBufferFilled_l(); + status_t resumeLocked(bool drainInputBuf); int64_t getDecodingTimeUs(); status_t parseHEVCCodecSpecificData( diff --git a/include/media/stagefright/SkipCutBuffer.h b/include/media/stagefright/SkipCutBuffer.h index 098aa69..61f9949 100644 --- a/include/media/stagefright/SkipCutBuffer.h +++ b/include/media/stagefright/SkipCutBuffer.h @@ -29,9 +29,10 @@ namespace android { */ class SkipCutBuffer: public RefBase { public: - // 'skip' is the number of bytes to skip from the beginning - // 'cut' is the number of bytes to cut from the end - SkipCutBuffer(int32_t skip, int32_t cut); + // 'skip' is the number of frames to skip from the beginning + // 'cut' is the number of frames to cut from the end + // 'num16BitChannels' is the number of channels, which are assumed to be 16 bit wide each + SkipCutBuffer(size_t skip, size_t cut, size_t num16Channels); // Submit one MediaBuffer for skipping and cutting. This may consume all or // some of the data in the buffer, or it may add data to it. diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h index 5e9d7d4..e91c03a 100644 --- a/include/media/stagefright/Utils.h +++ b/include/media/stagefright/Utils.h @@ -18,6 +18,7 @@ #define UTILS_H_ +#include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/AString.h> #include <stdint.h> #include <utils/Errors.h> @@ -85,6 +86,14 @@ void writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFp void readFromAMessage( const sp<AMessage> &msg, AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */); +audio_format_t getPCMFormat(const sp<AMessage> &format); + +void updateVideoTrackInfoFromESDS_MPEG4Video(sp<MetaData> meta); +bool checkDPFromVOLHeader(const uint8_t *ptr, size_t size); +bool checkDPFromCodecSpecificData(const uint8_t *ptr, size_t size); + +status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length); + } // namespace android #endif // UTILS_H_ diff --git a/include/media/stagefright/WAVEWriter.h b/include/media/stagefright/WAVEWriter.h new file mode 100644 index 0000000..766d8f4 --- /dev/null +++ b/include/media/stagefright/WAVEWriter.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WAVE_WRITER_H_ + +#define WAVE_WRITER_H_ + +#include <stdio.h> + +#include <media/stagefright/MediaWriter.h> +#include <utils/threads.h> + +namespace android { + + +#define ID_RIFF 0x46464952 +#define ID_WAVE 0x45564157 +#define ID_FMT 0x20746d66 +#define ID_DATA 0x61746164 +#define FORMAT_PCM 1 + + +struct MediaSource; +struct MetaData; + +struct wav_header { + uint32_t riff_id; + uint32_t riff_sz; + uint32_t riff_fmt; + uint32_t fmt_id; + uint32_t fmt_sz; + uint16_t audio_format; + uint16_t num_channels; + uint32_t sample_rate; + uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */ + uint16_t block_align; /* num_channels * bps / 8 */ + uint16_t bits_per_sample; + uint32_t data_id; + uint32_t data_sz; +}; + + +struct WAVEWriter : public MediaWriter { + WAVEWriter(const char *filename); + WAVEWriter(int fd); + + status_t initCheck() const; + + virtual status_t addSource(const sp<MediaSource> &source); + virtual bool reachedEOS(); + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + virtual status_t pause(); + +protected: + virtual ~WAVEWriter(); + +private: + int mFd; + status_t mInitCheck; + sp<MediaSource> mSource; + bool mStarted; + volatile bool mPaused; + volatile bool mResumed; + volatile bool mDone; + volatile bool mReachedEOS; + pthread_t mThread; + int64_t mEstimatedSizeBytes; + int64_t mEstimatedDurationUs; + + static void *ThreadWrapper(void *); + status_t threadFunc(); + bool exceedsFileSizeLimit(); + bool exceedsFileDurationLimit(); + + WAVEWriter(const WAVEWriter &); + WAVEWriter &operator=(const WAVEWriter &); +}; + +} // namespace android + +#endif // WAVE_WRITER_H_ |