demux_real_new.c

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

C
1,849
字号
			stream_skip(demuxer->stream, 4);  // "genr"			stream_read(demuxer->stream, buf, 4); // fourcc			buf[4] = 0;		    }		    else		    {					/* Desc #1 */			skip_str(1, demuxer);			/* Desc #2 */			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;			    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;			    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 ((sh->format == MKTAG('a', 't', 'r', 'c')) ||                    (sh->format == MKTAG('c', 'o', 'o', 'k')))    			    sh->wf->nBlockAlign = sub_packet_size;    			else    			    sh->wf->nBlockAlign = coded_frame_size;			    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;			    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);		    }		    sh->wf->wFormatTag = sh->format;		    		    mp_msg(MSGT_DEMUX,MSGL_V,"audio fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);		    if ( mp_msg_test(MSGT_DEMUX,MSGL_V) )		    print_wave_header(sh->wf, MSGL_V);		    /* Select audio stream with highest bitrate if multirate file*/		    if (priv->is_multirate && ((demuxer->audio->id == -1) ||		                               ((demuxer->audio->id >= 0) && priv->a_bitrate && (bitrate > priv->a_bitrate)))) {			    demuxer->audio->id = stream_id;			    priv->a_bitrate = bitrate;			    mp_msg(MSGT_DEMUX,MSGL_DBG2,"Multirate autoselected audio id %d with bitrate %d\n", stream_id, bitrate);		    }		    if(demuxer->audio->id==stream_id){			sh->ds=demuxer->audio;			demuxer->audio->sh=sh;        	priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]);        	priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double));		    }		    		    ++a_streams;#ifdef stream_skip#undef stream_skip#endif		}	  } else if (strstr(mimet,"X-MP3-draft-00")) {		    sh_audio_t *sh = new_sh_audio(demuxer, stream_id);		    /* Emulate WAVEFORMATEX struct: */		    sh->wf = malloc(sizeof(WAVEFORMATEX));		    memset(sh->wf, 0, sizeof(WAVEFORMATEX));		    sh->wf->nChannels = 0;//sh->channels;		    sh->wf->wBitsPerSample = 16;		    sh->wf->nSamplesPerSec = 0;//sh->samplerate;		    sh->wf->nAvgBytesPerSec = 0;//bitrate;		    sh->wf->nBlockAlign = 0;//frame_size;		    sh->wf->cbSize = 0;		    sh->wf->wFormatTag = sh->format = mmioFOURCC('a','d','u',0x55);		    		    if(demuxer->audio->id==stream_id){			    sh->ds=demuxer->audio;			    demuxer->audio->sh=sh;		    }		    		    ++a_streams;	  } else if (strstr(mimet,"x-ralf-mpeg4")) {		 mp_msg(MSGT_DEMUX,MSGL_ERR,"Real lossless audio not supported yet\n");	  } else {		 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown audio stream format\n");		}	} else if (!strncmp(mimet,"video/",6)) {	  if (strstr(mimet,"x-pn-realvideo") || strstr(mimet,"x-pn-multirate-realvideo")) {		stream_skip(demuxer->stream, 4);  // VIDO length, same as codec_data_size		tmp = stream_read_dword(demuxer->stream);		if(tmp != MKTAG('O', 'D', 'I', 'V'))		{		    mp_msg(MSGT_DEMUX,MSGL_V,"Video: can't find VIDO in codec data\n");		} else {		    /* video header */		    sh_video_t *sh = new_sh_video(demuxer, stream_id);		    sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */		    mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);		    /* emulate BITMAPINFOHEADER */		    sh->bih = malloc(sizeof(BITMAPINFOHEADER)+16);		    memset(sh->bih, 0, sizeof(BITMAPINFOHEADER)+16);	    	    sh->bih->biSize = 48;		    sh->disp_w = sh->bih->biWidth = stream_read_word(demuxer->stream);		    sh->disp_h = sh->bih->biHeight = stream_read_word(demuxer->stream);		    sh->bih->biPlanes = 1;		    sh->bih->biBitCount = 24;		    sh->bih->biCompression = sh->format;		    sh->bih->biSizeImage= sh->bih->biWidth*sh->bih->biHeight*3;		    sh->fps = (float) stream_read_word(demuxer->stream);		    if (sh->fps<=0) sh->fps=24; // we probably won't even care about fps		    sh->frametime = 1.0f/sh->fps;		    #if 1		    stream_skip(demuxer->stream, 4);#else		    mp_msg(MSGT_DEMUX, MSGL_V,"unknown1: 0x%X  \n",stream_read_dword(demuxer->stream));		    mp_msg(MSGT_DEMUX, MSGL_V,"unknown2: 0x%X  \n",stream_read_word(demuxer->stream));		    mp_msg(MSGT_DEMUX, MSGL_V,"unknown3: 0x%X  \n",stream_read_word(demuxer->stream));#endif//		    if(sh->format==0x30335652 || sh->format==0x30325652 )		    if(1)		    {			int tmp=stream_read_word(demuxer->stream);			if(tmp>0){			    sh->fps=tmp; sh->frametime = 1.0f/sh->fps;			}		    } else {	    		int fps=stream_read_word(demuxer->stream);			mp_msg(MSGT_DEMUX, MSGL_WARN,"realvid: ignoring FPS = %d\n",fps);		    }		    stream_skip(demuxer->stream, 2);		    		    // read codec sub-format (to make difference between low and high rate codec)		    ((unsigned int*)(sh->bih+1))[0]=stream_read_dword(demuxer->stream);		    /* h263 hack */		    tmp = stream_read_dword(demuxer->stream);		    ((unsigned int*)(sh->bih+1))[1]=tmp;		    mp_msg(MSGT_DEMUX,MSGL_V,"H.263 ID: %x\n", tmp);		    switch (tmp)		    {			case 0x10000000:			    /* sub id: 0 */			    /* codec id: rv10 */			    break;			case 0x10003000:			case 0x10003001:			    /* sub id: 3 */			    /* codec id: rv10 */			    sh->bih->biCompression = sh->format = mmioFOURCC('R', 'V', '1', '3');			    break;			case 0x20001000:			case 0x20100001:			case 0x20200002:			    /* codec id: rv20 */			    break;			case 0x30202002:			    /* codec id: rv30 */			    break;			case 0x40000000:			    /* codec id: rv40 */			    break;			default:			    /* codec id: none */			    mp_msg(MSGT_DEMUX,MSGL_V,"unknown id: %x\n", tmp);		    }		    if((sh->format<=0x30335652) && (tmp>=0x20200002)){			    // read data for the cmsg24[] (see vd_realvid.c)			    unsigned int cnt = codec_data_size - (stream_tell(demuxer->stream) - codec_pos);			    if (cnt < 2) {			        mp_msg(MSGT_DEMUX, MSGL_ERR,"realvid: cmsg24 data too short (size %u)\n", cnt);			    } else  {			        int ii;			        if (cnt > 8) {			            mp_msg(MSGT_DEMUX, MSGL_WARN,"realvid: cmsg24 data too big, please report (size %u)\n", cnt);			            cnt = 8;			        }			        for (ii = 0; ii < cnt; ii++)			            ((unsigned char*)(sh->bih+1))[8+ii]=(unsigned short)stream_read_char(demuxer->stream);			        sh->bih->biSize += cnt;			    }		    } 		    		    /* Select video stream with highest bitrate if multirate file*/		    if (priv->is_multirate && ((demuxer->video->id == -1) ||		                               ((demuxer->video->id >= 0) && priv->v_bitrate && (bitrate > priv->v_bitrate)))) {			    demuxer->video->id = stream_id;			    priv->v_bitrate = bitrate;			    mp_msg(MSGT_DEMUX,MSGL_DBG2,"Multirate autoselected video id %d with bitrate %d\n", stream_id, bitrate);		    }		    if(demuxer->video->id==stream_id){			sh->ds=demuxer->video;			demuxer->video->sh=sh;		    }		    		    ++v_streams;		}	  } else {		 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown video stream format\n");	  }	} else if (strstr(mimet,"logical-")) {		 if (strstr(mimet,"fileinfo")) {		     mp_msg(MSGT_DEMUX,MSGL_V,"Got a logical-fileinfo chunk\n");		 } else if (strstr(mimet,"-audio") || strstr(mimet,"-video")) {		    int i, stream_cnt;		    int stream_list[MAX_STREAMS];		    		    priv->is_multirate = 1;		    stream_skip(demuxer->stream, 4); // Length of codec data (repeated)		    stream_cnt = stream_read_dword(demuxer->stream); // Get number of audio or video streams		    if ((unsigned)stream_cnt >= MAX_STREAMS) {		        mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many streams in %s. Big troubles ahead.\n", mimet);		        goto skip_this_chunk;		    }		    for (i = 0; i < stream_cnt; i++)		        stream_list[i] = stream_read_word(demuxer->stream);		    for (i = 0; i < stream_cnt; i++)		        if ((unsigned)stream_list[i] >= MAX_STREAMS) {		            mp_msg(MSGT_DEMUX,MSGL_ERR,"Stream id out of range: %d. Ignored.\n", stream_list[i]);		            stream_skip(demuxer->stream, 4); // Skip DATA offset for broken stream		        } else {		            priv->str_data_offset[stream_list[i]] = stream_read_dword(demuxer->stream);		            mp_msg(MSGT_DEMUX,MSGL_V,"Stream %d with DATA offset 0x%08x\n", stream_list[i], priv->str_data_offset[stream_list[i]]);		        }		    // Skip the rest of this chunk		 } else 		     mp_msg(MSGT_DEMUX,MSGL_V,"Unknown logical stream\n");		}		else {		    mp_msg(MSGT_DEMUX, MSGL_ERR, "Not audio/video stream or unsupported!\n");		}//		break;//	    default:skip_this_chunk:		/* skip codec info */		tmp = stream_tell(demuxer->stream) - codec_pos;		mp_msg(MSGT_DEMUX,MSGL_V,"### skipping %d bytes of codec info\n", codec_data_size - tmp);#if 0		{ int i;		  for(i=0;i<codec_data_size - tmp;i++)		      mp_msg(MSGT_DEMUX, MSGL_V," %02X",stream_read_char(demuxer->stream));		  mp_msg(MSGT_DEMUX, MSGL_V,"\n");		}#else		stream_skip(demuxer->stream, codec_data_size - tmp);#endif		if (mimet)		    free (mimet);		break;//	    }	    }	    case MKTAG('D', 'A', 'T', 'A'):		goto header_end;	    case MKTAG('I', 'N', 'D', 'X'):	    default:		mp_msg(MSGT_DEMUX,MSGL_V,"Unknown chunk: %x\n", chunk_id);		stream_skip(demuxer->stream, chunk_size - 10);		break;	}    }header_end:    if(priv->is_multirate) {        mp_msg(MSGT_DEMUX,MSGL_V,"Selected video id %d audio id %d\n", demuxer->video->id, demuxer->audio->id);        /* Perform some sanity checks to avoid checking streams id all over the code*/        if (demuxer->audio->id >= MAX_STREAMS) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid audio stream %d. No sound will be played.\n", demuxer->audio->id);            demuxer->audio->id = -2;        } else if ((demuxer->audio->id >= 0) && (priv->str_data_offset[demuxer->audio->id] == 0)) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Audio stream %d not found. No sound will be played.\n", demuxer->audio->id);            demuxer->audio->id = -2;        }        if (demuxer->video->id >= MAX_STREAMS) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid video stream %d. No video will be played.\n", demuxer->video->id);            demuxer->video->id = -2;        } else if ((demuxer->video->id >= 0) && (priv->str_data_offset[demuxer->video->id] == 0)) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Video stream %d not found. No video will be played.\n", demuxer->video->id);            demuxer->video->id = -2;        }    }    if(priv->is_multirate && ((demuxer->video->id >= 0) || (demuxer->audio->id  >=0))) {        /* If audio or video only, seek to right place and behave like standard file */        if (demuxer->video->id < 0) {            // Stream is audio only, or -novideo            stream_seek(demuxer->stream, priv->data_chunk_offset = priv->str_data_offset[demuxer->audio->id]+10);            priv->is_multirate = 0;        }        if (demuxer->audio->id < 0) {            // Stream is video only, or -nosound            stream_seek(demuxer->stream, priv->data_chunk_offset = priv->str_data_offset[demuxer->video->id]+10);            priv->is_multirate = 0;        }    }  if(!priv->is_multirate) {//    printf("i=%d num_of_headers=%d   \n",i,num_of_headers);    priv->num_of_packets = stream_read_dword(demuxer->stream);    stream_skip(demuxer->stream, 4); /* next data header */    mp_msg(MSGT_DEMUX,MSGL_V,"Packets in file: %d\n", priv->num_of_packets);    if (priv->num_of_packets == 0)	priv->num_of_packets = -10;  } else {        

⌨️ 快捷键说明

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