• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

hardware/intel/common/libva


Commit MetaInfo

修订版152b03e88d08dc50e3c18f9c2de1b4355397a159 (tree)
时间2010-04-01 15:43:58
作者Austin Yuan <shengquan.yuan@gmai...>
CommiterAustin Yuan

Log Message

Added MIO example based on vaPutSurface

Signed-off-by: Austin Yuan <shengquan.yuan@gmail.com>

更改概述

差异

--- /dev/null
+++ b/va/android/android_surface_output.cpp
@@ -0,0 +1,1091 @@
1+/* ------------------------------------------------------------------
2+ * Copyright (C) 2008 PacketVideo
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13+ * express or implied.
14+ * See the License for the specific language governing permissions
15+ * and limitations under the License.
16+ * -------------------------------------------------------------------
17+ */
18+
19+//#define LOG_NDEBUG 0
20+#define LOG_TAG "VideoMIO"
21+#include <utils/Log.h>
22+#include <ui/ISurface.h>
23+
24+#include "android_surface_output.h"
25+#include <media/PVPlayer.h>
26+
27+#include "pvlogger.h"
28+#include "pv_mime_string_utils.h"
29+#include "oscl_snprintf.h"
30+
31+#include "oscl_dll.h"
32+
33+#ifdef __cplusplus
34+extern "C" {
35+#endif
36+
37+#include <va/va.h>
38+#include <va/va_x11.h>
39+
40+#ifdef __cplusplus
41+} /* extern "C" */
42+#endif
43+
44+// Define entry point for this DLL
45+OSCL_DLL_ENTRY_POINT_DEFAULT()
46+
47+//The factory functions.
48+#include "oscl_mem.h"
49+
50+using namespace android;
51+
52+OSCL_EXPORT_REF AndroidSurfaceOutput::AndroidSurfaceOutput() :
53+ OsclTimerObject(OsclActiveObject::EPriorityNominal, "androidsurfaceoutput")
54+{
55+ initData();
56+
57+ iColorConverter = NULL;
58+ mInitialized = false;
59+ mPvPlayer = NULL;
60+ mEmulation = false;
61+ iEosReceived = false;
62+ mNumberOfFramesToHold = 2;
63+}
64+
65+status_t AndroidSurfaceOutput::set(PVPlayer* pvPlayer, const sp<ISurface>& surface, bool emulation)
66+{
67+ mPvPlayer = pvPlayer;
68+ mEmulation = emulation;
69+ setVideoSurface(surface);
70+ return NO_ERROR;
71+}
72+
73+status_t AndroidSurfaceOutput::setVideoSurface(const sp<ISurface>& surface)
74+{
75+ LOGV("setVideoSurface(%p)", surface.get());
76+ // unregister buffers for the old surface
77+ if (mSurface != NULL) {
78+ LOGV("unregisterBuffers from old surface");
79+ mSurface->unregisterBuffers();
80+ }
81+ mSurface = surface;
82+ // register buffers for the new surface
83+ if ((mSurface != NULL) && (mBufferHeap.heap != NULL)) {
84+ LOGV("registerBuffers from old surface");
85+ mSurface->registerBuffers(mBufferHeap);
86+ }
87+ return NO_ERROR;
88+}
89+
90+void AndroidSurfaceOutput::initData()
91+{
92+ iVideoHeight = iVideoWidth = iVideoDisplayHeight = iVideoDisplayWidth = 0;
93+ iVideoFormat=PVMF_MIME_FORMAT_UNKNOWN;
94+ resetVideoParameterFlags();
95+
96+ iCommandCounter=0;
97+ iLogger=NULL;
98+ iCommandResponseQueue.reserve(5);
99+ iWriteResponseQueue.reserve(5);
100+ iObserver=NULL;
101+ iLogger=NULL;
102+ iPeer=NULL;
103+ iState=STATE_IDLE;
104+ iIsMIOConfigured = false;
105+}
106+
107+void AndroidSurfaceOutput::ResetData()
108+ //reset all data from this session.
109+{
110+ Cleanup();
111+
112+ //reset all the received media parameters.
113+ iVideoFormatString="";
114+ iVideoFormat=PVMF_MIME_FORMAT_UNKNOWN;
115+ resetVideoParameterFlags();
116+ iIsMIOConfigured = false;
117+}
118+
119+void AndroidSurfaceOutput::resetVideoParameterFlags()
120+{
121+ iVideoParameterFlags = VIDEO_PARAMETERS_INVALID;
122+}
123+
124+bool AndroidSurfaceOutput::checkVideoParameterFlags()
125+{
126+ return (iVideoParameterFlags & VIDEO_PARAMETERS_MASK) == VIDEO_PARAMETERS_VALID;
127+}
128+
129+/*
130+ * process the write response queue by sending writeComplete to the peer
131+ * (nominally the decoder node).
132+ *
133+ * numFramesToHold is the number of frames to be held in the MIO. During
134+ * playback, we hold the last frame which is used by SurfaceFlinger
135+ * to composite the final output.
136+ */
137+void AndroidSurfaceOutput::processWriteResponseQueue(int numFramesToHold)
138+{
139+ LOGV("processWriteResponseQueue: queued = %d, numFramesToHold = %d",
140+ iWriteResponseQueue.size(), numFramesToHold);
141+ while (iWriteResponseQueue.size() > numFramesToHold) {
142+ if (iPeer) {
143+ iPeer->writeComplete(iWriteResponseQueue[0].iStatus,
144+ iWriteResponseQueue[0].iCmdId,
145+ (OsclAny*)iWriteResponseQueue[0].iContext);
146+ }
147+ iWriteResponseQueue.erase(&iWriteResponseQueue[0]);
148+ }
149+}
150+
151+void AndroidSurfaceOutput::Cleanup()
152+//cleanup all allocated memory and release resources.
153+{
154+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Cleanup() In"));
155+ while (!iCommandResponseQueue.empty())
156+ {
157+ if (iObserver)
158+ iObserver->RequestCompleted(PVMFCmdResp(iCommandResponseQueue[0].iCmdId, iCommandResponseQueue[0].iContext, iCommandResponseQueue[0].iStatus));
159+ iCommandResponseQueue.erase(&iCommandResponseQueue[0]);
160+ }
161+
162+ processWriteResponseQueue(0);
163+
164+ // We'll close frame buf and delete here for now.
165+ closeFrameBuf();
166+
167+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Cleanup() Out"));
168+ }
169+
170+OSCL_EXPORT_REF AndroidSurfaceOutput::~AndroidSurfaceOutput()
171+{
172+ Cleanup();
173+}
174+
175+
176+PVMFStatus AndroidSurfaceOutput::connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver)
177+{
178+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::connect() called"));
179+ // Each Session could have its own set of Configuration parameters
180+ //in an array of structures and the session ID could be an index to that array.
181+
182+ //currently supports only one session
183+ if (iObserver)
184+ return PVMFFailure;
185+
186+ iObserver=aObserver;
187+ return PVMFSuccess;
188+}
189+
190+
191+PVMFStatus AndroidSurfaceOutput::disconnect(PvmiMIOSession aSession)
192+{
193+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::disconnect() called"));
194+ //currently supports only one session
195+ iObserver=NULL;
196+ return PVMFSuccess;
197+}
198+
199+
200+PvmiMediaTransfer* AndroidSurfaceOutput::createMediaTransfer(PvmiMIOSession& aSession,
201+ PvmiKvp* read_formats, int32 read_flags,
202+ PvmiKvp* write_formats, int32 write_flags)
203+{
204+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::createMediaTransfer() called"));
205+ return (PvmiMediaTransfer*)this;
206+}
207+
208+void AndroidSurfaceOutput::QueueCommandResponse(CommandResponse& aResp)
209+{
210+ //queue a command response and schedule processing.
211+
212+ iCommandResponseQueue.push_back(aResp);
213+
214+ //cancel any timer delay so the command response will happen ASAP.
215+ if (IsBusy())
216+ Cancel();
217+
218+ RunIfNotReady();
219+}
220+
221+PVMFCommandId AndroidSurfaceOutput::QueryUUID(const PvmfMimeString& aMimeType,
222+ Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
223+ bool aExactUuidsOnly, const OsclAny* aContext)
224+{
225+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::QueryUUID() called"));
226+
227+ OSCL_UNUSED_ARG(aMimeType);
228+ OSCL_UNUSED_ARG(aExactUuidsOnly);
229+
230+ PVMFCommandId cmdid=iCommandCounter++;
231+
232+ PVMFStatus status=PVMFFailure;
233+ int32 err ;
234+ OSCL_TRY(err, aUuids.push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID););
235+ if (err==OsclErrNone)
236+ status= PVMFSuccess;
237+
238+ CommandResponse resp(status,cmdid,aContext);
239+ QueueCommandResponse(resp);
240+ return cmdid;
241+}
242+
243+
244+PVMFCommandId AndroidSurfaceOutput::QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext)
245+{
246+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::QueryInterface() called"));
247+
248+ PVMFCommandId cmdid=iCommandCounter++;
249+
250+ PVMFStatus status=PVMFFailure;
251+ if(aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
252+ {
253+ PvmiCapabilityAndConfig* myInterface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*,this);
254+ aInterfacePtr = OSCL_STATIC_CAST(PVInterface*, myInterface);
255+ status= PVMFSuccess;
256+ }
257+ else
258+ {
259+ status=PVMFFailure;
260+ }
261+
262+ CommandResponse resp(status,cmdid,aContext);
263+ QueueCommandResponse(resp);
264+ return cmdid;
265+}
266+
267+
268+void AndroidSurfaceOutput::deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer)
269+{
270+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::deleteMediaTransfer() called"));
271+ // This class is implementing the media transfer, so no cleanup is needed
272+}
273+
274+
275+PVMFCommandId AndroidSurfaceOutput:: Init(const OsclAny* aContext)
276+{
277+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Init() called"));
278+
279+ PVMFCommandId cmdid=iCommandCounter++;
280+
281+ PVMFStatus status=PVMFFailure;
282+
283+ switch(iState)
284+ {
285+ case STATE_LOGGED_ON:
286+ status=PVMFSuccess;
287+ iState=STATE_INITIALIZED;
288+ break;
289+
290+ default:
291+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Invalid State"));
292+ status=PVMFErrInvalidState;
293+ break;
294+ }
295+
296+ CommandResponse resp(status,cmdid,aContext);
297+ QueueCommandResponse(resp);
298+ return cmdid;
299+}
300+
301+PVMFCommandId AndroidSurfaceOutput::Reset(const OsclAny* aContext)
302+{
303+ ResetData();
304+ PVMFCommandId cmdid=iCommandCounter++;
305+ CommandResponse resp(PVMFSuccess,cmdid,aContext);
306+ QueueCommandResponse(resp);
307+ return cmdid;
308+}
309+
310+
311+PVMFCommandId AndroidSurfaceOutput::Start(const OsclAny* aContext)
312+{
313+ iEosReceived = false;
314+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Start() called"));
315+
316+ PVMFCommandId cmdid=iCommandCounter++;
317+
318+ PVMFStatus status=PVMFFailure;
319+
320+ switch(iState)
321+ {
322+ case STATE_INITIALIZED:
323+ case STATE_PAUSED:
324+
325+ iState=STATE_STARTED;
326+ processWriteResponseQueue(0);
327+ status=PVMFSuccess;
328+ break;
329+
330+ default:
331+ status=PVMFErrInvalidState;
332+ break;
333+ }
334+
335+ CommandResponse resp(status,cmdid,aContext);
336+ QueueCommandResponse(resp);
337+ return cmdid;
338+}
339+
340+// post the last video frame to refresh screen after pause
341+void AndroidSurfaceOutput::postLastFrame()
342+{
343+ // ignore if no surface or heap
344+ if ((mSurface == NULL) || (mBufferHeap.heap == NULL)) return;
345+ mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
346+}
347+
348+PVMFCommandId AndroidSurfaceOutput::Pause(const OsclAny* aContext)
349+{
350+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Pause() called"));
351+
352+ PVMFCommandId cmdid=iCommandCounter++;
353+
354+ PVMFStatus status=PVMFFailure;
355+
356+ switch(iState)
357+ {
358+ case STATE_STARTED:
359+
360+ iState=STATE_PAUSED;
361+ status=PVMFSuccess;
362+
363+ // post last buffer to prevent stale data
364+ // if not configured, PVMFMIOConfigurationComplete is not sent
365+ // there should not be any media data.
366+ if(iIsMIOConfigured) {
367+ postLastFrame();
368+ }
369+ break;
370+
371+ default:
372+ status=PVMFErrInvalidState;
373+ break;
374+ }
375+
376+ CommandResponse resp(status,cmdid,aContext);
377+ QueueCommandResponse(resp);
378+ return cmdid;
379+}
380+
381+
382+PVMFCommandId AndroidSurfaceOutput::Flush(const OsclAny* aContext)
383+{
384+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Flush() called"));
385+
386+ PVMFCommandId cmdid=iCommandCounter++;
387+
388+ PVMFStatus status=PVMFFailure;
389+
390+ switch(iState)
391+ {
392+ case STATE_STARTED:
393+
394+ iState=STATE_INITIALIZED;
395+ status=PVMFSuccess;
396+ break;
397+
398+ default:
399+ status=PVMFErrInvalidState;
400+ break;
401+ }
402+
403+ CommandResponse resp(status,cmdid,aContext);
404+ QueueCommandResponse(resp);
405+ return cmdid;
406+}
407+
408+PVMFCommandId AndroidSurfaceOutput::DiscardData(const OsclAny* aContext)
409+{
410+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::DiscardData() called"));
411+
412+ PVMFCommandId cmdid=iCommandCounter++;
413+
414+ //this component doesn't buffer data, so there's nothing
415+ //needed here.
416+
417+ PVMFStatus status=PVMFSuccess;
418+ processWriteResponseQueue(0);
419+
420+ CommandResponse resp(status,cmdid,aContext);
421+ QueueCommandResponse(resp);
422+ return cmdid;
423+}
424+
425+PVMFCommandId AndroidSurfaceOutput::DiscardData(PVMFTimestamp aTimestamp, const OsclAny* aContext)
426+{
427+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::DiscardData() called"));
428+
429+ PVMFCommandId cmdid=iCommandCounter++;
430+
431+ aTimestamp = 0;
432+
433+ //this component doesn't buffer data, so there's nothing
434+ //needed here.
435+
436+ PVMFStatus status=PVMFSuccess;
437+ processWriteResponseQueue(0);
438+
439+ CommandResponse resp(status,cmdid,aContext);
440+ QueueCommandResponse(resp);
441+ return cmdid;
442+}
443+
444+PVMFCommandId AndroidSurfaceOutput::Stop(const OsclAny* aContext)
445+{
446+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::Stop() called"));
447+
448+ PVMFCommandId cmdid=iCommandCounter++;
449+
450+ PVMFStatus status=PVMFFailure;
451+
452+ switch(iState)
453+ {
454+ case STATE_STARTED:
455+ case STATE_PAUSED:
456+
457+#ifdef PERFORMANCE_MEASUREMENTS_ENABLED
458+ // FIXME: This should be moved to OMAP library
459+ PVOmapVideoProfile.MarkEndTime();
460+ PVOmapVideoProfile.PrintStats();
461+ PVOmapVideoProfile.Reset();
462+#endif
463+
464+ iState=STATE_INITIALIZED;
465+ status=PVMFSuccess;
466+ break;
467+
468+ default:
469+ status=PVMFErrInvalidState;
470+ break;
471+ }
472+
473+ CommandResponse resp(status,cmdid,aContext);
474+ QueueCommandResponse(resp);
475+ return cmdid;
476+}
477+
478+PVMFCommandId AndroidSurfaceOutput::CancelAllCommands(const OsclAny* aContext)
479+{
480+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::CancelAllCommands() called"));
481+
482+ PVMFCommandId cmdid=iCommandCounter++;
483+
484+ //commands are executed immediately upon being received, so
485+ //it isn't really possible to cancel them.
486+
487+ PVMFStatus status=PVMFSuccess;
488+
489+ CommandResponse resp(status,cmdid,aContext);
490+ QueueCommandResponse(resp);
491+ return cmdid;
492+}
493+
494+PVMFCommandId AndroidSurfaceOutput::CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext)
495+{
496+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::CancelCommand() called"));
497+
498+ PVMFCommandId cmdid=iCommandCounter++;
499+
500+ //commands are executed immediately upon being received, so
501+ //it isn't really possible to cancel them.
502+
503+ //see if the response is still queued.
504+ PVMFStatus status=PVMFFailure;
505+ for (uint32 i=0;i<iCommandResponseQueue.size();i++)
506+ {
507+ if (iCommandResponseQueue[i].iCmdId==aCmdId)
508+ {
509+ status=PVMFSuccess;
510+ break;
511+ }
512+ }
513+
514+ CommandResponse resp(status,cmdid,aContext);
515+ QueueCommandResponse(resp);
516+ return cmdid;
517+}
518+
519+void AndroidSurfaceOutput::ThreadLogon()
520+{
521+ if(iState==STATE_IDLE)
522+ {
523+ iLogger = PVLogger::GetLoggerObject("PVOmapVideo");
524+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::ThreadLogon() called"));
525+ AddToScheduler();
526+ iState=STATE_LOGGED_ON;
527+ }
528+}
529+
530+
531+void AndroidSurfaceOutput::ThreadLogoff()
532+{
533+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::ThreadLogoff() called"));
534+
535+ if(iState!=STATE_IDLE)
536+ {
537+ RemoveFromScheduler();
538+ iLogger=NULL;
539+ iState=STATE_IDLE;
540+ }
541+}
542+
543+
544+void AndroidSurfaceOutput::setPeer(PvmiMediaTransfer* aPeer)
545+{
546+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::setPeer() called"));
547+ // Set the observer
548+ iPeer = aPeer;
549+}
550+
551+
552+void AndroidSurfaceOutput::useMemoryAllocators(OsclMemAllocator* write_alloc)
553+{
554+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::useMemoryAllocators() called"));
555+ //not supported.
556+}
557+
558+// This routine will determine whether data can be accepted in a writeAsync
559+// call and if not, will return true;
560+bool AndroidSurfaceOutput::CheckWriteBusy(uint32 aSeqNum)
561+{
562+ // for all other cases, accept data now.
563+ return false;
564+}
565+
566+PVMFCommandId AndroidSurfaceOutput::writeAsync(uint8 aFormatType, int32 aFormatIndex, uint8* aData, uint32 aDataLen,
567+ const PvmiMediaXferHeader& data_header_info, OsclAny* aContext)
568+{
569+ // Do a leave if MIO is not configured except when it is an EOS
570+ if (!iIsMIOConfigured
571+ &&
572+ !((PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION == aFormatType)
573+ && (PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM == aFormatIndex)))
574+ {
575+ LOGE("data is pumped in before MIO is configured");
576+ OSCL_LEAVE(OsclErrInvalidState);
577+ return -1;
578+ }
579+
580+ uint32 aSeqNum=data_header_info.seq_num;
581+ PVMFTimestamp aTimestamp=data_header_info.timestamp;
582+ uint32 flags=data_header_info.flags;
583+
584+ if (aSeqNum < 6)
585+ {
586+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
587+ (0,"AndroidSurfaceOutput::writeAsync() seqnum %d ts %d context %d",aSeqNum,aTimestamp,aContext));
588+
589+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
590+ (0,"AndroidSurfaceOutput::writeAsync() Format Type %d Format Index %d length %d",aFormatType,aFormatIndex,aDataLen));
591+ }
592+
593+ PVMFStatus status=PVMFFailure;
594+
595+ switch(aFormatType)
596+ {
597+ case PVMI_MEDIAXFER_FMT_TYPE_COMMAND :
598+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
599+ (0,"AndroidSurfaceOutput::writeAsync() called with Command info."));
600+ //ignore
601+ status= PVMFSuccess;
602+ break;
603+
604+ case PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION :
605+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
606+ (0,"AndroidSurfaceOutput::writeAsync() called with Notification info."));
607+ switch(aFormatIndex)
608+ {
609+ case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM:
610+ iEosReceived = true;
611+ break;
612+ default:
613+ break;
614+ }
615+ //ignore
616+ status= PVMFSuccess;
617+ break;
618+
619+ case PVMI_MEDIAXFER_FMT_TYPE_DATA :
620+ switch(aFormatIndex)
621+ {
622+ case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
623+ //format-specific info contains codec headers.
624+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
625+ (0,"AndroidSurfaceOutput::writeAsync() called with format-specific info."));
626+
627+ if (iState<STATE_INITIALIZED)
628+ {
629+ PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
630+ (0,"AndroidSurfaceOutput::writeAsync: Error - Invalid state"));
631+ status=PVMFErrInvalidState;
632+ }
633+ else
634+ {
635+ status= PVMFSuccess;
636+ }
637+
638+ break;
639+
640+ case PVMI_MEDIAXFER_FMT_INDEX_DATA:
641+ //data contains the media bitstream.
642+
643+ //Verify the state
644+ if (iState!=STATE_STARTED)
645+ {
646+ PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
647+ (0,"AndroidSurfaceOutput::writeAsync: Error - Invalid state"));
648+ status=PVMFErrInvalidState;
649+ }
650+ else
651+ {
652+
653+ //printf("V WriteAsync { seq=%d, ts=%d }\n", data_header_info.seq_num, data_header_info.timestamp);
654+
655+ // Call playback to send data to IVA for Color Convert
656+ status = writeFrameBuf(aData, aDataLen, data_header_info);
657+
658+ PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
659+ (0,"AndroidSurfaceOutput::writeAsync: Playback Progress - frame %d",iFrameNumber++));
660+ }
661+ break;
662+
663+ default:
664+ PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
665+ (0,"AndroidSurfaceOutput::writeAsync: Error - unrecognized format index"));
666+ status= PVMFFailure;
667+ break;
668+ }
669+ break;
670+
671+ default:
672+ PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
673+ (0,"AndroidSurfaceOutput::writeAsync: Error - unrecognized format type"));
674+ status= PVMFFailure;
675+ break;
676+ }
677+
678+ //Schedule asynchronous response
679+ PVMFCommandId cmdid=iCommandCounter++;
680+ WriteResponse resp(status,cmdid,aContext,aTimestamp);
681+ iWriteResponseQueue.push_back(resp);
682+ RunIfNotReady();
683+
684+ return cmdid;
685+}
686+
687+void AndroidSurfaceOutput::writeComplete(PVMFStatus aStatus, PVMFCommandId write_cmd_id, OsclAny* aContext)
688+{
689+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::writeComplete() called"));
690+ //won't be called since this component is a sink.
691+}
692+
693+
694+PVMFCommandId AndroidSurfaceOutput::readAsync(uint8* data, uint32 max_data_len, OsclAny* aContext,
695+ int32* formats, uint16 num_formats)
696+{
697+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::readAsync() called"));
698+ //read not supported.
699+ OsclError::Leave(OsclErrNotSupported);
700+ return -1;
701+}
702+
703+
704+void AndroidSurfaceOutput::readComplete(PVMFStatus aStatus, PVMFCommandId read_cmd_id, int32 format_index,
705+ const PvmiMediaXferHeader& data_header_info, OsclAny* aContext)
706+{
707+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::readComplete() called"));
708+ //won't be called since this component is a sink.
709+}
710+
711+
712+void AndroidSurfaceOutput::statusUpdate(uint32 status_flags)
713+{
714+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::statusUpdate() called"));
715+ //won't be called since this component is a sink.
716+}
717+
718+
719+void AndroidSurfaceOutput::cancelCommand(PVMFCommandId command_id)
720+{
721+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::cancelCommand() called"));
722+
723+ //the purpose of this API is to cancel a writeAsync command and report
724+ //completion ASAP.
725+
726+ //in this implementation, the write commands are executed immediately
727+ //when received so it isn't really possible to cancel.
728+ //just report completion immediately.
729+ processWriteResponseQueue(0);
730+}
731+
732+void AndroidSurfaceOutput::cancelAllCommands()
733+{
734+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"AndroidSurfaceOutput::cancelAllCommands() called"));
735+
736+ //the purpose of this API is to cancel all writeAsync commands and report
737+ //completion ASAP.
738+
739+ //in this implementaiton, the write commands are executed immediately
740+ //when received so it isn't really possible to cancel.
741+ //just report completion immediately.
742+
743+ for (uint32 i=0;i<iWriteResponseQueue.size();i++)
744+ {
745+ //report completion
746+ if (iPeer)
747+ iPeer->writeComplete(iWriteResponseQueue[i].iStatus,iWriteResponseQueue[i].iCmdId,(OsclAny*)iWriteResponseQueue[i].iContext);
748+ iWriteResponseQueue.erase(&iWriteResponseQueue[i]);
749+ }
750+}
751+
752+void AndroidSurfaceOutput::setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver)
753+{
754+ OSCL_UNUSED_ARG(aObserver);
755+ //not needed since this component only supports synchronous capability & config
756+ //APIs.
757+}
758+
759+PVMFStatus AndroidSurfaceOutput::getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
760+ PvmiKvp*& aParameters, int& num_parameter_elements,
761+ PvmiCapabilityContext aContext)
762+{
763+ OSCL_UNUSED_ARG(aSession);
764+ OSCL_UNUSED_ARG(aContext);
765+ aParameters=NULL;
766+
767+ // This is a query for the list of supported formats.
768+ if(pv_mime_strcmp(aIdentifier, INPUT_FORMATS_CAP_QUERY) == 0)
769+ {
770+ aParameters=(PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
771+ if (aParameters == NULL) return PVMFErrNoMemory;
772+ aParameters[num_parameter_elements++].value.pChar_value=(char*) PVMF_MIME_YUV420;
773+
774+ return PVMFSuccess;
775+ }
776+
777+ //unrecognized key.
778+ return PVMFFailure;
779+}
780+
781+PVMFStatus AndroidSurfaceOutput::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
782+{
783+ //release parameters that were allocated by this component.
784+ if (aParameters)
785+ {
786+ oscl_free(aParameters);
787+ return PVMFSuccess;
788+ }
789+ return PVMFFailure;
790+}
791+
792+void AndroidSurfaceOutput ::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
793+{
794+ OsclError::Leave(OsclErrNotSupported);
795+}
796+
797+void AndroidSurfaceOutput::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext,
798+ PvmiKvp* aParameters, int num_parameter_elements)
799+{
800+ OsclError::Leave(OsclErrNotSupported);
801+}
802+
803+void AndroidSurfaceOutput::DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
804+{
805+ OsclError::Leave(OsclErrNotSupported);
806+}
807+
808+
809+void AndroidSurfaceOutput::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
810+ int num_elements, PvmiKvp * & aRet_kvp)
811+{
812+ OSCL_UNUSED_ARG(aSession);
813+
814+ aRet_kvp = NULL;
815+
816+ LOGV("setParametersSync");
817+ for (int32 i=0;i<num_elements;i++)
818+ {
819+ //Check against known video parameter keys...
820+ if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_FORMAT_KEY) == 0)
821+ {
822+ iVideoFormatString=aParameters[i].value.pChar_value;
823+ iVideoFormat=iVideoFormatString.get_str();
824+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
825+ (0,"AndroidSurfaceOutput::setParametersSync() Video Format Key, Value %s",iVideoFormatString.get_str()));
826+ }
827+ else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_WIDTH_KEY) == 0)
828+ {
829+ iVideoWidth=(int32)aParameters[i].value.uint32_value;
830+ iVideoParameterFlags |= VIDEO_WIDTH_VALID;
831+ LOGV("iVideoWidth=%d", iVideoWidth);
832+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
833+ (0,"AndroidSurfaceOutput::setParametersSync() Video Width Key, Value %d",iVideoWidth));
834+ }
835+ else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_HEIGHT_KEY) == 0)
836+ {
837+ iVideoHeight=(int32)aParameters[i].value.uint32_value;
838+ iVideoParameterFlags |= VIDEO_HEIGHT_VALID;
839+ LOGV("iVideoHeight=%d", iVideoHeight);
840+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
841+ (0,"AndroidSurfaceOutput::setParametersSync() Video Height Key, Value %d",iVideoHeight));
842+ }
843+ else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_DISPLAY_HEIGHT_KEY) == 0)
844+ {
845+ iVideoDisplayHeight=(int32)aParameters[i].value.uint32_value;
846+ iVideoParameterFlags |= DISPLAY_HEIGHT_VALID;
847+ LOGV("iVideoDisplayHeight=%d", iVideoDisplayHeight);
848+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
849+ (0,"AndroidSurfaceOutput::setParametersSync() Video Display Height Key, Value %d",iVideoDisplayHeight));
850+ }
851+ else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_DISPLAY_WIDTH_KEY) == 0)
852+ {
853+ iVideoDisplayWidth=(int32)aParameters[i].value.uint32_value;
854+ iVideoParameterFlags |= DISPLAY_WIDTH_VALID;
855+ LOGV("iVideoDisplayWidth=%d", iVideoDisplayWidth);
856+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
857+ (0,"AndroidSurfaceOutput::setParametersSync() Video Display Width Key, Value %d",iVideoDisplayWidth));
858+ }
859+ else if (pv_mime_strcmp(aParameters[i].key, MOUT_VIDEO_SUBFORMAT_KEY) == 0)
860+ {
861+ iVideoSubFormat=aParameters[i].value.pChar_value;
862+ iVideoParameterFlags |= VIDEO_SUBFORMAT_VALID;
863+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
864+ (0,"AndroidSurfaceOutput::setParametersSync() Video SubFormat Key, Value %s",iVideoSubFormat.getMIMEStrPtr()));
865+
866+LOGV("VIDEO SUBFORMAT SET TO %s\n",iVideoSubFormat.getMIMEStrPtr());
867+ }
868+ else
869+ {
870+ //if we get here the key is unrecognized.
871+
872+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
873+ (0,"AndroidSurfaceOutput::setParametersSync() Error, unrecognized key = %s", aParameters[i].key));
874+
875+ //set the return value to indicate the unrecognized key
876+ //and return.
877+ aRet_kvp = &aParameters[i];
878+ return;
879+ }
880+ }
881+ uint32 mycache = iVideoParameterFlags ;
882+ // if initialization is complete, update the app display info
883+ if( checkVideoParameterFlags() )
884+ initCheck();
885+ iVideoParameterFlags = mycache;
886+
887+ // when all necessary parameters are received, send
888+ // PVMFMIOConfigurationComplete event to observer
889+ if(!iIsMIOConfigured && checkVideoParameterFlags() )
890+ {
891+ iIsMIOConfigured = true;
892+ if(iObserver)
893+ {
894+ iObserver->ReportInfoEvent(PVMFMIOConfigurationComplete);
895+ }
896+ }
897+}
898+
899+PVMFCommandId AndroidSurfaceOutput::setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters,
900+ int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context)
901+{
902+ OsclError::Leave(OsclErrNotSupported);
903+ return -1;
904+}
905+
906+uint32 AndroidSurfaceOutput::getCapabilityMetric (PvmiMIOSession aSession)
907+{
908+ return 0;
909+}
910+
911+PVMFStatus AndroidSurfaceOutput::verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
912+{
913+ OSCL_UNUSED_ARG(aSession);
914+
915+ // Go through each parameter
916+ for (int32 i=0; i<num_elements; i++) {
917+ char* compstr = NULL;
918+ pv_mime_string_extract_type(0, aParameters[i].key, compstr);
919+ if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/media/format-type")) == 0) {
920+ if (pv_mime_strcmp(aParameters[i].value.pChar_value, PVMF_MIME_YUV420) == 0) {
921+ return PVMFSuccess;
922+ }
923+ else {
924+ return PVMFErrNotSupported;
925+ }
926+ }
927+ }
928+ return PVMFSuccess;
929+}
930+
931+//
932+// Private section
933+//
934+
935+void AndroidSurfaceOutput::Run()
936+{
937+ //send async command responses
938+ while (!iCommandResponseQueue.empty())
939+ {
940+ if (iObserver)
941+ iObserver->RequestCompleted(PVMFCmdResp(iCommandResponseQueue[0].iCmdId, iCommandResponseQueue[0].iContext, iCommandResponseQueue[0].iStatus));
942+ iCommandResponseQueue.erase(&iCommandResponseQueue[0]);
943+ }
944+
945+ //send async write completion
946+ if (iEosReceived) {
947+ LOGV("Flushing buffers after EOS");
948+ processWriteResponseQueue(0);
949+ } else {
950+ processWriteResponseQueue(1);
951+ }
952+}
953+
954+// create a frame buffer for software codecs
955+OSCL_EXPORT_REF bool AndroidSurfaceOutput::initCheck()
956+{
957+
958+ // initialize only when we have all the required parameters
959+ if (!checkVideoParameterFlags())
960+ return mInitialized;
961+
962+ // release resources if previously initialized
963+ closeFrameBuf();
964+
965+ // reset flags in case display format changes in the middle of a stream
966+ resetVideoParameterFlags();
967+
968+ // copy parameters in case we need to adjust them
969+ int displayWidth = iVideoDisplayWidth;
970+ int displayHeight = iVideoDisplayHeight;
971+ int frameWidth = iVideoWidth;
972+ int frameHeight = iVideoHeight;
973+ int frameSize;
974+
975+ // RGB-565 frames are 2 bytes/pixel
976+ displayWidth = (displayWidth + 1) & -2;
977+ displayHeight = (displayHeight + 1) & -2;
978+ frameWidth = (frameWidth + 1) & -2;
979+ frameHeight = (frameHeight + 1) & -2;
980+ frameSize = frameWidth * frameHeight * 2;
981+
982+ // create frame buffer heap and register with surfaceflinger
983+ sp<MemoryHeapBase> heap = new MemoryHeapBase(frameSize * kBufferCount);
984+ if (heap->heapID() < 0) {
985+ LOGE("Error creating frame buffer heap");
986+ return false;
987+ }
988+
989+ mBufferHeap = ISurface::BufferHeap(displayWidth, displayHeight,
990+ frameWidth, frameHeight, PIXEL_FORMAT_RGB_565, heap);
991+ mSurface->registerBuffers(mBufferHeap);
992+
993+ // create frame buffers
994+ for (int i = 0; i < kBufferCount; i++) {
995+ mFrameBuffers[i] = i * frameSize;
996+ }
997+
998+ // initialize software color converter
999+ iColorConverter = ColorConvert16::NewL();
1000+ iColorConverter->Init(displayWidth, displayHeight, frameWidth, displayWidth, displayHeight, displayWidth, CCROTATE_NONE);
1001+ iColorConverter->SetMemHeight(frameHeight);
1002+ iColorConverter->SetMode(1);
1003+
1004+ LOGV("video = %d x %d", displayWidth, displayHeight);
1005+ LOGV("frame = %d x %d", frameWidth, frameHeight);
1006+ LOGV("frame #bytes = %d", frameSize);
1007+
1008+ // register frame buffers with SurfaceFlinger
1009+ mFrameBufferIndex = 0;
1010+ mInitialized = true;
1011+ mPvPlayer->sendEvent(MEDIA_SET_VIDEO_SIZE, iVideoDisplayWidth, iVideoDisplayHeight);
1012+
1013+ return mInitialized;
1014+}
1015+
1016+OSCL_EXPORT_REF PVMFStatus AndroidSurfaceOutput::writeFrameBuf(uint8* aData, uint32 aDataLen, const PvmiMediaXferHeader& data_header_info)
1017+{
1018+ // post to SurfaceFlinger
1019+ if ((mSurface != NULL) && (mBufferHeap.heap != NULL)) {
1020+ if (++mFrameBufferIndex == kBufferCount) mFrameBufferIndex = 0;
1021+#if 0
1022+ {
1023+ uint32 *data_pointer = reinterpret_cast<uint32*>(aData);
1024+ LOGE("the surfaceid is %x, location %x..\n", *data_pointer, data_pointer);
1025+ LOGE("the vadisplay is %x, location %x \n", *(data_pointer + 1), data_pointer + 1);
1026+ }
1027+ iColorConverter->Convert(aData, static_cast<uint8*>(mBufferHeap.heap->base()) + mFrameBuffers[mFrameBufferIndex]);
1028+ mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
1029+#endif
1030+ uint32 *data_pointer = reinterpret_cast<uint32*>(aData);
1031+// VASurfaceID surface_id =
1032+// reinterpret_cast<VASurfaceID>(*(data_pointer + 1));
1033+ VASurfaceID surface_id = *(data_pointer);
1034+ VADisplay va_display = reinterpret_cast<VADisplay>(*(data_pointer + 1));
1035+ int data_len;
1036+
1037+ LOGE("the surfaceid is %x\n", surface_id);
1038+ LOGE("the vadisplay is %x\n", va_display);
1039+#if 0
1040+ vaPutSurface(va_display, surface_id, 0,
1041+ 0, 0, iVideoWidth, iVideoHeight,
1042+ 0, 0, iVideoDisplayWidth, iVideoDisplayHeight,
1043+ NULL, 0, 0);
1044+#else
1045+ vaPutSurfaceBuf(va_display, surface_id, 0,
1046+ static_cast<uint8*>(mBufferHeap.heap->base()) + mFrameBuffers[mFrameBufferIndex],
1047+ &data_len, 0, 0, iVideoWidth, iVideoHeight,
1048+ 0, 0, iVideoDisplayWidth, iVideoDisplayHeight,
1049+ NULL, 0, 0);
1050+ mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);
1051+#endif
1052+ }
1053+ return PVMFSuccess;
1054+}
1055+
1056+OSCL_EXPORT_REF void AndroidSurfaceOutput::closeFrameBuf()
1057+{
1058+ LOGV("closeFrameBuf");
1059+ if (!mInitialized) return;
1060+
1061+ mInitialized = false;
1062+ if (mSurface.get()) {
1063+ LOGV("unregisterBuffers");
1064+ mSurface->unregisterBuffers();
1065+ }
1066+
1067+ // free frame buffers
1068+ LOGV("free frame buffers");
1069+ for (int i = 0; i < kBufferCount; i++) {
1070+ mFrameBuffers[i] = 0;
1071+ }
1072+
1073+ // free heaps
1074+ LOGV("free frame heap");
1075+ mBufferHeap.heap.clear();
1076+
1077+ // free color converter
1078+ if (iColorConverter != 0)
1079+ {
1080+ LOGV("free color converter");
1081+ delete iColorConverter;
1082+ iColorConverter = 0;
1083+ }
1084+}
1085+
1086+OSCL_EXPORT_REF bool AndroidSurfaceOutput::GetVideoSize(int *w, int *h) {
1087+
1088+ *w = iVideoDisplayWidth;
1089+ *h = iVideoDisplayHeight;
1090+ return iVideoDisplayWidth != 0 && iVideoDisplayHeight != 0;
1091+}
--- /dev/null
+++ b/va/android/android_surface_output.h
@@ -0,0 +1,336 @@
1+/* ------------------------------------------------------------------
2+ * Copyright (C) 2008 PacketVideo
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13+ * express or implied.
14+ * See the License for the specific language governing permissions
15+ * and limitations under the License.
16+ * -------------------------------------------------------------------
17+ */
18+
19+#ifndef ANDROID_SURFACE_OUTPUT_H_INCLUDED
20+#define ANDROID_SURFACE_OUTPUT_H_INCLUDED
21+
22+#include "pvmi_mio_control.h"
23+#include "pvmi_media_transfer.h"
24+#include "oscl_scheduler_ao.h"
25+#include "pvmi_media_io_observer.h"
26+#include "oscl_file_io.h"
27+#include "pvmi_config_and_capability.h"
28+#include "oscl_string_containers.h"
29+#include "pvmi_media_io_clock_extension.h"
30+
31+#ifdef PERFORMANCE_MEASUREMENTS_ENABLED
32+#include "pvprofile.h"
33+#endif
34+
35+// FIXME: Move to OMAP library
36+// Linux and Kernel Includes for Frame Buffer
37+#include <fcntl.h>
38+#include <stdint.h>
39+#include <stdlib.h>
40+#include <stdio.h>
41+#include <string.h>
42+#include <unistd.h>
43+#include <sys/types.h>
44+#include <sys/stat.h>
45+#include <sys/ioctl.h>
46+#include <sys/time.h>
47+//#include <linux/fb.h>
48+//#include <linux/videodev.h>
49+
50+// SurfaceFlinger
51+#include <ui/ISurface.h>
52+
53+// interprocess shared memory support
54+#include <binder/MemoryBase.h>
55+#include <binder/MemoryHeapBase.h>
56+
57+// color converter
58+#include "cczoomrotation16.h"
59+
60+// define bits, mask and validity check for video parameters
61+#define VIDEO_PARAMETERS_INVALID 0
62+#define VIDEO_SUBFORMAT_VALID (1 << 0)
63+#define DISPLAY_HEIGHT_VALID (1 << 1)
64+#define DISPLAY_WIDTH_VALID (1 << 2)
65+#define VIDEO_HEIGHT_VALID (1 << 3)
66+#define VIDEO_WIDTH_VALID (1 << 4)
67+#define VIDEO_PARAMETERS_MASK (VIDEO_SUBFORMAT_VALID | DISPLAY_HEIGHT_VALID | \
68+ DISPLAY_WIDTH_VALID | VIDEO_HEIGHT_VALID | VIDEO_WIDTH_VALID)
69+#define VIDEO_PARAMETERS_VALID (VIDEO_SUBFORMAT_VALID | DISPLAY_HEIGHT_VALID | \
70+ DISPLAY_WIDTH_VALID | VIDEO_HEIGHT_VALID | VIDEO_WIDTH_VALID)
71+
72+namespace android {
73+ class PVPlayer;
74+}
75+
76+class PVLogger;
77+class PVMFMediaClock;
78+class AndroidSurfaceOutput;
79+
80+using namespace android;
81+
82+// FIXME: Not used?
83+// typedef void (*frame_decoded_f)(void *cookie, int width, int height, int pitch, int format, uint8* data);
84+
85+// This class implements the reference media IO for file output.
86+// This class constitutes the Media IO component
87+
88+class AndroidSurfaceOutput : public OsclTimerObject
89+ ,public PvmiMIOControl
90+ ,public PvmiMediaTransfer
91+ ,public PvmiCapabilityAndConfig
92+{
93+public:
94+ AndroidSurfaceOutput();
95+
96+ // parameter initialization
97+ virtual status_t set(android::PVPlayer* pvPlayer, const sp<ISurface>& surface, bool emulation);
98+ virtual status_t setVideoSurface(const sp<ISurface>& surface);
99+
100+ // For frame buffer
101+ virtual bool initCheck();
102+ virtual PVMFStatus writeFrameBuf(uint8* aData, uint32 aDataLen, const PvmiMediaXferHeader& data_header_info);
103+ virtual void postLastFrame();
104+ virtual void closeFrameBuf();
105+
106+ virtual ~AndroidSurfaceOutput();
107+
108+ bool GetVideoSize(int *w, int *h);
109+
110+ // APIs from PvmiMIOControl
111+
112+ PVMFStatus connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver);
113+
114+ PVMFStatus disconnect(PvmiMIOSession aSession);
115+
116+ PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
117+ bool aExactUuidsOnly=false, const OsclAny* aContext=NULL);
118+
119+ PVMFCommandId QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext=NULL);
120+
121+ PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession, PvmiKvp* read_formats=NULL, int32 read_flags=0,
122+ PvmiKvp* write_formats=NULL, int32 write_flags=0);
123+
124+ void deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer);
125+
126+ void processWriteResponseQueue(int numFramesToHold);
127+
128+ PVMFCommandId Init(const OsclAny* aContext=NULL);
129+
130+ PVMFCommandId Reset(const OsclAny* aContext=NULL);
131+
132+ PVMFCommandId Start(const OsclAny* aContext=NULL);
133+
134+ PVMFCommandId Pause(const OsclAny* aContext=NULL);
135+
136+ PVMFCommandId Flush(const OsclAny* aContext=NULL);
137+
138+ PVMFCommandId DiscardData(const OsclAny* aContext=NULL);
139+
140+ PVMFCommandId DiscardData( PVMFTimestamp aTimestamp=0, const OsclAny* aContext=NULL);
141+
142+ PVMFCommandId Stop(const OsclAny* aContext=NULL);
143+
144+ PVMFCommandId CancelAllCommands(const OsclAny* aContext=NULL);
145+
146+ PVMFCommandId CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext=NULL);
147+
148+ void ThreadLogon();
149+
150+ void ThreadLogoff();
151+
152+ // APIs from PvmiMediaTransfer
153+
154+ void setPeer(PvmiMediaTransfer* aPeer);
155+
156+ void useMemoryAllocators(OsclMemAllocator* write_alloc=NULL);
157+
158+ PVMFCommandId writeAsync(uint8 format_type, int32 format_index,
159+ uint8* data, uint32 data_len,
160+ const PvmiMediaXferHeader& data_header_info,
161+ OsclAny* aContext=NULL);
162+
163+ void writeComplete(PVMFStatus aStatus,
164+ PVMFCommandId write_cmd_id,
165+ OsclAny* aContext);
166+
167+ PVMFCommandId readAsync(uint8* data, uint32 max_data_len,
168+ OsclAny* aContext=NULL,
169+ int32* formats=NULL, uint16 num_formats=0);
170+
171+ void readComplete(PVMFStatus aStatus, PVMFCommandId read_cmd_id, int32 format_index,
172+ const PvmiMediaXferHeader& data_header_info, OsclAny* aContext);
173+
174+ void statusUpdate(uint32 status_flags);
175+
176+ void cancelCommand(PVMFCommandId command_id);
177+
178+ void cancelAllCommands();
179+
180+ // Pure virtuals from PvmiCapabilityAndConfig
181+
182+ void setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver);
183+
184+ PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
185+ PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext);
186+
187+ PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
188+
189+ void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
190+
191+ void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext,
192+ PvmiKvp* aParameters, int num_parameter_elements);
193+
194+ void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
195+
196+ void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
197+ int num_elements, PvmiKvp * & aRet_kvp);
198+
199+ PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters,
200+ int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context=NULL);
201+
202+ uint32 getCapabilityMetric (PvmiMIOSession aSession);
203+
204+ PVMFStatus verifyParametersSync (PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
205+
206+
207+protected:
208+ void initData();
209+ void resetVideoParameterFlags();
210+ bool checkVideoParameterFlags();
211+
212+ // From OsclTimerObject
213+ void Run();
214+
215+ void Reschedule();
216+
217+ void Cleanup();
218+ void ResetData();
219+
220+ PvmiMediaTransfer* iPeer;
221+
222+ // The PvmiMIOControl class observer.
223+ PvmiMIOObserver* iObserver;
224+
225+ //for generating command IDs
226+ uint32 iCommandCounter;
227+
228+ //State
229+ enum PVRefFOState
230+ {
231+ STATE_IDLE,
232+ STATE_LOGGED_ON,
233+ STATE_INITIALIZED,
234+ STATE_STARTED,
235+ STATE_PAUSED
236+ };
237+ PVRefFOState iState;
238+
239+ //Control command handling.
240+ class CommandResponse
241+ {
242+ public:
243+ CommandResponse(PVMFStatus s,PVMFCommandId id,const OsclAny* ctx)
244+ :iStatus(s),iCmdId(id),iContext(ctx)
245+ {}
246+
247+ PVMFStatus iStatus;
248+ PVMFCommandId iCmdId;
249+ const OsclAny* iContext;
250+ };
251+ Oscl_Vector<CommandResponse,OsclMemAllocator> iCommandResponseQueue;
252+ void QueueCommandResponse(CommandResponse&);
253+
254+ //Write command handling
255+ class WriteResponse
256+ {
257+ public:
258+ WriteResponse(PVMFStatus s,PVMFCommandId id,const OsclAny* ctx,const PVMFTimestamp& ts)
259+ :iStatus(s),iCmdId(id),iContext(ctx),iTimestamp(ts)
260+ {}
261+
262+ PVMFStatus iStatus;
263+ PVMFCommandId iCmdId;
264+ const OsclAny* iContext;
265+ PVMFTimestamp iTimestamp;
266+ };
267+ Oscl_Vector<WriteResponse,OsclMemAllocator> iWriteResponseQueue;
268+
269+ // Output file parameters
270+ OSCL_wHeapString<OsclMemAllocator> iOutputFileName;
271+ Oscl_FileServer iFs;
272+ bool iFsConnected;
273+ Oscl_File iOutputFile;
274+ bool iFileOpened;
275+
276+ bool iEosReceived;
277+
278+ // Video parameters
279+ uint32 iVideoParameterFlags;
280+ OSCL_HeapString<OsclMemAllocator> iVideoFormatString;
281+ PVMFFormatType iVideoFormat;
282+ int32 iVideoHeight;
283+ int32 iVideoWidth;
284+ int32 iVideoDisplayHeight;
285+ int32 iVideoDisplayWidth;
286+
287+ // hardware specific
288+ PVMFFormatType iVideoSubFormat;
289+ bool iVideoSubFormatValid;
290+
291+ //For logging
292+ PVLogger* iLogger;
293+
294+ //For implementing the write flow control
295+ bool CheckWriteBusy(uint32);
296+
297+ unsigned long iFrameNumber;
298+
299+ // software color conversion for software codecs
300+ ColorConvertBase* iColorConverter;
301+
302+ android::PVPlayer* mPvPlayer;
303+ bool mInitialized;
304+ bool mEmulation;
305+ sp<ISurface> mSurface;
306+
307+ // frame buffer support
308+ static const int kBufferCount = 2;
309+ int mFrameBufferIndex;
310+ ISurface::BufferHeap mBufferHeap;
311+ size_t mFrameBuffers[kBufferCount];
312+
313+ void convertFrame(void* src, void* dst, size_t len);
314+ //This bool is set true when all necassary parameters have been received.
315+ bool iIsMIOConfigured;
316+
317+ /*
318+ * The value of mNumberOfFramesToHold is hardware/platform specific.
319+ * 1. On non-overlay based platforms, its value it set to 2
320+ * so as to avoid potential tearings oberved during video playback.
321+ * 2. On overlay-based platforms, its value should be overwritten.
322+ * We have observed video decoder starvation when a value other than 1.
323+ *
324+ * We set the default value to 2 in this class. Please change its value
325+ * accordingly in the derived class.
326+ */
327+ int mNumberOfFramesToHold;
328+
329+#ifdef PERFORMANCE_MEASUREMENTS_ENABLED
330+ PVProfile PVOmapVideoProfile;
331+#endif
332+
333+};
334+
335+#endif // ANDROID_SURFACE_OUTPUT_H_INCLUDED
336+