⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maimp4demux.c

📁 mpeg4 demux 代码
💻 C
📖 第 1 页 / 共 5 页
字号:
          eStatus=MAI_STATUS_NOTOPEN;
      }
      else
      {
        m_u32 pts=(m_u32)lSeekValue;
        uiNewVSamplePosition=time_to_sample(VIDEO, pts);
        uiNewASamplePosition=time_to_sample(AUDIO, pts);
        /* check limits */
        if (uiNewVSamplePosition>g_uiVideoSampleCount)
          uiNewVSamplePosition=g_uiVideoSampleCount;
        if (uiNewASamplePosition>g_uiAudioSampleCount)
          uiNewASamplePosition=g_uiAudioSampleCount;

        g_uiVideoSampleNum=uiNewVSamplePosition;
        g_uiAudioSampleNum=uiNewASamplePosition;
        eStatus = MAI_STATUS_OK;
      }
    }
    else if (eSeekType==MAI_SEEKTYPE_ABS)
    {
      if (!g_bInit)
      {
        /* stream is not open yet, allow seek to exact byte position */
        if (!lSeekValue) /* seek to start allowed */
          eStatus=inputseek((m_u32)lSeekValue);
        else
          eStatus=MAI_STATUS_NOTOPEN;
      }
      else if (!lSeekValue) /* seek to start */
      {
        g_uiVideoSampleNum=0;
        g_uiAudioSampleNum=0;
      }
      else /* seek type not supported */
        eStatus=MAI_STATUS_UNSUPPORTED;
    }
    else if (eSeekType==MAI_SEEKTYPE_ABSPCT || eSeekType==MAI_SEEKTYPE_ABSALIGNED)
    {
      if (!g_bInit)
        eStatus=MAI_STATUS_NOTOPEN;
      else
      {
        m_u32 uiPercentPos=(m_u32)lSeekValue/10; /* adjust percentage to units of 10 */
        m_u32 uiTotalSamples=g_uiVideoSampleCount>g_uiAudioSampleCount?g_uiVideoSampleCount:g_uiAudioSampleCount;
        if (uiPercentPos>1000)
          uiPercentPos=1000;
        APIPRINTF( (M_TEXT("MAIengine_Command(Seek) ABSPCT/ABSALIGNED=%d\n"), (m_u32)lSeekValue) );
        eSeekType=MAI_SEEKTYPE_ABSPCT;
        if (g_uiVideoSampleCount) /* we know how many samples are in the stream */
        {
          MAISize_t ulTempPos=0;
          /* avoid division of int64 on MIPS due to library dependencies:
             ulNewDataPos = (SampleCount * (MAISize_t)uiPercentPos) / (MAISize_t)1000;
             */
          ulTempPos=(m_u32)g_uiVideoSampleCount * (MAISize_t)uiPercentPos;
          /* approx divide by 100 (110010b) using shifts */
          ulTempPos=(unsigned int)((ulTempPos>>7) + (ulTempPos>>9) + (ulTempPos>>12));
          /* approx divide by 10 (1010b) using shifts */
          uiNewVSamplePosition=(unsigned int)((ulTempPos>>4) + (ulTempPos>>5) + (ulTempPos>>8)  + (ulTempPos>>9));
        }
        if (g_uiAudioSampleCount) /* we know how many samples are in the stream */
        {
          MAISize_t ulTempPos=0;
          /* avoid division of int64 on MIPS due to library dependencies:
             ulNewDataPos = (SampleCount * (MAISize_t)uiPercentPos) / (MAISize_t)100;
             */
          ulTempPos=(m_u32)g_uiAudioSampleCount * (MAISize_t)uiPercentPos;
          /* approx divide by 100 (110010b) using shifts */
          ulTempPos=(unsigned int)((ulTempPos>>7) + (ulTempPos>>9) + (ulTempPos>>12));
          /* approx divide by 10 (1010b) using shifts */
          uiNewASamplePosition=(unsigned int)((ulTempPos>>4) + (ulTempPos>>5) + (ulTempPos>>8)  + (ulTempPos>>9));
        }
        /* check limits */
        if (uiNewVSamplePosition>g_uiVideoSampleCount)
          uiNewVSamplePosition=g_uiVideoSampleCount;
        if (uiNewASamplePosition>g_uiAudioSampleCount)
          uiNewASamplePosition=g_uiAudioSampleCount;
        g_uiVideoSampleNum=uiNewVSamplePosition;
        g_uiAudioSampleNum=uiNewASamplePosition;
        eStatus = MAI_STATUS_OK;
      }
    }
    else /* seek type not supported */
      eStatus=MAI_STATUS_UNSUPPORTED;
  }

  if (eStatus==MAI_STATUS_OK)
  {
    /* seek to new position successful, setup for first read */
    if (g_bFirstRead)
    {
      APIPRINTF( (M_TEXT("MP4DEMUX: _streamseek() Reseting bFileRead\n")) );
      g_bFirstRead=M_TRUE;
      /* we must let caller know that reads at the old position have ended */
      //MAICompBase_SendProgressCB(hComp, MAI_PROGRESSFLAG_EOS);
    }
  }

  return eStatus;
}

static void _InBufferPoolStateCB(MAICompBufferPool_t hBufferPool, MAIBufState_e ePoolState, void *pUserData)
{
  MAICompHandle_t hThisComp = (MAICompHandle_t)pUserData;
  /* This reports to us if BufferPool becomes: MAI_BUFSTATE_FILLED or MAI_BUFSTATE_EMPTY */
  PUTPRINTF((M_TEXT("MP4DEMUX: _InBufferPoolStateCB() ePoolState=%d\n"), ePoolState));
  if (g_pfProgressCB && (g_uiProgressSelectFlags & MAI_PROGRESS_BUFFER)!=0)
  {
    MAIProgressBuffer_t ProgressInfo;
    unsigned int uiMaxBufs;
    unsigned int uiMaxBufSize;
    unsigned int uiBufsFilled;
    unsigned int uiDataFilled;
    MAICompBufferPoolGetStatus(hBufferPool, &uiMaxBufs, &uiMaxBufSize, &uiBufsFilled, &uiDataFilled);
    /* setup progress info fields */
    memset(&ProgressInfo, 0, sizeof(MAIProgressBuffer_t));
    ProgressInfo.uiFlags=0;
    ProgressInfo.hComp=hThisComp;
    ProgressInfo.tCurrentTime = 0;
    ProgressInfo.eBufferUnitType=MAI_UNIT_BYTES;
    ProgressInfo.uiBufferAvail=(uiMaxBufs-uiBufsFilled)*uiMaxBufSize;
    ProgressInfo.uiBufferUsed=uiDataFilled;
    ProgressInfo.uiTotalBufferCount=uiMaxBufs;
    ProgressInfo.uiUsedBufferCount=uiBufsFilled;
    /* make progress call */
    PUTPRINTF((M_TEXT("MP4DEMUX: _InBufferPoolStateCB() making ProgressCB(MAI_PROGRESS_BUFFER)\n"), ePoolState));
    g_pfProgressCB(hThisComp, MAI_PROGRESS_BUFFER, &ProgressInfo, sizeof(ProgressInfo));
  }
  PUTPRINTF((M_TEXT("MP4DEMUX: _InBufferPoolStateCB() exiting\n")));
}


static MAIStatus_e MAICompInitInput(MAICompHandle_t hComp, unsigned int uiPinID,
                                   pfMAICompGetBufferCB_t *pfInputGetBuffer,
                                   pfMAICompPutBufferCB_t *pfInputPutBuffer)
{
	MAIStatus_e		eStatus = MAI_STATUS_UNSUPPORTED;

#ifndef FILESOURCE
  if (uiPinID==0) /* one input pin only */
  {
	  /* return the get/set function pointers to the upstream component */
    if (pfInputGetBuffer)
	    *pfInputGetBuffer = MAIMP4Demux_GetBuffer;
    if (pfInputPutBuffer)
	    *pfInputPutBuffer = MAIMP4Demux_PutBuffer;
	  eStatus = MAI_STATUS_OK;
  }
#endif
  return eStatus;
}

static MAIStatus_e MAICompInitOutput(MAICompHandle_t hComp, unsigned int uiPinID,
                                   pfMAICompGetBufferCB_t pfOutputGetBuf, pfMAICompPutBufferCB_t pfOutputPutBuf,
                                   MAICompHandle_t hBufferOwnerComp)
{
	MAIStatus_e		eStatus = MAI_STATUS_UNSUPPORTED;
  if (uiPinID==0) /* video pin */
  {
	  g_pfOutputVideoGetBuf = pfOutputGetBuf; // Callback to get buffer from upstream component (video decoder)
	  g_pfOutputVideoPutBuf = pfOutputPutBuf; // Callback to send buffer to upstream component (video decoder)
    g_hOutputVideoOwner = hBufferOwnerComp;
	  eStatus = MAI_STATUS_OK;
  }
  else if (uiPinID==1) /* audio pin */
  {
	  g_pfOutputAudioGetBuf = pfOutputGetBuf; // Callback to get buffer from upstream component (video decoder)
	  g_pfOutputAudioPutBuf = pfOutputPutBuf; // Callback to send buffer to upstream component (video decoder)
    g_hOutputAudioOwner = hBufferOwnerComp;
	  eStatus = MAI_STATUS_OK;
  }
  return eStatus;
}

static MAIStatus_e MAICompGetMediaType(MAICompHandle_t hComp, MAICompDirection_e eDirection, unsigned int uiPinID, MAIMediaType_t *pMediaType)
{
  MAIStatus_e	eStatus = MAI_STATUS_UNSUPPORTED;
  if (uiPinID==0 && eDirection==MAICOMP_DIR_INPUT)
  {
    if (!pMediaType)
      eStatus=MAI_STATUS_BADARG;
    else
    {
      MAIMediaTypeStream_t *pStreamInfo=(MAIMediaTypeStream_t *)pMediaType;
      /* clear the info structure */
      if (pStreamInfo->MediaTypeInfo.uiSize<sizeof(MAIMediaTypeStream_t))
        eStatus=MAI_STATUS_BADARG;  /* caller didn't pass a large enough structure */
      else
      {
        memcpy(pStreamInfo, &g_StreamInfo, sizeof(MAIMediaTypeStream_t));
        eStatus = MAI_STATUS_OK;
      }
    }
  }
  else if (eDirection==MAICOMP_DIR_OUTPUT)
  {
    if (!pMediaType)
      eStatus=MAI_STATUS_BADARG;
    else
    {
      if (uiPinID==0)
      {
        MAIMediaTypeVideo_t *pVideoInfo=(MAIMediaTypeVideo_t *)pMediaType;
        /* clear the info structure */
        memset(pVideoInfo, 0, sizeof(MAIMediaTypeVideo_t));
        /* fill in Common MediaType fields */
        pVideoInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeVideo_t);
        pVideoInfo->MediaTypeInfo.eMType=MAI_MTYPE_VIDEO;
        pVideoInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_WMV;
        pVideoInfo->MediaTypeInfo.uiFlags=0;
        /* TBD - fill in Video MediaType specific fields */
        eStatus=MAI_STATUS_OK;
      }
      else if (uiPinID==1)
      {
        MAIMediaTypeAudio_t *pAudioInfo=(MAIMediaTypeAudio_t *)pMediaType;
        /* clear the info structure */
        memset(pAudioInfo, 0, sizeof(MAIMediaTypeAudio_t));
        /* fill in Common MediaType fields */
        pAudioInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeAudio_t);
        pAudioInfo->MediaTypeInfo.eMType=MAI_MTYPE_AUDIO;
        pAudioInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_WMA;
        pAudioInfo->MediaTypeInfo.uiFlags=0;
        /* TBD - fill in Audio MediaType specific fields */
        eStatus=MAI_STATUS_OK;
      }
      else /* unsupported pin */
      {
        memset(pMediaType, 0, sizeof(MAIMediaType_t));
        pMediaType->uiSize=sizeof(MAIMediaType_t);
        pMediaType->eMType=MAI_MTYPE_NONE;
        pMediaType->eMSubtype=MAI_MSUBTYPE_NONE;
        pMediaType->uiFlags=0;
      }
    }
  }
  return eStatus;
}

static MAIStatus_e MAICompSetErrorCB(MAICompHandle_t hComp, pfMAICompErrorCB_t pfCB)
{
  g_pfErrorCB = pfCB;
  return MAI_STATUS_OK;
}

static MAIStatus_e MAICompSetProgressCB(MAICompHandle_t hComp, pfMAICompProgressCB_t pfCB, unsigned int uiProgressSelectFlags)
{
  g_pfProgressCB = pfCB;
  g_uiProgressSelectFlags=uiProgressSelectFlags;
  return MAI_STATUS_OK;
}

/*
** Function: MAICompGetState(hComp, peStateOut)
** Descript: Get the component's running state.
*/
static MAIStatus_e MAICompGetState(MAICompHandle_t hComp, MAIRunState_e *peStateOut)
{
  if (peStateOut)
    *peStateOut=g_eCompState;
  return MAI_STATUS_OK;
}

static void _ChangeState(MAICompHandle_t hComp, MAIRunState_e eNewState)
{
  /* State Definitions:
      MAI_RUNSTATE_NONE - component not initialized
      MAI_RUNSTATE_INIT - component initialized, thread not started yet
      MAI_RUNSTATE_PLAYING - component initialized, thread active
      MAI_RUNSTATE_PAUSED - component initialized, thread active, processing paused
      MAI_RUNSTATE_STOPPED - component initialized, thread exited
      MAI_RUNSTATE_DESTROYING - MAICompEnd() in progress - destroying thread
  */
  if (g_eCompState!=eNewState) /* state changed */
  {
    MAIRunState_e eLastState=g_eCompState; /* save last state */
    g_eCompState=eNewState; /* change state */
    if (g_pfProgressCB &&
         (g_uiProgressSelectFlags & MAI_PROGRESS_STATE)!=0) /* deliver progress call to report state change */
    {
      MAIProgressState_t SProgressInfo;
      memset(&SProgressInfo, 0, sizeof(MAIProgressState_t));
      SProgressInfo.hComp=hComp;
      SProgressInfo.eCurrentState=eNewState;
      SProgressInfo.eLastState=eLastState;
      g_pfProgressCB(hComp, MAI_PROGRESS_STATE, &SProgressInfo, sizeof(MAIProgressState_t));
    }
  }
}

MAIStatus_e _ReportStart(MAICompHandle_t hComp)
{
	MAIStatus_e		eStatus = MAI_STATUS_OK;
  /* deliver progress call to report SOS */
  if (g_pfProgressCB &&
       (g_uiProgressSelectFlags & MAI_PROGRESS_STREAM)!=0)
  {
    MAIProgressStream_t ProgressInfo;
    APIPRINTF((M_TEXT("MP4DEMUX: _ReportStart() Delivering START\n")));
    /* setup progress info fields */
    memset(&ProgressInfo, 0, sizeof(MAIProgressState_t));
    ProgressInfo.uiFlags=MAI_PROGRESSFLAG_START;
    if (g_pfOutputVideoGetBuf && g_pfOutputVideoPutBuf && g_uiVideoSampleCount)
      ProgressInfo.uiFlags|=MAI_PROGRESSFLAG_VIDEO;
    if (g_pfOutputAudioGetBuf && g_pfOutputAudioPutBuf && g_uiAudioSampleCount)
      ProgressInfo.uiFlags|=MAI_PROGRESSFLAG_AUDIO;
    ProgressInfo.hComp=hComp;
    ProgressInfo.eCurrentState=g_eCompState;
    ProgressInfo.tCurrentTime=g_tLastPTS;
    /* make progress call */
    g_pfProgressCB(hComp, MAI_PROGRESS_STREAM, &ProgressInfo, sizeof(ProgressInfo));
  }
  return eStatus;
}

/* send output buffers with EOS flag */
MAIStatus_e _ReportEOS(MAICompHandle_t hComp)
{
	MAIStatus_e		eStatus = MAI_STATUS_OK;
  MAICompBuffer_t *pBufferInfo;
  if (g_eEOS!=EOS_DELIVERED)
  {
    if (g_pfOutputVideoGetBuf && g_pfOutputVideoPutBuf && g_uiVideoSampleCount &&
         MAI_STATUS_OK==g_pfOutputVideoGetBuf(g_hOutputVideoOwner,&pBufferInfo))
    {
      APIPRINTF((M_TEXT("MP4DEMUX: _ReportEOS(Video)\n")));
      pBufferInfo->dwFlags = MAICOMPBUF_FLAG_EOS;
      pBufferInfo->uiDataSize = 0;
      eStatus=g_pfOutputVideoPutBuf(g_hOutputVideoOwner, pBufferInfo);
    }
    if (g_pfOutputAudioGetBuf && g_pfOutputAudioPutBuf && g_uiAudioSampleCount &&
         MAI_STATUS_OK==g_pfOutputAudioGetBuf(g_hOutputAudioOwner,&pBufferInfo))
    {
      APIPRINTF((M_TEXT("MP4DEMUX: _ReportEOS(Video)\n")));
      pBufferInfo->dwFlags = MAICOMPBUF_FLAG_EOS;
      pBufferInfo->uiDataSize = 0;
      eStatus=g_pfOutputAudioPutBuf(g_hOutputAudioOwner, pBufferInfo);
    }
    if (g_pfProgressCB &&
         (g_uiProgressSelectFlags & MAI_PROGRESS_STREAM)!=0) /* deliver progress call to report EOS */
    {
      MAIProgressStream_t ProgressInfo;
      APIPRINTF((M_TEXT("MP4DEMUX: _ReportEOS() Delivering EOS\n")));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -