📄 demux_audio.c
字号:
l -= w->cbSize; } } } if(verbose>0) print_wave_header(w); if(l) stream_skip(s,l); do { chunk_type = stream_read_fourcc(demuxer->stream); chunk_size = stream_read_dword_le(demuxer->stream); if (chunk_type != mmioFOURCC('d', 'a', 't', 'a')) stream_skip(demuxer->stream, chunk_size); } while (chunk_type != mmioFOURCC('d', 'a', 't', 'a')); demuxer->movi_start = stream_tell(s); demuxer->movi_end = s->end_pos;// printf("wav: %X .. %X\n",(int)demuxer->movi_start,(int)demuxer->movi_end); // Check if it contains dts audio if((w->wFormatTag == 0x01) && (w->nChannels == 2) && (w->nSamplesPerSec == 44100)) { unsigned char buf[16384]; // vlc uses 16384*4 (4 dts frames) unsigned int i; stream_read(s, buf, sizeof(buf)); for (i = 0; i < sizeof(buf); i += 2) { // DTS, 14 bit, LE if((buf[i] == 0xff) && (buf[i+1] == 0x1f) && (buf[i+2] == 0x00) && (buf[i+3] == 0xe8) && ((buf[i+4] & 0xfe) == 0xf0) && (buf[i+5] == 0x07)) { sh_audio->format = 0x2001; mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, LE\n"); break; } // DTS, 14 bit, BE if((buf[i] == 0x1f) && (buf[i+1] == 0xff) && (buf[i+2] == 0xe8) && (buf[i+3] == 0x00) && (buf[i+4] == 0x07) && ((buf[i+5] & 0xfe) == 0xf0)) { sh_audio->format = 0x2001; mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, BE\n"); break; } // DTS, 16 bit, BE if((buf[i] == 0x7f) && (buf[i+1] == 0xfe) && (buf[i+2] == 0x80) && (buf[i+3] == 0x01)) { sh_audio->format = 0x2001; mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, BE\n"); break; } // DTS, 16 bit, LE if((buf[i] == 0xfe) && (buf[i+1] == 0x7f) && (buf[i+2] == 0x01) && (buf[i+3] == 0x80)) { sh_audio->format = 0x2001; mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, LE\n"); break; } } if (sh_audio->format == 0x2001) mp_msg(MSGT_DEMUX,MSGL_DBG2,"[demux_audio] DTS sync offset = %u\n", i); } stream_seek(s,demuxer->movi_start); } break; case fLaC: sh_audio->format = mmioFOURCC('f', 'L', 'a', 'C'); demuxer->movi_start = stream_tell(s); demuxer->movi_end = s->end_pos; break; } priv = (da_priv_t*)malloc(sizeof(da_priv_t)); priv->frmt = frmt; priv->last_pts = -1; demuxer->priv = priv; demuxer->audio->id = 0; demuxer->audio->sh = sh_audio; sh_audio->ds = demuxer->audio; sh_audio->samplerate = sh_audio->audio.dwRate; if(stream_tell(s) != demuxer->movi_start) { mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking from 0x%X to start pos 0x%X\n", (int)stream_tell(s), (int)demuxer->movi_start); stream_seek(s,demuxer->movi_start); if (stream_tell(s) != demuxer->movi_start) { mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking failed, now at 0x%X!\n", (int)stream_tell(s)); if (next_frame_pos) { mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking to 0x%X instead\n", (int)next_frame_pos); stream_seek(s, next_frame_pos); } } } mp_msg(MSGT_DEMUX,MSGL_V,"demux_audio: audio data 0x%X - 0x%X \n",(int)demuxer->movi_start,(int)demuxer->movi_end); return 1;}int demux_audio_fill_buffer(demux_stream_t *ds) { int l; demux_packet_t* dp; sh_audio_t* sh_audio; demuxer_t* demux; da_priv_t* priv; stream_t* s;#ifdef MP_DEBUG assert(ds != NULL); assert(ds->sh != NULL); assert(ds->demuxer != NULL);#endif sh_audio = ds->sh; demux = ds->demuxer; priv = demux->priv; s = demux->stream; if(s->eof || (demux->movi_end && stream_tell(s) >= demux->movi_end) ) return 0; switch(priv->frmt) { case MP3 : while(1) { uint8_t hdr[4]; stream_read(s,hdr,4); if (s->eof || (demux->movi_end && stream_tell(s) >= demux->movi_end)) return 0; l = mp_decode_mp3_header(hdr); if(l < 0) { stream_skip(s,-3); } else { dp = new_demux_packet(l); memcpy(dp->buffer,hdr,4); stream_read(s,dp->buffer + 4,l-4); priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + 1152/(float)sh_audio->samplerate; // FIXME: 1152->576 if MPEG-2 break; } } break; case WAV : { l = sh_audio->wf->nAvgBytesPerSec; dp = new_demux_packet(l); l = stream_read(s,dp->buffer,l); priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + l/(float)sh_audio->i_bps; break; } case fLaC: { l = 65535; dp = new_demux_packet(l); l = stream_read(s,dp->buffer,l); priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + l/(float)sh_audio->i_bps; break; } default: printf("Audio demuxer : unknown format %d\n",priv->frmt); return 0; } resize_demux_packet(dp, l); ds->pts = priv->last_pts - (ds_tell_pts(demux->audio) - sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; ds_add_packet(ds, dp); return 1;}static void high_res_mp3_seek(demuxer_t *demuxer,float time) { uint8_t hdr[4]; int len,nf; da_priv_t* priv = demuxer->priv; sh_audio_t* sh = (sh_audio_t*)demuxer->audio->sh; nf = time*sh->samplerate/1152; while(nf > 0) { stream_read(demuxer->stream,hdr,4); len = mp_decode_mp3_header(hdr); if(len < 0) { stream_skip(demuxer->stream,-3); continue; } stream_skip(demuxer->stream,len-4); priv->last_pts += 1152/(float)sh->samplerate; nf--; }}void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){ sh_audio_t* sh_audio; stream_t* s; int base,pos; float len; da_priv_t* priv; if(!(sh_audio = demuxer->audio->sh)) return; s = demuxer->stream; priv = demuxer->priv; if(priv->frmt == MP3 && hr_mp3_seek && !(flags & 2)) { len = (flags & 1) ? rel_seek_secs - priv->last_pts : rel_seek_secs; if(len < 0) { stream_seek(s,demuxer->movi_start); len = priv->last_pts + len; priv->last_pts = 0; } if(len > 0) high_res_mp3_seek(demuxer,len); sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; resync_audio_stream(sh_audio); return; } base = flags&1 ? demuxer->movi_start : stream_tell(s); if(flags&2) pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs); else pos = base + (rel_seek_secs*sh_audio->i_bps); if(demuxer->movi_end && pos >= demuxer->movi_end) { pos = demuxer->movi_end; //sh_audio->delay = (stream_tell(s) - demuxer->movi_start)/(float)sh_audio->i_bps; //return; } else if(pos < demuxer->movi_start) pos = demuxer->movi_start; priv->last_pts = (pos-demuxer->movi_start)/(float)sh_audio->i_bps; sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; switch(priv->frmt) { case WAV: pos -= (pos % (sh_audio->channels * sh_audio->samplesize) ); // We need to decrease the pts by one step to make it the "last one" priv->last_pts -= sh_audio->wf->nAvgBytesPerSec/(float)sh_audio->i_bps; break; } stream_seek(s,pos); resync_audio_stream(sh_audio);}void demux_close_audio(demuxer_t* demuxer) { da_priv_t* priv = demuxer->priv; if(!priv) return; free(priv);}int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){ sh_audio_t *sh_audio=demuxer->audio->sh; int audio_length = demuxer->movi_end / sh_audio->i_bps; da_priv_t* priv = demuxer->priv; switch(cmd) { case DEMUXER_CTRL_GET_TIME_LENGTH: if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW; *((unsigned long *)arg)=(unsigned long)audio_length; return DEMUXER_CTRL_GUESS; case DEMUXER_CTRL_GET_PERCENT_POS: if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW; *((int *)arg)=(int)( (priv->last_pts*100) / audio_length); return DEMUXER_CTRL_OK; default: return DEMUXER_CTRL_NOTIMPL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -