Use MSGT_DECVIDEO in a video decoder.
[mplayer/glamo.git] / libmpcodecs / ad_hwmpa.c
blob30caa9b0f9b86127da504d1a4549fe492ca17ec4
1 /*
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.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
24 #include "config.h"
26 #include "mp_msg.h"
27 #include "help_mp.h"
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)",
39 "hwmpa",
40 "NicoDVB",
41 "NicoDVB",
42 "For hardware decoders"
45 LIBAD_EXTERN(hwmpa)
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;
51 frames_count = 0;
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);
57 if(x > 0)
59 frames_count++;
60 if(frames_count == no_frames)
62 *n = x;
63 return cnt;
66 cnt++;
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);
69 if(len > 0)
70 sh->a_in_buffer_len += len;
71 } while(len > 0);
72 mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Cannot sync MPA frame: %d\r\n", len);
73 return -1;
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;
81 return 1;
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)
89 return 0;
91 sh->channels = chans;
92 sh->samplerate = srate;
93 sh->i_bps = br * 125;
94 sh->samplesize = 2;
96 mp_msg(MSGT_DECAUDIO,MSGL_V,"AC_HWMPA initialized, bitrate: %d kb/s\r\n", len);
97 return 1;
100 static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
102 int len, start, tot;
103 int chans, srate, spf, mpa_layer, br;
104 int tot2;
106 tot = tot2 = 0;
108 while(tot2 < maxlen)
110 start = mpa_sync(sh, 1, &len, &chans, &srate, &spf, &mpa_layer, &br);
111 if(start < 0 || tot2 + spf * 2 * chans > maxlen)
112 break;
114 if(start + len > sh->a_in_buffer_len)
116 int l;
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);
119 if(! l)
120 break;
121 sh->a_in_buffer_len += l;
122 continue;
125 memcpy(&buf[tot], &(sh->a_in_buffer[start]), len);
126 tot += 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 */
133 break;
136 memset(&buf[tot], 0, tot2-tot);
137 return tot2;
141 static int control(sh_audio_t *sh,int cmd,void* arg, ...)
143 int start, len;
145 switch(cmd)
147 case ADCTRL_RESYNC_STREAM:
148 if(mpa_sync(sh, 1, &len, NULL, NULL, NULL, NULL, NULL) >= 0)
149 return CONTROL_TRUE;
150 else
151 return CONTROL_FALSE;
152 case ADCTRL_SKIP_FRAME:
153 start = mpa_sync(sh, 2, &len, NULL, NULL, NULL, NULL, NULL);
154 if(start < 0)
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);
159 return CONTROL_TRUE;
161 return CONTROL_UNKNOWN;
165 static void uninit(sh_audio_t *sh)