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

📄 maimp4demux.c

📁 mpeg4 demux 代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			{
				pData = (m_u8 *) malloc(sizeof(m_u8) * 16*1024);
				if(pData != NULL)
				{
					GetConfigInfo(pData,&lData);
					pBufferInfo->uiDataSize = lData;
					pBufferInfo->dwFlags = MAICOMPBUF_FLAG_NEWFORMAT;
					pBufferInfo->tTimeStamp = 0;
					memcpy(pBufferInfo->pBuffer, pData,lData);
					APIPRINTF((M_TEXT("MP4Demux: Passing config data to the video decoder, data size %d\n"),lData));
					g_pfOutputVideoPutBuf(g_hOutputVideoOwner,pBufferInfo);
					free(pData);
				}

			}
		}
}
//#define DUMP_OUTPUT
// Main working thread...
static m_u32 DemuxThread(MAIOSThread_t hThread, void *pUserData)
{
  MAICompHandle_t hComp=(MAICompHandle_t)pUserData;
  MAIStatus_e eStatus = MAI_STATUS_OK;
  unsigned int codec_version=0;
  unsigned int bytesread;
  TRACK_TYPES index;
  m_u32 filepos;
  m_u32 samplesize;
  m_u32 apts,vpts;
  m_bool  bAudioPTSKnown=M_FALSE, bVideoPTSKnown=M_FALSE;
  long vsize = 0;
  long scount;

	APIPRINTF((M_TEXT("MP4DEMUX: DemuxThread() enter: State=%d Terminate=%d\n"), g_eCompState, g_bTerminate) );
#ifdef DUMP_OUTPUT
  FILE	*fp_audio,*fp_video;

	fp_audio = fopen("audio.es","wb");
	if(fp_audio == NULL)
	{
		DPRINTF((M_TEXT("could not open audio output file   \n")));
		return 1;
	}
	fp_video = fopen("video.es","wb");
	if(fp_audio == NULL)
	{
		DPRINTF((M_TEXT("could not open video output file   \n")));
		return 1;
	}
#endif
	eStatus=_startprocessing(hComp);
	if (eStatus!=MAI_STATUS_OK && eStatus!=MAI_STATUS_ALREADYOPEN)
  {
	  APIPRINTF((M_TEXT("MP4DEMUX: DemuxThread(): _startprocessing failed: eStatus=0x%08X\n"), eStatus));
		return 0;
  }

  APIPRINTF((M_TEXT("MP4DEMUX: Start of demux loop\n")));
	while (g_eCompState!=MAI_RUNSTATE_NONE && g_eCompState!=MAI_RUNSTATE_DESTROYING)
	{
      if (g_eCompState==MAI_RUNSTATE_STOPPING)
        _ChangeState(hComp, MAI_RUNSTATE_STOPPED);
      if (g_eCompState==MAI_RUNSTATE_PAUSED || g_eCompState==MAI_RUNSTATE_STOPPED)
      {
        MAIOSSleep(200);
        continue;
      }
    /* start of a new stream */
    APIPRINTF((M_TEXT("MP4DEMUX: Start of New Stream\n")));
    _ChangeState(hComp, MAI_RUNSTATE_STARTING);

    APIPRINTF( (M_TEXT("MP4DEMUX: DemuxThread() Send SOS\n")) );
    _SendProgressCB(hComp, MAI_PROGRESSFLAG_START);

    _ReportStart(hComp); /* report Start of stream to engine */
		if ((g_eCompState & (MAI_RUNSTATE_INIT|MAI_RUNSTATE_IDLE|MAI_RUNSTATE_PAUSING|MAI_RUNSTATE_PAUSED|MAI_RUNSTATE_STARTING|MAI_RUNSTATE_PLAYING)) != 0 )
		{
      unsigned int loop_count=0;
      long uiVideoSamplesLeft=0, uiAudioSamplesLeft=0;
      unsigned int uiVideoSampleInc=1, uiAudioSampleInc=1;
		  /* run demux loop */
      if ((g_uiCurrentSpeed&MAI_SPEED_REVERSEFLAG)!=0)
      {
        uiAudioSamplesLeft = g_uiAudioSampleNum;
        uiVideoSamplesLeft = g_uiVideoSampleNum;
      }
      else
      {
        uiAudioSamplesLeft = g_uiAudioSampleCount - g_uiAudioSampleNum;
        uiVideoSamplesLeft = g_uiVideoSampleCount - g_uiVideoSampleNum;
      }
			APIPRINTF((M_TEXT("MP4DEMUX: total video samples %d, audio samples %d \n"),uiVideoSamplesLeft,uiAudioSamplesLeft));

			ConfigDecoders();
      /* loop while we still have audio or video packets left over */
			while ( (g_eCompState & (MAI_RUNSTATE_INIT|MAI_RUNSTATE_IDLE|MAI_RUNSTATE_PAUSING|MAI_RUNSTATE_PAUSED|MAI_RUNSTATE_STARTING|MAI_RUNSTATE_PLAYING)) != 0)
			{
        m_bool bIdle=M_TRUE;
				loop_count++;
        /* See if a speed change is requested */
        if (g_bSpeedChange)
        {
          g_bSpeedChange=M_FALSE;
          g_uiPlaySleep=0; /* default to no sleeps */
          if (g_uiCurrentSpeed!=g_uiNextSpeed)
          {
            /* speed has changed */
            if ((g_uiNextSpeed&MAI_SPEED_REVERSEFLAG)!=0)
            {
              unsigned int uiPlayRate=(g_uiNextSpeed==MAI_SPEED_UNSPECIFIED)?MAI_SPEED_NORMAL:(g_uiNextSpeed&MAI_SPEED_RATEMASK);
              /* pick a reasonable sleep time: (spacing_in_ms*MAI_SPEED_NORMAL)/uiPlayRate */
              g_uiPlaySleep=(60*MAI_SPEED_NORMAL)/uiPlayRate;
              if (g_uiPlaySleep>1000)
                g_uiPlaySleep=1000;

              if (g_uiAudioSampleNum>2)
                g_uiAudioSampleNum-=2;
              else
                g_uiAudioSampleNum = 0;
              if (g_uiVideoSampleNum>2)
                g_uiVideoSampleNum-=2;
              else
                g_uiVideoSampleNum = 0;
            }
            if (g_uiAudioSampleCount)
            {
              /* make sure audio is synced up with video sample position */
              g_uiAudioSampleNum=time_to_sample(AUDIO, vpts+AUDIO_READ_AHEAD);              // DARRELL
              apts=vpts;
            }
            /* check for direction change */
            if ((g_uiNextSpeed&MAI_SPEED_REVERSEFLAG)!=(g_uiCurrentSpeed&MAI_SPEED_REVERSEFLAG))
            {
              /* codecs must treat direction change as a discontinuity */
              g_bVDiscon=M_TRUE;
              g_bADiscon=M_TRUE;
            }
            /* update Samples Left variables */
            if ((g_uiNextSpeed&MAI_SPEED_REVERSEFLAG)!=0)
            {
              uiAudioSamplesLeft = g_uiAudioSampleNum;
              uiVideoSamplesLeft = g_uiVideoSampleNum;
            }
            else
            {
              uiAudioSamplesLeft = g_uiAudioSampleCount - g_uiAudioSampleNum;
              uiVideoSamplesLeft = g_uiVideoSampleCount - g_uiVideoSampleNum;
            }
            g_uiCurrentSpeed=g_uiNextSpeed;
          }
        }
        /* See if a seek is pending */
        if (g_bSeekPending)
        {
          if (_streamseek(hComp, g_lSeekValue, g_eSeekType)==MAI_STATUS_OK)
          {
            g_bVDiscon=M_TRUE;
            g_bADiscon=M_TRUE;
          }
          if ((g_uiCurrentSpeed&MAI_SPEED_REVERSEFLAG)!=0)
          {
            uiAudioSamplesLeft = g_uiAudioSampleNum;
            uiVideoSamplesLeft = g_uiVideoSampleNum;
          }
          else
          {
            uiAudioSamplesLeft = g_uiAudioSampleCount - g_uiAudioSampleNum;
            uiVideoSamplesLeft = g_uiVideoSampleCount - g_uiVideoSampleNum;
          }
          bAudioPTSKnown = 0;
          bVideoPTSKnown = 0;
          g_bSeekPending = M_FALSE;
          g_eEOS=EOS_NONE;
          _ReportStart(hComp); /* report Start of stream to engine */
        }
        if ((g_eCompState&(MAI_RUNSTATE_PAUSED|MAI_RUNSTATE_PAUSING))!=0)
        {
          _ChangeState(hComp, MAI_RUNSTATE_PAUSED);
          MAIOSSleep(200);
          continue;
        }
        if ((!g_pfOutputAudioGetBuf || uiAudioSamplesLeft==0) && (!g_pfOutputVideoGetBuf || uiVideoSamplesLeft==0))
        {
          m_bool bPausingAtEOS=M_FALSE;
          /* no more data to read - must be EOS */
          if ((g_eCompState&(MAI_RUNSTATE_INIT|MAI_RUNSTATE_STARTING|MAI_RUNSTATE_PLAYING)) != 0)
          {
            APIPRINTF(( M_TEXT("MP4DEMUX: Pausing at EOS\n") ));
            _ChangeState(hComp, MAI_RUNSTATE_PAUSING); /* enter pause since we can't read past EOS */
            bPausingAtEOS=M_TRUE;
          }
          _ReportEOS(hComp);
          if (g_bLooping)
          {
            APIPRINTF(( M_TEXT("MP4DEMUX: Looping at EOS\n") ));
            if (bPausingAtEOS && (g_eCompState&(MAI_RUNSTATE_PLAYING|MAI_RUNSTATE_PAUSING))!=0)
              _ChangeState(hComp, MAI_RUNSTATE_PAUSED); /* we should always be in paused state during seek */
            else
              bPausingAtEOS=M_FALSE;
            APIPRINTF(( M_TEXT("MP4DEMUX: Looping set SeekPending(TRUE)\n") ));
            g_bSeekPending = M_TRUE;
            g_lSeekValue = 0; /* seek to beginning */
            g_eSeekType = MAI_SEEKTYPE_ABS;
            if (bPausingAtEOS)
              _ChangeState(hComp, MAI_RUNSTATE_STARTING); /* we'll be starting up again after seek */
          }
          continue;
        }

        /* decide if we should read next audio or video packet */
        DPRINTF((M_TEXT("MP4DEMUX: videonum=%d vpts=%d(%d) audionum=%d apts=%d(%d)\n"),
               g_uiVideoSampleNum,vpts,bVideoPTSKnown,
               g_uiAudioSampleNum,apts,bAudioPTSKnown));
        if (!g_pfOutputAudioGetBuf) /* audio output not connected */
					index = VIDEO;
        else if (!g_pfOutputVideoGetBuf) /* video output not connected */
					index = AUDIO;
        else if ((g_uiCurrentSpeed&(MAI_SPEED_REVERSEFLAG|MAI_SPEED_RATEMASK))!=MAI_SPEED_NORMAL)
        {
          /* trick mode - so provide only Video */
          index = VIDEO;
        }
        else if (bAudioPTSKnown && bVideoPTSKnown)
        {
          /* use PTS to determine which stream to read from next */
          if (uiAudioSamplesLeft>0 && apts<(vpts+AUDIO_READ_AHEAD))
					  index = AUDIO;
          else
					  index = VIDEO;
        }
        else
        {
          /* worst case, just cycle between audio and video packet reading -  VERY inefficient! */
				  if(uiVideoSamplesLeft==0 ||
            (uiAudioSamplesLeft>0 && (loop_count%2)))
					  index = AUDIO;
				  else
					  index = VIDEO;
        }
        if ((g_eCompState&MAI_RUNSTATE_STARTING)!=0 && (uiVideoSamplesLeft || uiAudioSamplesLeft))
        {
          g_eEOS=EOS_NONE; /* clear EOS, we have samples to play */
          _ChangeState(hComp, MAI_RUNSTATE_PLAYING);
        }

        if(index == VIDEO && uiVideoSamplesLeft > 0)
        {
          if (g_pfOutputVideoGetBuf)
          {
            MAICompBuffer_t *pBufferInfo;
            unsigned int sampleread=0;
            m_bool bNewPTS=M_TRUE;
            sample_info(g_uiVideoSampleNum,index,&samplesize,&filepos);
            scount = sample_timming_info(g_uiVideoSampleNum,index,&vpts);
            bIdle=M_FALSE;
            bVideoPTSKnown=M_TRUE;
            g_tLastPTS=vpts;
            DPRINTF((M_TEXT("MP4DEMUX: g_uiVideoSampleNum=%d vpts=%d scount=%d samplesize=%d\n"),
                   g_uiVideoSampleNum,vpts,scount,samplesize));
            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: OutputVideoGetBuf()\n")));
              if (MAI_STATUS_OK!=g_pfOutputVideoGetBuf(g_hOutputVideoOwner,&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_pfOutputVideoPutBuf(g_hOutputVideoOwner, pBufferInfo);
                }
                break;
              }
              //fwrite(pBufferInfo->pBuffer+sampleread,1,bytesread,fp_video);

              pBufferInfo->dwFlags |= MAICOMPBUF_FLAG_VIDEO;
              if (bNewPTS)
              {
                TIME_LOHI_TO_MAITIME(vpts, 0, pBufferInfo->tTimeStamp);
                pBufferInfo->dwFlags |= MAICOMPBUF_FLAG_PTS;
                bNewPTS=M_FALSE;
              }
              if (g_bVDiscon) /* See if stream discontinuity  */
              {
                PUTPRINTF((M_TEXT("MP4DEMUX: g_uiVideoSampleNum=%d vpts=%d DATADISCON\n"),
                   g_uiVideoSampleNum,vpts));
                pBufferInfo->dwFlags |= MAICOMPBUF_FLAG_DATADISCON;
                g_bVDiscon = M_FALSE;
              }
              pBufferInfo->uiDataSize = bytesread;
              PUTPRINTF((M_TEXT("MP4DEMUX: OutputVideoPutBuf(DataSize=%d PTS=%d Flags=0x%X)\n"),
                   pBufferInfo->uiDataSize,MAITIME_LO32(pBufferInfo->tTimeStamp)));
              g_pfOutputVideoPutBuf(g_hOutputVideoOwner, pBufferInfo);
              pBufferInfo=NULL;
              sampleread+=bytesread;
            }
            if (g_uiPlaySleep)
              MAIOSSleep(g_uiPlaySleep);
          }
          else
          { // video decoder is not connected
#ifdef DUMP_OUTPUT
            m_u8 *data_buffer;
            sample_info(g_uiVideoSampleNum,index,&samplesize,&filepos);
            scount = sample_timming_info(g_uiAudioSampleNum,index,&apts);
            //DPRINTF((M_TEXT("MP4DEMUX: g_uiVideoSampleNum %d, vpts %d, scount %d\n"),g_uiVideoSampleNum,vpts,scount));
            if(vsize+samplesize > 10000)
              vsize = vsize;
            if (MAI_STATUS_OK!=inputseek(filepos))
              break;
            data_buffer = (m_u8*) malloc(samplesize * sizeof(m_u8));
            if(data_buffer == NULL) {
              ERRORPRINTF((M_TEXT("MP4DEMUX: Could not allocate memory, sample size %d, sample num %d \n"),samplesize,g_uiVideoSampleNum));
              _ChangeState(hComp, MAI_RUNSTATE_ERROR);
              break;
            }
            if (MAI_STATUS_OK!=inputread(data_buffer, samplesize, &bytesread))
              break;
            fwrite(data_buffer,1,bytesread,fp_video);
            vsize += bytesread;
            if(data_buffer != NULL) {
              free(data_buffer);
              data_buffer = NULL;
            }
#endif
          }
          if ((g_uiCurrentSpeed&MAI_SPEED_REVERSEFLAG)!=0)
          {
            if (g_uiVideoSampleNum<uiVideoSampleInc)
            {
              g_uiVideoSampleNum=0;
              uiVideoSamplesLeft=0;
            }
            else
            {
              g_uiVideoSampleNum-=uiVideoSampleInc;
              uiVideoSamplesLeft+=uiVideoSampleInc;

⌨️ 快捷键说明

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