blob: 5f0f734c3b7bd54801139553ffac26cc3f65086d [file] [log] [blame]
/* ------------------------------------------------------------------
* 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