summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-09 18:58:20 +0100
committerwm4 <wm4@nowhere>2012-12-11 00:37:54 +0100
commit071d24e19de6c2c0278e80f21e10572a4d694ddf (patch)
tree5da015dbb8a0a22211e28aae7a334b2cdbac1e34 /demux
parent2dd2d9bcfcf57b9921c9ef360746dd59c45574fd (diff)
downloadmpv-071d24e19de6c2c0278e80f21e10572a4d694ddf.tar.bz2
mpv-071d24e19de6c2c0278e80f21e10572a4d694ddf.tar.xz
audio/decode: remove ad_dvdpcm and use ad_lavc for DVD PCM
ad_dvdpcm reads MPEG specific headers directly (passed through codecdata by demux_mpg), so you couldn't use ffmpeg's "pcm_dvd" with demux_mpg. Change demux_mpg to set the correct audio parameters directly. The code for this is taken from ad_dvdpcm. ad_dvdpcm is evil because it still does partial packet reads (with demux_read_data()), and it's redundant to libavcodec anyway.
Diffstat (limited to 'demux')
-rw-r--r--demux/demux_mpg.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/demux/demux_mpg.c b/demux/demux_mpg.c
index 92d6290ab0..83d27def11 100644
--- a/demux/demux_mpg.c
+++ b/demux/demux_mpg.c
@@ -286,6 +286,49 @@ static void new_audio_stream(demuxer_t *demux, int aid){
if(demux->audio->id==-1) demux->audio->id=aid;
}
+static void dvdpcm_header(sh_audio_t *sh)
+{
+ if (sh->format != 0x10001)
+ return;
+
+ WAVEFORMATEX *wf = calloc(sizeof(*wf), 1);
+
+ if(sh->codecdata_len==3){
+ // we have LPCM header:
+ unsigned char h=sh->codecdata[1];
+ wf->nChannels=1+(h&7);
+ switch((h>>4)&3){
+ case 0: wf->nSamplesPerSec=48000;break;
+ case 1: wf->nSamplesPerSec=96000;break;
+ case 2: wf->nSamplesPerSec=44100;break;
+ case 3: wf->nSamplesPerSec=32000;break;
+ }
+ switch ((h >> 6) & 3) {
+ case 0:
+ wf->wBitsPerSample = 2 * 8;
+ break;
+ case 1:
+ mp_tmsg(MSGT_DECAUDIO, MSGL_INFO, "Samples of this format are needed to improve support. Please contact the developers.\n");
+ wf->nAvgBytesPerSec = wf->nChannels * wf->nSamplesPerSec * 5 / 2;
+ case 2:
+ wf->wBitsPerSample = 3 * 8;
+ break;
+ default:
+ wf->wBitsPerSample = 2 * 8;
+ }
+ } else {
+ // use defaults:
+ wf->nChannels=2;
+ wf->nSamplesPerSec=48000;
+ wf->wBitsPerSample = 2 * 8;
+ }
+ if (!wf->nAvgBytesPerSec)
+ wf->nAvgBytesPerSec = wf->wBitsPerSample / 8 * wf->nChannels * wf->nSamplesPerSec;
+ if (wf->wBitsPerSample == 16)
+ sh->format = 0x20776172; // 'raw ', pcm_s16be
+ sh->wf = wf;
+}
+
static int demux_mpg_read_packet(demuxer_t *demux,int id){
int d av_unused;
int len;
@@ -526,6 +569,7 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
// printf("[%02X] ",c);
len-=3;
if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
+ dvdpcm_header((sh_audio_t*)(ds->sh));
}
// printf(" \n");
} // if(demux->audio->id==aid)
@@ -559,6 +603,7 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
if(priv->es_map[id - 0x1B0])
sh->format = priv->es_map[id - 0x1B0];
mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
+ dvdpcm_header(sh);
}
}
} else