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

📄 mp4videoinfo.cpp

📁 完整的RTP RTSP代码库
💻 CPP
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved. *  * Contributor(s):  *		Dave Mackie		dmackie@cisco.com */// N.B. mp4extract just extracts tracks/samples from an mp4 file// For many track types this is insufficient to reconsruct a valid// elementary stream (ES). Use "mp4creator -extract=<trackId>" if// you need the ES reconstructed. #include "mp4.h"#include "mpeg4ip_getopt.h"#include "mp4av.h"#include "mp4av_h264.h"char* ProgName;char* Mp4PathName;char* Mp4FileName;static void ParseH264 (uint8_t *bptr, uint32_t blen, 		       uint32_t len_size, bool dump_off){  uint8_t *fptr = bptr;  while (blen > len_size) {    uint32_t nal_len = 0;    switch (len_size) {    case 1: nal_len = *bptr; break;    case 2: nal_len = (bptr[0] << 8) | bptr[1]; break;    case 3: nal_len = (bptr[0] << 16) | (bptr[1] << 8) | bptr[2]; break;    case 4: nal_len = (bptr[0] << 24) | (bptr[1] << 16) | (bptr[2] << 8) | bptr[3]; break;    }    bptr += len_size;    blen -= len_size;    uint8_t nal_type = *bptr & 0x1f;    switch (nal_type) {    case H264_NAL_TYPE_NON_IDR_SLICE: printf(" NIDR-"); break;    case H264_NAL_TYPE_DP_A_SLICE: printf(" DPA-"); break;    case H264_NAL_TYPE_DP_B_SLICE: printf(" DPB-"); break;    case H264_NAL_TYPE_DP_C_SLICE: printf(" DPC-"); break;    case H264_NAL_TYPE_IDR_SLICE: printf(" IDR-"); break;    case H264_NAL_TYPE_SEI: printf(" SEI"); break;    case H264_NAL_TYPE_SEQ_PARAM: printf(" SEQ"); break;    case H264_NAL_TYPE_PIC_PARAM: printf(" PIC"); break;    case H264_NAL_TYPE_ACCESS_UNIT: printf(" AU"); break;    case H264_NAL_TYPE_END_OF_SEQ: printf(" EOS"); break;    case H264_NAL_TYPE_END_OF_STREAM: printf(" EOST"); break;    case H264_NAL_TYPE_FILLER_DATA: printf(" FILL"); break;    default: printf(" UNK(0x%x)", nal_type); break;    }    if (h264_nal_unit_type_is_slice(nal_type)) {      uint8_t slice_type;      h264_find_slice_type(bptr, nal_len, &slice_type, true);      printf("%s", h264_get_slice_name(slice_type));    }    uint32_t off =  bptr - fptr - len_size;    if (dump_off) printf("(%u)", off);    bptr += nal_len;    if (nal_len > blen) {      blen = 0;    } else       blen -= nal_len;  }}static void ParseMpeg2 (uint8_t *bptr, uint32_t blen, bool dump_off){  int offset;  int frame_type;  offset = MP4AV_Mpeg3FindPictHdr(bptr, blen, &frame_type);  if (offset >= 0) {    printf(" %c temp ref %u", frame_type == 1 ? 'I' : (frame_type == 2 ? 'P' : 'B'),	   MP4AV_Mpeg3PictHdrTempRef(bptr + offset));  } else {    printf("offset %d", offset);  }}static void ParseMpeg4 (uint8_t *bptr, uint32_t blen, bool dump_off){  uint8_t *fptr = bptr;  while (blen > 4) {    if (bptr[0] == 0 &&	bptr[1] == 0 &&	bptr[2] == 1) {      if (bptr[3] > 0 && bptr[3] < MP4AV_MPEG4_VOL_START) {	printf(" VDOS");      } else if (bptr[3] < 0x2f) {	printf(" VOL");      } else if (bptr[3] == MP4AV_MPEG4_VOSH_START) {	printf(" VOSH");      } else if (bptr[3] == MP4AV_MPEG4_VOSH_END) {	printf(" VOSHE");      } else if (bptr[3] == MP4AV_MPEG4_USER_DATA_START) {	printf(" UD");      } else if (bptr[3] == MP4AV_MPEG4_GOV_START) {	printf(" GOV");      } else if (bptr[3] == 0xB4) {	printf(" VSE");      } else if (bptr[3] == MP4AV_MPEG4_VO_START) {	printf(" VOS");      } else if (bptr[3] == MP4AV_MPEG4_VOP_START) {	int type = MP4AV_Mpeg4GetVopType(bptr, blen);	switch (type) {	case VOP_TYPE_I: printf(" VOP-I"); break;	case VOP_TYPE_P: printf(" VOP-P"); break;	case VOP_TYPE_B: printf(" VOP-B"); break;	case VOP_TYPE_S: printf(" VOP-S"); break;	}      } else printf(" 0x%x", bptr[3]);      uint32_t off = bptr - fptr;      if (dump_off) printf("(%u)", off);    }    bptr++;    blen--;  }}static void DumpTrack (MP4FileHandle mp4file, MP4TrackId tid, 		       bool dump_off, bool dump_rend){  uint32_t numSamples;  MP4SampleId sid;  uint8_t *buffer;  uint32_t max_frame_size;  uint32_t timescale;  uint64_t msectime, rendmsectime;  const char *media_data_name;  uint32_t len_size = 0;  uint8_t video_type = 0;  numSamples = MP4GetTrackNumberOfSamples(mp4file, tid);  max_frame_size = MP4GetTrackMaxSampleSize(mp4file, tid) + 4;  media_data_name = MP4GetTrackMediaDataName(mp4file, tid);  if (strcasecmp(media_data_name, "avc1") == 0) {    MP4GetTrackH264LengthSize(mp4file, tid, &len_size);  } else if (strcasecmp(media_data_name, "mp4v") == 0) {    video_type = MP4GetTrackEsdsObjectTypeId(mp4file, tid);  }  buffer = (uint8_t *)malloc(max_frame_size);  if (buffer == NULL) {    printf("couldn't get buffer\n");    return;  }  timescale = MP4GetTrackTimeScale(mp4file, tid);  printf("mp4file %s, track %d, samples %d, timescale %d\n", 	 Mp4FileName, tid, numSamples, timescale);  for (sid = 1; sid <= numSamples; sid++) {    MP4Timestamp sampleTime;    MP4Duration sampleDuration, sampleRenderingOffset;    bool isSyncSample = FALSE;    bool ret;    u_int8_t *temp;    uint32_t this_frame_size = max_frame_size;    temp = buffer;    ret = MP4ReadSample(mp4file, 			tid,			sid,			&temp,			&this_frame_size,			&sampleTime,			&sampleDuration,			&sampleRenderingOffset,			&isSyncSample);    msectime = sampleTime;    msectime *= TO_U64(1000);    msectime /= timescale;    printf("sampleId %6d, size %5u time "U64"("U64")",	  sid,  MP4GetSampleSize(mp4file, tid, sid), 	   sampleTime, msectime);    if (dump_rend) {      rendmsectime = sampleRenderingOffset;      rendmsectime *= TO_U64(1000);      rendmsectime /= timescale;      printf(" "U64","U64"("U64","U64") ", sampleRenderingOffset, 	     sampleTime + sampleRenderingOffset,	     rendmsectime,	     msectime + rendmsectime);    }    if (strcasecmp(media_data_name, "mp4v") == 0) {      if (MP4_IS_MPEG4_VIDEO_TYPE(video_type))	ParseMpeg4(temp, this_frame_size, dump_off);      else if (MP4_IS_MPEG1_VIDEO_TYPE(video_type) ||	       MP4_IS_MPEG2_VIDEO_TYPE(video_type)) {	ParseMpeg2(temp, this_frame_size, dump_off);      }    } else if (strcasecmp(media_data_name, "avc1") == 0) {      ParseH264(temp, this_frame_size, len_size, dump_off);    }    printf("\n");  }}int main(int argc, char** argv){  const char* usageString =     "[options] mp4file where:\n"    "\t--track(-t)= <track-id> - display track id\n"    "\t--dump-offset(-d) - dump offset within sample\n"    "\t--rendering-offset(-r) - dump rendering offset\n"    "\t--verbose=<level> - mp4 file verbosity\n"    "\t--version(-V) - display version\n";  MP4TrackId trackId = MP4_INVALID_TRACK_ID;  u_int32_t verbosity = MP4_DETAILS_ERROR;  bool dump_offset = false;  bool dump_rend = false;  /* begin processing command line */  ProgName = argv[0];  while (true) {    int c = -1;    int option_index = 0;    static struct option long_options[] = {      { "track", 1, 0, 't' },      { "verbose", 2, 0, 'v' },      { "version", 0, 0, 'V' },      { "dump-offset", 0, 0, 'd'},      { "rendering-offset", 0, 0, 'r'},      { "help", 0, 0, '?'},      { NULL, 0, 0, 0 }    };    c = getopt_long_only(argc, argv, "t:v::V?",			 long_options, &option_index);    if (c == -1)      break;    switch (c) {    case 'd': dump_offset = true; break;    case 'r': dump_rend = true; break;    case 't':      if (sscanf(optarg, "%u", &trackId) != 1) {	fprintf(stderr, 		"%s: bad track-id specified: %s\n",		ProgName, optarg);	exit(1);      }      break;    case 'v':      verbosity |= MP4_DETAILS_READ;      if (optarg) {	u_int32_t level;	if (sscanf(optarg, "%u", &level) == 1) {	  if (level >= 2) {	    verbosity |= MP4_DETAILS_TABLE;	  } 	  if (level >= 3) {	    verbosity |= MP4_DETAILS_SAMPLE;	  } 	  if (level >= 4) {	    verbosity = MP4_DETAILS_ALL;	  }	}      }      break;    case '?':      fprintf(stderr, "usage: %s %s", ProgName, usageString);      exit(0);    case 'V':      fprintf(stderr, "%s - %s version %s\n", 	      ProgName, MPEG4IP_PACKAGE, MPEG4IP_VERSION);      exit(0);    default:      fprintf(stderr, "%s: unknown option specified, ignoring: %c\n", 	      ProgName, c);    }  }  /* check that we have at least one non-option argument */  if ((argc - optind) < 1) {    fprintf(stderr, "usage: %s %s", ProgName, usageString);    exit(1);  }	  if (verbosity) {    fprintf(stderr, "%s version %s\n", ProgName, MPEG4IP_VERSION);  }  /* point to the specified file names */  Mp4PathName = argv[optind++];  char* lastSlash = strrchr(Mp4PathName, '/');  if (lastSlash) {    Mp4FileName = lastSlash + 1;  } else {    Mp4FileName = Mp4PathName;   }  /* warn about extraneous non-option arguments */  if (optind < argc) {    fprintf(stderr, "%s: unknown options specified, ignoring: ", ProgName);    while (optind < argc) {      fprintf(stderr, "%s ", argv[optind++]);    }    fprintf(stderr, "\n");  }  /* end processing of command line */  MP4FileHandle mp4File = MP4Read(Mp4PathName, verbosity);  if (!mp4File) {    exit(1);  }    if (trackId == MP4_INVALID_TRACK_ID) {    u_int32_t numTracks = MP4GetNumberOfTracks(mp4File, MP4_VIDEO_TRACK_TYPE);    printf("tracks %d\n", numTracks);    for (u_int32_t ix = 0; ix < numTracks; ix++) {      trackId = MP4FindTrackId(mp4File, ix, MP4_VIDEO_TRACK_TYPE);      DumpTrack(mp4File, trackId, dump_offset, dump_rend);    }  } else {    DumpTrack(mp4File, trackId, dump_offset, dump_rend);  }  MP4Close(mp4File);  return(0);}

⌨️ 快捷键说明

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