# HG changeset patch # User rtognimp # Date 1134145537 0 # Node ID 9a0a376a54b13aa54ace4c192ffbdaecd945125f # Parent d29d6028a943abc73e78eacbdd21139dfba89885 Move audio packets reordering from codec interface to demuxers for real files (old and new format), pass only real extradata to the codec Enable cook codec from lavc, prefer lavc codecs for 14_4 and 28_8 formats. Disable internal 28_8, it's broken now and will be removed soon diff -r d29d6028a943 -r 9a0a376a54b1 etc/codecs.conf --- a/etc/codecs.conf Fri Dec 09 12:51:13 2005 +0000 +++ b/etc/codecs.conf Fri Dec 09 16:25:37 2005 +0000 @@ -2100,11 +2100,32 @@ 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 @@ 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 -r d29d6028a943 -r 9a0a376a54b1 libmpcodecs/ad_realaud.c --- a/libmpcodecs/ad_realaud.c Fri Dec 09 12:51:13 2005 +0000 +++ b/libmpcodecs/ad_realaud.c Fri Dec 09 16:25:37 2005 +0000 @@ -291,10 +291,10 @@ 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 @@ 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 @@ 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; } - -#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); + } // sipr flavor -#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 @@ 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 -r d29d6028a943 -r 9a0a376a54b1 libmpdemux/demux_real.c --- a/libmpdemux/demux_real.c Fri Dec 09 12:51:13 2005 +0000 +++ b/libmpdemux/demux_real.c Fri Dec 09 16:25:37 2005 +0000 @@ -38,6 +38,13 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 -r d29d6028a943 -r 9a0a376a54b1 libmpdemux/demux_realaud.c --- a/libmpdemux/demux_realaud.c Fri Dec 09 12:51:13 2005 +0000 +++ b/libmpdemux/demux_realaud.c Fri Dec 09 16:25:37 2005 +0000 @@ -36,6 +36,7 @@ unsigned short frame_size; unsigned short sub_packet_size; char genr[4]; + char * audio_buf; } ra_priv_t; @@ -68,6 +69,7 @@ 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 @@ 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 @@ dp->pos = demuxer->filepos; dp->flags = 0; ds_add_packet(ds, dp); + } return 1; } @@ -234,23 +252,12 @@ 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 @@ { 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; }