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

📄 maimp4demux.c

📁 mpeg4 demux 代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* setup progress info fields */
      memset(&ProgressInfo, 0, sizeof(MAIProgressState_t));
      ProgressInfo.uiFlags=MAI_PROGRESSFLAG_EOS;
      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));
    }
    g_eEOS=EOS_DELIVERED;
  }
  return eStatus;
}

#ifdef FILESOURCE
/*
** Function: MAICompSetStream(hComp, uiStreamID, pszURI, eURIType, pMediaType)
** Descript: Set stream source.
*/
static MAIStatus_e MAICompSetStream(MAICompHandle_t hComp, unsigned int uiStreamID, MAIStr_t *pURI, MAIStrType_e eURIType, MAIMediaType_t *pMediaType)
{
  MAIStatus_e eStatus = MAI_STATUS_OK;
	if (!pURI)
	{
    _endprocessing(hComp);
    inputclose(hComp);
    if (g_bInit)
      CloseParser();
    g_bInit=M_FALSE;
	}
	else
	{
    /* did we receive stream mediatype info? */
    if (pMediaType && (pMediaType->uiFlags&MAI_MTFLAG_TYPESTREAM)!=0 && pMediaType->uiSize>=sizeof(MAIMediaTypeStream_t))
    {
      MAIMediaTypeStream_t *pStreamInfo=(MAIMediaTypeStream_t *)pMediaType;
      /* store mediatype info that may be passed from engine's prescan */
      unsigned int uiMediaTypeSize=(pMediaType->uiSize>sizeof(MAIMediaTypeStream_t))?sizeof(MAIMediaTypeStream_t):pMediaType->uiSize;
      if ((g_StreamInfo.uiFlags&MAI_STREAMMTFLAG_FORMATKNOWN)==0)
      {
        /* format not yet determined by parser, so take all format fields being received */
        memcpy(&g_StreamInfo, pMediaType, uiMediaTypeSize);
        g_StreamInfo.MediaTypeInfo.uiSize=uiMediaTypeSize;
      }
      else
      {
        /* just take the fields we don't know */
        g_StreamInfo.LenInBytes=pStreamInfo->LenInBytes;
      }
    }
    else
    {
      memset(&g_StreamInfo, 0, sizeof(MAIMediaTypeStream_t));
      g_StreamInfo.MediaTypeInfo.uiFlags=MAI_MTFLAG_TYPESTREAM;
      g_StreamInfo.MediaTypeInfo.uiSize=sizeof(MAIMediaTypeStream_t);
    }
    /* open a URI */
#ifdef UNICODE
		eStatus=MAI_STATUS_UNSUPPORTED;
#else
		if (eURIType==MAI_STRTYPE_USER)
		{
		 /* add support for User defined object here */
			void *pObject=(void *)pURI;
			APIPRINTF((M_TEXT("MP4DEMUX: SetStream(%d, %p, USER) pObject=%p\n"), uiStreamID, pURI, pObject));
			/* not yet supported */
			eStatus=MAI_STATUS_UNSUPPORTED;
		}
		else if (eURIType==MAI_STRTYPE_CHAR)
    {
      char *pszURI=(char *)pURI;
      APIPRINTF((M_TEXT("MP4DEMUX: SetStream(%d, %s, CHAR)\n"), uiStreamID, pszURI));
      strcpy(m_pszFilePath, pszURI); /* File to read */

      /* make sure previous file is closed */
      _endprocessing(hComp);
      inputclose(hComp);
      if (g_bInit)
        CloseParser();
      g_bInit=M_FALSE;
      /* open new file */
      eStatus=inputopen();
    }
    else
      eStatus=MAI_STATUS_BADARG;
#endif
	}
  return eStatus;
}
#endif

static MAIStatus_e MAICompStart(MAICompHandle_t hComp)
{
  MAIStatus_e		eStatus = MAI_STATUS_OK;
  int iParserStatus = 0;
  APIPRINTF((M_TEXT("MP4DEMUX: MAICompStart() enter: state=%d\n"), g_eCompState));
  if (g_eCompState!=MAI_RUNSTATE_NONE)
    return MAI_STATUS_WRONGSTATE;

  _ChangeState(hComp, MAI_RUNSTATE_INIT);

  g_bTerminate=0;
  g_eEOS=EOS_NONE;
  g_bVDiscon=M_FALSE;
  g_bADiscon=M_FALSE;
  g_bFirstRead=M_TRUE;

  g_bSeekPending=M_FALSE;
  g_lSeekValue=0;
  g_eSeekType=MAI_SEEKTYPE_NONE;

  /* Allocate buffers */
  if (g_hInBufferPool==M_HANDLE_INVALID) /* Allocate buffers */
  {
    eStatus=MAICompBufferPoolCreate(g_uiInBufferSize, g_uiInMaxBuffers, &g_hInBufferPool);
    if (MAI_STATUS_OK!=eStatus)
      return eStatus;
    /* setup a state change callback to report buffer fullness to MAIengine */
    MAICompBufferPoolSetStateCB(g_hInBufferPool, _InBufferPoolStateCB, hComp);
  }

  // We don't have a handle to the reader since it's file based, so just
  // startup the demux thread
  g_hThread = MAIOSThreadCreate(DemuxThread, hComp, 0);
  if (g_hThread==M_HANDLE_INVALID)
  {
    ERRORPRINTF((M_TEXT("MP4DEMUX: MAIOSThreadCreate failed")));
    eStatus = MAI_STATUS_EXECFAILED;
  }
  else
  {
    MAIOSThreadSetPriority(g_hThread, g_uiThreadPriority);
    eStatus=MAIOSThreadStart(g_hThread);
  }
  APIPRINTF((M_TEXT("MP4DEMUX: MAICompStart() done: result=0x%08X state=%d\n"), eStatus, g_eCompState));
  return eStatus;
}

static MAIStatus_e MAICompEnd(MAICompHandle_t hComp)
{
  // Terminate outstanding reads and stop the reader thread
  APIPRINTF((M_TEXT("MP4DEMUX: MAICompEnd() enter: state=%d\n"), g_eCompState));
  if (g_eCompState==MAI_RUNSTATE_DESTROYING ||
      g_eCompState==MAI_RUNSTATE_NONE)
  {
      APIPRINTF((M_TEXT("MP4DEMUX: MAICompEnd() exit: not started\n")));
      return MAI_STATUS_WRONGSTATE;
  }
  _ChangeState(hComp, MAI_RUNSTATE_DESTROYING);
  if (g_bTerminate==0)
    g_bTerminate=1;

  /* Abort at blocked BufferPut/Get's */
  MAICompBufferPoolAbort(g_hInBufferPool, M_FALSE);
  g_hInBufferPool=M_HANDLE_INVALID;

  MAIOSThreadDestroy(g_hThread, M_TRUE);
  g_hThread=M_HANDLE_INVALID;

  // If we had a handle to the reader, it should be destroyed here.

  // Free memory...
  MAICompBufferPoolDestroy(g_hInBufferPool, M_TRUE);

  _ChangeState(hComp, MAI_RUNSTATE_NONE);

  APIPRINTF((M_TEXT("MP4DEMUX: MAICompEnd() exit\n")));
  return MAI_STATUS_OK;
}

//initialize the MP4 parser and parse meta data
MAIStatus_e _startprocessing(MAICompHandle_t hComp)
{
  MAIStatus_e eStatus = MAI_STATUS_OK;
  APIPRINTF((M_TEXT("MP4DEMUX: _startprocessing() enter: bInit=%d\n"), g_bInit));
  if (g_bInit)
    eStatus=MAI_STATUS_ALREADYOPEN;
  else
  {
    FILE_BRAND file_brand;
    m_u8*	inBuffer1;
    unsigned int bytesread;

	  inBuffer1 = (m_u8 *) malloc(16*1024*sizeof(m_u8));
	  if(inBuffer1 == NULL)
	  {
		  ERRORPRINTF((M_TEXT("MP4DEMUX: Error, could not allocate memory \n")));
		  return 0;
	  }
    g_eEOS=EOS_NONE;
    g_uiPlaySleep=0;
    inputopen();
    inputpeek(inBuffer1, 16*1024, &bytesread);
	  if(bytesread > 0)
		  check_file_type(inBuffer1,bytesread,&file_brand);
	  else
	  {
		  ERRORPRINTF((M_TEXT("MP4Demux: Error reading input file !!!\n")));
		  return 0;
	  }
	  if(inBuffer1 != NULL) {
		  free(inBuffer1);
		  inBuffer1 = NULL;
	  }

	  switch(file_brand)
	  {
		  case eISOM: // ISO 15444-3
			  ParseISOM(g_hFile);
			  eStatus = MAI_STATUS_OK;
			  break;
		  case eMP41:
		  case eMP42:// ISO/IEC 14496-1:2001
			  ParseMP4(g_hFile);
			  eStatus = MAI_STATUS_OK;
			  break;
		  default:
			  ERRORPRINTF((M_TEXT("MP4Demux: Exiting unknown input file type !!! \n")));
        g_bInit=M_FALSE;
			  eStatus = MAI_STATUS_UNSUPPORTED;
        break;
	  }
    if (eStatus==MAI_STATUS_OK)
    {
      unsigned int apts_start=0, vpts_start=0;
      unsigned int apts_end=0, vpts_end=0;
      unsigned int pts_start=0, pts_end=0;
      /* reset current sample number indexes */
      g_uiVideoSampleNum=0;
      g_uiAudioSampleNum=0;

	    g_uiVideoSampleCount = GetSampeCount(VIDEO);
	    g_uiAudioSampleCount = GetSampeCount(AUDIO);

        /* fill in Stream format information */
      g_StreamInfo.MediaTypeInfo.eMType = MAI_MTYPE_MP4; /* MP4 muxed */
      g_StreamInfo.MediaTypeInfo.eMSubtype = MAI_MSUBTYPE_NONE;
      if (g_uiVideoSampleCount)
      {
        sample_timming_info(0,VIDEO,&vpts_start);
        sample_timming_info(g_uiVideoSampleCount-1,VIDEO,&vpts_end);
      }
      else
        vpts_end=vpts_start=0;
      if (g_uiAudioSampleCount)
      {
        sample_timming_info(0,AUDIO,&apts_start);
        sample_timming_info(g_uiAudioSampleCount-1,AUDIO,&apts_end);
      }
      else
        apts_end=apts_start=0;
      pts_start = vpts_start?vpts_start:apts_start;
      pts_end =(vpts_end>apts_end)?vpts_end:apts_end;
      g_StreamInfo.uiFlags|=MAI_STREAMMTFLAG_FORMATKNOWN|MAI_STREAMMTFLAG_STARTTIME|MAI_STREAMMTFLAG_ENDTIME;
      if (g_uiVideoSampleCount || g_uiAudioSampleCount)
        g_StreamInfo.uiFlags|=MAI_STREAMMTFLAG_CANSEEK;
      MAITIME_ASSIGN32(g_StreamInfo.tStartTime, pts_start);
      MAITIME_ASSIGN32(g_StreamInfo.LenInTime, pts_end);
      MAITIME_ASSIGN32(g_StreamInfo.tEndTime, pts_end);
      APIPRINTF((M_TEXT("MP4DEMUX: InitMP4Parse() VideoSampleCount=%d AudioSampleCount=%d startpts=%d endpts=%d\n"),
        g_uiVideoSampleCount, g_uiAudioSampleCount, pts_start, pts_end));

      g_bInit=M_TRUE;
    }
    else
    {
      if (g_pfErrorCB)
        g_pfErrorCB(hComp, MAI_STATUS_OPENERROR, 0);
    }
  }
  APIPRINTF((M_TEXT("MP4DEMUX: _startprocessing() done: bInit=%d eStatus=0x%08X\n"),
     g_bInit, eStatus));
  return eStatus; /* success */
}

MAIStatus_e _endprocessing(MAICompHandle_t hComp)
{
  MAIStatus_e eStatus = MAI_STATUS_OK;
  APIPRINTF((M_TEXT("MP4DEMUX: _endprocessing() enter\n")));
  if (!g_bInit)
    eStatus=MAI_STATUS_WRONGSTATE;
  else
  {
    //CloseParser();
    //g_bInit=M_FALSE;
  }
  APIPRINTF((M_TEXT("MP4DEMUX: _endprocessing() exit: status=0x%X\n"), eStatus));
  return eStatus;
}

// send configuration info to audio and video decoders
void ConfigDecoders()
{
  m_u8 *data_buffer;
  m_u8 *pData;
  m_u16 channelcount=0;
  m_u16 samplerate=0;
  long lData;
  MAICompBuffer_t *pBufferInfo;

		if(g_uiAudioSampleCount > 0) // send special header to aac decoder
		{
			GetAudioInfo(&channelcount,&samplerate);
			data_buffer = (m_u8*) malloc(10 * sizeof(m_u8));
			data_buffer[0] = 'f';
			data_buffer[1] = 'a';
			data_buffer[2] = 'a';
			data_buffer[3] = 'c';

			data_buffer[4] = (m_u8) 0x02; // object type: hard coded value
			data_buffer[5] = (m_u8) channelcount;
			data_buffer[6] = (m_u8) (samplerate & 0x000000ff);
			data_buffer[7] = (samplerate & 0x0000ff00) >> 8;
			data_buffer[8] = (samplerate & 0x00ff0000) >> 16;
			data_buffer[9] = (samplerate & 0xff000000) >> 24;

			if (g_pfOutputAudioGetBuf && MAI_STATUS_OK == g_pfOutputAudioGetBuf(g_hOutputAudioOwner,&pBufferInfo))
			{
					if(10 > pBufferInfo->uiBufSize)
					{
						ERRORPRINTF((M_TEXT("MP4DEMUX: Error - Data is larger than buffer size!\n")));
					}
					memcpy(pBufferInfo->pBuffer, data_buffer,10);

					pBufferInfo->dwFlags = 0;  /* default - no special flags */
					pBufferInfo->tTimeStamp = 0;
					pBufferInfo->uiDataSize = 10;
					PUTPRINTF((M_TEXT("MP4DEMUX: Passing the data to the audio decoder\n")));
					g_pfOutputAudioPutBuf(g_hOutputAudioOwner,pBufferInfo);
					if(data_buffer){
						free(data_buffer);
						data_buffer = NULL;
					}
			}
		}
		// send configuration data to mpeg4 video decoder
		if(g_uiVideoSampleCount > 0)
		{
			if (g_pfOutputVideoGetBuf && MAI_STATUS_OK==g_pfOutputVideoGetBuf(g_hOutputVideoOwner,&pBufferInfo))

⌨️ 快捷键说明

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