blob: 94d8e3c5ee412ec0120ce4c689e16a0ccc162be1 [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 PVMI_MEDIA_IO_FILEOUTPUT_H_INCLUDED
#define PVMI_MEDIA_IO_FILEOUTPUT_H_INCLUDED
#ifndef PVMI_MIO_CONTROL_H_INCLUDED
#include "pvmi_mio_control.h"
#endif
#ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED
#include "pvmi_media_transfer.h"
#endif
#ifndef OSCL_SCHEDULER_AO_H_INCLUDED
#include "oscl_scheduler_ao.h"
#endif
#ifndef PVMI_MEDIA_IO_OBSERVER_H_INCLUDED
#include "pvmi_media_io_observer.h"
#endif
#ifndef OSCL_FILE_IO_H_INCLUDED
#include "oscl_file_io.h"
#endif
#ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED
#include "pvmi_config_and_capability.h"
#endif
#ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
#include "oscl_string_containers.h"
#endif
#ifndef PVMI_MEDIA_IO_CLOCK_EXTENSION_H_INCLUDED
#include "pvmi_media_io_clock_extension.h"
#endif
#include "avi_write.h"
class PVLogger;
class PVRefFileOutputTestObserver;
class OsclClock;
class PVRefFileOutput;
#define DEFAULT_NUM_DECODED_FRAMES_CAPABILITY 6
typedef struct
{
uint32 chunkID;
uint32 chunkSize;
uint32 format;
} RIFFChunk;
typedef struct
{
uint32 subchunk1ID;
uint32 subchunk1Size;
uint16 audioFormat;
uint16 numChannels;
uint32 sampleRate;
uint32 byteRate;
uint16 blockAlign;
uint16 bitsPerSample;
} fmtSubchunk;
typedef struct
{
uint32 subchunk2ID;
uint32 subchunk2Size;
} dataSubchunk;
// A test feature for simulating a component with active timing.
class PVRefFileOutputActiveTimingSupport: public PvmiClockExtensionInterface
{
public:
PVRefFileOutputActiveTimingSupport(uint32 limit)
: iLastTimestampValid(false)
, iDelay(0)
, iQueueLimit(limit)
, iClock(NULL)
, iLogger(NULL)
{}
virtual ~PVRefFileOutputActiveTimingSupport()
{}
//from PvmiClockExtensionInterface
OSCL_IMPORT_REF PVMFStatus SetClock(OsclClock *clockVal) ;
//from PVInterface
OSCL_IMPORT_REF void addRef() ;
OSCL_IMPORT_REF void removeRef() ;
OSCL_IMPORT_REF bool queryInterface(const PVUuid& uuid, PVInterface*& iface) ;
void queryUuid(PVUuid& uuid);
uint32 GetDelayMsec(PVMFTimestamp&);
void AdjustClock(PVMFTimestamp& aTs);
PVMFTimestamp iLastTimestamp;
bool iLastTimestampValid;
uint32 iDelay;
uint32 iQueueLimit;
OsclClock* iClock;
PVLogger* iLogger;
//query for whether playback clock is in frame-step mode.
bool FrameStepMode();
};
// This class implements the reference media IO for file output.
// This class constitutes the Media IO component
class PVRefFileOutput : public OsclTimerObject
, public PvmiMIOControl
, public PvmiMediaTransfer
, public PvmiCapabilityAndConfig
{
public:
OSCL_IMPORT_REF PVRefFileOutput(const oscl_wchar* aFileName,
bool aActiveTiming = false);
OSCL_IMPORT_REF PVRefFileOutput(const OSCL_wString& aFileName, bool logStrings = false);
// Expanded constructor with test features.
OSCL_IMPORT_REF PVRefFileOutput(const OSCL_wString& aFileName
, PVRefFileOutputTestObserver*aObserver
, bool aActiveTiming, uint32 aQueueLimit
, bool aSimFlowControl
, bool logStrings = true);
~PVRefFileOutput();
// 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);
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, 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);
void setFormatMask(uint32 mask);
void UpdateWaveChunkSize();
void WriteHeaders();
void InitializeAVI(int width, int height);
void AddChunk(uint8* chunk, uint32 size, uint32 ckid);
int32 yuv2rgb(uint8 * pBufRGBRev, uint8 * pBufYUV, int32 width, int32 height);
void UpdateVideoChunkHeaderIdx();
private:
void initData();
// 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, bool discard)
: iStatus(s), iCmdId(id), iContext(ctx), iTimestamp(ts), iDiscard(discard)
{}
PVMFStatus iStatus;
PVMFCommandId iCmdId;
const OsclAny* iContext;
PVMFTimestamp iTimestamp;
bool iDiscard;
};
Oscl_Vector<WriteResponse, OsclMemAllocator> iWriteResponseQueue;
// Output file parameters
OSCL_wHeapString<OsclMemAllocator> iOutputFileName;
Oscl_FileServer iFs;
bool iFsConnected;
Oscl_File iOutputFile;
bool iFileOpened;
// Audio parameters.
OSCL_HeapString<OsclMemAllocator> iAudioFormatString;
PVMFFormatType iAudioFormat;
int32 iAudioNumChannels;
bool iAudioNumChannelsValid;
int32 iAudioSamplingRate;
bool iAudioSamplingRateValid;
// Video parameters
OSCL_HeapString<OsclMemAllocator> iVideoFormatString;
PVMFFormatType iVideoFormat;
int32 iVideoHeight;
bool iVideoHeightValid;
int32 iVideoWidth;
bool iVideoWidthValid;
int32 iVideoDisplayHeight;
bool iVideoDisplayHeightValid;
int32 iVideoDisplayWidth;
bool iVideoDisplayWidthValid;
// Text parameters
OSCL_HeapString<OsclMemAllocator> iTextFormatString;
PVMFFormatType iTextFormat;
//For logging
PVLogger* iLogger;
//A switch for selecting whether to log some strings along
//with the media data in the output file.
bool iLogStrings;
bool iParametersLogged;
void LogParameters();
void LogFrame(uint32 aSeqNum, const PVMFTimestamp& aTimestamp, uint32);
void LogEndOfStream(uint32 aSeqNum, const PVMFTimestamp& aTimestamp);
void LogCodecHeader(uint32 aSeqNum, const PVMFTimestamp& aTimestamp, uint32);
//For implementing the write flow control
bool iWriteBusy;
uint32 iWriteBusySeqNum;
bool CheckWriteBusy(uint32);
//a test feature for testing flow control in the peer.
bool iSimFlowControl;
//a test observer class
PVRefFileOutputTestObserver* iTestObserver;
//a test feature for simulating active timing.
PVRefFileOutputActiveTimingSupport* iActiveTiming;
//a test feature to allow the commands such as GetCapability
//to return a distinctive format type
uint32 iFormatMask;
//called when re-config notification is recvd
PVMFStatus HandleReConfig(uint32 aReconfigSeqNum);
//if iUseClockExtension set to true, no data is dropped
bool iUseClockExtension;
// used to create the WAV file output.
RIFFChunk iRIFFChunk;
fmtSubchunk iFmtSubchunk;
dataSubchunk iDataSubchunk;
bool iHeaderWritten;
uint32 iAudioFormatType;
uint32 iVideoFormatType;
PVMFTimestamp iVideoLastTimeStamp;
bool iInitializeAVIDone;
AVIMainHeader iAVIMainHeader;
AVIStreamHeader iAVIStreamHeader;
BitMapInfoHeader bi_hdr;
AVIIndex iAVIIndex;
uint32 iAVIChunkSize;
uint32 iVideoHeaderPosition;
IndexBuffer iIndexBuffer;
uint32 iAVIMainHeaderPosition;
uint32 iAVIStreamHeaderPosition;
uint32 iVideoCount;
uint32 iPreviousOffset;
};
//An observer class for test support.
class PVRefFileOutputTestObserver
{
public:
virtual ~PVRefFileOutputTestObserver() {}
OSCL_IMPORT_REF virtual void Pos(PVMFTimestamp& aTimestamp) = 0;
};
#endif // PVMI_MEDIA_IO_FILEOUTPUT_H_INCLUDED