[MPlayer-cvslog] CVS: main/libmpdemux demux_real.c, 1.74, 1.75 demux_realaud.c, 1.9, 1.10
Roberto Togni CVS
syncmail at mplayerhq.hu
Fri Dec 9 17:25:39 CET 2005
CVS change done by Roberto Togni CVS
Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var2/tmp/cvs-serv5540/libmpdemux
Modified Files:
demux_real.c demux_realaud.c
Log Message:
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
Index: demux_real.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_real.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -r1.74 -r1.75
--- demux_real.c 30 Oct 2005 09:19:05 -0000 1.74
+++ demux_real.c 9 Dec 2005 16:25:37 -0000 1.75
@@ -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;
Index: demux_realaud.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_realaud.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- demux_realaud.c 30 Aug 2005 23:59:21 -0000 1.9
+++ demux_realaud.c 9 Dec 2005 16:25:37 -0000 1.10
@@ -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;
}
More information about the MPlayer-cvslog
mailing list