demux_real_1.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,824 行 · 第 1/5 页
C
1,824 行
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 { 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; } break; case 2: // force generating index generate_index(demuxer); demuxer->seekable = 1; break; default: // do nothing break; } if(priv->is_multirate) demuxer->seekable = 0; // No seeking yet for multirate streams // detect streams: if(demuxer->video->id==-1 && v_streams>0){ // find the valid video stream: if(!ds_fill_buffer(demuxer->video)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,"RM: " MSGTR_MissingVideoStream); } } if(demuxer->audio->id==-1 && a_streams>0){ // find the valid audio stream: if(!ds_fill_buffer(demuxer->audio)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,"RM: " MSGTR_MissingAudioStream); } } if(demuxer->video->sh){ sh_video_t *sh=demuxer->video->sh; mp_msg(MSGT_DEMUX,MSGL_V,"VIDEO: %.4s [%08X,%08X] %dx%d (aspect %4.2f) %4.2f fps\n", (char *)&sh->format,((unsigned int*)(sh->bih+1))[1],((unsigned int*)(sh->bih+1))[0], sh->disp_w,sh->disp_h,sh->aspect,sh->fps); } if(demuxer->audio->sh){ sh_audio_t *sh=demuxer->audio->sh; mp_msg(MSGT_DEMUX,MSGL_V,"AUDIO: %.4s [%08X]\n", (char *)&sh->format,sh->format); } return demuxer;}static void demux_close_real(demuxer_t *demuxer){ int i; real_priv_t* priv = demuxer->priv; if (priv){ for(i=0; i<MAX_STREAMS; i++) if(priv->index_table[i]) free(priv->index_table[i]); if (priv->audio_buf) free(priv->audio_buf); if (priv->audio_timestamp) free(priv->audio_timestamp); free(priv); } return;}/* please upload RV10 samples WITH INDEX CHUNK */static void demux_seek_real(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){ real_priv_t *priv = demuxer->priv; demux_stream_t *d_audio = demuxer->audio; demux_stream_t *d_video = demuxer->video; sh_audio_t *sh_audio = d_audio->sh; sh_video_t *sh_video = d_video->sh; int vid = d_video->id, aid = d_audio->id; int next_offset = 0; int64_t cur_timestamp = 0; int streams = 0; int retried = 0; if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid]) streams |= 1; if (sh_audio && (unsigned)aid < MAX_STREAMS && priv->index_table_size[aid]) streams |= 2;// printf("streams: %d\n", streams); if (!streams) return; if (flags & 1) /* seek absolute */ priv->current_apacket = priv->current_vpacket = 0; if (flags & 2) // percent seek rel_seek_secs *= priv->duration; if ((streams & 1) && priv->current_vpacket >= priv->index_table_size[vid])
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?