resolved conflicts for merge of 2917f475 to master

Change-Id: I63f4689fabb2aee1682d785ad9c41f06de380396
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_StreamPlayer.cpp b/src/android/android_StreamPlayer.cpp
index 5097dc2..ade5280 100644
--- a/src/android/android_StreamPlayer.cpp
+++ b/src/android/android_StreamPlayer.cpp
@@ -160,17 +160,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::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 609ef28..5ac11e1 100644
--- a/src/android/android_defs.h
+++ b/src/android/android_defs.h
@@ -135,7 +135,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 b0f79fa..289fbc4 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", pItems->itemSize);
-                    return SL_RESULT_PARAMETER_INVALID;
+                // 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;
 
@@ -182,7 +201,8 @@
           case ANDROID_MP2TSEVENT_NONE:
           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: