summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--Makefile1
-rw-r--r--audio/decode/ad.c2
-rw-r--r--audio/decode/ad_dvdpcm.c162
-rw-r--r--demux/demux_mpg.c45
-rw-r--r--etc/codecs.conf3
5 files changed, 47 insertions, 166 deletions
diff --git a/Makefile b/Makefile
index 43688ec0aa..db41f6d4e2 100644
--- a/Makefile
+++ b/Makefile
@@ -123,7 +123,6 @@ SOURCES = talloc.c \
audio/mixer.c \
audio/reorder_ch.c \
audio/decode/ad.c \
- audio/decode/ad_dvdpcm.c \
audio/decode/ad_lavc.c \
audio/decode/ad_spdif.c \
audio/decode/dec_audio.c \
diff --git a/audio/decode/ad.c b/audio/decode/ad.c
index f091914244..9af7112bf0 100644
--- a/audio/decode/ad.c
+++ b/audio/decode/ad.c
@@ -33,7 +33,6 @@
extern const ad_functions_t mpcodecs_ad_mpg123;
extern const ad_functions_t mpcodecs_ad_ffmpeg;
-extern const ad_functions_t mpcodecs_ad_dvdpcm;
extern const ad_functions_t mpcodecs_ad_spdif;
const ad_functions_t * const mpcodecs_ad_drivers[] =
@@ -42,7 +41,6 @@ const ad_functions_t * const mpcodecs_ad_drivers[] =
&mpcodecs_ad_mpg123,
#endif
&mpcodecs_ad_ffmpeg,
- &mpcodecs_ad_dvdpcm,
&mpcodecs_ad_spdif,
NULL
};
diff --git a/audio/decode/ad_dvdpcm.c b/audio/decode/ad_dvdpcm.c
deleted file mode 100644
index 3b12c71c12..0000000000
--- a/audio/decode/ad_dvdpcm.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "core/mp_msg.h"
-#include "ad_internal.h"
-
-static const ad_info_t info =
-{
- "Uncompressed DVD/VOB LPCM audio decoder",
- "dvdpcm",
- "Nick Kurshev",
- "A'rpi",
- ""
-};
-
-LIBAD_EXTERN(dvdpcm)
-
-static int init(sh_audio_t *sh)
-{
-/* DVD PCM Audio:*/
- sh->i_bps = 0;
- if(sh->codecdata_len==3){
- // we have LPCM header:
- unsigned char h=sh->codecdata[1];
- sh->channels=1+(h&7);
- switch((h>>4)&3){
- case 0: sh->samplerate=48000;break;
- case 1: sh->samplerate=96000;break;
- case 2: sh->samplerate=44100;break;
- case 3: sh->samplerate=32000;break;
- }
- switch ((h >> 6) & 3) {
- case 0:
- sh->sample_format = AF_FORMAT_S16_BE;
- sh->samplesize = 2;
- break;
- case 1:
- mp_tmsg(MSGT_DECAUDIO, MSGL_INFO, "Samples of this format are needed to improve support. Please contact the developers.\n");
- sh->i_bps = sh->channels * sh->samplerate * 5 / 2;
- case 2:
- sh->sample_format = AF_FORMAT_S24_BE;
- sh->samplesize = 3;
- break;
- default:
- sh->sample_format = AF_FORMAT_S16_BE;
- sh->samplesize = 2;
- }
- } else {
- // use defaults:
- sh->channels=2;
- sh->samplerate=48000;
- sh->sample_format = AF_FORMAT_S16_BE;
- sh->samplesize = 2;
- }
- if (!sh->i_bps)
- sh->i_bps = sh->samplesize * sh->channels * sh->samplerate;
- return 1;
-}
-
-static int preinit(sh_audio_t *sh)
-{
- sh->audio_out_minsize=2048;
- return 1;
-}
-
-static void uninit(sh_audio_t *sh)
-{
-}
-
-static int control(sh_audio_t *sh,int cmd,void* arg, ...)
-{
- int skip;
- switch(cmd)
- {
- case ADCTRL_SKIP_FRAME:
- skip=sh->i_bps/16;
- skip=skip&(~3);
- demux_read_data(sh->ds,NULL,skip);
- return CONTROL_TRUE;
- }
- return CONTROL_UNKNOWN;
-}
-
-static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
-{
- int j,len;
- if (sh_audio->samplesize == 3) {
- if (((sh_audio->codecdata[1] >> 6) & 3) == 1) {
- // 20 bit
- // not sure if the "& 0xf0" and "<< 4" are the right way around
- // can somebody clarify?
- for (j = 0; j < minlen; j += 12) {
- char tmp[10];
- len = demux_read_data(sh_audio->ds, tmp, 10);
- if (len < 10) break;
- // first sample
- buf[j + 0] = tmp[0];
- buf[j + 1] = tmp[1];
- buf[j + 2] = tmp[8] & 0xf0;
- // second sample
- buf[j + 3] = tmp[2];
- buf[j + 4] = tmp[3];
- buf[j + 5] = tmp[8] << 4;
- // third sample
- buf[j + 6] = tmp[4];
- buf[j + 7] = tmp[5];
- buf[j + 8] = tmp[9] & 0xf0;
- // fourth sample
- buf[j + 9] = tmp[6];
- buf[j + 10] = tmp[7];
- buf[j + 11] = tmp[9] << 4;
- }
- len = j;
- } else {
- // 24 bit
- for (j = 0; j < minlen; j += 12) {
- char tmp[12];
- len = demux_read_data(sh_audio->ds, tmp, 12);
- if (len < 12) break;
- // first sample
- buf[j + 0] = tmp[0];
- buf[j + 1] = tmp[1];
- buf[j + 2] = tmp[8];
- // second sample
- buf[j + 3] = tmp[2];
- buf[j + 4] = tmp[3];
- buf[j + 5] = tmp[9];
- // third sample
- buf[j + 6] = tmp[4];
- buf[j + 7] = tmp[5];
- buf[j + 8] = tmp[10];
- // fourth sample
- buf[j + 9] = tmp[6];
- buf[j + 10] = tmp[7];
- buf[j + 11] = tmp[11];
- }
- len = j;
- }
- } else
- len=demux_read_data(sh_audio->ds,buf,(minlen+3)&(~3));
- return len;
-}
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
diff --git a/etc/codecs.conf b/etc/codecs.conf
index 3988dd6cd1..2d3d3cefdc 100644
--- a/etc/codecs.conf
+++ b/etc/codecs.conf
@@ -1953,7 +1953,8 @@ audiocodec dvdpcm
info "Uncompressed DVD/VOB LPCM"
status working
format 0x10001
- driver dvdpcm
+ driver ffmpeg
+ dll pcm_dvd
audiocodec fflpcm
info "Blu-ray LPCM"