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

📄 demux_mov.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
//  QuickTime MOV file parser by A'rpi//  additional work by Atmos//  based on TOOLS/movinfo.c by A'rpi & Al3x//  compressed header support from moov.c of the openquicktime lib.//  References: http://openquicktime.sf.net/, http://www.heroinewarrior.com///  http://www.geocities.com/SiliconValley/Lakes/2160/fformats/files/mov.pdf//  (above url no longer works, file mirrored somewhere? ::atmos)//  The QuickTime File Format PDF from Apple://  http://developer.apple.com/techpubs/quicktime/qtdevdocs/PDF/QTFileFormat.pdf//  (Complete list of documentation at http://developer.apple.com/quicktime/)//  MP4-Lib sources from http://mpeg4ip.sf.net/ might be usefull fot .mp4//  aswell as .mov specific stuff.//  All sort of Stuff about MPEG4://  http://www.cmlab.csie.ntu.edu.tw/~pkhsiao/thesis.html//  I really recommend N4270-1.doc and N4270-2.doc which are exact specs//  of the MP4-File Format and the MPEG4 Specific extensions. ::atmos#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "stream.h"#include "demuxer.h"#include "stheader.h"#include "bswap.h"#include "qtpalette.h"#include "parse_mp4.h" // .MP4 specific stuff#ifdef MACOSX#include <QuickTime/QuickTime.h>#else#include "../loader/qtx/qtxsdk/components.h"#endif#ifdef HAVE_ZLIB#include <zlib.h>#endif#ifndef _FCNTL_H#include <fcntl.h>#endif#define BE_16(x) (((unsigned char *)(x))[0] <<  8 | \		  ((unsigned char *)(x))[1])#define BE_32(x) (((unsigned char *)(x))[0] << 24 | \		  ((unsigned char *)(x))[1] << 16 | \		  ((unsigned char *)(x))[2] <<  8 | \		  ((unsigned char *)(x))[3])#define char2short(x,y)	BE_16(&(x)[(y)])#define char2int(x,y) 	BE_32(&(x)[(y)])typedef struct {    unsigned int pts; // duration    unsigned int size;    off_t pos;} mov_sample_t;typedef struct {    unsigned int sample; // number of the first sample in the chunk    unsigned int size;   // number of samples in the chunk    int desc;            // for multiple codecs mode - not used    off_t pos;} mov_chunk_t;typedef struct {    unsigned int first;    unsigned int spc;    unsigned int sdid;} mov_chunkmap_t;typedef struct {    unsigned int num;    unsigned int dur;} mov_durmap_t;typedef struct {    unsigned int dur;    unsigned int pos;    int speed;    //    int frames;    int start_sample;    int start_frame;    int pts_offset;} mov_editlist_t;#define MOV_TRAK_UNKNOWN 0#define MOV_TRAK_VIDEO 1#define MOV_TRAK_AUDIO 2#define MOV_TRAK_FLASH 3#define MOV_TRAK_GENERIC 4#define MOV_TRAK_CODE 5typedef struct {    int id;    int type;    off_t pos;    //    unsigned int media_handler;    unsigned int data_handler;    //    int timescale;    unsigned int length;    int samplesize;  // 0 = variable    int duration;    // 0 = variable    int width,height; // for video    unsigned int fourcc;    unsigned int nchannels;    unsigned int samplebytes;    //    int tkdata_len;  // track data     unsigned char* tkdata;    int stdata_len;  // stream data    unsigned char* stdata;    //    unsigned char* stream_header;    int stream_header_len; // if >0, this header should be sent before the 1st frame    //    int samples_size;    mov_sample_t* samples;    int chunks_size;    mov_chunk_t* chunks;    int chunkmap_size;    mov_chunkmap_t* chunkmap;    int durmap_size;    mov_durmap_t* durmap;    int keyframes_size;    unsigned int* keyframes;    int editlist_size;    mov_editlist_t* editlist;    int editlist_pos;    //    void* desc; // image/sound/etc description (pointer to ImageDescription etc)} mov_track_t;void mov_build_index(mov_track_t* trak,int timescale){    int i,j,s;    int last=trak->chunks_size;    unsigned int pts=0;#if 0    if (trak->chunks_size <= 0)    {	mp_msg(MSGT_DEMUX, MSGL_WARN, "No chunk offset table, trying to build one!\n");		trak->chunks_size = trak->samples_size; /* XXX: FIXME ! */	trak->chunks = realloc(trak->chunks, sizeof(mov_chunk_t)*trak->chunks_size);		for (i=0; i < trak->chunks_size; i++)	    trak->chunks[i].pos = -1;    }#endif    mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV track #%d: %d chunks, %d samples\n",trak->id,trak->chunks_size,trak->samples_size);    mp_msg(MSGT_DEMUX, MSGL_V, "pts=%d  scale=%d  time=%5.3f\n",trak->length,trak->timescale,(float)trak->length/(float)trak->timescale);    // process chunkmap:    i=trak->chunkmap_size;    while(i>0){	--i;	for(j=trak->chunkmap[i].first;j<last;j++){	    trak->chunks[j].desc=trak->chunkmap[i].sdid;	    trak->chunks[j].size=trak->chunkmap[i].spc;	}	last=trak->chunkmap[i].first;    }#if 0    for (i=0; i < trak->chunks_size; i++)    {	/* fixup position */	if (trak->chunks[i].pos == -1)	    if (i > 0)		trak->chunks[i].pos = trak->chunks[i-1].pos + trak->chunks[i-1].size;	    else		trak->chunks[i].pos = 0; /* FIXME: set initial pos */#endif    // calc pts of chunks:    s=0;    for(j=0;j<trak->chunks_size;j++){        trak->chunks[j].sample=s;        s+=trak->chunks[j].size;    }    // workaround for fixed-size video frames (dv and uncompressed)    if(!trak->samples_size && trak->type!=MOV_TRAK_AUDIO){	trak->samples_size=s;	trak->samples=malloc(sizeof(mov_sample_t)*s);	for(i=0;i<s;i++)	    trak->samples[i].size=trak->samplesize;	trak->samplesize=0;    }    if(!trak->samples_size){	// constant sampesize	if(trak->durmap_size==1 || (trak->durmap_size==2 && trak->durmap[1].num==1)){	    trak->duration=trak->durmap[0].dur;	} else mp_msg(MSGT_DEMUX, MSGL_ERR, "*** constant samplesize & variable duration not yet supported! ***\nContact the author if you have such sample file!\n");	return;    }        // calc pts:    s=0;    for(j=0;j<trak->durmap_size;j++){	for(i=0;i<trak->durmap[j].num;i++){	    trak->samples[s].pts=pts;	    ++s;	    pts+=trak->durmap[j].dur;	}    }        // calc sample offsets    s=0;    for(j=0;j<trak->chunks_size;j++){	off_t pos=trak->chunks[j].pos;	for(i=0;i<trak->chunks[j].size;i++){	    trak->samples[s].pos=pos;	    mp_msg(MSGT_DEMUX, MSGL_DBG3, "Sample %5d: pts=%8d  off=0x%08X  size=%d\n",s,		trak->samples[s].pts,		(int)trak->samples[s].pos,		trak->samples[s].size);	    pos+=trak->samples[s].size;	    ++s;	}    }    // precalc editlist entries    if(trak->editlist_size>0){	int frame=0;	int e_pts=0;	for(i=0;i<trak->editlist_size;i++){	    mov_editlist_t* el=&trak->editlist[i];	    int sample=0;	    int pts=el->pos;	    el->start_frame=frame;	    if(pts<0){		// skip!		el->frames=0; continue;	    }	    // find start sample	    for(;sample<trak->samples_size;sample++){		if(pts<=trak->samples[sample].pts) break;	    }	    el->start_sample=sample;	    el->pts_offset=((long long)e_pts*(long long)trak->timescale)/(long long)timescale-trak->samples[sample].pts;	    pts+=((long long)el->dur*(long long)trak->timescale)/(long long)timescale;	    e_pts+=el->dur;	    // find end sample	    for(;sample<trak->samples_size;sample++){		if(pts<=trak->samples[sample].pts) break;	    }	    el->frames=sample-el->start_sample;	    frame+=el->frames;	    mp_msg(MSGT_DEMUX,MSGL_V,"EL#%d: pts=%d  1st_sample=%d  frames=%d (%5.3fs)  pts_offs=%d\n",i,		el->pos,el->start_sample, el->frames,		(float)(el->dur)/(float)timescale, el->pts_offset);	}    }}#define MOV_MAX_TRACKS 256typedef struct {    off_t moov_start;    off_t moov_end;    off_t mdat_start;    off_t mdat_end;    int track_db;    mov_track_t* tracks[MOV_MAX_TRACKS];    int timescale; // movie timescale    int duration;  // movie duration (in movie timescale units)} mov_priv_t;#define MOV_FOURCC(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d))int mov_check_file(demuxer_t* demuxer){    int flags=0;    int no=0;    mov_priv_t* priv=malloc(sizeof(mov_priv_t));        mp_msg(MSGT_DEMUX,MSGL_V,"Checking for MOV\n");        memset(priv,0,sizeof(mov_priv_t));        while(1){	int i;	int skipped=8;	off_t len=stream_read_dword(demuxer->stream);	unsigned int id=stream_read_dword(demuxer->stream);	if(stream_eof(demuxer->stream)) break; // EOF	if (len == 1) /* real size is 64bits - cjb */	{#ifndef _LARGEFILE_SOURCE	    if (stream_read_dword(demuxer->stream) != 0)		mp_msg(MSGT_DEMUX, MSGL_WARN, "64bit file, but you've compiled MPlayer without LARGEFILE support!\n");	    len = stream_read_dword(demuxer->stream);#else	    len = stream_read_qword(demuxer->stream);#endif	    skipped += 8;	}#if 0	else if (len == 0) /* deleted chunk */	{	    /* XXX: CJB! is this right? - alex */	    goto skip_chunk;	}#endif	else if(len<8) break; // invalid chunk	switch(id){	case MOV_FOURCC('f','t','y','p'): {	  unsigned int tmp;	  // File Type Box (ftyp): 	  // char[4]  major_brand	   (eg. 'isom')	  // int      minor_version	   (eg. 0x00000000)	  // char[4]  compatible_brands[]  (eg. 'mp41')	  // compatible_brands list spans to the end of box#if 1	  tmp = stream_read_dword(demuxer->stream);	  switch(tmp) {	    case MOV_FOURCC('i','s','o','m'):	      mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Major Brand: ISO Base Media\n");     	      break;	    case MOV_FOURCC('m','p','4','1'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: ISO/IEC 14496-1 (MPEG-4 system) v1\n");     	      break;	    case MOV_FOURCC('m','p','4','2'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: ISO/IEC 14496-1 (MPEG-4 system) v2\n");     	      break;	    case MOV_FOURCC('M','4','A',' '):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Apple iTunes AAC-LC Audio\n");     	      break;	    case MOV_FOURCC('M','4','P',' '):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Apple iTunes AAC-LC Protected Audio\n");     	      break;	    case MOV_FOURCC('q','t',' ',' '):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Original QuickTime\n");     	      break;	    case MOV_FOURCC('3','g','p','1'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 1\n");     	      break;	    case MOV_FOURCC('3','g','p','2'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 2\n");     	      break;	    case MOV_FOURCC('3','g','p','3'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 3\n");     	      break;	    case MOV_FOURCC('3','g','p','4'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 4\n");     	      break;	    case MOV_FOURCC('3','g','p','5'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 5\n");     	      break;	    case MOV_FOURCC('m','m','p','4'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Mobile ISO/IEC 14496-1 (MPEG-4 system)\n");     	      break;	    default:	      tmp = be2me_32(tmp);  	      mp_msg(MSGT_DEMUX,MSGL_WARN,"ISO: Unknown File Type Major Brand: %.4s\n",&tmp);	  }	  mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Minor Version: %d\n",	      stream_read_dword(demuxer->stream));	  skipped += 8;	  // List all compatible brands	  for(i = 0; i < ((len-16)/4); i++) {	    tmp = be2me_32(stream_read_dword(demuxer->stream));	    mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Compatible Brand #%d: %.4s\n",i,&tmp);

⌨️ 快捷键说明

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