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

📄 mp4parse.cpp

📁 mpeg4 demux 代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* <LIC_AMD_STD>
 * Copyright (C) 2003-2005 Advanced Micro Devices, Inc.  All Rights Reserved.
 *
 * Unless otherwise designated in writing, this software and any related
 * documentation are the confidential proprietary information of AMD.
 * THESE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY
 * UNLESS OTHERWISE NOTED IN WRITING, EXPRESS OR IMPLIED WARRANTY OF ANY
 * KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
 * NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE AND IN NO
 * EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER.
 *
 * AMD does not assume any responsibility for any errors which may appear
 * in the Materials nor any responsibility to support or update the
 * Materials.  AMD retains the right to modify the Materials at any time,
 * without notice, and is not obligated to provide such modified
 * Materials to you. AMD is not obligated to furnish, support, or make
 * any further information available to you.
 * </LIC_AMD_STD>  */
/* <CTL_AMD_STD>
 * </CTL_AMD_STD>  */
/* <DOC_AMD_STD>
 * </DOC_AMD_STD>  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "mp4parse.h"
#include "mp4util.h"

#include "mai_component.h" /* to access Reader component */

#define DPRINTF(_args_)      /* MAIOSDebugPrint _args_ */
#define APIPRINTF(_args_)    /* MAIOSDebugPrint _args_ */
#define INFOPRINTF(_args_)   /* MAIOSDebugPrint _args_ */

#define USE_FILE_READ

#define BUFF_SIZE		1024*1024
#define MAX_TRACKS		20

typedef struct _TRACK_ {
	CTrackHeaderBox *pTrkHdrBox;
	CMediaHeaderBox *pMediaHdr;
	TRACK_TYPES type;
} TRACK;

unsigned char inBuffer[BUFF_SIZE];

CSampleDescriptionBox	*pSampleDescription[NUM_TRACK_TYPES];
CTimeToSampleBox		*pTimeToSample[NUM_TRACK_TYPES];
CSampleToChunkBox		*pSampleToChunk[NUM_TRACK_TYPES];
CChunkOffsetBox			*pCunkOffset[NUM_TRACK_TYPES];
CSampleSizeBox			*pSampleSize[NUM_TRACK_TYPES];
CDataReferenceBox		*pDataReference;
CTrackHeaderBox			*pTrkHdrBox;
CMovieHeaderBox			*pMovHdrBox;
CMediaDataBox			*pMediaDataBox;

TRACK TrackList[MAX_TRACKS];

m_bool g_bSeenMetaData=0;

void Parse_mdia(Byte_Stream &input_stream, long lData,m_bool bMP4File, int TrackNum);

extern "C" MAIStatus_e inputread(unsigned char *pucData, unsigned int uiSize, unsigned int *puiBytesRead);
extern "C" MAIStatus_e inputseek(unsigned int uiOffset);

void InitParser()
{
  int i;

  for(i=0;i<MAX_TRACKS;i++)
	{
		TrackList[i].pMediaHdr = NULL;
		TrackList[i].pTrkHdrBox = NULL;
		TrackList[i].type = UNKNOWN;
	}

  for(i=0;i<NUM_TRACK_TYPES;i++)
  {
    pSampleDescription[i] = NULL;
    pTimeToSample[i] = NULL;
    pSampleToChunk[i] = NULL;
    pCunkOffset[i] = NULL;
    pSampleSize[i] = NULL;
  }
  pDataReference = NULL;
  pTrkHdrBox = NULL;
  pMovHdrBox = NULL;
  pMediaDataBox = NULL;
}


void CloseParser()
{
	int i;
	for(i=0;i< NUM_TRACK_TYPES;i++)
	{
		if(pSampleDescription[i])
    {
			delete pSampleDescription[i];
      pSampleDescription[i] = NULL;
    }
		if(pTimeToSample[i])
    {
			delete pTimeToSample[i];
      pTimeToSample[i] = NULL;
    }
		if(pSampleToChunk[i])
    {
			delete pSampleToChunk[i];
      pSampleToChunk[i] = NULL;
    }
		if(pSampleSize[i])
    {
			delete pSampleSize[i];
      pSampleSize[i] = NULL;
    }
	}
	for(i=0;i<MAX_TRACKS;i++)
	{
		if(TrackList[i].pMediaHdr)
    {
			delete TrackList[i].pMediaHdr;
      TrackList[i].pMediaHdr = NULL;
    }
		if(TrackList[i].pTrkHdrBox)
    {
			delete TrackList[i].pTrkHdrBox;
      TrackList[i].pTrkHdrBox = NULL;
    }
  }

}

// parse mdia, container for media info in a track
void Parse_mdia(Byte_Stream &input_stream, long lData,m_bool bMP4File,int TrackNum)
{
	long Len=0,Len1=0,Len2=0;
	unsigned int mid ,mid1,mid2 ;
	int index;
  CHandlerBox				*pHandler;

  while(lData > 8)
  {
	Len = input_stream.GetUINT();
	mid = input_stream.GetUINT();
	lData -= Len;
  switch(mid)
  {
	case FOURCC('m','d','h','d'): // media header
    TrackList[TrackNum].pMediaHdr = new CMediaHeaderBox(Len);
    TrackList[TrackNum].pMediaHdr->ReadData(input_stream);
    break;
  case FOURCC('h','d','l','r'): // handler, media type
    m_u32 handler_type;
    pHandler = new CHandlerBox(Len);
    pHandler->ReadData(input_stream,Len-8);
    handler_type = pHandler->GetHandlerType();
    switch(handler_type)
    {
    case FOURCC('s','o','u','n'):
      index = AUDIO;
      TrackList[TrackNum].type = AUDIO;
      break;
    case FOURCC('v','i','d','e'):
      index = VIDEO;
      TrackList[TrackNum].type = VIDEO;
      break;
    case FOURCC('h','i','n','t'):
      index = HINT;
      TrackList[TrackNum].type = HINT;
      break;
    default:
      index = OD;
      TrackList[TrackNum].type = OD;
      break;
    }
    delete pHandler;

    pHandler=NULL;
    break;
    case FOURCC('m','i','n','f'): // media information container
      while(Len > 8)
      {
        Len1 =input_stream.GetUINT();
        mid1 = input_stream.GetUINT();
        Len -= Len1;

        switch(mid1)
        {
        case FOURCC('v','m','h','d'): //
          if(Len1 > 8)
            input_stream.Advance(Len1-8);

          break;
        case FOURCC('s','m','h','d'): //
          if(Len1 > 8)
            input_stream.Advance(Len1-8);

          break;
        case FOURCC('h','m','h','d'): // data info box
          if(Len1 > 8)
            input_stream.Advance(Len1-8);
          break;

        case FOURCC('d','i','n','f'): // data info box
          Len2 =input_stream.GetUINT();
          mid2 = input_stream.GetUINT();
          if(Len2 > 8)
            input_stream.Advance(Len2-8);
          // TODO:
          /*
          if(mid2 == FOURCC('d','r','e','f'))
          {
          pDataReference = new CDataReferenceBox(Len1) ;
          pDataReference->ReadData(input_stream,Len2-8);
          }
          */
          break;
        case FOURCC('s','t','b','l'): // time space map
          while(Len1 > 8)
          {
            Len2 =input_stream.GetUINT();
            mid2 = input_stream.GetUINT();
            Len1 -= Len2;
            switch(mid2)
            {
            case FOURCC('s','t','s','d'): // sample descriptions (codec types, initialization,etc.)
              // TODO, look for mp4a, mp4v, and esds , while(Len2 > 8) or pass Len2 to ReadData
              if(index == VIDEO || index == AUDIO )
              {
                if(pSampleDescription[index])
                {
                  delete pSampleDescription[index];
                  pSampleDescription[index] = NULL;
                }
                pSampleDescription[index] = new CSampleDescriptionBox(Len2);
                pSampleDescription[index]->ReadData(input_stream,index,bMP4File);
              }	else
              {
                input_stream.Advance(Len2-8);
              }
              break;
            case FOURCC('s','t','t','s'): // (decoding) time-to-sample
              if(pTimeToSample[index])
              {
                delete pTimeToSample[index];
                pTimeToSample[index] = NULL;
              }
              pTimeToSample[index] = new CTimeToSampleBox(Len2);
              pTimeToSample[index]->ReadData(input_stream);
              break;
            case FOURCC('s','t','s','c'): // sample-to-chunk, partial data-offset information
              if(pSampleToChunk[index])
              {
                delete pSampleToChunk[index];
                pSampleToChunk[index] = NULL;
              }
              pSampleToChunk[index] = new CSampleToChunkBox(Len2);
              pSampleToChunk[index]->ReadData(input_stream);
              break;
            case FOURCC('s','t','s','z'): // sample sizes (framing)
              if(pSampleSize[index])
              {
                delete pSampleSize[index];
                pSampleSize[index] = NULL;
              }
              pSampleSize[index] = new CSampleSizeBox(Len2);
              pSampleSize[index]->ReadData(input_stream);
              break;
            case FOURCC('s','t','c','o'): // chunk offset, partial data-offset information
              if(pCunkOffset[index])
              {
                delete pCunkOffset[index];
                pCunkOffset[index] = NULL;
              }
              pCunkOffset[index] = new CChunkOffsetBox(Len2);
              pCunkOffset[index]->ReadData(input_stream);
              break;
            case FOURCC('m','p','4','a'):
              if(Len2 > 8)
                input_stream.Advance(Len2-8);
              break;
            case FOURCC('m','p','4','v'):
              if(Len2 > 8)
                input_stream.Advance(Len2-8);
              break;
            default:
              if(Len2 > 8)
                input_stream.Advance(Len2-8);
              break;
            }
          }
          break;
        default:
          if(Len1 > 8)
            input_stream.Advance(Len1-8);
          break;
        }
      }
      break;
    default:
      if(Len > 8)
        input_stream.Advance(Len-8);
      break;
    }
  }
	Len = 0;
}

void ParseMP4(MAIOSFile_t g_hFile)
{
  unsigned int bytesread,bytesprocessed=0;
  unsigned long filepos=0,boxlength;
  long lbytesLeft;
  Byte_Stream input_stream;
  unsigned char *ptemp;
  long offset = 0;
  long Len ,Len1 ;
  unsigned int mid,mid1;
  int TrackCount=0;
  m_bool bSeek = 1;

  g_bSeenMetaData = 0;

  InitParser();

  while(1)
  {
    if(bSeek = 1)
      inputseek(filepos);
    inputread(inBuffer, BUFF_SIZE, &bytesread);
    if(bytesread <= 8 || g_bSeenMetaData )
      break;
    offset = 0;
    ptemp = inBuffer;
    input_stream.Initialize(ptemp, bytesread);
		bytesprocessed = 0;

		while(bytesprocessed < bytesread - 8)
		{
			long dwLen =input_stream.GetUINT();
			unsigned int id = input_stream.GetUINT();
			lbytesLeft = bytesread - bytesprocessed;
			boxlength = dwLen;
			bSeek = 0;
			if(g_bSeenMetaData ) // got the required meta data
				break;
			switch(id)
			{
      case FOURCC('m','o','o','v'): // all meta-data
        g_bSeenMetaData = 1;
        if(dwLen > lbytesLeft)

⌨️ 快捷键说明

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