2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "libaf/af_format.h"
30 #include "ad_internal.h"
32 #include "libmpdemux/mp3_hdr.h"
34 //based on ad_hwac3.c and ad_libmad.c
36 static const ad_info_t info
=
38 "MPEG audio pass-through (fake decoder)",
42 "For hardware decoders"
47 static int mpa_sync(sh_audio_t
*sh
, int no_frames
, int *n
, int *chans
, int *srate
, int *spf
, int *mpa_layer
, int *br
)
49 int cnt
= 0, x
= 0, len
, frames_count
;
54 while(cnt
+ 4 < sh
->a_in_buffer_len
)
56 x
= mp_get_mp3_header(&(sh
->a_in_buffer
[cnt
]), chans
, srate
, spf
, mpa_layer
, br
);
60 if(frames_count
== no_frames
)
68 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
);
70 sh
->a_in_buffer_len
+= len
;
72 mp_msg(MSGT_DECAUDIO
,MSGL_INFO
,"Cannot sync MPA frame: %d\r\n", len
);
76 static int preinit(sh_audio_t
*sh
)
78 sh
->audio_out_minsize
= 4608;//check
79 sh
->audio_in_minsize
= 4608;//check
80 sh
->sample_format
= AF_FORMAT_MPEG2
;
84 static int init(sh_audio_t
*sh
)
86 int cnt
, chans
, srate
, spf
, mpa_layer
, br
, len
;
88 if((cnt
= mpa_sync(sh
, 1, &len
, &chans
, &srate
, &spf
, &mpa_layer
, &br
)) < 0)
92 sh
->samplerate
= srate
;
96 mp_msg(MSGT_DECAUDIO
,MSGL_V
,"AC_HWMPA initialized, bitrate: %d kb/s\r\n", len
);
100 static int decode_audio(sh_audio_t
*sh
,unsigned char *buf
,int minlen
,int maxlen
)
103 int chans
, srate
, spf
, mpa_layer
, br
;
110 start
= mpa_sync(sh
, 1, &len
, &chans
, &srate
, &spf
, &mpa_layer
, &br
);
111 if(start
< 0 || tot2
+ spf
* 2 * chans
> maxlen
)
114 if(start
+ len
> sh
->a_in_buffer_len
)
117 l
= FFMIN(sh
->a_in_buffer_size
- sh
->a_in_buffer_len
, start
+ len
);
118 l
= demux_read_data(sh
->ds
,&sh
->a_in_buffer
[sh
->a_in_buffer_len
], l
);
121 sh
->a_in_buffer_len
+= l
;
125 memcpy(&buf
[tot
], &(sh
->a_in_buffer
[start
]), len
);
128 sh
->a_in_buffer_len
-= start
+ len
;
129 memmove(sh
->a_in_buffer
, &(sh
->a_in_buffer
[start
+ len
]), sh
->a_in_buffer_len
);
130 tot2
+= spf
* 2 * chans
;
132 /* HACK: seems to fix most A/V sync issues */
136 memset(&buf
[tot
], 0, tot2
-tot
);
141 static int control(sh_audio_t
*sh
,int cmd
,void* arg
, ...)
147 case ADCTRL_RESYNC_STREAM
:
148 if(mpa_sync(sh
, 1, &len
, NULL
, NULL
, NULL
, NULL
, NULL
) >= 0)
151 return CONTROL_FALSE
;
152 case ADCTRL_SKIP_FRAME
:
153 start
= mpa_sync(sh
, 2, &len
, NULL
, NULL
, NULL
, NULL
, NULL
);
155 return CONTROL_FALSE
;
157 sh
->a_in_buffer_len
-= start
;
158 memmove(sh
->a_in_buffer
, &(sh
->a_in_buffer
[start
]), sh
->a_in_buffer_len
);
161 return CONTROL_UNKNOWN
;
165 static void uninit(sh_audio_t
*sh
)