1 /* 2 ** 3 ** Copyright 2008, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef ANDROID_AUDIO_MIO_H 19 #define ANDROID_AUDIO_MIO_H 20 21 #ifndef PVMI_MIO_CONTROL_H_INCLUDED 22 #include "pvmi_mio_control.h" 23 #endif 24 #ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED 25 #include "pvmi_media_transfer.h" 26 #endif 27 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED 28 #include "oscl_scheduler_ao.h" 29 #endif 30 #ifndef PVMI_MEDIA_IO_OBSERVER_H_INCLUDED 31 #include "pvmi_media_io_observer.h" 32 #endif 33 #ifndef OSCL_FILE_IO_H_INCLUDED 34 #include "oscl_file_io.h" 35 #endif 36 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED 37 #include "pvmi_config_and_capability.h" 38 #endif 39 #ifndef OSCL_STRING_CONTAINERS_H_INCLUDED 40 #include "oscl_string_containers.h" 41 #endif 42 #ifndef PVMI_MEDIA_IO_CLOCK_EXTENSION_H_INCLUDED 43 #include "pvmi_media_io_clock_extension.h" 44 #endif 45 46 #ifndef ANDROID_AUDIO_OUTPUT_THREADSAFE_CALLBACK_AO_H_INCLUDED 47 #include "android_audio_output_threadsafe_callbacks.h" 48 #endif 49 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED 50 #include "pvmf_media_clock.h" 51 #endif 52 #ifdef PERFORMANCE_MEASUREMENTS_ENABLED 53 #ifndef _PVPROFILE_H 54 #include "pvprofile.h" 55 #endif 56 #endif 57 58 #include <media/MediaPlayerInterface.h> 59 60 class PVLogger; 61 class PVMFMediaClock; 62 63 using namespace android; 64 65 // Write command handling 66 // the audio output thread queues the responses, this mio dequeues and processes them 67 class WriteResponse 68 { 69 public: WriteResponse(PVMFStatus s,PVMFCommandId id,const OsclAny * ctx,const PVMFTimestamp & ts)70 WriteResponse(PVMFStatus s, PVMFCommandId id, const OsclAny* ctx, const PVMFTimestamp& ts) : 71 iStatus(s), iCmdId(id), iContext(ctx), iTimestamp(ts) 72 {} 73 74 PVMFStatus iStatus; 75 PVMFCommandId iCmdId; 76 const OsclAny* iContext; 77 PVMFTimestamp iTimestamp; 78 }; 79 80 // Active timing support 81 class AndroidAudioMIOActiveTimingSupport : 82 public PvmiClockExtensionInterface, public PVMFMediaClockStateObserver 83 { 84 public: 85 86 AndroidAudioMIOActiveTimingSupport(int32 minCorrection=0, int32 maxCorrection=0) : iClock(NULL)87 iClock(NULL), 88 iClockNotificationsInf(NULL), 89 iClockState(PVMFMediaClock::STOPPED), 90 iAudioThreadSem(0), 91 iStartTime(0), 92 iFrameCount(0), 93 iMsecsPerFrame(25), 94 iDriverLatency(0), 95 iUpdateClock(true), 96 iMinCorrection(minCorrection), 97 iMaxCorrection(maxCorrection) 98 { 99 } 100 ~AndroidAudioMIOActiveTimingSupport()101 ~AndroidAudioMIOActiveTimingSupport() 102 { 103 if (iClock && iClockNotificationsInf) 104 { 105 iClockNotificationsInf->RemoveClockStateObserver(*this); 106 iClock->DestroyMediaClockNotificationsInterface(iClockNotificationsInf); 107 iClockNotificationsInf = NULL; 108 } 109 } 110 111 //from PvmiClockExtensionInterface 112 OSCL_IMPORT_REF PVMFStatus SetClock(PVMFMediaClock* clockVal); 113 114 // from PVMFMediaClockStateObserver 115 void ClockStateUpdated(); 116 117 //from PVInterface addRef()118 OSCL_IMPORT_REF void addRef() {} removeRef()119 OSCL_IMPORT_REF void removeRef() {} 120 OSCL_IMPORT_REF bool queryInterface(const PVUuid& uuid, PVInterface*& iface); 121 void NotificationsInterfaceDestroyed(); 122 123 void queryUuid(PVUuid& uuid); 124 ForceClockUpdate()125 void ForceClockUpdate() { iUpdateClock = true; } 126 void UpdateClock(); 127 clockState()128 PVMFMediaClock::PVMFMediaClockState clockState() { return iClockState; } setThreadSemaphore(OsclSemaphore * s)129 void setThreadSemaphore(OsclSemaphore* s) { iAudioThreadSem = s; } 130 131 void setDriverLatency(uint32 latency); incFrameCount(uint32_t numFrames)132 void incFrameCount(uint32_t numFrames) { iFrameCount += numFrames; } setFrameRate(float msecsPerFrame)133 void setFrameRate(float msecsPerFrame) { iMsecsPerFrame = msecsPerFrame; } msecsPerFrame()134 float msecsPerFrame() { return iMsecsPerFrame; } 135 136 private: 137 PVMFMediaClock* iClock; 138 PVMFMediaClockNotificationsInterface *iClockNotificationsInf; 139 PVMFMediaClock::PVMFMediaClockState iClockState; 140 OsclSemaphore* iAudioThreadSem; 141 142 uint32 iStartTime; 143 uint32 iFrameCount; 144 float iMsecsPerFrame; 145 uint32 iDriverLatency; 146 bool iUpdateClock; 147 int32 iMinCorrection; 148 int32 iMaxCorrection; 149 }; 150 151 // Audio MIO component 152 class AndroidAudioMIO : public OsclTimerObject, 153 public PvmiMIOControl, 154 public PvmiMediaTransfer, 155 public PvmiCapabilityAndConfig 156 { 157 public: 158 OSCL_IMPORT_REF AndroidAudioMIO(const char* name); 159 160 OSCL_IMPORT_REF ~AndroidAudioMIO(); 161 162 // APIs from PvmiMIOControl 163 164 PVMFStatus connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver); 165 166 PVMFStatus disconnect(PvmiMIOSession aSession); 167 168 virtual PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType, 169 Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, 170 bool aExactUuidsOnly=false, const OsclAny* aContext=NULL); 171 172 virtual PVMFCommandId QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext=NULL); 173 174 PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession, PvmiKvp* read_formats=NULL, int32 read_flags=0, 175 PvmiKvp* write_formats=NULL, int32 write_flags=0); 176 deleteMediaTransfer(PvmiMIOSession & aSession,PvmiMediaTransfer * media_transfer)177 void deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer) {} 178 179 PVMFCommandId Init(const OsclAny* aContext=NULL); 180 181 PVMFCommandId Reset(const OsclAny* aContext=NULL); 182 183 PVMFCommandId Start(const OsclAny* aContext=NULL); 184 185 PVMFCommandId Pause(const OsclAny* aContext=NULL); 186 187 PVMFCommandId Flush(const OsclAny* aContext=NULL); 188 189 virtual PVMFCommandId DiscardData(const OsclAny* aContext=NULL); 190 191 virtual PVMFCommandId DiscardData(PVMFTimestamp aTimestamp=0, const OsclAny* aContext=NULL); 192 193 virtual PVMFCommandId Stop(const OsclAny* aContext=NULL); 194 195 virtual PVMFCommandId CancelAllCommands(const OsclAny* aContext=NULL); 196 197 virtual PVMFCommandId CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext=NULL); 198 cancelCommand(PVMFCommandId aCmdId)199 virtual void cancelCommand(PVMFCommandId aCmdId) {} 200 201 void ThreadLogon(); 202 203 void ThreadLogoff(); 204 205 // APIs from PvmiMediaTransfer 206 207 void setPeer(PvmiMediaTransfer* aPeer); 208 209 void useMemoryAllocators(OsclMemAllocator* write_alloc=NULL) {} 210 211 PVMFCommandId writeAsync(uint8 format_type, int32 format_index, 212 uint8* data, uint32 data_len, 213 const PvmiMediaXferHeader& data_header_info, 214 OsclAny* aContext=NULL); 215 writeComplete(PVMFStatus aStatus,PVMFCommandId write_cmd_id,OsclAny * aContext)216 void writeComplete(PVMFStatus aStatus, PVMFCommandId write_cmd_id, OsclAny* aContext) {} 217 218 PVMFCommandId readAsync(uint8* data, uint32 max_data_len, OsclAny* aContext=NULL, 219 int32* formats=NULL, uint16 num_formats=0) { 220 OsclError::Leave(OsclErrNotSupported); 221 return -1; 222 } 223 readComplete(PVMFStatus aStatus,PVMFCommandId read_cmd_id,int32 format_index,const PvmiMediaXferHeader & data_header_info,OsclAny * aContext)224 void readComplete(PVMFStatus aStatus, PVMFCommandId read_cmd_id, int32 format_index, 225 const PvmiMediaXferHeader& data_header_info, OsclAny* aContext) {} 226 statusUpdate(uint32 status_flags)227 void statusUpdate(uint32 status_flags) {} 228 cancelAllCommands()229 virtual void cancelAllCommands() { returnAllBuffers(); } 230 231 // Pure virtuals from PvmiCapabilityAndConfig 232 setObserver(PvmiConfigAndCapabilityCmdObserver * aObserver)233 void setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver) { OSCL_UNUSED_ARG(aObserver); } 234 235 PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, 236 PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext); 237 238 PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 239 createContext(PvmiMIOSession aSession,PvmiCapabilityContext & aContext)240 void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext) { 241 OsclError::Leave(OsclErrNotSupported); 242 } 243 setContextParameters(PvmiMIOSession aSession,PvmiCapabilityContext & aContext,PvmiKvp * aParameters,int num_parameter_elements)244 void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, 245 PvmiKvp* aParameters, int num_parameter_elements) { 246 OsclError::Leave(OsclErrNotSupported); 247 } 248 DeleteContext(PvmiMIOSession aSession,PvmiCapabilityContext & aContext)249 void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext) { 250 OsclError::Leave(OsclErrNotSupported); 251 } 252 253 virtual void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, 254 int num_elements, PvmiKvp * & aRet_kvp); 255 256 PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, 257 int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context=NULL) { 258 OsclError::Leave(OsclErrNotSupported); 259 return -1; 260 } 261 getCapabilityMetric(PvmiMIOSession aSession)262 uint32 getCapabilityMetric (PvmiMIOSession aSession) { return 0; } 263 264 PVMFStatus verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 265 266 // Functions specific to this MIO 267 void setAudioSink(const sp<MediaPlayerInterface::AudioSink>& audioSink); 268 writeAudioBuffer(uint8 * aData,uint32 aDataLen,PVMFCommandId cmdId,OsclAny * aContext,PVMFTimestamp aTimestamp)269 virtual void writeAudioBuffer(uint8* aData, uint32 aDataLen, PVMFCommandId cmdId, 270 OsclAny* aContext, PVMFTimestamp aTimestamp) {} 271 272 protected: 273 // From OsclTimerObject 274 void Run(); 275 void sendResponse(PVMFCommandId cmdid, const OsclAny* context, PVMFTimestamp timestamp); 276 277 // Specific to this MIO 278 void initData(); 279 280 void Cleanup(); 281 returnAllBuffers()282 virtual void returnAllBuffers() {} 283 284 void ResetData(); 285 286 // request active object which the audio output thread uses to schedule this timer object to run 287 AndroidAudioOutputThreadSafeCallbackAO *iWriteCompleteAO; 288 289 // write response queue, needs to use lock mechanism to access 290 Oscl_Vector<WriteResponse,OsclMemAllocator> iWriteResponseQueue; 291 292 // lock used to access the write response queue 293 OsclMutex iWriteResponseQueueLock; 294 295 // From setPeer 296 PvmiMediaTransfer* iPeer; 297 298 // The PvmiMIOControl class observer. 299 PvmiMIOObserver* iObserver; 300 301 // for generating command IDs 302 uint32 iCommandCounter; 303 304 //State 305 enum PVAudioMIOState 306 { 307 STATE_MIO_IDLE 308 ,STATE_MIO_LOGGED_ON 309 ,STATE_MIO_INITIALIZED 310 ,STATE_MIO_STARTED 311 ,STATE_MIO_PAUSED 312 }; 313 PVAudioMIOState iState; 314 315 // Control command handling. 316 class CommandResponse 317 { 318 public: CommandResponse(PVMFStatus s,PVMFCommandId id,const OsclAny * ctx)319 CommandResponse(PVMFStatus s,PVMFCommandId id,const OsclAny* ctx) 320 :iStatus(s),iCmdId(id),iContext(ctx) 321 {} 322 323 PVMFStatus iStatus; 324 PVMFCommandId iCmdId; 325 const OsclAny* iContext; 326 }; 327 Oscl_Vector<CommandResponse,OsclMemAllocator> iCommandResponseQueue; 328 PVMFCommandId QueueCmdResponse(PVMFStatus status, const OsclAny* aContext); 329 void ProcessWriteResponseQueue(); 330 331 // Audio parameters. 332 PVMFFormatType iAudioFormat; 333 int32 iAudioNumChannels; 334 bool iAudioNumChannelsValid; 335 int32 iAudioSamplingRate; 336 bool iAudioSamplingRateValid; 337 338 bool iAudioThreadCreatedAndMIOConfigured; 339 340 // For logging 341 PVLogger* iLogger; 342 343 // For implementing the write flow control 344 bool iWriteBusy; 345 bool CheckWriteBusy(uint32); 346 347 bool iFlushPending; 348 uint32 iDataQueued; 349 350 sp<MediaPlayerInterface::AudioSink> mAudioSink; 351 }; 352 353 #endif // ANDROID_AUDIO_MIO_H 354 355