summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/codecs.conf37
-rw-r--r--libmpcodecs/ad_realaud.c126
-rw-r--r--libmpdemux/demux_real.c200
-rw-r--r--libmpdemux/demux_realaud.c41
4 files changed, 199 insertions, 205 deletions
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<bs;j++){
- int x=(i&1) ? (p[(i>>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;y<h;y++)
- for(x=0;x<w;x++){
- demux_read_data(sh->ds, 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;
}