Ejemplo n.º 1
0
int CProgramConfig_LookupElement(
        CProgramConfig *pPce,
        UINT            channelConfig,
        const UINT      tag,
        const UINT      channelIdx,
        UCHAR           chMapping[],
        AUDIO_CHANNEL_TYPE chType[],
        UCHAR           chIndex[],
        UCHAR          *elMapping,
        MP4_ELEMENT_ID  elList[],
        MP4_ELEMENT_ID  elType
       )
{
  if (channelConfig > 0)
  {
    /* Constant channel mapping must have
       been set during initialization. */
    if ( elType == ID_SCE
      || elType == ID_CPE
      || elType == ID_LFE )
    {
      *elMapping = pPce->elCounter;
      if (elList[pPce->elCounter] != elType) {
        /* Not in the list */
        if ( (channelConfig == 2) && (elType == ID_SCE) )
        { /* This scenario occurs with HE-AAC v2 streams of buggy encoders.
             Due to other decoder implementations decoding of these kind of streams is desired. */
          channelConfig = 1;
        } else {
          return 0;
        }
      }
      /* Assume all front channels */
      getImplicitAudioChannelTypeAndIndex(&chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
      if (elType == ID_CPE) {
        chType[channelIdx+1] = chType[channelIdx];
        chIndex[channelIdx+1] = chIndex[channelIdx]+1;
      }
      pPce->elCounter++;
    }
    /* Accept all non-channel elements, too. */
    return 1;
  }
  else
  {
#ifdef TP_PCE_ENABLE
    if (!pPce->isValid)
#endif /* TP_PCE_ENABLE */
    {
      /* Implicit channel mapping. */
      if ( elType == ID_SCE
        || elType == ID_CPE
        || elType == ID_LFE )
      {
        /* Store all channel element IDs */
        elList[pPce->elCounter] = elType;
        *elMapping = pPce->elCounter++;
      }
    }
#ifdef  TP_PCE_ENABLE
    else {
      /* Accept the additional channel(s), only if the tag is in the lists */
      int isCpe = 0, i;
      /* Element counter */
      int ec[PC_NUM_HEIGHT_LAYER] = {0};
      /* Channel counters */
      int cc[PC_NUM_HEIGHT_LAYER] = {0};
      int fc[PC_NUM_HEIGHT_LAYER] = {0};
      int sc[PC_NUM_HEIGHT_LAYER] = {0};
      int bc[PC_NUM_HEIGHT_LAYER] = {0};
      int lc = 0;;

      /* General MPEG (PCE) composition rules:
         - Over all:
             <normal height channels><top height channels><bottom height channels>
         - Within each height layer:
             <front channels><side channels><back channels>
         - Exception:
             The LFE channels have no height info and thus they are arranged at the very
             end of the normal height layer channels.
       */

      switch (elType)
      {
      case ID_CPE:
        isCpe = 1;
      case ID_SCE:
        /* search in front channels */
        for (i = 0; i < pPce->NumFrontChannelElements; i++) {
          int heightLayer = pPce->FrontElementHeightInfo[i];
          if (isCpe == pPce->FrontElementIsCpe[i] && pPce->FrontElementTagSelect[i] == tag) {
            int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
            AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_FRONT);
            for (h = heightLayer-1; h >= 0; h-=1) {
              int el;
              /* Count front channels/elements */
              for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
                if (pPce->FrontElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
                }
              }
              /* Count side channels/elements */
              for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
                if (pPce->SideElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
                }
              }
              /* Count back channels/elements */
              for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
                if (pPce->BackElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
                }
              }
              if (h == 0) {  /* normal height */
                elIdx += pPce->NumLfeChannelElements;
                chIdx += pPce->NumLfeChannelElements;
              }
            }
            chMapping[chIdx] = channelIdx;
            chType[chIdx] = aChType;
            chIndex[chIdx] = fc[heightLayer];
            if (isCpe) {
              chMapping[chIdx+1] = channelIdx+1;
              chType[chIdx+1] = aChType;
              chIndex[chIdx+1] = fc[heightLayer]+1;
            }
            *elMapping = elIdx;
            return 1;
          }
          ec[heightLayer] += 1;
          if (pPce->FrontElementIsCpe[i]) {
            cc[heightLayer] += 2;
            fc[heightLayer] += 2;
          } else {
            cc[heightLayer] += 1;
            fc[heightLayer] += 1;
          }
        }
        /* search in side channels */
        for (i = 0; i < pPce->NumSideChannelElements; i++) {
          int heightLayer = pPce->SideElementHeightInfo[i];
          if (isCpe == pPce->SideElementIsCpe[i] && pPce->SideElementTagSelect[i] == tag) {
            int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
            AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_SIDE);
            for (h = heightLayer-1; h >= 0; h-=1) {
              int el;
              /* Count front channels/elements */
              for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
                if (pPce->FrontElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
                }
              }
              /* Count side channels/elements */
              for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
                if (pPce->SideElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
                }
              }
              /* Count back channels/elements */
              for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
                if (pPce->BackElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
                }
              }
              if (h == 0) {  /* LFE channels belong to the normal height layer */
                elIdx += pPce->NumLfeChannelElements;
                chIdx += pPce->NumLfeChannelElements;
              }
            }
            chMapping[chIdx] = channelIdx;
            chType[chIdx] = aChType;
            chIndex[chIdx] = sc[heightLayer];
            if (isCpe) {
              chMapping[chIdx+1] = channelIdx+1;
              chType[chIdx+1] = aChType;
              chIndex[chIdx+1] = sc[heightLayer]+1;
            }
            *elMapping = elIdx;
            return 1;
          }
          ec[heightLayer] += 1;
          if (pPce->SideElementIsCpe[i]) {
            cc[heightLayer] += 2;
            sc[heightLayer] += 2;
          } else {
            cc[heightLayer] += 1;
            sc[heightLayer] += 1;
          }
        }
        /* search in back channels */
        for (i = 0; i < pPce->NumBackChannelElements; i++) {
          int heightLayer = pPce->BackElementHeightInfo[i];
          if (isCpe == pPce->BackElementIsCpe[i] && pPce->BackElementTagSelect[i] == tag) {
            int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
            AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_BACK);
            for (h = heightLayer-1; h >= 0; h-=1) {
              int el;
              /* Count front channels/elements */
              for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
                if (pPce->FrontElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
                }
              }
              /* Count side channels/elements */
              for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
                if (pPce->SideElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
                }
              }
              /* Count back channels/elements */
              for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
                if (pPce->BackElementHeightInfo[el] == h) {
                  elIdx += 1;
                  chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
                }
              }
              if (h == 0) {  /* normal height */
                elIdx += pPce->NumLfeChannelElements;
                chIdx += pPce->NumLfeChannelElements;
              }
            }
            chMapping[chIdx] = channelIdx;
            chType[chIdx] = aChType;
            chIndex[chIdx] = bc[heightLayer];
            if (isCpe) {
              chMapping[chIdx+1] = channelIdx+1;
              chType[chIdx+1] = aChType;
              chIndex[chIdx+1] = bc[heightLayer]+1;
            }
            *elMapping = elIdx;
            return 1;
          }
          ec[heightLayer] += 1;
          if (pPce->BackElementIsCpe[i]) {
            cc[heightLayer] += 2;
            bc[heightLayer] += 2;
          } else {
            cc[heightLayer] += 1;
            bc[heightLayer] += 1;
          }
        }
        break;

      case ID_LFE:
      { /* Unfortunately we have to go through all normal height
           layer elements to get the position of the LFE channels.
           Start with counting the front channels/elements at normal height */
        for (i = 0; i < pPce->NumFrontChannelElements; i+=1) {
          int heightLayer = pPce->FrontElementHeightInfo[i];
          ec[heightLayer] += 1;
          cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
        }
        /* Count side channels/elements at normal height */
        for (i = 0; i < pPce->NumSideChannelElements; i+=1) {
          int heightLayer = pPce->SideElementHeightInfo[i];
          ec[heightLayer] += 1;
          cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
        }
        /* Count back channels/elements at normal height */
        for (i = 0; i < pPce->NumBackChannelElements; i+=1) {
          int heightLayer = pPce->BackElementHeightInfo[i];
          ec[heightLayer] += 1;
          cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
        }

        /* search in lfe channels */
        for (i = 0; i < pPce->NumLfeChannelElements; i++) {
          int elIdx = ec[0];  /* LFE channels belong to the normal height layer */
          int chIdx = cc[0];
          if ( pPce->LfeElementTagSelect[i] == tag ) {
            chMapping[chIdx] = channelIdx;
            *elMapping = elIdx;
            chType[chIdx] = ACT_LFE;
            chIndex[chIdx] = lc;
            return 1;
          }
          ec[0] += 1;
          cc[0] += 1;
          lc += 1;
        }
      } break;

      /* Non audio elements */
      case ID_CCE:
        /* search in cce channels */
        for (i = 0; i < pPce->NumValidCcElements; i++) {
          if (pPce->ValidCcElementTagSelect[i] == tag) {
            return 1;
          }
        }
        break;
      case ID_DSE:
        /* search associated data elements */
        for (i = 0; i < pPce->NumAssocDataElements; i++) {
          if (pPce->AssocDataElementTagSelect[i] == tag) {
            return 1;
          }
        }
        break;
      default:
        return 0;
      }
      return 0;  /* not found in any list */
    }
#endif /* TP_PCE_ENABLE */
  }

  return 1;
}
Ejemplo n.º 2
0
int CProgramConfig_LookupElement(
        CProgramConfig *pPce,
        const UINT      channelConfig,
        const UINT      tag,
        const UINT      channelIdx,
        UCHAR           chMapping[],
        AUDIO_CHANNEL_TYPE chType[],
        UCHAR           chIndex[],
        UCHAR          *elMapping,
        MP4_ELEMENT_ID  elList[],
        MP4_ELEMENT_ID  elType
       )
{
  if (channelConfig > 0)
  {
    /* Constant channel mapping must have
       been set during initialization. */
    if ( elType == ID_SCE
      || elType == ID_CPE
      || elType == ID_LFE )
    {
      *elMapping = pPce->elCounter;
      if (elList[pPce->elCounter] != elType) {
        /* Not in the list */
        return 0;
      }
      /* Assume all front channels */
      getImplicitAudioChannelTypeAndIndex(&chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
      if (elType == ID_CPE) {
        chType[channelIdx+1] = chType[channelIdx];
        chIndex[channelIdx+1] = chIndex[channelIdx]+1;
      }
      pPce->elCounter++;
    }
    /* Accept all non-channel elements, too. */
    return 1;
  }
  else
  {
#ifdef TP_PCE_ENABLE
    if (!pPce->isValid)
#endif /* TP_PCE_ENABLE */
    {
      /* Implicit channel mapping. */
      if ( elType == ID_SCE
        || elType == ID_CPE
        || elType == ID_LFE )
      {
        /* Store all channel element IDs */
        elList[pPce->elCounter] = elType;
        *elMapping = pPce->elCounter++;
      }
    }
#ifdef  TP_PCE_ENABLE
    else {
      /* Accept the additional channel(s), only if the tag is in the lists */
      int isCpe = 0, i;
      int cc = 0, fc = 0, sc = 0, bc = 0, lc = 0, ec = 0; /* Channel and element counters */

      switch (elType)
      {
      case ID_CPE:
        isCpe = 1;
      case ID_SCE:
        /* search in front channels */
        for (i = 0; i < pPce->NumFrontChannelElements; i++) {
          if (isCpe == pPce->FrontElementIsCpe[i] && pPce->FrontElementTagSelect[i] == tag) {
            chMapping[cc] = channelIdx;
            chType[cc] = ACT_FRONT;
            chIndex[cc] = fc;
            if (isCpe) {
              chMapping[cc+1] = channelIdx+1;
              chType[cc+1] = ACT_FRONT;
              chIndex[cc+1] = fc+1;
            }
            *elMapping = ec;
            return 1;
          }
          ec++;
          if (pPce->FrontElementIsCpe[i]) {
            cc+=2; fc+=2;
          } else {
            cc++; fc++;
          }
        }
        /* search in side channels */
        for (i = 0; i < pPce->NumSideChannelElements; i++) {
          if (isCpe == pPce->SideElementIsCpe[i] && pPce->SideElementTagSelect[i] == tag) {
            chMapping[cc] = channelIdx;
            chType[cc] = ACT_SIDE;
            chIndex[cc] = sc;
            if (isCpe) {
              chMapping[cc+1] = channelIdx+1;
              chType[cc+1] = ACT_SIDE;
              chIndex[cc+1] = sc+1;
            }
            *elMapping = ec;
            return 1;
          }
          ec++;
          if (pPce->SideElementIsCpe[i]) {
            cc+=2; sc+=2;
          } else {
            cc++; sc++;
          }
        }
        /* search in back channels */
        for (i = 0; i < pPce->NumBackChannelElements; i++) {
          if (isCpe == pPce->BackElementIsCpe[i] && pPce->BackElementTagSelect[i] == tag) {
            chMapping[cc] = channelIdx;
            chType[cc] = ACT_BACK;
            chIndex[cc] = bc;
            if (isCpe) {
              chMapping[cc+1] = channelIdx+1;
              chType[cc+1] = ACT_BACK;
              chIndex[cc+1] = bc+1;
            }
            *elMapping = ec;
            return 1;
          }
          ec++;
          if (pPce->BackElementIsCpe[i]) {
            cc+=2; bc+=2;
          } else {
            cc++; bc++;
          }
        }
        break;

      case ID_LFE:
        /* Initialize channel counter and element counter */
        cc = pPce->NumEffectiveChannels;
        ec = pPce->NumFrontChannelElements+ pPce->NumSideChannelElements + pPce->NumBackChannelElements;
        /* search in lfe channels */
        for (i = 0; i < pPce->NumLfeChannelElements; i++) {
          if ( pPce->LfeElementTagSelect[i] == tag ) {
            chMapping[cc] = channelIdx;
            *elMapping = ec;
            chType[cc] = ACT_LFE;
            chIndex[cc] = lc;
            return 1;
          }
          ec++;
          cc++;
          lc++;
        }
        break;

      /* Non audio elements */
      case ID_CCE:
        /* search in cce channels */
        for (i = 0; i < pPce->NumValidCcElements; i++) {
          if (pPce->ValidCcElementTagSelect[i] == tag) {
            return 1;
          }
        }
        break;
      case ID_DSE:
        /* search associated data elements */
        for (i = 0; i < pPce->NumAssocDataElements; i++) {
          if (pPce->AssocDataElementTagSelect[i] == tag) {
            return 1;
          }
        }
        break;
      default:
        return 0;
      }
      return 0;  /* not found in any list */
    }
#endif /* TP_PCE_ENABLE */
  }

  return 1;
}