Index: branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 30)
+++ branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 41)
@@ -110,4 +110,11 @@
     free (m_pchBitstreamFile) ;
 
+#if FLEX_CODING_ORDER
+  if (m_pchMVCJointCodingOrder != NULL)
+  {
+    free(m_pchMVCJointCodingOrder) ;
+  }
+#endif
+
   for(Int i = 0; i< m_pchDepthReconFileList.size(); i++ )
   {
@@ -153,4 +160,9 @@
   string cfg_ReconFile;
   string cfg_dQPFile;
+
+#if FLEX_CODING_ORDER
+  string cfg_JointCodingOrdering;
+#endif
+
   po::Options opts;
   opts.addOptions()
@@ -191,4 +203,8 @@
   ("NumberOfViews",         m_iNumberOfViews,    0, "Number of views")
 
+#if FLEX_CODING_ORDER
+  ("3DVFlexOrder",          m_b3DVFlexOrder,   false, "flexible coding order flag" )
+  ("3DVCodingOrder",		cfg_JointCodingOrdering,  string(""), "The coding order for joint texture-depth coding")
+#endif
 
   /* Unit definition parameters */
@@ -367,5 +383,9 @@
 #endif
 #if POZNAN_NONLINEAR_DEPTH
-  ("DepthPower,-dpow",    m_fDepthPower,      (Double)1.0, "Depth power value (for non-linear processing)")
+  ("NonlinearDepth",           m_bUseNonlinearDepth,    true, "usage of non-linear depth representation")    
+  ("NonlinearDepthModel",      m_aiNonlinearDepthModel, std::vector<Int>(0,0), "Nodes for definition of non-linear depth representation")    
+#if POZNAN_NONLINEAR_DEPTH_THRESHOLD
+  ("NonlinearDepthThreshold",  m_iNonlinearDepthThreshold, 100, "Threshold for usage of Nonlinear depth representation")    
+#endif
 #endif
 
@@ -398,4 +418,36 @@
   m_pchBitstreamFile = cfg_BitstreamFile.empty() ? NULL : strdup(cfg_BitstreamFile.c_str());
   m_pchdQPFile = cfg_dQPFile.empty() ? NULL : strdup(cfg_dQPFile.c_str());
+
+#if FLEX_CODING_ORDER && HHI_VSO
+  m_pchMVCJointCodingOrder	= cfg_JointCodingOrdering.empty()?NULL:strdup(cfg_JointCodingOrdering.c_str());
+  // If flexible order is enabled and if depth comes before the texture for a view, disable VSO
+  Bool depthComesFirst = false;
+  if ( m_b3DVFlexOrder )
+  {
+    for(Int iViewIdx=0; iViewIdx<m_iNumberOfViews; iViewIdx++)
+    {
+      for ( Int ii=1; ii<12; ii+=2 )
+      {
+        Int iViewIdxCfg = (Int)(m_pchMVCJointCodingOrder[ii]-'0');
+        if ( iViewIdxCfg == iViewIdx )
+        {
+          if ( m_pchMVCJointCodingOrder[ii-1]=='D' ) // depth comes first for this view
+          {
+            depthComesFirst = true;
+            break;
+          }
+          else
+          {
+            assert(m_pchMVCJointCodingOrder[ii-1]=='T');
+          }
+        }
+      }
+    }
+  }
+  if (depthComesFirst)
+  {
+    m_bUseVSO = false;		
+  }
+#endif
 
 
@@ -458,18 +510,44 @@
 
 #if POZNAN_NONLINEAR_DEPTH
-if (m_fDepthPower<=0) 
-  {
-    Float fDepthQP = m_adQP[ m_adQP.size()  < 2 ? 0 : 1];
-    m_fDepthPower = (fDepthQP-30) *0.25/20.0 + 1.25;
-    if (m_fDepthPower<=1.0) m_fDepthPower = 1.0;
-    // QP = 30 = 1.25
-    // QP = 50 = 1.5
-    if (m_fDepthPower>=1.66) m_fDepthPower = 1.66;
-  };
-
-#if POZNAN_NONLINEAR_DEPTH_SEND_AS_BYTE
-  m_fDepthPower = dequantizeDepthPower(quantizeDepthPower((Float)m_fDepthPower));
-#endif
-
+#if POZNAN_NONLINEAR_DEPTH_THRESHOLD
+  if(m_bUseNonlinearDepth && m_iNonlinearDepthThreshold>0)
+  {
+    FILE *base_depth_file;
+    unsigned char *depth_buf;
+    int histogram[256];
+    int i, size;
+    float weighted_avg;
+    base_depth_file = fopen(m_pchDepthInputFileList[0], "rb");
+    if (base_depth_file)
+    {
+      size = m_iSourceWidth*m_iSourceHeight;
+      depth_buf = (unsigned char *)malloc(size);
+      fread(depth_buf, 1, size, base_depth_file);
+      fclose(base_depth_file);
+      memset(histogram, 0, sizeof(histogram));
+      for (i=0; i<size;++i) histogram[depth_buf[i]]++;
+      weighted_avg = 0;
+      for (i=0; i<256; ++i) weighted_avg += i*histogram[i];
+      weighted_avg /= size;
+
+      if (weighted_avg<m_iNonlinearDepthThreshold)
+      {
+        m_bUseNonlinearDepth = 0;
+        printf ("\nWeighted average of depth histogram:%f < %d, turning NonlinearDepthRepresentation OFF\n", weighted_avg, m_iNonlinearDepthThreshold);
+      }
+    }
+  }
+#endif
+
+  if(m_bUseNonlinearDepth)
+  {
+    m_cNonlinearDepthModel.m_iNum = (Int)m_aiNonlinearDepthModel.size();
+    m_cNonlinearDepthModel.m_aiPoints[0]=0;
+    for (int i=0; i<m_cNonlinearDepthModel.m_iNum; ++i)
+      m_cNonlinearDepthModel.m_aiPoints[i+1] = m_aiNonlinearDepthModel[i];
+
+    m_cNonlinearDepthModel.m_aiPoints[m_cNonlinearDepthModel.m_iNum+1]=0;
+    m_cNonlinearDepthModel.Init();
+  }
 #endif
 
@@ -555,5 +633,5 @@
                                       LOG2_DISP_PREC_LUT 
 #if POZNAN_NONLINEAR_DEPTH                                      
-                                      ,m_fDepthPower
+                                      ,(m_bUseNonlinearDepth ? &m_cNonlinearDepthModel : NULL)
 #endif
                                       );
@@ -572,5 +650,5 @@
                                       LOG2_DISP_PREC_LUT 
 #if POZNAN_NONLINEAR_DEPTH                                      
-                                      ,m_fDepthPower
+                                      ,(m_bUseNonlinearDepth ? &m_cNonlinearDepthModel : NULL)
 #endif                                      
                                       );
@@ -589,5 +667,5 @@
     LOG2_DISP_PREC_LUT 
 #if POZNAN_NONLINEAR_DEPTH                                      
-    ,m_fDepthPower
+    ,(m_bUseNonlinearDepth ? &m_cNonlinearDepthModel : NULL)
 #endif    
     );
@@ -605,5 +683,5 @@
     LOG2_DISP_PREC_LUT 
 #if POZNAN_NONLINEAR_DEPTH                                      
-    ,m_fDepthPower
+    ,(m_bUseNonlinearDepth ? &m_cNonlinearDepthModel : NULL)
 #endif    
     );
@@ -1064,5 +1142,5 @@
 #endif
 #if POZNAN_NONLINEAR_DEPTH
-  printf("DepthPower:%f ", m_fDepthPower);
+  printf("NLDR:%d ", m_bUseNonlinearDepth ? 1 : 0);
 #endif
   printf("\n");
Index: branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncCfg.h	(revision 30)
+++ branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncCfg.h	(revision 41)
@@ -81,4 +81,9 @@
   Bool      m_bUsingDepthMaps ;
 
+#if FLEX_CODING_ORDER
+  char*		m_pchMVCJointCodingOrder;		///<  texture-depth coding order
+  Bool		m_b3DVFlexOrder;		///<  flexible coding order flag
+#endif
+
 
   // coding structure
@@ -290,5 +295,8 @@
 
 #if POZNAN_NONLINEAR_DEPTH
-  Double    m_fDepthPower;									  ///< Depth power value
+  std::vector<Int>            m_aiNonlinearDepthModel;
+  TComNonlinearDepthModel     m_cNonlinearDepthModel;
+  Int                         m_iNonlinearDepthThreshold;
+  Bool                        m_bUseNonlinearDepth;
 #endif
 
Index: branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncTop.cpp	(revision 30)
+++ branches/0.3-poznan-univ/source/App/TAppEncoder/TAppEncTop.cpp	(revision 41)
@@ -142,5 +142,6 @@
 
 #if POZNAN_NONLINEAR_DEPTH
-    m_acTEncTopList[iViewIdx]->setDepthPower                   ( (Float)m_fDepthPower );
+    m_acTEncTopList[iViewIdx]->setNonlinearDepthModel         ( m_cNonlinearDepthModel );
+    m_acTEncTopList[iViewIdx]->setUseNonlinearDepth           ( m_bUseNonlinearDepth );
 #endif
 
@@ -256,4 +257,27 @@
     for(Int iViewIdx=0; iViewIdx<m_iNumberOfViews; iViewIdx++)
     {
+#if FLEX_CODING_ORDER
+      // Detect whether depth comes before than texture for this view
+      Bool isDepthFirst = false;
+      if ( m_b3DVFlexOrder )
+      {
+        for ( Int ii=1; ii<12; ii+=2 )
+        {
+          Int iViewIdxCfg = (Int)(m_pchMVCJointCodingOrder[ii]-'0');
+          if ( iViewIdxCfg == iViewIdx )
+          {
+            if ( m_pchMVCJointCodingOrder[ii-1]=='D' ) // depth comes first for this view
+            {
+              isDepthFirst = true;
+            }
+            else
+            {
+              assert(m_pchMVCJointCodingOrder[ii-1]=='T');
+            }
+            break;
+          }
+        }
+      }
+#endif
       m_iDepthFrameRcvdVector.push_back(0) ;
       m_acTEncDepthTopList.push_back(new TEncTop);
@@ -375,4 +399,7 @@
       m_acTEncDepthTopList[iViewIdx]->setUseDMM( m_bUseDMM );
 #endif
+#if FLEX_CODING_ORDER && HHI_DMM_PRED_TEX
+      m_acTEncDepthTopList[iViewIdx]->setUseDMM34( (m_b3DVFlexOrder && isDepthFirst) ? false : m_bUseDMM );
+#endif
 #if CONSTRAINED_INTRA_PRED
       m_acTEncDepthTopList[iViewIdx]->setUseConstrainedIntraPred      ( m_bUseConstrainedIntraPred );
@@ -401,5 +428,9 @@
 #endif
 #if HHI_MPI
+#if FLEX_CODING_ORDER
+      m_acTEncDepthTopList[iViewIdx]->setUseMVI( (m_b3DVFlexOrder && isDepthFirst) ? false : m_bUseMVI );
+#else
       m_acTEncDepthTopList[iViewIdx]->setUseMVI( m_bUseMVI );
+#endif
 #endif
 #if POZNAN_DBMP
@@ -407,8 +438,9 @@
 #endif
 #if POZNAN_ENCODE_ONLY_DISOCCLUDED_CU
-	    m_acTEncDepthTopList[iViewIdx]->setUseCUSkip                      ( m_uiUseCUSkip );
+	    m_acTEncDepthTopList[iViewIdx]->setUseCUSkip                   ( m_uiUseCUSkip );
 #endif
 #if POZNAN_NONLINEAR_DEPTH
-      m_acTEncDepthTopList[iViewIdx]->setDepthPower                   ( (Float)m_fDepthPower );
+      m_acTEncDepthTopList[iViewIdx]->setNonlinearDepthModel         ( m_cNonlinearDepthModel );
+      m_acTEncDepthTopList[iViewIdx]->setUseNonlinearDepth           ( m_bUseNonlinearDepth );
 #endif
 
@@ -690,5 +722,6 @@
           m_acTVideoIOYuvDepthInputFileList[iViewIdx]->read( pcPdmDepthOrg, m_aiPad, m_bUsingDepthMaps );
 #if POZNAN_NONLINEAR_DEPTH
-		      pcPdmDepthOrg->nonlinearDepthForward(pcPdmDepthOrg, m_fDepthPower);		  
+          if( m_bUseNonlinearDepth )
+            pcPdmDepthOrg->nonlinearDepthForward(pcPdmDepthOrg, m_cNonlinearDepthModel);		  
 #endif
         }
@@ -714,5 +747,6 @@
           m_acTVideoIOYuvDepthInputFileList[iViewIdx]->read( pcDepthPicYuvOrg, m_aiPad  ) ;
 #if POZNAN_NONLINEAR_DEPTH
-		      pcDepthPicYuvOrg->nonlinearDepthForward(pcDepthPicYuvOrg, m_fDepthPower);		  
+          if( m_bUseNonlinearDepth )
+            pcDepthPicYuvOrg->nonlinearDepthForward(pcDepthPicYuvOrg, m_cNonlinearDepthModel);		  
 #endif
           bDepthEos[iViewIdx] = ( m_acTVideoIOYuvDepthInputFileList[iViewIdx]->isEof() == 1 ?   true : false  );
@@ -744,4 +778,71 @@
 #endif
 
+#if FLEX_CODING_ORDER
+    if (m_b3DVFlexOrder)
+    {
+      Int i=0;
+      Int iViewIdx = 0;
+      bool bThisViewContinueReadingPics = false;
+      bool bThisViewContinueReadingDepthPics = false;
+      Int iNumberofDepthViews = m_bUsingDepthMaps?m_iNumberOfViews:0;
+      for(Int j=0; j < (m_iNumberOfViews+ iNumberofDepthViews); j++ )     // Start encoding
+      {
+        if (m_pchMVCJointCodingOrder[i]=='T')
+        {
+          i++;
+          assert(isdigit(m_pchMVCJointCodingOrder[i]));
+          iViewIdx = (Int)(m_pchMVCJointCodingOrder[i]-'0');
+          bThisViewContinueReadingPics = bContinueReadingPics[iViewIdx];
+#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
+          // If no depth picture reconstruction for current view and current POC is available sythesize one
+          Int   iCurrPoc         = m_acTEncTopList[ 0 ]->getNextFrameId();
+          Bool  bCurrPicDepthRec = getPicFromView( iViewIdx, iCurrPoc, true ) != NULL && getPicFromView( iViewIdx, iCurrPoc, true )->getReconMark();
+          if(m_bUseTexDqpAccordingToDepth && !bCurrPicDepthRec)
+          {
+            xStoreDepthSynthPicsInBuffer(iViewIdx);
+          }
+#endif
+          m_acTEncTopList[iViewIdx]->encode( bEos[iViewIdx], m_cListPicYuvRecMap[iViewIdx], pcBitstream, bThisViewContinueReadingPics );
+          bContinueReadingPics[iViewIdx]=bThisViewContinueReadingPics;
+          bAllContinueReadingPics = bAllContinueReadingPics||bContinueReadingPics[iViewIdx];
+
+          if(pcBitstream->getNumberOfWrittenBits()!=0)
+          {
+            m_cTVideoIOBitsFile.writeBits( pcBitstream );
+          }
+          pcBitstream->resetBits(); //GT: also done later in ....
+          pcBitstream->rewindStreamPacket( );
+          // write bistream to file if necessary
+          xWriteOutput( iViewIdx ); //GT: Write Reconfiles (when gop is complete?)
+          i++;
+        }
+        else if ( m_pchMVCJointCodingOrder[i] == 'D')
+        {
+          i++;
+          if( m_bUsingDepthMaps )
+          {
+            assert(isdigit(m_pchMVCJointCodingOrder[i]));
+            iViewIdx = (Int)(m_pchMVCJointCodingOrder[i]-'0');
+            bThisViewContinueReadingDepthPics = bContinueReadingDepthPics[iViewIdx];
+            m_acTEncDepthTopList[iViewIdx]->encode( bDepthEos[iViewIdx], m_cListPicYuvDepthRecMap[iViewIdx], pcBitstream, bThisViewContinueReadingDepthPics );
+            bContinueReadingDepthPics[iViewIdx]=bThisViewContinueReadingDepthPics;
+
+            bAllContinueReadingDepthPics = bAllContinueReadingDepthPics||bContinueReadingDepthPics[iViewIdx];
+            if(pcBitstream->getNumberOfWrittenBits()!=0)
+            {
+              m_cTVideoIOBitsFile.writeBits( pcBitstream );
+            }
+            pcBitstream->resetBits();
+            pcBitstream->rewindStreamPacket( );
+            // write bistream to file if necessary
+            xWriteOutput( iViewIdx, true );
+            i++;
+          }
+        }
+      }
+    }
+    else
+    {
+#endif
     //GT: Encode
     for(Int iViewIdx=0; iViewIdx < m_iNumberOfViews; iViewIdx++ )     // Start encoding
@@ -755,5 +856,12 @@
             //*
 #if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
+#if FLEX_CODING_ORDER
+      // If no depth picture reconstruction for current view and current POC is available sythesize one
+      Int   iCurrPoc         = m_acTEncTopList[ 0 ]->getNextFrameId();
+      Bool  bCurrPicDepthRec = getPicFromView( iViewIdx, iCurrPoc, true ) != NULL && getPicFromView( iViewIdx, iCurrPoc, true )->getReconMark();
+      if(m_bUseTexDqpAccordingToDepth && !bCurrPicDepthRec)
+#else
       if(m_bUseTexDqpAccordingToDepth)
+#endif
       {
         xStoreDepthSynthPicsInBuffer(iViewIdx);
@@ -798,5 +906,7 @@
       }
     }
-
+#if FLEX_CODING_ORDER
+    }
+#endif
     // delete extra picture buffers
     if( bCurrPocCoded )
@@ -1004,5 +1114,5 @@
     riNextPocToDump++;
 #if POZNAN_NONLINEAR_DEPTH
-    if(isDepth)
+    if(isDepth && m_bUseNonlinearDepth)
     {
       TComPicYuv *pcPicOrg = i->second;
@@ -1011,5 +1121,5 @@
       pcPicPow->create( pcPicOrg->getWidth(), pcPicOrg->getHeight(), pcPicOrg->getMaxCuWidth(), pcPicOrg->getMaxCuHeight(), pcPicOrg->getMaxCuDepth() );
       //cPicPower.create(pcSPS->getWidth(), pcSPS->getHeight(), pcSPS->getMaxCUWidth(), pcSPS->getMaxCUHeight(), pcSPS->getMaxCUDepth() ); 
-      pcPicOrg->nonlinearDepthBackward(pcPicPow, m_fDepthPower);		
+      pcPicOrg->nonlinearDepthBackward(pcPicPow, m_cNonlinearDepthModel);		
       rpcTVideoIOYuvReconFile->write( pcPicPow, m_aiPad );
 // to do destroy pcPicow
