Mercurial > mplayer.hg
comparison libmpdemux/demux_realaud.c @ 17400:7dd65dccf4f5
Support sipr codec in old RealAudio files.
Closes bugzilla #435
author | rtognimp |
---|---|
date | Sun, 15 Jan 2006 21:58:10 +0000 |
parents | 9a0a376a54b1 |
children | 67c30d47ffd4 |
comparison
equal
deleted
inserted
replaced
17399:5e11e2cb1043 | 17400:7dd65dccf4f5 |
---|---|
20 #define FOURCC_DOTRA mmioFOURCC('.','r','a', 0xfd) | 20 #define FOURCC_DOTRA mmioFOURCC('.','r','a', 0xfd) |
21 #define FOURCC_144 mmioFOURCC('1','4','_','4') | 21 #define FOURCC_144 mmioFOURCC('1','4','_','4') |
22 #define FOURCC_288 mmioFOURCC('2','8','_','8') | 22 #define FOURCC_288 mmioFOURCC('2','8','_','8') |
23 #define FOURCC_DNET mmioFOURCC('d','n','e','t') | 23 #define FOURCC_DNET mmioFOURCC('d','n','e','t') |
24 #define FOURCC_LPCJ mmioFOURCC('l','p','c','J') | 24 #define FOURCC_LPCJ mmioFOURCC('l','p','c','J') |
25 #define FOURCC_SIPR mmioFOURCC('s','i','p','r') | |
26 | |
27 | |
28 static unsigned char sipr_swaps[38][2]={ | |
29 {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68}, | |
30 {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46}, | |
31 {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56}, | |
32 {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83}, | |
33 {77,80} }; | |
34 | |
35 // Map flavour to bytes per second | |
36 static int sipr_fl2bps[4] = {813, 1062, 625, 2000}; // 6.5, 8.5, 5, 16 kbit per second | |
25 | 37 |
26 | 38 |
27 typedef struct { | 39 typedef struct { |
28 unsigned short version; | 40 unsigned short version; |
29 unsigned int dotranum; | 41 unsigned int dotranum; |
34 unsigned int coded_framesize; | 46 unsigned int coded_framesize; |
35 unsigned short sub_packet_h; | 47 unsigned short sub_packet_h; |
36 unsigned short frame_size; | 48 unsigned short frame_size; |
37 unsigned short sub_packet_size; | 49 unsigned short sub_packet_size; |
38 char genr[4]; | 50 char genr[4]; |
39 char * audio_buf; | 51 unsigned char *audio_buf; |
40 } ra_priv_t; | 52 } ra_priv_t; |
41 | 53 |
42 | 54 |
43 | 55 |
44 static int ra_check_file(demuxer_t* demuxer) | 56 static int ra_check_file(demuxer_t* demuxer) |
75 return 0; | 87 return 0; |
76 | 88 |
77 len = wf->nBlockAlign; | 89 len = wf->nBlockAlign; |
78 demuxer->filepos = stream_tell(demuxer->stream); | 90 demuxer->filepos = stream_tell(demuxer->stream); |
79 | 91 |
80 if (sh->format == FOURCC_288) { | 92 if ((sh->format == FOURCC_288) || (sh->format == FOURCC_SIPR)) { |
93 if (sh->format == FOURCC_SIPR) { | |
94 int n; | |
95 int bs = ra_priv->sub_packet_h * ra_priv->frame_size * 2 / 96; // nibbles per subpacket | |
96 stream_read(demuxer->stream, ra_priv->audio_buf, ra_priv->sub_packet_h * ra_priv->frame_size); | |
97 // Perform reordering | |
98 for(n = 0; n < 38; n++) { | |
99 int j; | |
100 int i = bs * sipr_swaps[n][0]; | |
101 int o = bs * sipr_swaps[n][1]; | |
102 // swap nibbles of block 'i' with 'o' TODO: optimize | |
103 for(j = 0; j < bs; j++) { | |
104 int x = (i & 1) ? (ra_priv->audio_buf[i >> 1] >> 4) : (ra_priv->audio_buf[i >> 1] & 0x0F); | |
105 int y = (o & 1) ? (ra_priv->audio_buf[o >> 1] >> 4) : (ra_priv->audio_buf[o >> 1] & 0x0F); | |
106 if(o & 1) | |
107 ra_priv->audio_buf[o >> 1] = (ra_priv->audio_buf[o >> 1] & 0x0F) | (x << 4); | |
108 else | |
109 ra_priv->audio_buf[o >> 1] = (ra_priv->audio_buf[o >> 1] & 0xF0) | x; | |
110 if(i & 1) | |
111 ra_priv->audio_buf[i >> 1] = (ra_priv->audio_buf[i >> 1] & 0x0F) | (y << 4); | |
112 else | |
113 ra_priv->audio_buf[i >> 1] = (ra_priv->audio_buf[i >> 1] & 0xF0) | y; | |
114 ++i; ++o; | |
115 } | |
116 } | |
117 } else { | |
81 for (y = 0; y < ra_priv->sub_packet_h; y++) | 118 for (y = 0; y < ra_priv->sub_packet_h; y++) |
82 for (x = 0; x < ra_priv->sub_packet_h / 2; x++) | 119 for (x = 0; x < ra_priv->sub_packet_h / 2; x++) |
83 stream_read(demuxer->stream, ra_priv->audio_buf + x * 2 *ra_priv->frame_size + | 120 stream_read(demuxer->stream, ra_priv->audio_buf + x * 2 *ra_priv->frame_size + |
84 y * ra_priv->coded_framesize, ra_priv->coded_framesize); | 121 y * ra_priv->coded_framesize, ra_priv->coded_framesize); |
122 } | |
85 // Release all the audio packets | 123 // Release all the audio packets |
86 for (x = 0; x < ra_priv->sub_packet_h * ra_priv->frame_size / len; x++) { | 124 for (x = 0; x < ra_priv->sub_packet_h * ra_priv->frame_size / len; x++) { |
87 dp = new_demux_packet(len); | 125 dp = new_demux_packet(len); |
88 memcpy(dp->buffer, ra_priv->audio_buf + x * len, len); | 126 memcpy(dp->buffer, ra_priv->audio_buf + x * len, len); |
89 dp->pts = x ? 0 : demuxer->filepos / ra_priv->data_size; | 127 dp->pts = x ? 0 : demuxer->filepos / ra_priv->data_size; |
145 ra_priv->dotranum = stream_read_dword(demuxer->stream); | 183 ra_priv->dotranum = stream_read_dword(demuxer->stream); |
146 ra_priv->data_size = stream_read_dword(demuxer->stream); | 184 ra_priv->data_size = stream_read_dword(demuxer->stream); |
147 ra_priv->version2 = stream_read_word(demuxer->stream); | 185 ra_priv->version2 = stream_read_word(demuxer->stream); |
148 ra_priv->hdr_size = stream_read_dword(demuxer->stream); | 186 ra_priv->hdr_size = stream_read_dword(demuxer->stream); |
149 ra_priv->codec_flavor = stream_read_word(demuxer->stream); | 187 ra_priv->codec_flavor = stream_read_word(demuxer->stream); |
188 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Flavor: %d\n", ra_priv->codec_flavor); | |
150 ra_priv->coded_framesize = stream_read_dword(demuxer->stream); | 189 ra_priv->coded_framesize = stream_read_dword(demuxer->stream); |
190 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Coded frame size: %d\n", ra_priv->coded_framesize); | |
151 stream_skip(demuxer->stream, 4); // data size? | 191 stream_skip(demuxer->stream, 4); // data size? |
152 stream_skip(demuxer->stream, 8); | 192 stream_skip(demuxer->stream, 8); |
153 ra_priv->sub_packet_h = stream_read_word(demuxer->stream); | 193 ra_priv->sub_packet_h = stream_read_word(demuxer->stream); |
194 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Sub packet h: %d\n", ra_priv->sub_packet_h); | |
154 ra_priv->frame_size = stream_read_word(demuxer->stream); | 195 ra_priv->frame_size = stream_read_word(demuxer->stream); |
155 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Frame size: %d\n", ra_priv->frame_size); | 196 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Frame size: %d\n", ra_priv->frame_size); |
156 ra_priv->sub_packet_size = stream_read_word(demuxer->stream); | 197 ra_priv->sub_packet_size = stream_read_word(demuxer->stream); |
157 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Sub packet size: %d\n", ra_priv->sub_packet_size); | 198 mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Sub packet size: %d\n", ra_priv->sub_packet_size); |
158 stream_skip(demuxer->stream, 2); | 199 stream_skip(demuxer->stream, 2); |
260 ra_priv->audio_buf = malloc(ra_priv->sub_packet_h * ra_priv->frame_size); | 301 ra_priv->audio_buf = malloc(ra_priv->sub_packet_h * ra_priv->frame_size); |
261 break; | 302 break; |
262 case FOURCC_DNET: | 303 case FOURCC_DNET: |
263 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET -> AC3\n"); | 304 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET -> AC3\n"); |
264 break; | 305 break; |
306 case FOURCC_SIPR: | |
307 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: SIPR\n"); | |
308 sh->wf->nBlockAlign = ra_priv->coded_framesize; | |
309 sh->wf->nAvgBytesPerSec = sipr_fl2bps[ra_priv->codec_flavor]; | |
310 ra_priv->audio_buf = malloc(ra_priv->sub_packet_h * ra_priv->frame_size); | |
311 break; | |
265 default: | 312 default: |
266 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%d)\n", sh->format); | 313 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%d)\n", sh->format); |
267 } | 314 } |
268 | 315 |
269 print_wave_header(sh->wf); | 316 print_wave_header(sh->wf); |