merge in ics-mr1-release history after reset to ics-mr1
diff --git a/include/OMXAL/OpenMAXAL_Android.h b/include/OMXAL/OpenMAXAL_Android.h
index 10f36f4..34b9dd9 100644
--- a/include/OMXAL/OpenMAXAL_Android.h
+++ b/include/OMXAL/OpenMAXAL_Android.h
@@ -57,6 +57,13 @@
#define XA_ANDROID_ITEMKEY_BUFFERQUEUEEVENT ((XAuint32) 0x00000003)
#define XA_ANDROID_ITEMKEY_FORMAT_CHANGE ((XAuint32) 0x00000004)
+// optional data for XA_ANDROID_ITEMKEY_FORMAT_CHANGE, used when only one stream changes format,
+// and the others remain continuous (i.e. no temporal discontinuity is introduced for them)
+// candidate for being exposed in NDK
+#define XA_ANDROID_FORMATCHANGE_ITEMDATA_VIDEO ((XAuint32) 0x00000001)
+// not supported at this stage, for illustration purposes only
+//#define XA_ANDROID_FORMATCHANGE_ITEMDATA_AUDIO ((XAuint32) 0x00000002)
+
#define XA_ANDROIDBUFFERQUEUEEVENT_NONE ((XAuint32) 0x00000000)
#define XA_ANDROIDBUFFERQUEUEEVENT_PROCESSED ((XAuint32) 0x00000001)
#if 0 // reserved for future use
diff --git a/src/android/android_GenericPlayer.cpp b/src/android/android_GenericPlayer.cpp
index 10e613f..85a8b1a 100644
--- a/src/android/android_GenericPlayer.cpp
+++ b/src/android/android_GenericPlayer.cpp
@@ -600,6 +600,12 @@
}
}
+ // if we observe the player position going backwards, even without without a seek, then recover
+ if (mObservedPositionMs != ANDROID_UNKNOWN_TIME && positionMs < mObservedPositionMs) {
+ mDeliveredNewPosMs = ANDROID_UNKNOWN_TIME;
+ mObservedPositionMs = positionMs;
+ }
+
// delayUs is the expected delay between current position and marker;
// the default is infinity in case there are no upcoming marker(s)
int64_t delayUs = -1;
diff --git a/src/android/android_StreamPlayer.cpp b/src/android/android_StreamPlayer.cpp
index 3847520..b87733c 100644
--- a/src/android/android_StreamPlayer.cpp
+++ b/src/android/android_StreamPlayer.cpp
@@ -24,6 +24,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <binder/IPCThreadState.h>
+#include "mpeg2ts/ATSParser.h"
//--------------------------------------------------------------------------------------------------
namespace android {
@@ -158,14 +159,27 @@
msg->setInt64(IStreamListener::kKeyResumeAtPTS,
(int64_t)oldFront->mItems.mTsCmdData.mPts);
receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/);
- } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_FORMAT_CHANGE) {
+ } else if (oldFront->mItems.mTsCmdData.mTsCmdCode
+ & ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL) {
sp<AMessage> msg = new AMessage();
- // positive value for format change key makes the discontinuity "hard", see key def
- msg->setInt32(IStreamListener::kKeyFormatChange, (int32_t) 1);
+ msg->setInt32(
+ IStreamListener::kKeyDiscontinuityMask,
+ ATSParser::DISCONTINUITY_FORMATCHANGE);
+ receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/);
+ } else if (oldFront->mItems.mTsCmdData.mTsCmdCode
+ & ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO) {
+ sp<AMessage> msg = new AMessage();
+ msg->setInt32(
+ IStreamListener::kKeyDiscontinuityMask,
+ ATSParser::DISCONTINUITY_VIDEO_FORMAT);
receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/);
}
+ // note that here we are intentionally only supporting
+ // ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO, see IAndroidBufferQueue.c
+
+ // some commands may introduce a time discontinuity, reevaluate position if needed
if (oldFront->mItems.mTsCmdData.mTsCmdCode & (ANDROID_MP2TSEVENT_DISCONTINUITY |
- ANDROID_MP2TSEVENT_DISCON_NEWPTS | ANDROID_MP2TSEVENT_FORMAT_CHANGE)) {
+ ANDROID_MP2TSEVENT_DISCON_NEWPTS | ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL)) {
const sp<StreamPlayer> player(mPlayer.promote());
if (player != NULL) {
// FIXME see note at onSeek
diff --git a/src/android/android_defs.h b/src/android/android_defs.h
index 2332a73..3106b41 100644
--- a/src/android/android_defs.h
+++ b/src/android/android_defs.h
@@ -134,7 +134,8 @@
// associated presentation time stamp
#define ANDROID_MP2TSEVENT_DISCON_NEWPTS ((SLuint32) 0x1 << 2)
// buffer marks a format change with previous TS data, resume display as soon as possible
-#define ANDROID_MP2TSEVENT_FORMAT_CHANGE ((SLuint32) 0x1 << 3)
+#define ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL ((SLuint32) 0x1 << 3)
+#define ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO ((SLuint32) 0x1 << 4)
/**
* Event mask for AAC ADTS events associated with ADTS data
diff --git a/src/itf/IAndroidBufferQueue.c b/src/itf/IAndroidBufferQueue.c
index 278b7fd..884f637 100644
--- a/src/itf/IAndroidBufferQueue.c
+++ b/src/itf/IAndroidBufferQueue.c
@@ -119,10 +119,29 @@
break;
case SL_ANDROID_ITEMKEY_FORMAT_CHANGE:
- pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_FORMAT_CHANGE;
- if (pItems->itemSize != 0) {
- SL_LOGE("Invalid item parameter size %u for format change, ignoring value",
- pItems->itemSize);
+ // distinguish between a "full" format change and one where it says what changed
+ if (pItems->itemSize == 0) {
+ SL_LOGV("Received format change with no data == full format change");
+ pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL;
+ } else if (pItems->itemSize == sizeof(SLuint32)) {
+ XAuint32 formatData = *((XAuint32*)pItems->itemData);
+ // intentionally only supporting video change when reading which specific
+ // stream has changed, interpret other changes as full change
+ if (formatData == XA_ANDROID_FORMATCHANGE_ITEMDATA_VIDEO) {
+ pBuff->mItems.mTsCmdData.mTsCmdCode |=
+ ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO;
+ SL_LOGV("Received video format change");
+ } else {
+ // note that we don't support specifying
+ // ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL by having all bits of
+ // the data mask set, we default to it with unsupported masks
+ SL_LOGE("Received format change with unsupported data, ignoring data");
+ pBuff->mItems.mTsCmdData.mTsCmdCode |=
+ ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL;
+ }
+ } else {
+ SL_LOGE("Received format change with invalid data size, ignoring data");
+ pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL;
}
break;
@@ -178,7 +197,8 @@
case ANDROID_MP2TSEVENT_EOS:
case ANDROID_MP2TSEVENT_DISCONTINUITY:
case ANDROID_MP2TSEVENT_DISCON_NEWPTS:
- case ANDROID_MP2TSEVENT_FORMAT_CHANGE:
+ case ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL:
+ case ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO:
break;
// no combinations are allowed
default: