summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authornicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-01-15 10:25:14 +0000
committernicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-01-15 10:25:14 +0000
commit7737fb018d8a4bb381b07e5a1d748cd4fd338e48 (patch)
tree76b08024d7b177ad1fdb422321a47c379034db93 /libmpcodecs
parentbd645471b8d7e4b594dac98900cd5927938d8852 (diff)
downloadmpv-7737fb018d8a4bb381b07e5a1d748cd4fd338e48.tar.bz2
mpv-7737fb018d8a4bb381b07e5a1d748cd4fd338e48.tar.xz
ad_hwmpa: pass-through fake audio codec for hardware mpeg decoders
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@17398 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/Makefile1
-rw-r--r--libmpcodecs/ad.c2
-rw-r--r--libmpcodecs/ad_hwmpa.c136
3 files changed, 139 insertions, 0 deletions
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile
index 9f58b7b045..bc89a7c8cb 100644
--- a/libmpcodecs/Makefile
+++ b/libmpcodecs/Makefile
@@ -7,6 +7,7 @@ LIBNAME2 = libmpencoders.a
AUDIO_SRCS_LIB=ad_hwac3.c \
ad_liba52.c \
ad_mp3lib.c \
+ ad_hwmpa.c \
AUDIO_SRCS_NAT=ad_alaw.c \
ad_dk3adpcm.c \
diff --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c
index a6f14dbfc9..5cca0f9cc6 100644
--- a/libmpcodecs/ad.c
+++ b/libmpcodecs/ad.c
@@ -20,6 +20,7 @@ extern ad_functions_t mpcodecs_ad_mp3lib;
extern ad_functions_t mpcodecs_ad_ffmpeg;
extern ad_functions_t mpcodecs_ad_liba52;
extern ad_functions_t mpcodecs_ad_hwac3;
+extern ad_functions_t mpcodecs_ad_hwmpa;
extern ad_functions_t mpcodecs_ad_pcm;
extern ad_functions_t mpcodecs_ad_dvdpcm;
extern ad_functions_t mpcodecs_ad_alaw;
@@ -51,6 +52,7 @@ ad_functions_t* mpcodecs_ad_drivers[] =
&mpcodecs_ad_liba52,
&mpcodecs_ad_hwac3,
#endif
+ &mpcodecs_ad_hwmpa,
#ifdef USE_LIBAVCODEC
&mpcodecs_ad_ffmpeg,
#endif
diff --git a/libmpcodecs/ad_hwmpa.c b/libmpcodecs/ad_hwmpa.c
new file mode 100644
index 0000000000..a3fcb0277b
--- /dev/null
+++ b/libmpcodecs/ad_hwmpa.c
@@ -0,0 +1,136 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+#include "help_mp.h"
+
+#include "libaf/af_format.h"
+#include "ad_internal.h"
+
+#include "libmpdemux/mp3_hdr.h"
+
+//based on ad_hwac3.c and ad_libmad.c
+static int isdts = -1;
+
+static ad_info_t info =
+{
+ "MPEG audio pass-through (fake decoder)",
+ "hwmpa",
+ "NicoDVB",
+ "NicoDVB",
+ "For hardware decoders"
+};
+
+LIBAD_EXTERN(hwmpa)
+
+static int mpa_sync(sh_audio_t *sh, int no_frames, int *n, int *chans, int *srate, int *spf, int *mpa_layer, int *br)
+{
+ int cnt = 0, x = 0, len, frames_count;
+
+ frames_count = 0;
+ do
+ {
+ while(cnt + 4 < sh->a_in_buffer_len)
+ {
+ if(((sh->a_in_buffer[cnt] << 8) | sh->a_in_buffer[cnt+1]) & 0xffe0 != 0xffe0)
+ continue;
+ x = mp_get_mp3_header(&(sh->a_in_buffer[cnt]), chans, srate, spf, mpa_layer, br);
+ if(x > 0)
+ {
+ frames_count++;
+ if(frames_count == no_frames)
+ {
+ *n = x;
+ return cnt;
+ }
+ }
+ cnt++;
+ }
+ len = demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],sh->a_in_buffer_size-sh->a_in_buffer_len);
+ if(len > 0)
+ sh->a_in_buffer_len += len;
+ } while(len > 0);
+ mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Cannot sync MPA frame: %d\r\n", len);
+ return -1;
+}
+
+static int preinit(sh_audio_t *sh)
+{
+ sh->audio_out_minsize = 48;//check
+ sh->audio_in_minsize = 4608;//check
+ sh->sample_format = AF_FORMAT_MPEG2;
+ return 1;
+}
+
+static int init(sh_audio_t *sh)
+{
+ int cnt, chans, srate, spf, mpa_layer, br, len;
+
+ if((cnt = mpa_sync(sh, 1, &len, &chans, &srate, &spf, &mpa_layer, &br)) < 0)
+ return 0;
+
+ sh->channels = chans;
+ sh->samplerate = srate;
+ sh->i_bps = br * 125;
+ sh->samplesize = 2;
+
+ mp_msg(MSGT_DECAUDIO,MSGL_V,"AC_HWMPA initialized, bitrate: %d kb/s\r\n", len);
+ return 1;
+}
+
+static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
+{
+ int len, start, cnt2, tot;
+ int chans, srate, spf, mpa_layer, br;
+
+ tot = cnt2 = 0;
+ while(tot < minlen && tot+4608<=maxlen)
+ {
+ start = mpa_sync(sh, 1, &len, &chans, &srate, &spf, &mpa_layer, &br);
+ if(start < 0)
+ break;
+
+ if(start + len < sh->a_in_buffer_len && start + len >= maxlen)
+ break;
+ memcpy(&buf[cnt2], &(sh->a_in_buffer[start]), len);
+ cnt2 += len;
+ sh->a_in_buffer_len -= start + len;
+ memmove(sh->a_in_buffer, &(sh->a_in_buffer[start + len]), sh->a_in_buffer_len);
+ tot += start + len;
+ }
+
+ return tot;
+}
+
+
+static int control(sh_audio_t *sh,int cmd,void* arg, ...)
+{
+ int start, len, n;
+
+ switch(cmd)
+ {
+ case ADCTRL_RESYNC_STREAM:
+ if(mpa_sync(sh, 1, &len, NULL, NULL, NULL, NULL, NULL) >= 0)
+ return CONTROL_TRUE;
+ else
+ return CONTROL_FALSE;
+ case ADCTRL_SKIP_FRAME:
+ start = mpa_sync(sh, 2, &len, NULL, NULL, NULL, NULL, NULL);
+ if(len < 0)
+ return CONTROL_FALSE;
+
+ sh->a_in_buffer_len -= start;
+ memmove(sh->a_in_buffer, &(sh->a_in_buffer[start]), sh->a_in_buffer_len);
+ return CONTROL_TRUE;
+ }
+ return CONTROL_UNKNOWN;
+}
+
+
+static void uninit(sh_audio_t *sh)
+{
+}