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 + -
显示快捷键?