| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * 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 ANDROID_SURFACE_OUTPUT_H_INCLUDED |
| #define ANDROID_SURFACE_OUTPUT_H_INCLUDED |
| |
| #include "pvmi_mio_control.h" |
| #include "pvmi_media_transfer.h" |
| #include "oscl_scheduler_ao.h" |
| #include "pvmi_media_io_observer.h" |
| #include "oscl_file_io.h" |
| #include "pvmi_config_and_capability.h" |
| #include "oscl_string_containers.h" |
| #include "pvmi_media_io_clock_extension.h" |
| |
| #ifdef PERFORMANCE_MEASUREMENTS_ENABLED |
| #include "pvprofile.h" |
| #endif |
| |
| // FIXME: Move to OMAP library |
| // Linux and Kernel Includes for Frame Buffer |
| #include <fcntl.h> |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <sys/ioctl.h> |
| #include <sys/time.h> |
| //#include <linux/fb.h> |
| //#include <linux/videodev.h> |
| |
| // SurfaceFlinger |
| #include <surfaceflinger/ISurface.h> |
| |
| // interprocess shared memory support |
| #include <binder/MemoryBase.h> |
| #include <binder/MemoryHeapBase.h> |
| |
| // color converter |
| #include "cczoomrotation16.h" |
| |
| // define bits, mask and validity check for video parameters |
| #define VIDEO_PARAMETERS_INVALID 0 |
| #define VIDEO_SUBFORMAT_VALID (1 << 0) |
| #define DISPLAY_HEIGHT_VALID (1 << 1) |
| #define DISPLAY_WIDTH_VALID (1 << 2) |
| #define VIDEO_HEIGHT_VALID (1 << 3) |
| #define VIDEO_WIDTH_VALID (1 << 4) |
| #define VIDEO_PARAMETERS_MASK (VIDEO_SUBFORMAT_VALID | DISPLAY_HEIGHT_VALID | \ |
| DISPLAY_WIDTH_VALID | VIDEO_HEIGHT_VALID | VIDEO_WIDTH_VALID) |
| #define VIDEO_PARAMETERS_VALID (VIDEO_SUBFORMAT_VALID | DISPLAY_HEIGHT_VALID | \ |
| DISPLAY_WIDTH_VALID | VIDEO_HEIGHT_VALID | VIDEO_WIDTH_VALID) |
| |
| namespace android { |
| class PVPlayer; |
| } |
| |
| class PVLogger; |
| class PVMFMediaClock; |
| class AndroidSurfaceOutput; |
| |
| using namespace android; |
| |
| // FIXME: Not used? |
| // typedef void (*frame_decoded_f)(void *cookie, int width, int height, int pitch, int format, uint8* data); |
| |
| // This class implements the reference media IO for file output. |
| // This class constitutes the Media IO component |
| |
| class AndroidSurfaceOutput : public OsclTimerObject |
| ,public PvmiMIOControl |
| ,public PvmiMediaTransfer |
| ,public PvmiCapabilityAndConfig |
| { |
| public: |
| AndroidSurfaceOutput(); |
| |
| // parameter initialization |
| virtual status_t set(android::PVPlayer* pvPlayer, const sp<ISurface>& surface, bool emulation); |
| virtual status_t setVideoSurface(const sp<ISurface>& surface); |
| |
| // For frame buffer |
| virtual bool initCheck(); |
| virtual PVMFStatus writeFrameBuf(uint8* aData, uint32 aDataLen, const PvmiMediaXferHeader& data_header_info); |
| virtual void postLastFrame(); |
| virtual void closeFrameBuf(); |
| |
| virtual ~AndroidSurfaceOutput(); |
| |
| bool GetVideoSize(int *w, int *h); |
| |
| // APIs from PvmiMIOControl |
| |
| PVMFStatus connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver); |
| |
| PVMFStatus disconnect(PvmiMIOSession aSession); |
| |
| PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, |
| bool aExactUuidsOnly=false, const OsclAny* aContext=NULL); |
| |
| PVMFCommandId QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext=NULL); |
| |
| PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession, PvmiKvp* read_formats=NULL, int32 read_flags=0, |
| PvmiKvp* write_formats=NULL, int32 write_flags=0); |
| |
| void deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer); |
| |
| void processWriteResponseQueue(int numFramesToHold); |
| |
| PVMFCommandId Init(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId Reset(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId Start(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId Pause(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId Flush(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId DiscardData(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId DiscardData( PVMFTimestamp aTimestamp=0, const OsclAny* aContext=NULL); |
| |
| PVMFCommandId Stop(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId CancelAllCommands(const OsclAny* aContext=NULL); |
| |
| PVMFCommandId CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext=NULL); |
| |
| void ThreadLogon(); |
| |
| void ThreadLogoff(); |
| |
| // APIs from PvmiMediaTransfer |
| |
| void setPeer(PvmiMediaTransfer* aPeer); |
| |
| void useMemoryAllocators(OsclMemAllocator* write_alloc=NULL); |
| |
| PVMFCommandId writeAsync(uint8 format_type, int32 format_index, |
| uint8* data, uint32 data_len, |
| const PvmiMediaXferHeader& data_header_info, |
| OsclAny* aContext=NULL); |
| |
| void writeComplete(PVMFStatus aStatus, |
| PVMFCommandId write_cmd_id, |
| OsclAny* aContext); |
| |
| PVMFCommandId readAsync(uint8* data, uint32 max_data_len, |
| OsclAny* aContext=NULL, |
| int32* formats=NULL, uint16 num_formats=0); |
| |
| void readComplete(PVMFStatus aStatus, PVMFCommandId read_cmd_id, int32 format_index, |
| const PvmiMediaXferHeader& data_header_info, OsclAny* aContext); |
| |
| void statusUpdate(uint32 status_flags); |
| |
| void cancelCommand(PVMFCommandId command_id); |
| |
| void cancelAllCommands(); |
| |
| // Pure virtuals from PvmiCapabilityAndConfig |
| |
| void setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver); |
| |
| PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, |
| PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext); |
| |
| PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); |
| |
| void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); |
| |
| void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, |
| PvmiKvp* aParameters, int num_parameter_elements); |
| |
| void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); |
| |
| void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, |
| int num_elements, PvmiKvp * & aRet_kvp); |
| |
| PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, |
| int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context=NULL); |
| |
| uint32 getCapabilityMetric (PvmiMIOSession aSession); |
| |
| PVMFStatus verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); |
| |
| |
| protected: |
| void initData(); |
| void resetVideoParameterFlags(); |
| bool checkVideoParameterFlags(); |
| |
| // From OsclTimerObject |
| void Run(); |
| |
| void Reschedule(); |
| |
| void Cleanup(); |
| void ResetData(); |
| |
| PvmiMediaTransfer* iPeer; |
| |
| // The PvmiMIOControl class observer. |
| PvmiMIOObserver* iObserver; |
| |
| //for generating command IDs |
| uint32 iCommandCounter; |
| |
| //State |
| enum PVRefFOState |
| { |
| STATE_IDLE, |
| STATE_LOGGED_ON, |
| STATE_INITIALIZED, |
| STATE_STARTED, |
| STATE_PAUSED |
| }; |
| PVRefFOState iState; |
| |
| //Control command handling. |
| class CommandResponse |
| { |
| public: |
| CommandResponse(PVMFStatus s,PVMFCommandId id,const OsclAny* ctx) |
| :iStatus(s),iCmdId(id),iContext(ctx) |
| {} |
| |
| PVMFStatus iStatus; |
| PVMFCommandId iCmdId; |
| const OsclAny* iContext; |
| }; |
| Oscl_Vector<CommandResponse,OsclMemAllocator> iCommandResponseQueue; |
| void QueueCommandResponse(CommandResponse&); |
| |
| //Write command handling |
| class WriteResponse |
| { |
| public: |
| WriteResponse(PVMFStatus s,PVMFCommandId id,const OsclAny* ctx,const PVMFTimestamp& ts) |
| :iStatus(s),iCmdId(id),iContext(ctx),iTimestamp(ts) |
| {} |
| |
| PVMFStatus iStatus; |
| PVMFCommandId iCmdId; |
| const OsclAny* iContext; |
| PVMFTimestamp iTimestamp; |
| }; |
| Oscl_Vector<WriteResponse,OsclMemAllocator> iWriteResponseQueue; |
| |
| // Output file parameters |
| OSCL_wHeapString<OsclMemAllocator> iOutputFileName; |
| Oscl_FileServer iFs; |
| bool iFsConnected; |
| Oscl_File iOutputFile; |
| bool iFileOpened; |
| |
| bool iEosReceived; |
| |
| // Video parameters |
| uint32 iVideoParameterFlags; |
| OSCL_HeapString<OsclMemAllocator> iVideoFormatString; |
| PVMFFormatType iVideoFormat; |
| int32 iVideoHeight; |
| int32 iVideoWidth; |
| int32 iVideoDisplayHeight; |
| int32 iVideoDisplayWidth; |
| |
| // hardware specific |
| PVMFFormatType iVideoSubFormat; |
| bool iVideoSubFormatValid; |
| |
| //For logging |
| PVLogger* iLogger; |
| |
| //For implementing the write flow control |
| bool CheckWriteBusy(uint32); |
| |
| unsigned long iFrameNumber; |
| |
| // software color conversion for software codecs |
| ColorConvertBase* iColorConverter; |
| |
| android::PVPlayer* mPvPlayer; |
| bool mInitialized; |
| bool mEmulation; |
| sp<ISurface> mSurface; |
| |
| // frame buffer support |
| static const int kBufferCount = 2; |
| int mFrameBufferIndex; |
| ISurface::BufferHeap mBufferHeap; |
| size_t mFrameBuffers[kBufferCount]; |
| |
| void convertFrame(void* src, void* dst, size_t len); |
| //This bool is set true when all necassary parameters have been received. |
| bool iIsMIOConfigured; |
| |
| /* |
| * The value of mNumberOfFramesToHold is decoder specific. |
| * |
| * Please make sure that the number of unique output buffers from the decoder |
| * (either hardware or software) is not less than 1 + mNumberOfFramesToHold; |
| * otherwise, we will have starvation. |
| * |
| * On some platforms, mNumberOfFramesToHold needs to set to more than 1 (such as |
| * 2) in order to workaround a tearing issue from SF during video playback. |
| * |
| */ |
| int mNumberOfFramesToHold; |
| |
| #ifdef PERFORMANCE_MEASUREMENTS_ENABLED |
| PVProfile PVOmapVideoProfile; |
| #endif |
| |
| }; |
| |
| #endif // ANDROID_SURFACE_OUTPUT_H_INCLUDED |
| |