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

📄 maimp4demux.c

📁 mpeg4 demux 代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            }
            g_bVDiscon=M_TRUE;
          }
          else
          {
            g_uiVideoSampleNum++;
            uiVideoSamplesLeft--;
          }
        } //end of video sample if
        else if(index == AUDIO && uiAudioSamplesLeft > 0)
        {
          if (g_pfOutputAudioGetBuf)
          {
            MAICompBuffer_t *pBufferInfo;
            unsigned int sampleread=0;
            m_bool bNewPTS=M_TRUE;
            sample_info(g_uiAudioSampleNum,index,&samplesize,&filepos);
            scount = sample_timming_info(g_uiAudioSampleNum,index,&apts);
            bIdle=M_FALSE;
            bAudioPTSKnown=M_TRUE;
            g_tLastPTS=apts;
            DPRINTF((M_TEXT("MP4DEMUX: g_uiAudioSampleNum %d, apts %d ,scount %d\n"),g_uiAudioSampleNum,apts,scount));
            if (MAI_STATUS_OK!=inputseek(filepos))
              break;

            while (sampleread<samplesize) /* we may do multiple Get/PutBuffer to output sample */
            {
              unsigned int bytestoread;
              PUTPRINTF((M_TEXT("MP4DEMUX: OutputAudioGetBuf()\n")));
              if (MAI_STATUS_OK!=g_pfOutputAudioGetBuf(g_hOutputAudioOwner,&pBufferInfo))
                break;
              pBufferInfo->uiDataSize=0;
              bytestoread=(samplesize-sampleread);
              if (bytestoread>pBufferInfo->uiBufSize)
                bytestoread=pBufferInfo->uiBufSize;
              if (MAI_STATUS_OK!=inputread(pBufferInfo->pBuffer, bytestoread, &bytesread))
              {
                if (pBufferInfo) /* return the output buffer */
                  g_pfOutputAudioPutBuf(g_hOutputAudioOwner, pBufferInfo);
                break;
              }
              //fwrite(pBufferInfo->pBuffer+sampleread,1,bytesread,fp_video);

              pBufferInfo->dwFlags |= MAICOMPBUF_FLAG_AUDIO;
              if (bNewPTS)
              {
                TIME_LOHI_TO_MAITIME(apts, 0, pBufferInfo->tTimeStamp);
                pBufferInfo->dwFlags |= MAICOMPBUF_FLAG_PTS;
                bNewPTS=M_FALSE;
              }
              if (g_bADiscon) /* See if stream discontinuity  */
              {
                pBufferInfo->dwFlags |= MAICOMPBUF_FLAG_DATADISCON;
                g_bADiscon = M_FALSE;
                PUTPRINTF((M_TEXT("MP4DEMUX: g_uiAudioSampleNum=%d apts=%d DATADISCON\n"),
                   g_uiAudioSampleNum,apts));
              }
              pBufferInfo->uiDataSize = bytesread;
              PUTPRINTF((M_TEXT("MP4DEMUX: OutputAudioPutBuf(DataSize=%d PTS=%d Flags=0x%X)\n"),
                   pBufferInfo->uiDataSize,MAITIME_LO32(pBufferInfo->tTimeStamp)));
              g_pfOutputAudioPutBuf(g_hOutputAudioOwner, pBufferInfo);
              pBufferInfo=NULL;
              sampleread+=bytesread;
            }
          }
          if ((g_uiCurrentSpeed&MAI_SPEED_REVERSEFLAG)!=0)
          {
            if (g_uiVideoSampleNum<uiAudioSampleInc)
            {
              g_uiAudioSampleNum=0;
              uiAudioSamplesLeft=0;
            }
            else
            {
              g_uiAudioSampleNum-=uiAudioSampleInc;
              uiAudioSamplesLeft+=uiAudioSampleInc;
            }
            g_bADiscon=M_TRUE;
          }
          else
          {
            g_uiAudioSampleNum++;
            uiAudioSamplesLeft--;
          }
        }
        if (bIdle)
        {
			    MAIOSSleep(200);  /* prevent spinning when reaching last packet */
		    }
      } /* while loop to process samples */
    }
    else
    {
			MAIOSSleep(200);  /* prevent spinning in unsupported states */
		}
  } /* main while loop */

  if (g_eCompState!=MAI_RUNSTATE_NONE
        && (g_eCompState&(MAI_RUNSTATE_INIT|MAI_RUNSTATE_DESTROYING))==0)
    _ChangeState(hComp, MAI_RUNSTATE_INIT);
  _endprocessing(hComp);
  APIPRINTF((M_TEXT("MP4DEMUX: DemuxThread() exit\n")));
  return 0;
}


static MAIStatus_e MAIMP4Demux_GetBuffer(MAICompHandle_t hComp,MAICompBuffer_t **ppBufferInfo)
{
  MAICompBuffer_t *pFreeBufferInfo=NULL;
  MAIStatus_e eStatus=MAI_STATUS_NOBUFAVAIL;
  PUTPRINTF((M_TEXT("MP4DEMUX: MAIDecoder_GetBuffer\n")));

  if ((g_eCompState&(MAI_RUNSTATE_DESTROYING|MAI_RUNSTATE_STOPPED))!=0)
    eStatus=MAI_STATUS_STOPPED;
  else
  {
    /* get an empty buffer from the buffer pool */
    eStatus=MAICompBufferPoolGet(g_hInBufferPool, MAI_BUFSTATE_EMPTY, &pFreeBufferInfo, MAI_TIMEOUT_INFINITE);

    if ((g_eCompState&(MAI_RUNSTATE_DESTROYING|MAI_RUNSTATE_STOPPED))!=0)
    {
      if (eStatus==MAI_STATUS_OK) /* put back the buffer since we're terminating */
        eStatus=MAICompBufferPoolPut(g_hInBufferPool, MAI_BUFSTATE_EMPTY, pFreeBufferInfo, MAI_TIMEOUT_INFINITE);
      eStatus=MAI_STATUS_STOPPED;
    }
    else if (eStatus==MAI_STATUS_OK)
      *ppBufferInfo = pFreeBufferInfo;
  }
  PUTPRINTF((M_TEXT("MP4DEMUX: MAIDecoder_GetBuffer() done: %d\n"), eStatus));
  return eStatus;
}

static MAIStatus_e MAIMP4Demux_PutBuffer(MAICompHandle_t hComp,MAICompBuffer_t *pBufferInfo)
{
  MAIStatus_e eStatus;
  PUTPRINTF((M_TEXT("MP4DEMUX: MAIDecoder_PutBuffer() enter: size=%d pts=%d\n"), pBufferInfo->uiDataSize, (unsigned int)pBufferInfo->tTimeStamp));
  if ((pBufferInfo->dwFlags & MAICOMPBUF_FLAG_EOS)!=0)
  {
    APIPRINTF((M_TEXT("MP4DEMUX: MAIDecoder_PutBuffer() MAICOMPBUF_FLAG_EOS\n")));
  }
  /* put a filled buffer back into the buffer pool */
  eStatus=MAICompBufferPoolPut(g_hInBufferPool, MAI_BUFSTATE_FILLED, pBufferInfo, MAI_TIMEOUT_INFINITE);
  PUTPRINTF((M_TEXT("MP4DEMUX: MAIDecoder_PutBuffer() done: %d\n"), eStatus));
  return eStatus;
}

static MAIStatus_e MAICompConnect(MAICompHandle_t hComp, MAICompHandle_t hCompToConnect, MAICompDirection_e eDirection, MAICompPinID_t uiPinID, MAIMediaType_t *pMediaType)
{
  MAIStatus_e	eStatus = MAI_STATUS_UNSUPPORTED;
  APIPRINTF((M_TEXT("MP4DEMUX: MAICompConnect(hCompToConnect=%p, eDirection=%d)\n"),
    hCompToConnect, eDirection));
  if (eDirection==MAICOMP_DIR_INPUT)
  {
    MAICompHandleInfo_t *pConnectToCompInfo=(MAICompHandleInfo_t *)hCompToConnect;
    if (!pConnectToCompInfo)
    {
      /* no handle, so we disconnect */
      g_hReaderComp=M_NULL;
      eStatus=MAI_STATUS_OK;
    }
    else if ((pConnectToCompInfo->Info.eType&(MAICOMP_TYPE_READER|MAICOMP_TYPE_CAPTURE))==0)
      eStatus=MAI_STATUS_BADARG; /* not a reader/capture source filter */
    else if (!pConnectToCompInfo->pfReadBuffer)
      eStatus=MAI_STATUS_BADARG; /* no ReadBuffer interface to pull data from */
    else
    {
      g_hReaderComp=hCompToConnect; /* save the reader handle */
      /* start processing - this will attempt open the file (read headers, etc.) */
	    eStatus=_startprocessing(hComp);
	    if (eStatus!=MAI_STATUS_OK && eStatus!=MAI_STATUS_ALREADYOPEN)
      {
	      APIPRINTF((M_TEXT("MP4DEMUX: MAICompConnect(): _startprocessing failed: eStatus=0x%08X\n"), eStatus));
      }
      else
      {
	      APIPRINTF((M_TEXT("MP4DEMUX: MAICompConnect(): _startprocessing success\n")));
      }
    }
  }
  return eStatus;
}

static MAIStatus_e MAICompSendCommand(MAICompHandle_t hComp, m_u32 uiCommand,
                               m_u32 uiParam1, m_u32 uiParam2, m_u32 uiParam3,
                               void *pUserInstance, MAITimeOut_t uiTimeOut)
{
  MAIStatus_e eStatus = MAI_STATUS_OK;

  switch (uiCommand)
  {
    case MAICOMP_CMD_SEEK:
      APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_SEEK) %d %d\n"), uiParam1, uiParam2));
      g_lSeekValue = (m_s32)uiParam2; /* position in the file to seek to */
      g_eSeekType = (MAISeekType_e)uiParam1;
      if (g_eCompState==MAI_RUNSTATE_NONE || g_eCompState==MAI_RUNSTATE_INIT)
      {
        /* not streaming, so it's safe to just do a seek */
        eStatus=_streamseek(hComp, g_lSeekValue, g_eSeekType);
        g_bSeekPending = M_FALSE;
      }
      else /* we're streaming, so Reads may be busy */
      {
        g_bSeekPending = M_TRUE; /* Flag a seek to the running thread */
        //_ChangeState(hComp, MAI_RUNSTATE_SEEKING);
        //eStatus=MAI_STATUS_WRONGSTATE; /* can't seek while thread is busy reading */
      }
      break;

    case MAICOMP_CMD_PLAY:
      if (g_eCompState!=MAI_RUNSTATE_NONE && g_eCompState!=MAI_RUNSTATE_INIT)
      {
        unsigned int uiTotalWait=0;
        MAISpeed_e NewSpeed=(MAISpeed_e)uiParam1;
        unsigned int uiNewPlayRate=NewSpeed&MAI_SPEED_RATEMASK;
        APIPRINTF((M_TEXT("MP4DEMUX: SendCommand() CMD_PLAY(speed=0x%X): state=0x%X CurrentSpeed=%d\n"),
              uiParam1, g_eCompState, g_uiCurrentSpeed));
        /* wait for completion of any special state transitions */
        while ((g_eCompState&(MAI_RUNSTATE_STARTING|MAI_RUNSTATE_PAUSING|MAI_RUNSTATE_SEEKING|MAI_RUNSTATE_STOPPING))!=0
                  && uiTotalWait<1000)
        {
          uiTotalWait+=200;
          MAIOSSleep(200);
        }
        /* wait for any pending seeks */
        while (g_bSeekPending && (g_eCompState&(MAI_RUNSTATE_PLAYING|MAI_RUNSTATE_PAUSED|MAI_RUNSTATE_SEEKING))!=0
                  && uiTotalWait<10000)
        {
          uiTotalWait+=200;
          MAIOSSleep(200);
        }
        APIPRINTF((M_TEXT("MP4DEMUX: SendCommand() CMD_PLAY(): wait done: time=%d state=0x%X\n"),
              uiTotalWait, g_eCompState));
        if (uiNewPlayRate!=0 && NewSpeed!=MAI_SPEED_UNSPECIFIED)
        {
          g_uiNextSpeed=NewSpeed;
          g_bSpeedChange=M_TRUE;
        }
      }
      if (g_eCompState==MAI_RUNSTATE_PAUSED)
        _ChangeState(hComp, MAI_RUNSTATE_PLAYING);
      else if ((g_eCompState&(MAI_RUNSTATE_STOPPING|MAI_RUNSTATE_STOPPED))!=0)
      {
        _ChangeState(hComp, MAI_RUNSTATE_STARTING);
        if (g_hInBufferPool!=M_HANDLE_INVALID)
        {
          APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_PLAY) ClearAbort(In)\n")));
          MAICompBufferPoolClearAbort(g_hInBufferPool);
        }
      }
      break;

    case MAICOMP_CMD_PAUSE:
      APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_PAUSE) enter: state=0x%X\n"), g_eCompState));
      if ((g_eCompState&(MAI_RUNSTATE_PLAYING|MAI_RUNSTATE_PAUSING))!=0)
      {
        unsigned int uiTotalWait=0;
        if (g_hInBufferPool!=M_HANDLE_INVALID)
        {
          APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_PAUSE) ClearAbort(In)\n")));
          MAICompBufferPoolClearAbort(g_hInBufferPool);
        }
        _ChangeState(hComp, MAI_RUNSTATE_PAUSING);
        while ((g_eCompState&MAI_RUNSTATE_PAUSED)==0 && uiTotalWait<uiTimeOut)
        {
          uiTotalWait+=200;
          MAIOSSleep(200);
        }
      }
      APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_PAUSE) done: state=0x%X\n"),g_eCompState));
      break;

    case MAICOMP_CMD_STOP:
      APIPRINTF(("MP4DEMUX: SendCommand(MAICOMP_CMD_STOP)\n"));
      if (g_eCompState!=MAI_RUNSTATE_NONE &&
            (g_eCompState&(MAI_RUNSTATE_STARTING|MAI_RUNSTATE_PLAYING|MAI_RUNSTATE_PAUSING|MAI_RUNSTATE_PAUSED|MAI_RUNSTATE_STOPPING))!=0)
      {
        unsigned int uiTotalWait=0;
        _ChangeState(hComp, MAI_RUNSTATE_STOPPING);
        if (g_hInBufferPool!=M_HANDLE_INVALID)
        {
          APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_STOP) PoolAbort(In)\n")));
          MAICompBufferPoolAbort(g_hInBufferPool, M_FALSE);
        }
        while ((g_eCompState&MAI_RUNSTATE_STOPPING)!=0 && uiTotalWait<uiTimeOut)
        {
          uiTotalWait+=200;
          MAIOSSleep(200);
        }
        g_uiOffset=0;
      }
      else
      {
        APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(MAICOMP_CMD_STOP) wrong state\n")));
        eStatus=MAI_STATUS_WRONGSTATE;
      }
      break;

    default:
      APIPRINTF((M_TEXT("MP4DEMUX: SendCommand(%d) unsupported\n"), uiCommand));
      eStatus=MAI_STATUS_UNSUPPORTED;
      break;
  }
  return eStatus;
}

static MAIStatus_e MAICompGetParam(MAICompHandle_t hComp, unsigned int uiParam, void *pvParamData, unsigned int uiDataSize)
{
  MAIStatus_e eStatus = MAI_STATUS_OK;
  if (!pvParamData)
    eStatus=MAI_STATUS_BADARG;
  else
    switch(uiParam)
    {
      case MAI_PARAM_PRIORITY:
        *((unsigned int *)pvParamData) = g_uiThreadPriority;
        break;
      case MAI_PARAM_LOOP:
        APIPRINTF((M_TEXT("MP4DEMUX: MAICompGetParam(MAI_PARAM_LOOP) bLoop=%d\n"), uiParam));
        if (pvParamData && uiDataSize>=sizeof(m_bool)) /* make sure user supplies us a big enough buffer to return setting */
          *((m_bool *)pvParamData)=g_bLooping;
        else
          eStatus=MAI_STATUS_BADARG;
        break;
      case MAI_PARAM_STREAMINDEX:
        if (uiDataSize<sizeof(MAIParamStreamIndex_t))
          eStatus=MAI_STATUS_BADARG; /* structure smaller than expected */
        else
        {
          MAIParamStreamIndex_t *pStreamIndex=(MAIParamStreamIndex_t *)pvParamData;
          unsigned int uiTotalIndexSize=sizeof(MAIParamStreamIndex_t);
          if (g_bFileOpen)
          {
            uiTotalIndexSize+=sizeof(MAIParamStreamIndexEntry_t)*g_uiVideoSampleCount;
            pStreamIndex->uiSize=uiTotalIndexSize;
            if ((pStreamIndex->uiFlags&MAI_STREAMINDEX_FLAG_QUERYSIZE)!=0)
            {
              /* caller is just interested in the size of the memory required to hold the index */
              eStatus=MAI_STATUS_OK;
            }
            else if (pStreamIndex->uiSize<uiTotalIndexSize)
          

⌨️ 快捷键说明

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