Mercurial > mplayer.hg
comparison libmpcodecs/ad_ra1428.c @ 10261:05a50c0ce239
RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders.
author | rtognimp |
---|---|
date | Sun, 08 Jun 2003 20:29:04 +0000 |
parents | |
children | d51610530481 |
comparison
equal
deleted
inserted
replaced
10260:597ad4eb02fc | 10261:05a50c0ce239 |
---|---|
1 // SAMPLE audio decoder - you can use this file as template when creating new codec! | |
2 | |
3 #include <stdio.h> | |
4 #include <stdlib.h> | |
5 #include <unistd.h> | |
6 | |
7 #include "config.h" | |
8 #include "ad_internal.h" | |
9 | |
10 static ad_info_t info = { | |
11 "RealAudio 1.0 and 2.0 native decoder", | |
12 "ra1428", | |
13 "Roberto Togni", | |
14 "http://www.honeypot.net/audio", | |
15 "Decoders taken from a public domain Amiga player" | |
16 }; | |
17 | |
18 LIBAD_EXTERN(ra1428) | |
19 | |
20 #include "native/common1428.h" | |
21 | |
22 | |
23 | |
24 static int preinit(sh_audio_t *sh) { | |
25 sh->samplerate=sh->wf->nSamplesPerSec; | |
26 sh->samplesize=sh->wf->wBitsPerSample/8; | |
27 sh->channels=sh->wf->nChannels; | |
28 sh->sample_format=AFMT_S16_LE; | |
29 | |
30 switch (sh->format) { | |
31 case mmioFOURCC('1','4','_','4'): | |
32 mp_msg(MSGT_DECAUDIO,MSGL_INFO,"[ra1428] RealAudio 1.0 (14_4)\n"); | |
33 sh->i_bps=1800; | |
34 break; | |
35 case mmioFOURCC('2','8','_','8'): | |
36 mp_msg(MSGT_DECAUDIO,MSGL_INFO,"[ra1428] RealAudio 2.0 (28_8)\n"); | |
37 sh->i_bps=1200; | |
38 break; | |
39 default: | |
40 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"[ra1428] Unhandled format in preinit: %x\n", sh->format); | |
41 return 0; | |
42 } | |
43 | |
44 sh->audio_out_minsize=128000; // no idea how to get... :( | |
45 sh->audio_in_minsize=((short*)(sh->wf+1))[1]*sh->wf->nBlockAlign; | |
46 | |
47 return 1; // return values: 1=OK 0=ERROR | |
48 } | |
49 | |
50 | |
51 | |
52 static int init(sh_audio_t *sh) { | |
53 switch (sh->format) { | |
54 case mmioFOURCC('1','4','_','4'): | |
55 (Real_144*)sh->context = init_144(); | |
56 break; | |
57 case mmioFOURCC('2','8','_','8'): | |
58 (Real_288*)sh->context = init_288(); | |
59 break; | |
60 default: | |
61 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"[ra1428] Unhandled format in init: %x\n", sh->format); | |
62 return 0; | |
63 } | |
64 | |
65 return 1; // return values: 1=OK 0=ERROR | |
66 } | |
67 | |
68 | |
69 | |
70 static void uninit(sh_audio_t *sh) { | |
71 switch (sh->format) { | |
72 case mmioFOURCC('1','4','_','4'): | |
73 free_144((Real_144*)sh->context); | |
74 break; | |
75 case mmioFOURCC('2','8','_','8'): | |
76 free_288((Real_288*)sh->context); | |
77 break; | |
78 default: | |
79 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"[ra1428] Unhandled format in uninit: %x\n", sh->format); | |
80 return; | |
81 } | |
82 } | |
83 | |
84 | |
85 | |
86 static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) { | |
87 int w=sh->wf->nBlockAlign; | |
88 int h=((short*)(sh->wf+1))[1]; | |
89 int cfs=((short*)(sh->wf+1))[3]; | |
90 int i,j; | |
91 | |
92 if(sh->a_in_buffer_len<=0){ | |
93 switch (sh->format) { | |
94 case mmioFOURCC('1','4','_','4'): | |
95 demux_read_data(sh->ds, sh->a_in_buffer, sh->wf->nBlockAlign); | |
96 sh->a_in_buffer_size= | |
97 sh->a_in_buffer_len=sh->wf->nBlockAlign; | |
98 break; | |
99 case mmioFOURCC('2','8','_','8'): | |
100 for (j = 0; j < h; j++) | |
101 for (i = 0; i < h/2; i++) | |
102 demux_read_data(sh->ds, sh->a_in_buffer+i*2*w+j*cfs, cfs); | |
103 sh->a_in_buffer_size= | |
104 sh->a_in_buffer_len=sh->wf->nBlockAlign*h; | |
105 break; | |
106 default: | |
107 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"[ra1428] Unhandled format in decode_audio: %x\n", sh->format); | |
108 return 0; | |
109 } | |
110 } | |
111 | |
112 switch (sh->format) { | |
113 case mmioFOURCC('1','4','_','4'): | |
114 decode_144((Real_144*)sh->context,sh->a_in_buffer+sh->a_in_buffer_size-sh->a_in_buffer_len,(signed short*)buf); | |
115 break; | |
116 case mmioFOURCC('2','8','_','8'): | |
117 decode_288((Real_288*)sh->context,sh->a_in_buffer+sh->a_in_buffer_size-sh->a_in_buffer_len,(signed short*)buf); | |
118 break; | |
119 default: | |
120 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"[ra1428] Unhandled format in init: %x\n", sh->format); | |
121 return 0; | |
122 } | |
123 | |
124 sh->a_in_buffer_len-=cfs; | |
125 | |
126 return AUDIOBLOCK*2; // return value: number of _bytes_ written to output buffer, | |
127 // or -1 for EOF (or uncorrectable error) | |
128 } | |
129 | |
130 static int control(sh_audio_t *sh,int cmd,void* arg, ...){ | |
131 // various optional functions you MAY implement: | |
132 switch(cmd){ | |
133 case ADCTRL_RESYNC_STREAM: | |
134 // it is called once after seeking, to resync. | |
135 // Note: sh_audio->a_in_buffer_len=0; is done _before_ this call! | |
136 // ... | |
137 return CONTROL_TRUE; | |
138 case ADCTRL_SKIP_FRAME: | |
139 // it is called to skip (jump over) small amount (1/10 sec or 1 frame) | |
140 // of audio data - used to sync audio to video after seeking | |
141 // if you don't return CONTROL_TRUE, it will defaults to: | |
142 // ds_fill_buffer(sh_audio->ds); // skip 1 demux packet | |
143 // ... | |
144 return CONTROL_TRUE; | |
145 } | |
146 return CONTROL_UNKNOWN; | |
147 } |