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

📄 dumptrack.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
字号:
/*
 * Copyright (c) 2004-2005 Mike Matsnev.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice immediately at the beginning of the file, without modification,
 *    this list of conditions, and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Absolutely no warranty of function or purpose is made by the author
 *    Mike Matsnev.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * $Id: dumptrack.c,v 1.3 2005/03/07 11:24:21 mike Exp $
 * 
 */

/*
 * This is a complete sample of MatroskaParser usage. The program will dump
 * one of source file tracks to stdout.
 */

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

/* windows-specific */
#ifdef WIN32
#include <io.h>
#endif

#include "../MatroskaParser/MatroskaParser.h"

/* first we need to create an I/O object that the parser will use to read the
 * source file
 */
struct StdIoStream {
  struct InputStream  base;
  FILE		      *fp;
  int		      error;
};
typedef struct StdIoStream StdIoStream;

#define	CACHESIZE     65536

/* StdIoStream methods */

/* read count bytes into buffer starting at file position pos
 * return the number of bytes read, -1 on error or 0 on EOF
 */
int   StdIoRead(StdIoStream *st, ulonglong pos, void *buffer, int count) {
  size_t  rd;
  if (fseek(st->fp, pos, SEEK_SET)) {
    st->error = errno;
    return -1;
  }
  rd = fread(buffer, 1, count, st->fp);
  if (rd == 0) {
    if (feof(st->fp))
      return 0;
    st->error = errno;
    return -1;
  }
  return rd;
}

/* scan for a signature sig(big-endian) starting at file position pos
 * return position of the first byte of signature or -1 if error/not found
 */
longlong StdIoScan(StdIoStream *st, ulonglong start, unsigned signature) {
  int	      c;
  unsigned    cmp = 0;
  FILE	      *fp = st->fp;

  if (fseek(fp, start, SEEK_SET))
    return -1;

  while ((c = getc(fp)) != EOF) {
    cmp = ((cmp << 8) | c) & 0xffffffff;
    if (cmp == signature)
      return ftell(fp) - 4;
  }

  return -1;
}

/* return cache size, this is used to limit readahead */
unsigned StdIoGetCacheSize(StdIoStream *st) {
  return CACHESIZE;
}

/* return last error message */
const char *StdIoGetLastError(StdIoStream *st) {
  return strerror(st->error);
}

/* memory allocation, this is done via stdlib */
void  *StdIoMalloc(StdIoStream *st, size_t size) {
  return malloc(size);
}

void  *StdIoRealloc(StdIoStream *st, void *mem, size_t size) {
  return realloc(mem,size);
}

void  StdIoFree(StdIoStream *st, void *mem) {
  free(mem);
}

/* progress report handler for lengthy operations
 * returns 0 to abort operation, nonzero to continue
 */
int   StdIoProgress(StdIoStream *st, ulonglong cur, ulonglong max) {
  return 1;
}

/* main program */
int   main(int argc,char **argv) {
  StdIoStream	st;
  MatroskaFile	*mf;
  char		err_msg[256];
  unsigned	i;
  int		track;
  FILE		*out = stdout;

  if (argc < 2 || argc > 3) {
    fprintf(stderr,"Usage: %s filename.mkv [track_num]\n",argv[0]);
    return 1;
  }

#ifdef WIN32
  { /* windows-specific, turn off text translation */
    int nfd = dup(fileno(stdout));
    _setmode(nfd, _O_BINARY);
    out = _fdopen(nfd,"wb");
  }
#endif

  /* fill in I/O object */
  memset(&st,0,sizeof(st));
  st.base.read = StdIoRead;
  st.base.scan = StdIoScan;
  st.base.getsize = StdIoGetCacheSize;
  st.base.geterror = StdIoGetLastError;
  st.base.memalloc = StdIoMalloc;
  st.base.memrealloc = StdIoRealloc;
  st.base.memfree = StdIoFree;
  st.base.progress = StdIoProgress;

  /* open source file */
  st.fp = fopen(argv[1],"rb");
  if (st.fp == NULL) {
    fprintf(stderr,"Can't open '%s': %s\n",argv[1],strerror(errno));
    return 1;
  }
  setvbuf(st.fp, NULL, _IOFBF, CACHESIZE);

  /* initialize matroska parser */
  mf = mkv_OpenEx(&st.base, /* pointer to I/O object */
    0, /* starting position in the file */
    0, /* flags, you can set MKVF_AVOID_SEEKS if this is a non-seekable stream */
    err_msg, sizeof(err_msg)); /* error message is returned here */
  if (mf == NULL) {
    fclose(st.fp);
    fprintf(stderr,"Can't parse Matroska file: %s\n", err_msg);
    return 1;
  }

  /* if track_num was not specified, then list tracks */
  if (argc == 2) {
    for (i = 0; i < mkv_GetNumTracks(mf); ++i) {
      TrackInfo	*ti = mkv_GetTrackInfo(mf, i);
      printf("Track %u: %s\n", i, ti->CodecID);
    }
  } else {
    ulonglong	      StartTime, EndTime, FilePos;
    unsigned	      rt, FrameSize, FrameFlags;
    unsigned	      fb = 0;
    void	      *frame = NULL;
    CompressedStream  *cs = NULL;

    /* extract track */
    track = atoi(argv[2]);
    if (track < 0 || (unsigned)track >= mkv_GetNumTracks(mf)) {
      fprintf(stderr,"Invalid track number: %d\n", track);
      goto done;
    }

    /* mask other tracks because we don't need them */
    mkv_SetTrackMask(mf, ~(1 << track));

    /* init zlib decompressor if needed */
    if (mkv_GetTrackInfo(mf,track)->CompEnabled) {
      cs = cs_Create(mf, track, err_msg, sizeof(err_msg));
      if (cs == NULL) {
	fprintf(stderr,"Can't create decompressor: %s\n",err_msg);
	goto done;
      }
    }

    /* read frames from file */
    while (mkv_ReadFrame(mf, 0, &rt, &StartTime, &EndTime, &FilePos, &FrameSize, &FrameFlags) == 0)
    {
      if (cs) {
	char	buffer[1024];

	cs_NextFrame(cs,FilePos,FrameSize);
	for (;;) {
	  int rd = cs_ReadData(cs,buffer,sizeof(buffer));
	  if (rd < 0) {
	    fprintf(stderr,"Error decompressing data: %s\n",cs_GetLastError(cs));
	    goto done;
	  }
	  if (rd == 0)
	    break;
	  fwrite(buffer,1,rd,out);
	}
      } else {
	size_t	  rd;

	if (fseek(st.fp, FilePos, SEEK_SET)) {
	  fprintf(stderr,"fseek(): %s\n", strerror(errno));
	  goto done;
	}

	if (fb < FrameSize) {
	  fb = FrameSize;
	  frame = realloc(frame, fb);
	  if (frame == NULL) {
	    fprintf(stderr,"Out of memory\n");
	    goto done;
	  }
	}

	rd = fread(frame,1,FrameSize,st.fp);
	if (rd != FrameSize) {
	  if (rd == 0) {
	    if (feof(st.fp))
	      fprintf(stderr,"Unexpected EOF while reading frame\n");
	    else
	      fprintf(stderr,"Error reading frame: %s\n",strerror(errno));
	  } else
	    fprintf(stderr,"Short read while reading frame\n");
	  goto done;
	}

	fwrite(frame,1,FrameSize,out);
      }
    }
  }

done:
  /* close matroska parser */
  mkv_Close(mf);

  /* close file */
  fclose(st.fp);

  return 0;
}

⌨️ 快捷键说明

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