demux_real_1.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,824 行 · 第 1/5 页

C
1,824
字号
extern void print_wave_header(WAVEFORMATEX *h, int verbose_level);static demuxer_t* demux_open_real(demuxer_t* demuxer){    real_priv_t* priv = demuxer->priv;    int num_of_headers;    int a_streams=0;    int v_streams=0;    int i;    int header_size;    header_size = stream_read_dword(demuxer->stream); /* header size */    mp_msg(MSGT_DEMUX,MSGL_V, "real: Header size: %d\n", header_size);    i = stream_read_word(demuxer->stream); /* version */    mp_msg(MSGT_DEMUX,MSGL_V, "real: Header object version: %d\n", i);    if (header_size == 0x10)    	i = stream_read_word(demuxer->stream);    else /* we should test header_size here too. */    	i = stream_read_dword(demuxer->stream);    mp_msg(MSGT_DEMUX,MSGL_V, "real: File version: %d\n", i);    num_of_headers = stream_read_dword(demuxer->stream);    /* parse chunks */    for (i = 1; i <= num_of_headers; i++)//    for (i = 1; ; i++)    {	int chunk_id, chunk_pos, chunk_size;		chunk_pos = stream_tell(demuxer->stream);	chunk_id = stream_read_dword_le(demuxer->stream);	chunk_size = stream_read_dword(demuxer->stream);	stream_skip(demuxer->stream, 2); /* version */	mp_msg(MSGT_DEMUX,MSGL_V, "Chunk: %.4s (%x) (size: 0x%x, offset: 0x%x)\n",	    (char *)&chunk_id, chunk_id, chunk_size, chunk_pos);		if (chunk_size < 10){	    mp_msg(MSGT_DEMUX,MSGL_ERR,"demux_real: invalid chunksize! (%d)\n",chunk_size);	    break; //return;	}		switch(chunk_id)	{	    case MKTAG('P', 'R', 'O', 'P'):		/* Properties header */		stream_skip(demuxer->stream, 4); /* max bitrate */		stream_skip(demuxer->stream, 4); /* avg bitrate */		stream_skip(demuxer->stream, 4); /* max packet size */		stream_skip(demuxer->stream, 4); /* avg packet size */		stream_skip(demuxer->stream, 4); /* nb packets */		priv->duration = stream_read_dword(demuxer->stream)/1000; /* duration */		stream_skip(demuxer->stream, 4); /* preroll */		priv->index_chunk_offset = stream_read_dword(demuxer->stream);		mp_msg(MSGT_DEMUX,MSGL_V,"First index chunk offset: 0x%x\n", priv->index_chunk_offset);		priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10;		mp_msg(MSGT_DEMUX,MSGL_V,"First data chunk offset: 0x%x\n", priv->data_chunk_offset);		stream_skip(demuxer->stream, 2); /* nb streams */#if 0		stream_skip(demuxer->stream, 2); /* flags */#else		{		    int flags = stream_read_word(demuxer->stream);		    		    if (flags)		    {		    mp_msg(MSGT_DEMUX,MSGL_V,"Flags (%x): ", flags);		    if (flags & 0x1)			mp_msg(MSGT_DEMUX,MSGL_V,"[save allowed] ");		    if (flags & 0x2)			mp_msg(MSGT_DEMUX,MSGL_V,"[perfect play (more buffers)] ");		    if (flags & 0x4)			mp_msg(MSGT_DEMUX,MSGL_V,"[live broadcast] ");		    mp_msg(MSGT_DEMUX,MSGL_V,"\n");		    }		}#endif		break;	    case MKTAG('C', 'O', 'N', 'T'):	    {		/* Content description header */		char *buf;		int len;		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);		    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "name", buf);		    free(buf);		}		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);		    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "author", buf);		    free(buf);		}		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);		    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "copyright", buf);		    free(buf);		}		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);	    	    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "comment", buf);		    free(buf);		}		break;	    }	    case MKTAG('M', 'D', 'P', 'R'):	    {		/* Media properties header */		int stream_id;		int bitrate;		int codec_data_size;		int codec_pos;		int tmp;		int len;		char *descr, *mimet = NULL;		stream_id = stream_read_word(demuxer->stream);		mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id);				stream_skip(demuxer->stream, 4); /* max bitrate */		bitrate = stream_read_dword(demuxer->stream); /* avg bitrate */		stream_skip(demuxer->stream, 4); /* max packet size */		stream_skip(demuxer->stream, 4); /* avg packet size */		stream_skip(demuxer->stream, 4); /* start time */		stream_skip(demuxer->stream, 4); /* preroll */		stream_skip(demuxer->stream, 4); /* duration */				if ((len = stream_read_char(demuxer->stream)) > 0) {		    descr = malloc(len+1);	    	stream_read(demuxer->stream, descr, len);		    descr[len] = 0;		    mp_msg(MSGT_DEMUX, MSGL_INFO,"Stream description: %s\n", descr);		    free(descr);		}		if ((len = stream_read_char(demuxer->stream)) > 0) {		    mimet = malloc(len+1);	    	stream_read(demuxer->stream, mimet, len);		    mimet[len] = 0;		    mp_msg(MSGT_DEMUX, MSGL_INFO,"Stream mimetype: %s\n", mimet);		}				/* Type specific header */		codec_data_size = stream_read_dword(demuxer->stream);		codec_pos = stream_tell(demuxer->stream);#ifdef MP_DEBUG#define stream_skip(st,siz) { int i; for(i=0;i<siz;i++) mp_msg(MSGT_DEMUX,MSGL_V," %02X",stream_read_char(st)); mp_msg(MSGT_DEMUX,MSGL_V,"\n");}#endif	if (!strncmp(mimet,"audio/",6)) {	  if (strstr(mimet,"x-pn-realaudio") || strstr(mimet,"x-pn-multirate-realaudio")) {		tmp = stream_read_dword(demuxer->stream);		if (tmp != MKTAG(0xfd, 'a', 'r', '.'))		{		    mp_msg(MSGT_DEMUX,MSGL_V,"Audio: can't find .ra in codec data\n");		} else {		    /* audio header */		    sh_audio_t *sh = new_sh_audio(demuxer, stream_id);		    char buf[128]; /* for codec name */		    int frame_size;		    int sub_packet_size;		    int sub_packet_h;		    int version;		    int flavor;		    int coded_frame_size;		    int codecdata_length;		    int i;		    char *buft;		    int hdr_size;		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id);		    mp_msg(MSGT_DEMUX,MSGL_V,"Found audio stream!\n");		    version = stream_read_word(demuxer->stream);		    mp_msg(MSGT_DEMUX,MSGL_V,"version: %d\n", version);                   if (version == 3) {                    stream_skip(demuxer->stream, 2);                    stream_skip(demuxer->stream, 10);                    stream_skip(demuxer->stream, 4);                    // Name, author, (c) are also in CONT tag                    if ((i = stream_read_char(demuxer->stream)) != 0) {                      buft = malloc(i+1);                      stream_read(demuxer->stream, buft, i);                      buft[i] = 0;                      demux_info_add(demuxer, "Name", buft);                      free(buft);                    }                    if ((i = stream_read_char(demuxer->stream)) != 0) {                      buft = malloc(i+1);                      stream_read(demuxer->stream, buft, i);                      buft[i] = 0;                      demux_info_add(demuxer, "Author", buft);                      free(buft);                    }                    if ((i = stream_read_char(demuxer->stream)) != 0) {                      buft = malloc(i+1);                      stream_read(demuxer->stream, buft, i);                      buft[i] = 0;                      demux_info_add(demuxer, "Copyright", buft);                      free(buft);                    }                    if ((i = stream_read_char(demuxer->stream)) != 0)                      mp_msg(MSGT_DEMUX,MSGL_WARN,"Last header byte is not zero!\n");                    stream_skip(demuxer->stream, 1);                    i = stream_read_char(demuxer->stream);                    sh->format = stream_read_dword_le(demuxer->stream);                    if (i != 4) {                      mp_msg(MSGT_DEMUX,MSGL_WARN,"Audio FourCC size is not 4 (%d), please report to "                             "MPlayer developers\n", i);                      stream_skip(demuxer->stream, i - 4);                    }                    if (sh->format != mmioFOURCC('l','p','c','J')) {                      mp_msg(MSGT_DEMUX,MSGL_WARN,"Version 3 audio with FourCC %8x, please report to "                             "MPlayer developers\n", sh->format);                    }                    sh->channels = 1;                    sh->samplesize = 16;                    sh->samplerate = 8000;                    frame_size = 240;                    strcpy(buf, "14_4");                   } else {		    stream_skip(demuxer->stream, 2); // 00 00		    stream_skip(demuxer->stream, 4); /* .ra4 or .ra5 */		    stream_skip(demuxer->stream, 4); // ???		    stream_skip(demuxer->stream, 2); /* version (4 or 5) */		    hdr_size = stream_read_dword(demuxer->stream); // header size		    mp_msg(MSGT_DEMUX,MSGL_V,"header size: %d\n", hdr_size);		    flavor = stream_read_word(demuxer->stream);/* codec flavor id */		    coded_frame_size = stream_read_dword(demuxer->stream);/* needed by codec */		    mp_msg(MSGT_DEMUX,MSGL_V,"coded_frame_size: %d\n", coded_frame_size);		    stream_skip(demuxer->stream, 4); // big number		    stream_skip(demuxer->stream, 4); // bigger number		    stream_skip(demuxer->stream, 4); // 2 || -''-		    sub_packet_h = stream_read_word(demuxer->stream);		    mp_msg(MSGT_DEMUX,MSGL_V,"sub_packet_h: %d\n", sub_packet_h);		    frame_size = stream_read_word(demuxer->stream);		    mp_msg(MSGT_DEMUX,MSGL_V,"frame_size: %d\n", frame_size);		    sub_packet_size = stream_read_word(demuxer->stream);		    mp_msg(MSGT_DEMUX,MSGL_V,"sub_packet_size: %d\n", sub_packet_size);		    stream_skip(demuxer->stream, 2); // 0		    		    if (version == 5)			stream_skip(demuxer->stream, 6); //0,srate,0		    sh->samplerate = stream_read_word(demuxer->stream);		    stream_skip(demuxer->stream, 2);  // 0		    sh->samplesize = stream_read_word(demuxer->stream)/8;		    sh->channels = stream_read_word(demuxer->stream);		    mp_msg(MSGT_DEMUX,MSGL_V,"samplerate: %d, channels: %d\n",			sh->samplerate, sh->channels);		    if (version == 5)		    {			stream_read(demuxer->stream, buf, 4);  // interleaver id			priv->intl_id[stream_id] = MKTAG(buf[0], buf[1], buf[2], buf[3]);			stream_read(demuxer->stream, buf, 4); // fourcc			buf[4] = 0;		    }		    else		    {					/* Interleaver id */			get_str(1, demuxer, buf, sizeof(buf));			priv->intl_id[stream_id] = MKTAG(buf[0], buf[1], buf[2], buf[3]);			/* Codec FourCC */			get_str(1, demuxer, buf, sizeof(buf));		    }                   }		    /* Emulate WAVEFORMATEX struct: */		    sh->wf = malloc(sizeof(WAVEFORMATEX));		    memset(sh->wf, 0, sizeof(WAVEFORMATEX));		    sh->wf->nChannels = sh->channels;		    sh->wf->wBitsPerSample = sh->samplesize*8;		    sh->wf->nSamplesPerSec = sh->samplerate;		    sh->wf->nAvgBytesPerSec = bitrate/8;		    sh->wf->nBlockAlign = frame_size;		    sh->wf->cbSize = 0;		    sh->format = MKTAG(buf[0], buf[1], buf[2], buf[3]);		    switch (sh->format)		    {			case MKTAG('d', 'n', 'e', 't'):			    mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET -> AC3\n");//			    sh->format = 0x2000;			    break;			case MKTAG('1', '4', '_', '4'):                sh->wf->nBlockAlign = 0x14;                            break;			case MKTAG('2', '8', '_', '8'):			    sh->wf->nBlockAlign = coded_frame_size;			    break;			case MKTAG('s', 'i', 'p', 'r'):			case MKTAG('a', 't', 'r', 'c'):			case MKTAG('c', 'o', 'o', 'k'):			    // realaudio codec plugins - common:			    stream_skip(demuxer->stream,3);  // Skip 3 unknown bytes 			    if (version==5)			      stream_skip(demuxer->stream,1);  // Skip 1 additional unknown byte 			    codecdata_length=stream_read_dword(demuxer->stream);			    // Check extradata len, we can't store bigger values in cbSize anyway			    if ((unsigned)codecdata_length > 0xffff) {			        mp_msg(MSGT_DEMUX,MSGL_ERR,"Extradata too big (%d)\n", codecdata_length);				goto skip_this_chunk;			    }			    sh->wf->cbSize = codecdata_length;			    sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize);			    stream_read(demuxer->stream, ((char*)(sh->wf+1)), codecdata_length); // extras                if (priv->intl_id[stream_id] == MKTAG('g', 'e', 'n', 'r'))    			    sh->wf->nBlockAlign = sub_packet_size;    			else    			    sh->wf->nBlockAlign = coded_frame_size;			    break;			case MKTAG('r', 'a', 'a', 'c'):			case MKTAG('r', 'a', 'c', 'p'):			    /* This is just AAC. The two or five bytes of */			    /* config data needed for libfaad are stored */			    /* after the audio headers. */			    stream_skip(demuxer->stream,3);  // Skip 3 unknown bytes 			    if (version==5)				stream_skip(demuxer->stream,1);  // Skip 1 additional unknown byte 			    codecdata_length=stream_read_dword(demuxer->stream);			    if (codecdata_length>=1) {				sh->codecdata_len = codecdata_length - 1;				sh->codecdata = calloc(sh->codecdata_len, 1);				stream_skip(demuxer->stream, 1);				stream_read(demuxer->stream, sh->codecdata, sh->codecdata_len);			    }			    sh->format = mmioFOURCC('M', 'P', '4', 'A');			    break;			default:			    mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%s)\n", buf);		    }		    // Interleaver setup		    priv->sub_packet_size[stream_id] = sub_packet_size;		    priv->sub_packet_h[stream_id] = sub_packet_h;		    priv->coded_framesize[stream_id] = coded_frame_size;		    priv->audiopk_size[stream_id] = frame_size;		    sh->wf->wFormatTag = sh->format;		    		    mp_msg(MSGT_DEMUX,MSGL_V,"audio fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);

⌨️ 快捷键说明

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