diff --git a/etc/codecs.conf b/etc/codecs.conf index 92fbaa4249..5163cddd04 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -2100,11 +2100,32 @@ audiocodec qtmace6 driver qtaudio dll "QuickTime.qts" +audiocodec ffra144 + info "FFmpeg RealAudio 1.0" + status working + format 0x345F3431 ; "14_4" + driver ffmpeg + dll "real_144" + +audiocodec ffra288 + info "FFmpeg RealAudio 2.0" + status working + format 0x385F3832 ; "28_8" + driver ffmpeg + dll "real_288" + +audiocodec ffcook + info "FFmpeg COOK audio decoder" + status working + format 0x6B6F6F63 ; "cook" + driver ffmpeg + dll "cook" + audiocodec mpra1428 info "RealAudio 1.0 / 2.0 native decoder" status working format 0x345F3431 ; "14_4" - format 0x385F3832 ; "28_8" +; format 0x385F3832 ; "28_8" ; broken after demuxer changes driver ra1428 audiocodec ra144 @@ -2376,20 +2397,6 @@ audiocodec ffmac6 driver ffmpeg dll "mace6" -audiocodec ffra144 - info "FFmpeg RealAudio 1.0" - status untested - format 0x345F3431 ; "14_4" - driver ffmpeg - dll "real_144" - -audiocodec ffra288 - info "FFmpeg RealAudio 2.0" - status crashing - format 0x385F3832 ; "28_8" - driver ffmpeg - dll "real_288" - audiocodec ffsonic info "FFmpeg Sonic" status untested diff --git a/libmpcodecs/ad_realaud.c b/libmpcodecs/ad_realaud.c index 18039d49b6..2d4361f9ea 100644 --- a/libmpcodecs/ad_realaud.c +++ b/libmpcodecs/ad_realaud.c @@ -291,10 +291,10 @@ static int preinit(sh_audio_t *sh){ sh->wf->wBitsPerSample, sh->wf->nChannels, 100, // quality - ((short*)(sh->wf+1))[0], // subpacket size - ((short*)(sh->wf+1))[3], // coded frame size - ((short*)(sh->wf+1))[4], // codec data length - ((char*)(sh->wf+1))+10 // extras + sh->wf->nBlockAlign, // subpacket size + sh->wf->nBlockAlign, // coded frame size + sh->wf->cbSize, // codec data length + (char*)(sh->wf+1) // extras }; #ifdef USE_WIN32DLL wra_init_t winit_data={ @@ -302,10 +302,10 @@ static int preinit(sh_audio_t *sh){ sh->wf->wBitsPerSample, sh->wf->nChannels, 100, // quality - ((short*)(sh->wf+1))[0], // subpacket size - ((short*)(sh->wf+1))[3], // coded frame size - ((short*)(sh->wf+1))[4], // codec data length - ((char*)(sh->wf+1))+10 // extras + sh->wf->nBlockAlign, // subpacket size + sh->wf->nBlockAlign, // coded frame size + sh->wf->cbSize, // codec data length + (char*)(sh->wf+1) // extras }; #endif #ifdef USE_WIN32DLL @@ -336,42 +336,35 @@ static int preinit(sh_audio_t *sh){ raSetPwd(sh->context,"Ardubancel Quazanga"); // set password... lol. } + if (sh->format == mmioFOURCC('s','i','p','r')) { + short flavor; + + if (sh->wf->nAvgBytesPerSec > 1531) + flavor = 3; + else if (sh->wf->nAvgBytesPerSec > 937) + flavor = 1; + else if (sh->wf->nAvgBytesPerSec > 719) + flavor = 0; + else + flavor = 2; + mp_msg(MSGT_DECAUDIO,MSGL_V,"Got sipr flavor %d from bitrate %d\n",flavor, sh->wf->nAvgBytesPerSec); + #ifdef USE_WIN32DLL if (dll_type == 1) - result=wraSetFlavor(sh->context,((short*)(sh->wf+1))[2]); + result=wraSetFlavor(sh->context,flavor); else #endif - result=raSetFlavor(sh->context,((short*)(sh->wf+1))[2]); + result=raSetFlavor(sh->context,flavor); if(result){ mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder flavor setup failed, error code: 0x%X\n",result); return 0; } + } // sipr flavor -#ifdef USE_WIN32DLL - if (dll_type == 1) - prop=wraGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],0,&len); - else -#endif - prop=raGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],0,&len); - mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Audio codec: [%d] %s\n",((short*)(sh->wf+1))[2],prop); - -#ifdef USE_WIN32DLL - if (dll_type == 1) - prop=wraGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],1,&len); - else -#endif - prop=raGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],1,&len); - if(prop){ - sh->i_bps=((*((int*)prop))+4)/8; - mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Audio bitrate: %5.3f kbit/s (%d bps) \n",(*((int*)prop))*0.001f,sh->i_bps); - } else - sh->i_bps=12000; // dunno :((( [12000 seems to be OK for crash.rmvb too] + sh->i_bps=sh->wf->nAvgBytesPerSec; -// prop=raGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],0x13,&len); -// mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Samples/block?: %d \n",(*((int*)prop))); - sh->audio_out_minsize=128000; // no idea how to get... :( - sh->audio_in_minsize=((short*)(sh->wf+1))[1]*sh->wf->nBlockAlign; + sh->audio_in_minsize = sh->wf->nBlockAlign; return 1; // return values: 1=OK 0=ERROR } @@ -413,83 +406,16 @@ static void uninit(sh_audio_t *sh){ rv_handle = NULL; } -static unsigned char sipr_swaps[38][2]={ - {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68}, - {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46}, - {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56}, - {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83}, - {77,80} }; - static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen){ int result; int len=-1; - int sps=((short*)(sh->wf+1))[0]; - int w=sh->wf->nBlockAlign; // 5 - int h=((short*)(sh->wf+1))[1]; - int cfs=((short*)(sh->wf+1))[3]; -// printf("bs=%d sps=%d w=%d h=%d \n",sh->wf->nBlockAlign,sps,w,h); - -#if 1 - if(sh->a_in_buffer_len<=0){ - if (sh->ds->eof) return 0; - // fill the buffer! - if (sh->format == mmioFOURCC('1','4','_','4')) { - demux_read_data(sh->ds, sh->a_in_buffer, sh->wf->nBlockAlign); - sh->a_in_buffer_size= - sh->a_in_buffer_len=sh->wf->nBlockAlign; - } else - if (sh->format == mmioFOURCC('2','8','_','8')) { - int i,j; - for (j = 0; j < h; j++) - for (i = 0; i < h/2; i++) - demux_read_data(sh->ds, sh->a_in_buffer+i*2*w+j*cfs, cfs); - sh->a_in_buffer_size= - sh->a_in_buffer_len=sh->wf->nBlockAlign*h; - } else - if((sh->format == mmioFOURCC('s','i','p','r')) || !sps){ // is !sps really needed? (cook with sipr matrix?) - // 'sipr' way - int j,n; - int bs=h*w*2/96; // nibbles per subpacket - unsigned char *p=sh->a_in_buffer; - demux_read_data(sh->ds, p, h*w); - for(n=0;n<38;n++){ - int i=bs*sipr_swaps[n][0]; - int o=bs*sipr_swaps[n][1]; - // swap nibbles of block 'i' with 'o' TODO: optimize - for(j=0;j>1)]>>4) : (p[(i>>1)]&15); - int y=(o&1) ? (p[(o>>1)]>>4) : (p[(o>>1)]&15); - if(o&1) p[(o>>1)]=(p[(o>>1)]&0x0F)|(x<<4); - else p[(o>>1)]=(p[(o>>1)]&0xF0)|x; - if(i&1) p[(i>>1)]=(p[(i>>1)]&0x0F)|(y<<4); - else p[(i>>1)]=(p[(i>>1)]&0xF0)|y; - ++i;++o; - } - } - sh->a_in_buffer_size= - sh->a_in_buffer_len=w*h; - } else { - // 'cook' way - int x,y; - w/=sps; - for(y=0;yds, sh->a_in_buffer+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); - } - sh->a_in_buffer_size= - sh->a_in_buffer_len=w*h*sps; - } - } - -#else if(sh->a_in_buffer_len<=0){ // fill the buffer! demux_read_data(sh->ds, sh->a_in_buffer, sh->wf->nBlockAlign); sh->a_in_buffer_size= sh->a_in_buffer_len=sh->wf->nBlockAlign; } -#endif #ifdef USE_WIN32DLL if (dll_type == 1) diff --git a/libmpdemux/demux_real.c b/libmpdemux/demux_real.c index 4ac8b6074a..1e07e8bd75 100644 --- a/libmpdemux/demux_real.c +++ b/libmpdemux/demux_real.c @@ -38,6 +38,13 @@ Video codecs: (supported by RealPlayer8 for Linux) #define MAX_STREAMS 32 +static unsigned char sipr_swaps[38][2]={ + {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68}, + {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46}, + {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56}, + {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83}, + {77,80} }; + typedef struct { int timestamp; int offset; @@ -92,6 +99,18 @@ typedef struct { int a_bitrate; ///< Audio bitrate int v_bitrate; ///< Video bitrate int stream_switch; ///< Flag used to switch audio/video demuxing + + /** + * Used to reorder audio data + */ + int sub_packet_size[MAX_STREAMS]; ///< sub packet size, per stream + int sub_packet_h[MAX_STREAMS]; ///< number of coded frames per block + int coded_framesize[MAX_STREAMS]; ///< coded frame size, per stream + int audiopk_size[MAX_STREAMS]; ///< audio packet size + unsigned char *audio_buf; ///< place to store reordered audio data + int audio_timestamp; ///< timestamp for all audio packets in a block + int sub_packet_cnt; ///< number of subpacket already received + int audio_filepos; ///< file position of first audio packet in block } real_priv_t; /* originally from FFmpeg */ @@ -531,6 +550,8 @@ static int demux_real_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds) int version; int reserved; demux_packet_t *dp; + int x, sps, cfs, sph, spc, w; + int audioreorder_getnextpk = 0; while(1){ @@ -622,6 +643,11 @@ got_audio: ds=demuxer->audio; mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (id: %d)\n", stream_id); + if (flags & 2) { + priv->sub_packet_cnt = 0; + audioreorder_getnextpk = 0; + } + // parse audio chunk: { #ifdef CRACK_MATRIX @@ -649,8 +675,79 @@ got_audio: free(sub_packet_lengths); return 1; } + if ((((sh_audio_t*)ds->sh)->format == mmioFOURCC('2', '8', '_', '8')) || + (((sh_audio_t*)ds->sh)->format == mmioFOURCC('c', 'o', 'o', 'k')) || + (((sh_audio_t*)ds->sh)->format == mmioFOURCC('a', 't', 'r', 'c')) || + (((sh_audio_t*)ds->sh)->format == mmioFOURCC('s', 'i', 'p', 'r'))) { + sps = priv->sub_packet_size[stream_id]; + sph = priv->sub_packet_h[stream_id]; + cfs = priv->coded_framesize[stream_id]; + w = priv->audiopk_size[stream_id]; + spc = priv->sub_packet_cnt; + switch (((sh_audio_t*)ds->sh)->format) { + case mmioFOURCC('2', '8', '_', '8'): + for (x = 0; x < sph / 2; x++) + stream_read(demuxer->stream, priv->audio_buf + x * 2 * w + spc * cfs, cfs); + break; + case mmioFOURCC('c', 'o', 'o', 'k'): + case mmioFOURCC('a', 't', 'r', 'c'): + for (x = 0; x < w / sps; x++) + stream_read(demuxer->stream, priv->audio_buf + sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + + (spc >> 1)), sps); + break; + case mmioFOURCC('s', 'i', 'p', 'r'): + stream_read(demuxer->stream, priv->audio_buf + spc * w, w); + if (spc == sph - 1) { + int n; + int bs = sph * w * 2 / 96; // nibbles per subpacket + // Perform reordering + for(n=0; n < 38; n++) { + int j; + int i = bs * sipr_swaps[n][0]; + int o = bs * sipr_swaps[n][1]; + // swap nibbles of block 'i' with 'o' TODO: optimize + for(j = 0;j < bs; j++) { + int x = (i & 1) ? (priv->audio_buf[i >> 1] >> 4) : (priv->audio_buf[i >> 1] & 0x0F); + int y = (o & 1) ? (priv->audio_buf[o >> 1] >> 4) : (priv->audio_buf[o >> 1] & 0x0F); + if(o & 1) + priv->audio_buf[o >> 1] = (priv->audio_buf[o >> 1] & 0x0F) | (x << 4); + else + priv->audio_buf[o >> 1] = (priv->audio_buf[o >> 1] & 0xF0) | x; + if(i & 1) + priv->audio_buf[i >> 1] = (priv->audio_buf[i >> 1] & 0x0F) | (y << 4); + else + priv->audio_buf[i >> 1] = (priv->audio_buf[i >> 1] & 0xF0) | y; + ++i; ++o; + } + } + } + break; + } + priv->audio_need_keyframe = 0; + priv->audio_timestamp = timestamp / 1000.0f; + priv->a_pts = timestamp; // All packets in a block have the same timestamp + if (priv->sub_packet_cnt == 0) + priv->audio_filepos = demuxer->filepos; + if (++(priv->sub_packet_cnt) < sph) + audioreorder_getnextpk = 1; + else { + int apk_usize = ((WAVEFORMATEX*)((sh_audio_t*)ds->sh)->wf)->nBlockAlign; + audioreorder_getnextpk = 0; + priv->sub_packet_cnt = 0; + // Release all the audio packets + for (x = 0; x < sph*w/apk_usize; x++) { + dp = new_demux_packet(apk_usize); + memcpy(dp->buffer, priv->audio_buf + x * apk_usize, apk_usize); + dp->pts = x ? 0 : priv->audio_timestamp; + dp->pos = priv->audio_filepos; // all equal + dp->flags = x ? 0 : 0x10; // Mark first packet as keyframe + ds_add_packet(ds, dp); + } + } + } else { // Not a codec that require reordering dp = new_demux_packet(len); - stream_read(demuxer->stream, dp->buffer, len); + stream_read(demuxer->stream, dp->buffer, len); + #ifdef CRACK_MATRIX mp_msg(MSGT_DEMUX, MSGL_V,"*** audio block len=%d\n",len); { // HACK - used for reverse engineering the descrambling matrix @@ -691,6 +788,8 @@ got_audio: dp->pos = demuxer->filepos; dp->flags = (flags & 0x2) ? 0x10 : 0; ds_add_packet(ds, dp); + + } // codec_id check, codec default case } // we will not use audio index if we use -idx and have a video if(!demuxer->video->sh && index_mode == 2 && (unsigned)demuxer->audio->id < MAX_STREAMS) @@ -706,6 +805,10 @@ got_audio: priv->stream_switch = 1; } + // If we're reordering audio packets and we need more data get it + if (audioreorder_getnextpk) + continue; + return 1; } @@ -933,6 +1036,7 @@ if(stream_id<256){ demuxer->audio->id=stream_id; sh->ds=demuxer->audio; demuxer->audio->sh=sh; + priv->audio_buf = malloc(priv->sub_packet_h[demuxer->audio->id] * priv->audiopk_size[demuxer->audio->id]); mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d\n",stream_id); goto got_audio; } @@ -1260,30 +1364,11 @@ static demuxer_t* demux_open_real(demuxer_t* demuxer) sh->wf->nChannels = sh->channels; sh->wf->wBitsPerSample = sh->samplesize*8; sh->wf->nSamplesPerSec = sh->samplerate; - sh->wf->nAvgBytesPerSec = bitrate; + sh->wf->nAvgBytesPerSec = bitrate/8; sh->wf->nBlockAlign = frame_size; sh->wf->cbSize = 0; sh->format = MKTAG(buf[0], buf[1], buf[2], buf[3]); -#if 0 - switch (sh->format){ - case MKTAG('d', 'n', 'e', 't'): - mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET (AC3 with low-bitrate extension)\n"); - break; - case MKTAG('s', 'i', 'p', 'r'): - mp_msg(MSGT_DEMUX,MSGL_V,"Audio: SiproLab's ACELP.net\n"); - break; - case MKTAG('c', 'o', 'o', 'k'): - mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Real's GeneralCooker (?) (RealAudio G2?) (unsupported)\n"); - break; - case MKTAG('a', 't', 'r', 'c'): - mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Sony ATRAC3 (RealAudio 8) (unsupported)\n"); - break; - default: - mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%s)\n", buf); - } -#endif - switch (sh->format) { case MKTAG('d', 'n', 'e', 't'): @@ -1291,74 +1376,40 @@ static demuxer_t* demux_open_real(demuxer_t* demuxer) // sh->format = 0x2000; break; case MKTAG('1', '4', '_', '4'): - sh->wf->cbSize = 10; - sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - ((short*)(sh->wf+1))[0]=0; - ((short*)(sh->wf+1))[1]=240; - ((short*)(sh->wf+1))[2]=0; - ((short*)(sh->wf+1))[3]=0x14; - ((short*)(sh->wf+1))[4]=0; + sh->wf->nBlockAlign = 0x14; break; case MKTAG('2', '8', '_', '8'): - sh->wf->cbSize = 10; - sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - ((short*)(sh->wf+1))[0]=sub_packet_size; - ((short*)(sh->wf+1))[1]=sub_packet_h; - ((short*)(sh->wf+1))[2]=flavor; - ((short*)(sh->wf+1))[3]=coded_frame_size; - ((short*)(sh->wf+1))[4]=0; + sh->wf->nBlockAlign = coded_frame_size; + priv->sub_packet_size[stream_id] = sub_packet_size; + priv->sub_packet_h[stream_id] = sub_packet_h; + priv->coded_framesize[stream_id] = coded_frame_size; + priv->audiopk_size[stream_id] = frame_size; break; case MKTAG('s', 'i', 'p', 'r'): -#if 0 - sh->format = 0x130; - /* for buggy directshow loader */ - sh->wf->cbSize = 4; - sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - sh->wf->wBitsPerSample = 0; - sh->wf->nAvgBytesPerSec = 1055; - sh->wf->nBlockAlign = 19; -// sh->wf->nBlockAlign = frame_size / 288; - buf[0] = 30; - buf[1] = 1; - buf[2] = 1; - buf[3] = 0; - memcpy((sh->wf+18), (char *)&buf[0], 4); -// sh->wf[sizeof(WAVEFORMATEX)+1] = 30; -// sh->wf[sizeof(WAVEFORMATEX)+2] = 1; -// sh->wf[sizeof(WAVEFORMATEX)+3] = 1; -// sh->wf[sizeof(WAVEFORMATEX)+4] = 0; - break; -#endif case MKTAG('a', 't', 'r', 'c'): -#if 0 - sh->format = 0x270; - /* 14 bytes extra header needed ! */ - sh->wf->cbSize = 14; - sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - sh->wf->nAvgBytesPerSec = 16537; // 8268 - sh->wf->nBlockAlign = 384; // 192 - sh->wf->wBitsPerSample = 0; /* from AVI created by VirtualDub */ - break; -#endif case MKTAG('c', 'o', 'o', 'k'): // realaudio codec plugins - common: -// sh->wf->cbSize = 4+2+24; stream_skip(demuxer->stream,3); // Skip 3 unknown bytes if (version==5) stream_skip(demuxer->stream,1); // Skip 1 additional unknown byte codecdata_length=stream_read_dword(demuxer->stream); - sh->wf->cbSize = 10+codecdata_length; + sh->wf->cbSize = codecdata_length; sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - ((short*)(sh->wf+1))[0]=sub_packet_size; - ((short*)(sh->wf+1))[1]=sub_packet_h; - ((short*)(sh->wf+1))[2]=flavor; - ((short*)(sh->wf+1))[3]=coded_frame_size; - ((short*)(sh->wf+1))[4]=codecdata_length; -// stream_read(demuxer->stream, ((char*)(sh->wf+1))+6, 24); // extras - stream_read(demuxer->stream, ((char*)(sh->wf+1))+10, codecdata_length); // extras + stream_read(demuxer->stream, ((char*)(sh->wf+1)), codecdata_length); // extras + if ((sh->format == MKTAG('a', 't', 'r', 'c')) || + (sh->format == MKTAG('c', 'o', 'o', 'k'))) + sh->wf->nBlockAlign = sub_packet_size; + else + sh->wf->nBlockAlign = coded_frame_size; + + priv->sub_packet_size[stream_id] = sub_packet_size; + priv->sub_packet_h[stream_id] = sub_packet_h; + priv->coded_framesize[stream_id] = coded_frame_size; + priv->audiopk_size[stream_id] = frame_size; break; + case MKTAG('r', 'a', 'a', 'c'): case MKTAG('r', 'a', 'c', 'p'): /* This is just AAC. The two or five bytes of */ @@ -1397,6 +1448,7 @@ static demuxer_t* demux_open_real(demuxer_t* demuxer) demuxer->audio->id=stream_id; sh->ds=demuxer->audio; demuxer->audio->sh=sh; + priv->audio_buf = malloc(priv->sub_packet_h[demuxer->audio->id] * priv->audiopk_size[demuxer->audio->id]); } ++a_streams; diff --git a/libmpdemux/demux_realaud.c b/libmpdemux/demux_realaud.c index 5ec68bdb00..b553bba09b 100644 --- a/libmpdemux/demux_realaud.c +++ b/libmpdemux/demux_realaud.c @@ -36,6 +36,7 @@ typedef struct { unsigned short frame_size; unsigned short sub_packet_size; char genr[4]; + char * audio_buf; } ra_priv_t; @@ -68,6 +69,7 @@ static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds) sh_audio_t *sh = ds->sh; WAVEFORMATEX *wf = sh->wf; demux_packet_t *dp; + int x, y; if (demuxer->stream->eof) return 0; @@ -75,6 +77,21 @@ static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds) len = wf->nBlockAlign; demuxer->filepos = stream_tell(demuxer->stream); + if (sh->format == FOURCC_288) { + for (y = 0; y < ra_priv->sub_packet_h; y++) + for (x = 0; x < ra_priv->sub_packet_h / 2; x++) + stream_read(demuxer->stream, ra_priv->audio_buf + x * 2 *ra_priv->frame_size + + y * ra_priv->coded_framesize, ra_priv->coded_framesize); + // Release all the audio packets + for (x = 0; x < ra_priv->sub_packet_h * ra_priv->frame_size / len; x++) { + dp = new_demux_packet(len); + memcpy(dp->buffer, ra_priv->audio_buf + x * len, len); + dp->pts = x ? 0 : demuxer->filepos / ra_priv->data_size; + dp->pos = demuxer->filepos; // all equal + dp->flags = x ? 0 : 0x10; // Mark first packet as keyframe + ds_add_packet(ds, dp); + } + } else { dp = new_demux_packet(len); stream_read(demuxer->stream, dp->buffer, len); @@ -82,6 +99,7 @@ static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds) dp->pos = demuxer->filepos; dp->flags = 0; ds_add_packet(ds, dp); + } return 1; } @@ -234,23 +252,12 @@ static demuxer_t* demux_open_ra(demuxer_t* demuxer) switch (sh->format) { case FOURCC_144: mp_msg(MSGT_DEMUX,MSGL_V,"Audio: 14_4\n"); - sh->wf->cbSize = 10/*+codecdata_length*/; - sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - ((short*)(sh->wf+1))[0]=0; - ((short*)(sh->wf+1))[1]=240; - ((short*)(sh->wf+1))[2]=0; - ((short*)(sh->wf+1))[3]=0x14; - ((short*)(sh->wf+1))[4]=0; + sh->wf->nBlockAlign = 0x14; break; case FOURCC_288: mp_msg(MSGT_DEMUX,MSGL_V,"Audio: 28_8\n"); - sh->wf->cbSize = 10/*+codecdata_length*/; - sh->wf = realloc(sh->wf, sizeof(WAVEFORMATEX)+sh->wf->cbSize); - ((short*)(sh->wf+1))[0]=0; - ((short*)(sh->wf+1))[1]=ra_priv->sub_packet_h; - ((short*)(sh->wf+1))[2]=ra_priv->codec_flavor; - ((short*)(sh->wf+1))[3]=ra_priv->coded_framesize; - ((short*)(sh->wf+1))[4]=0; + sh->wf->nBlockAlign = ra_priv->coded_framesize; + ra_priv->audio_buf = malloc(ra_priv->sub_packet_h * ra_priv->frame_size); break; case FOURCC_DNET: mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET -> AC3\n"); @@ -276,9 +283,11 @@ static void demux_close_ra(demuxer_t *demuxer) { ra_priv_t* ra_priv = demuxer->priv; - if (ra_priv) + if (ra_priv) { + if (ra_priv->audio_buf) + free (ra_priv->audio_buf); free(ra_priv); - + } return; }