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);