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.
28 #include "libaf/af_format.h"
29 #include "ad_internal.h"
31 #include "libmpdemux/mp3_hdr.h"
33 //based on ad_hwac3.c and ad_libmad.c
35 static const ad_info_t info
=
37 "MPEG audio pass-through (fake decoder)",
41 "For hardware decoders"
46 static int mpa_sync(sh_audio_t
*sh
, int no_frames
, int *n
, int *chans
, int *srate
, int *spf
, int *mpa_layer
, int *br
)
48 int cnt
= 0, x
= 0, len
, frames_count
;
53 while(cnt
+ 4 < sh
->a_in_buffer_len
)
55 x
= mp_get_mp3_header(&(sh
->a_in_buffer
[cnt
]), chans
, srate
, spf
, mpa_layer
, br
);
59 if(frames_count
== no_frames
)
67 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
);
69 sh
->a_in_buffer_len
+= len
;
71 mp_msg(MSGT_DECAUDIO
,MSGL_INFO
,"Cannot sync MPA frame: %d\r\n", len
);
75 static int preinit(sh_audio_t
*sh
)
77 sh
->audio_out_minsize
= 4608;//check
78 sh
->audio_in_minsize
= 4608;//check
79 sh
->sample_format
= AF_FORMAT_MPEG2
;
83 static int init(sh_audio_t
*sh
)
85 int cnt
, chans
, srate
, spf
, mpa_layer
, br
, len
;
87 if((cnt
= mpa_sync(sh
, 1, &len
, &chans
, &srate
, &spf
, &mpa_layer
, &br
)) < 0)
91 sh
->samplerate
= srate
;
95 mp_msg(MSGT_DECAUDIO
,MSGL_V
,"AC_HWMPA initialized, bitrate: %d kb/s\r\n", len
);
99 static int decode_audio(sh_audio_t
*sh
,unsigned char *buf
,int minlen
,int maxlen
)
102 int chans
, srate
, spf
, mpa_layer
, br
;
109 start
= mpa_sync(sh
, 1, &len
, &chans
, &srate
, &spf
, &mpa_layer
, &br
);
110 if(start
< 0 || tot2
+ spf
* 2 * chans
> maxlen
)
113 if(start
+ len
> sh
->a_in_buffer_len
)
116 l
= FFMIN(sh
->a_in_buffer_size
- sh
->a_in_buffer_len
, start
+ len
);
117 l
= demux_read_data(sh
->ds
,&sh
->a_in_buffer
[sh
->a_in_buffer_len
], l
);
120 sh
->a_in_buffer_len
+= l
;
124 memcpy(&buf
[tot
], &(sh
->a_in_buffer
[start
]), len
);
127 sh
->a_in_buffer_len
-= start
+ len
;
128 memmove(sh
->a_in_buffer
, &(sh
->a_in_buffer
[start
+ len
]), sh
->a_in_buffer_len
);
129 tot2
+= spf
* 2 * chans
;
131 /* HACK: seems to fix most A/V sync issues */
135 memset(&buf
[tot
], 0, tot2
-tot
);
140 static int control(sh_audio_t
*sh
,int cmd
,void* arg
, ...)
146 case ADCTRL_RESYNC_STREAM
:
147 if(mpa_sync(sh
, 1, &len
, NULL
, NULL
, NULL
, NULL
, NULL
) >= 0)
150 return CONTROL_FALSE
;
151 case ADCTRL_SKIP_FRAME
:
152 start
= mpa_sync(sh
, 2, &len
, NULL
, NULL
, NULL
, NULL
, NULL
);
154 return CONTROL_FALSE
;
156 sh
->a_in_buffer_len
-= start
;
157 memmove(sh
->a_in_buffer
, &(sh
->a_in_buffer
[start
]), sh
->a_in_buffer_len
);
160 return CONTROL_UNKNOWN
;
164 static void uninit(sh_audio_t
*sh
)