Bug 3329759 Implement streamInformation and volume in OpenMAX AL
- Implement StreamInformation for video size notification.
- Implement the XAVolumeItf for volume control
- Fix bug in GUID -> MPH hash.
- Fixed typo in GenericPlayer::pause() log
- Do not signal a discontinuity automatically when the ABQ is
cleared because clearing the queue doesn't imply there will
be a discontinuity in the data (e.g. the same data that was
cleared could be reenqueued)
- In "native-media" test app: add test code to exercise the
XAVolumeItf functionality.
Change-Id: I9f69f8cacbdce51b6d96d60141ec1d0f645df991
diff --git a/src/itf/IAndroidBufferQueue.c b/src/itf/IAndroidBufferQueue.c
index bea4701..fa4c7e9 100644
--- a/src/itf/IAndroidBufferQueue.c
+++ b/src/itf/IAndroidBufferQueue.c
@@ -158,6 +158,7 @@
thiz->mBufferArray[i].mDataBuffer = NULL;
thiz->mBufferArray[i].mDataSize = 0;
thiz->mBufferArray[i].mDataSizeConsumed = 0;
+ thiz->mBufferArray[i].mBufferContext = NULL;
switch (thiz->mBufferType) {
case kAndroidBufferTypeMpeg2Ts:
thiz->mBufferArray[i].mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
@@ -191,7 +192,8 @@
SLresult IAndroidBufferQueue_Enqueue(SLAndroidBufferQueueItf self,
- const void *pData,
+ void *pBufferContext,
+ void *pData,
SLuint32 dataLength,
const SLAndroidBufferItem *pItems,
SLuint32 itemsLength)
@@ -233,6 +235,7 @@
oldRear->mDataBuffer = pData;
oldRear->mDataSize = dataLength;
oldRear->mDataSizeConsumed = 0;
+ oldRear->mBufferContext = pBufferContext;
thiz->mRear = newRear;
++thiz->mState.count;
setItems(pItems, itemsLength, thiz->mBufferType, oldRear);
diff --git a/src/itf/IEngine.c b/src/itf/IEngine.c
index 648767c..7d07c02 100644
--- a/src/itf/IEngine.c
+++ b/src/itf/IEngine.c
@@ -311,6 +311,7 @@
thiz->mAndroidBufferQueue.mBufferArray[i].mDataBuffer = NULL;
thiz->mAndroidBufferQueue.mBufferArray[i].mDataSize = 0;
thiz->mAndroidBufferQueue.mBufferArray[i].mDataSizeConsumed = 0;
+ thiz->mAndroidBufferQueue.mBufferArray[i].mBufferContext = NULL;
switch (thiz->mAndroidBufferQueue.mBufferType) {
case kAndroidBufferTypeMpeg2Ts:
thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData.
@@ -1156,6 +1157,17 @@
if (XA_CONTAINERTYPE_MPEG_TS ==
thiz->mDataSource.mFormat.mMIME.containerType) {
thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
+
+ // Set the container type for the StreamInformation interface
+ XAMediaContainerInformation *containerInfo =
+ (XAMediaContainerInformation*)
+ // always storing container info at index 0, as per spec
+ &(thiz->mStreamInfo.mStreamInfoTable.itemAt(0).
+ containerInfo);
+ containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS;
+ // there are no streams at this stage
+ containerInfo->numStreams = 0;
+
} else {
thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
SL_LOGE("Invalid buffer type in Android Buffer Queue");
@@ -1173,6 +1185,7 @@
thiz->mAndroidBufferQueue.mBufferArray[i].mDataBuffer = NULL;
thiz->mAndroidBufferQueue.mBufferArray[i].mDataSize = 0;
thiz->mAndroidBufferQueue.mBufferArray[i].mDataSizeConsumed = 0;
+ thiz->mAndroidBufferQueue.mBufferArray[i].mBufferContext = NULL;
switch (thiz->mAndroidBufferQueue.mBufferType) {
case kAndroidBufferTypeMpeg2Ts:
thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData.
diff --git a/src/itf/IStreamInformation.c b/src/itf/IStreamInformation.c
index a983caa..0769784 100644
--- a/src/itf/IStreamInformation.c
+++ b/src/itf/IStreamInformation.c
@@ -26,6 +26,7 @@
#ifdef ANDROID
IStreamInformation *thiz = (IStreamInformation *) self;
interface_lock_exclusive(thiz);
+ // always storing container info at index 0, as per spec
info = (XAMediaContainerInformation*)&(thiz->mStreamInfoTable.itemAt(0).containerInfo);
interface_unlock_exclusive(thiz);
// even though the pointer to the media container info is returned, the values aren't set
@@ -63,6 +64,7 @@
IStreamInformation *thiz = (IStreamInformation *) self;
interface_lock_exclusive(thiz);
+
XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
// streams in the container are numbered 1..nbStreams
if (streamIndex <= nbStreams) {
@@ -73,6 +75,7 @@
streamIndex, nbStreams);
result = XA_RESULT_PARAMETER_INVALID;
}
+
interface_unlock_exclusive(thiz);
}
#endif
@@ -87,8 +90,62 @@
{
XA_ENTER_INTERFACE
- SL_LOGE("unsupported XAStreamInformationItf function");
- result = XA_RESULT_CONTENT_UNSUPPORTED;
+ if (NULL == info) {
+ result = XA_RESULT_PARAMETER_INVALID;
+ } else {
+
+#ifndef ANDROID
+ result = XA_RESULT_FEATURE_UNSUPPORTED;
+#else
+
+ IStreamInformation *thiz = (IStreamInformation *) self;
+
+ interface_lock_exclusive(thiz);
+
+ XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
+ // streams in the container are numbered 1..nbStreams
+ if (streamIndex <= nbStreams) {
+ result = XA_RESULT_SUCCESS;
+ const StreamInfo& streamInfo = thiz->mStreamInfoTable.itemAt((size_t)streamIndex);
+
+ switch (streamInfo.domain) {
+ case XA_DOMAINTYPE_CONTAINER:
+ *(XAMediaContainerInformation *)info = streamInfo.containerInfo;
+ break;
+ case XA_DOMAINTYPE_AUDIO:
+ *(XAAudioStreamInformation *)info = streamInfo.audioInfo;
+ break;
+ case XA_DOMAINTYPE_VIDEO:
+ *(XAVideoStreamInformation *)info = streamInfo.videoInfo;
+ break;
+ case XA_DOMAINTYPE_IMAGE:
+ *(XAImageStreamInformation *)info = streamInfo.imageInfo;
+ break;
+ case XA_DOMAINTYPE_TIMEDTEXT:
+ *(XATimedTextStreamInformation *)info = streamInfo.textInfo;
+ break;
+ case XA_DOMAINTYPE_MIDI:
+ *(XAMIDIStreamInformation *)info = streamInfo.midiInfo;
+ break;
+ case XA_DOMAINTYPE_VENDOR:
+ *(XAVendorStreamInformation *)info = streamInfo.vendorInfo;
+ break;
+ default:
+ SL_LOGE("StreamInformation::QueryStreamInformation index %lu has unknown domain %lu", streamIndex, streamInfo.domain);
+ result = XA_RESULT_INTERNAL_ERROR;
+ break;
+ }
+
+ } else {
+ SL_LOGE("Querying stream type for stream %ld, only %ld streams available",
+ streamIndex, nbStreams);
+ result = XA_RESULT_PARAMETER_INVALID;
+ }
+
+ interface_unlock_exclusive(thiz);
+#endif
+
+ }
XA_LEAVE_INTERFACE
}
@@ -149,10 +206,15 @@
XA_LEAVE_INTERFACE;
}
- SL_LOGE("unsupported XAStreamInformationItf function");
- result = XA_RESULT_CONTENT_UNSUPPORTED;
- *numStreams = 0;
- activeStreams = NULL;
+ IStreamInformation *thiz = (IStreamInformation *) self;
+
+ interface_lock_exclusive(thiz);
+
+ result = XA_RESULT_SUCCESS;
+ *numStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
+ activeStreams = thiz->mActiveStreams;
+
+ interface_unlock_exclusive(thiz);
XA_LEAVE_INTERFACE
}
@@ -182,21 +244,40 @@
IStreamInformation_SetActiveStream
};
+
void IStreamInformation_init(void *self)
{
+ SL_LOGV("IStreamInformation_init\n");
IStreamInformation *thiz = (IStreamInformation *) self;
thiz->mItf = &IStreamInformation_Itf;
thiz->mCallback = NULL;
thiz->mContext = NULL;
+ for (int i=0 ; i < NB_SUPPORTED_STREAMS ; i++) {
+ thiz->mActiveStreams[i] = XA_BOOLEAN_FALSE;
+ }
+
#ifdef ANDROID
+ // placement new constructor for C++ field within C struct
+ (void) new (&thiz->mStreamInfoTable) android::Vector<StreamInfo>();
// initialize container info
StreamInfo contInf;
- contInf.domain = XA_DOMAINTYPE_UNKNOWN; // there should really be a domain for the container!
+ contInf.domain = XA_DOMAINTYPE_CONTAINER;
contInf.containerInfo.containerType = XA_CONTAINERTYPE_UNSPECIFIED;
contInf.containerInfo.mediaDuration = XA_TIME_UNKNOWN;
+ // FIXME shouldn't this be 1 ?
contInf.containerInfo.numStreams = 0;
+ // always storing container info at index 0, as per spec: here, the table was still empty
thiz->mStreamInfoTable.add(contInf);
#endif
}
+
+
+void IStreamInformation_deinit(void *self) {
+#ifdef ANDROID
+ IStreamInformation *thiz = (IStreamInformation *) self;
+ // explicit destructor
+ thiz->mStreamInfoTable.~Vector<StreamInfo>();
+#endif
+}