demux_real.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,820 行 · 第 1/5 页
C
1,820 行
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); sh->codecdatatype = 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); 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); mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", 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 if (strstr(mimet,"x-pn-encrypted-ra")) { mp_msg(MSGT_DEMUX,MSGL_ERR,"Encrypted audio is not supported\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); mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "real", 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)); memset(sh->bih, 0, sizeof(BITMAPINFOHEADER)); sh->bih->biSize = sizeof(BITMAPINFOHEADER); 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 and store codec extradata unsigned int cnt = codec_data_size - (stream_tell(demuxer->stream) - codec_pos); if (cnt > 0x7fffffff - sizeof(BITMAPINFOHEADER)) { mp_msg(MSGT_DEMUX, MSGL_ERR,"Extradata too big (%u)\n", cnt); } else { sh->bih = realloc(sh->bih, sizeof(BITMAPINFOHEADER) + cnt); sh->bih->biSize += cnt; stream_read(demuxer->stream, ((unsigned char*)(sh->bih+1)), cnt); } } if(sh->format == 0x30315652 && ((unsigned char*)(sh->bih+1))[6] == 0x30) sh->bih->biCompression = sh->format = mmioFOURCC('R', 'V', '1', '3'); /* 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 { priv->audio_curpos = priv->str_data_offset[demuxer->audio->id] + 18; stream_seek(demuxer->stream, priv->str_data_offset[demuxer->audio->id]+10); priv->a_num_of_packets=priv->a_num_of_packets = stream_read_dword(demuxer->stream); priv->video_curpos = priv->str_data_offset[demuxer->video->id] + 18; stream_seek(demuxer->stream, priv->str_data_offset[demuxer->video->id]+10); priv->v_num_of_packets = stream_read_dword(demuxer->stream); priv->stream_switch = 1; /* Index required for multirate playback, force building if it's not there */ /* but respect user request to force index regeneration */ if (index_mode == -1) index_mode = 1; } priv->audio_need_keyframe = 0; priv->video_after_seek = 0; switch (index_mode){ case -1: // untouched if (priv->index_chunk_offset && parse_index_chunk(demuxer)) { demuxer->seekable = 1; } break; case 1: // use (generate index) if (priv->index_chunk_offset && parse_index_chunk(demuxer)) { demuxer->seekable = 1; } else { generate_index(demuxer); demuxer->seekable = 1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?