11 #include "libaf/af_format.h"
12 #include "ad_internal.h"
14 #include "libmpdemux/mp3_hdr.h"
16 //based on ad_hwac3.c and ad_libmad.c
18 static const ad_info_t info
=
20 "MPEG audio pass-through (fake decoder)",
24 "For hardware decoders"
29 static int mpa_sync(sh_audio_t
*sh
, int no_frames
, int *n
, int *chans
, int *srate
, int *spf
, int *mpa_layer
, int *br
)
31 int cnt
= 0, x
= 0, len
, frames_count
;
36 while(cnt
+ 4 < sh
->a_in_buffer_len
)
38 x
= mp_get_mp3_header(&(sh
->a_in_buffer
[cnt
]), chans
, srate
, spf
, mpa_layer
, br
);
42 if(frames_count
== no_frames
)
50 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
);
52 sh
->a_in_buffer_len
+= len
;
54 mp_msg(MSGT_DECAUDIO
,MSGL_INFO
,"Cannot sync MPA frame: %d\r\n", len
);
58 static int preinit(sh_audio_t
*sh
)
60 sh
->audio_out_minsize
= 4608;//check
61 sh
->audio_in_minsize
= 4608;//check
62 sh
->sample_format
= AF_FORMAT_MPEG2
;
66 static int init(sh_audio_t
*sh
)
68 int cnt
, chans
, srate
, spf
, mpa_layer
, br
, len
;
70 if((cnt
= mpa_sync(sh
, 1, &len
, &chans
, &srate
, &spf
, &mpa_layer
, &br
)) < 0)
74 sh
->samplerate
= srate
;
78 mp_msg(MSGT_DECAUDIO
,MSGL_V
,"AC_HWMPA initialized, bitrate: %d kb/s\r\n", len
);
82 static int decode_audio(sh_audio_t
*sh
,unsigned char *buf
,int minlen
,int maxlen
)
85 int chans
, srate
, spf
, mpa_layer
, br
;
92 start
= mpa_sync(sh
, 1, &len
, &chans
, &srate
, &spf
, &mpa_layer
, &br
);
93 if(start
< 0 || tot2
+ spf
* 2 * chans
> maxlen
)
96 if(start
+ len
> sh
->a_in_buffer_len
)
99 l
= FFMIN(sh
->a_in_buffer_size
- sh
->a_in_buffer_len
, start
+ len
);
100 l
= demux_read_data(sh
->ds
,&sh
->a_in_buffer
[sh
->a_in_buffer_len
], l
);
103 sh
->a_in_buffer_len
+= l
;
107 memcpy(&buf
[tot
], &(sh
->a_in_buffer
[start
]), len
);
110 sh
->a_in_buffer_len
-= start
+ len
;
111 memmove(sh
->a_in_buffer
, &(sh
->a_in_buffer
[start
+ len
]), sh
->a_in_buffer_len
);
112 tot2
+= spf
* 2 * chans
;
114 /* HACK: seems to fix most A/V sync issues */
118 memset(&buf
[tot
], 0, tot2
-tot
);
123 static int control(sh_audio_t
*sh
,int cmd
,void* arg
, ...)
129 case ADCTRL_RESYNC_STREAM
:
130 if(mpa_sync(sh
, 1, &len
, NULL
, NULL
, NULL
, NULL
, NULL
) >= 0)
133 return CONTROL_FALSE
;
134 case ADCTRL_SKIP_FRAME
:
135 start
= mpa_sync(sh
, 2, &len
, NULL
, NULL
, NULL
, NULL
, NULL
);
137 return CONTROL_FALSE
;
139 sh
->a_in_buffer_len
-= start
;
140 memmove(sh
->a_in_buffer
, &(sh
->a_in_buffer
[start
]), sh
->a_in_buffer_len
);
143 return CONTROL_UNKNOWN
;
147 static void uninit(sh_audio_t
*sh
)