summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-06-08 20:46:14 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-06-08 20:46:14 +0000
commita545ffc48e8ac97722bb262316ff53fcb54a6787 (patch)
tree31aa7a1a5fa5ad30d6f496e8f5fcb6cb10e395d4 /libmpdemux
parent4f7e20115fef19791ef8a066f6cbf700c338d749 (diff)
downloadmpv-a545ffc48e8ac97722bb262316ff53fcb54a6787.tar.bz2
mpv-a545ffc48e8ac97722bb262316ff53fcb54a6787.tar.xz
sub-packet demuxer for rv20/rv30, patch by Florian Schneider <flo-mplayer-dev@gmx.net>
(little cleanup and fprintf->mp_msg by me) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6341 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_real.c233
1 files changed, 196 insertions, 37 deletions
diff --git a/libmpdemux/demux_real.c b/libmpdemux/demux_real.c
index a12c7fb1f0..130e526ed0 100644
--- a/libmpdemux/demux_real.c
+++ b/libmpdemux/demux_real.c
@@ -8,6 +8,10 @@
TODO: fix the whole syncing mechanism
$Log$
+ Revision 1.12 2002/06/08 20:46:14 arpi
+ sub-packet demuxer for rv20/rv30, patch by Florian Schneider <flo-mplayer-dev@gmx.net>
+ (little cleanup and fprintf->mp_msg by me)
+
Revision 1.11 2002/04/30 23:29:38 alex
completed real seeking - working very well with audio only files
@@ -329,6 +333,8 @@ int real_check_file(demuxer_t* demuxer)
return 1;
}
+void hexdump(char *, unsigned long);
+
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
@@ -337,6 +343,7 @@ int demux_real_fill_buffer(demuxer_t *demuxer)
real_priv_t *priv = demuxer->priv;
demux_stream_t *ds = NULL;
sh_audio_t *sh_audio = NULL;
+ sh_video_t *sh_video = NULL;
int len;
int timestamp;
int stream_id;
@@ -367,8 +374,10 @@ loop:
/* 0x1 - reliable */
/* 0x2 - keyframe */
-// printf("packet#%d: pos: %d, len: %d, stream_id: %d, timestamp: %d, flags: %x\n",
-// priv->current_packet, stream_tell(demuxer->stream)-12, len, stream_id, timestamp, flags);
+// debug re-enabled (FS)
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "len:%d\n", len);
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet#%d: pos: 0x%0x, len: %d, stream_id: %d, timestamp: %d, flags: %x\n",
+ priv->current_packet, (int)(stream_tell(demuxer->stream)-12), len, stream_id, timestamp, flags);
priv->current_packet++;
len -= 12;
@@ -378,7 +387,7 @@ loop:
{
if (priv->a_streams[i] == stream_id)
{
-// printf("packet is audio (id: %d)\n", stream_id);
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (id: %d)\n", stream_id);
ds = demuxer->audio; /* FIXME */
sh_audio = ds->sh;
priv->current_apacket++;
@@ -390,8 +399,9 @@ loop:
{
if (priv->v_streams[i] == stream_id)
{
-// printf("packet is video (id: %d)\n", stream_id);
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is video (id: %d)\n", stream_id);
ds = demuxer->video; /* FIXME */
+ sh_video = ds->sh;
priv->current_vpacket++;
break;
}
@@ -400,7 +410,7 @@ loop:
/* id not found */
if (ds == NULL)
{
- printf("unknown stream id (%d)\n", stream_id);
+ mp_msg(MSGT_DEMUX,MSGL_DBG2, "unknown stream id (%d)\n", stream_id);
stream_skip(demuxer->stream, len);
goto loop;
}
@@ -411,11 +421,13 @@ loop:
demuxer->filepos, (flags & 0x2) ? 0x10 : 0);
#else
{
- demux_packet_t *dp = new_demux_packet(len);
+ demux_packet_t *dp=NULL;
+// = new_demux_packet(len);
- stream_read(demuxer->stream, dp->buffer, len);
/* if DNET, swap bytes! */
- if (sh_audio != NULL)
+ if (sh_audio != NULL) {
+ dp = new_demux_packet(len);
+ stream_read(demuxer->stream, dp->buffer, len);
if (sh_audio->format == 0x2000)
{
char *ptr = dp->buffer;
@@ -428,10 +440,154 @@ loop:
ptr += 2;
}
}
- dp->pts = timestamp/90000.0f;
- dp->pos = demuxer->filepos;
- dp->flags = (flags & 0x2) ? 0x10 : 0;
- ds_add_packet(ds, dp);
+ dp->pts = timestamp/90000.0f;
+ dp->pos = demuxer->filepos;
+ dp->flags = (flags & 0x2) ? 0x10 : 0;
+ ds_add_packet(ds, dp);
+ }
+ if (sh_video != NULL) {
+ if (sh_video->format==0x30335652 && 1) {
+ // we need a more complicated demuxing
+ // a block may contain multiple packets
+ // as well as a packet may be contained in multiple blocks
+ int vpkg_header, vpkg_blknum, vpkg_length, vpkg_offset;
+ int vpkg_seqnum=-1, vpkg_oldseqnum=0, vpkg_seqnumread=0;
+ int vpkg_ofs;
+ unsigned int* extra;
+
+
+ while(len>0){
+
+ // read packet header
+ // bit 7: 1=last block in block chain
+ // bit 6: 1=short header (only one block?)
+ vpkg_header=stream_read_char(demuxer->stream); --len;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "hdr: %0.2X (len=%d) ",vpkg_header,len);
+
+ if (0x40==(vpkg_header&0xc0)) {
+ // seems to be a very short header
+ // 2 bytes, purpose of the second byte yet unknown
+ int bummer;
+ bummer=stream_read_char(demuxer->stream); --len;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "%0.2X",bummer);
+ vpkg_offset=0;
+ vpkg_length=len;
+ } else {
+
+ if (0==(vpkg_header&0x40)) {
+ // sub-seqnum (bits 0-6: number of fragment. bit 7: ???)
+ vpkg_seqnum=stream_read_char(demuxer->stream);
+ --len;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "subseq: %0.2X ",vpkg_seqnum);
+ }
+
+ // size of the complete packet
+ // bit 14 is always one (same applies to the offset)
+ vpkg_length=stream_read_word(demuxer->stream);
+ len-=2;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "%0.2X %0.2X ",vpkg_length>>8,vpkg_length&0xff);
+ vpkg_length&=0x3fff;
+
+ // offset of the following data inside the complete packet
+ // Note: if (hdr&0xC0)==0x80 then offset is relative to the
+ // _end_ of the packet, so it's equal to fragment size!!!
+ vpkg_offset=stream_read_word(demuxer->stream);
+ len-=2;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "%0.2X %0.2X ",vpkg_offset>>8,vpkg_offset&0xff);
+ if (vpkg_offset==0) {
+ vpkg_offset=stream_read_word(demuxer->stream);
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "%0.2X %0.2X ",vpkg_offset>>8,vpkg_offset&0xff);
+ len-=2;
+ }
+ vpkg_offset&=0x3fff;
+
+ vpkg_seqnum=stream_read_char(demuxer->stream); --len;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "%0.2X ",vpkg_seqnum);
+ }
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\n");
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "blklen=%d\n", len);
+ mp_msg(MSGT_DEMUX,MSGL_DBG2, "block: hdr=0x%0x, len=%d, offset=%d, seqnum=%d\n",
+ vpkg_header, vpkg_length, vpkg_offset, vpkg_seqnum);
+
+ if(ds->asf_packet){
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "we have an incomplete packet (oldseq=%d new=%d)\n",ds->asf_seq,vpkg_seqnum);
+ // we have an incomplete packet:
+ if(ds->asf_seq!=vpkg_seqnum){
+ // this fragment is for new packet, close the old one
+ ds_add_packet(ds,ds->asf_packet);
+ ds->asf_packet=NULL;
+ } else {
+ // append data to it!
+ demux_packet_t* dp=ds->asf_packet;
+ extra=(unsigned int*)(dp->buffer+vpkg_length);
+ ++extra[0];
+ if((extra[0]&3)==0){ // increase buffer size, if more than 4 subpackets
+ mp_msg(MSGT_DEMUX,MSGL_DBG2, "buffer too small!!!!!\n");
+ dp->buffer=realloc(dp->buffer,vpkg_length+(extra[0]+5)*8);
+ extra=(unsigned int*)(dp->buffer+vpkg_length);
+ }
+ extra[2+2*extra[0]]=1;
+ extra[3+2*extra[0]]=dp->len;
+ if(0x80==(vpkg_header&0xc0)){
+ // last fragment!
+ if(dp->len!=vpkg_length-vpkg_offset)
+ mp_msg(MSGT_DEMUX,MSGL_V,"warning! assembled.len=%d frag.len=%d total.len=%d \n",dp->len,vpkg_offset,vpkg_length-vpkg_offset);
+ stream_read(demuxer->stream, dp->buffer + dp->len, vpkg_offset);
+ dp->len+=vpkg_offset;
+ len-=vpkg_offset;
+ mp_dbg(MSGT_DEMUX,MSGL_DBG2, "fragment (%d bytes) appended, %d bytes left\n",vpkg_offset,len);
+ // we know that this is the last fragment -> we can close the packet!
+ ds_add_packet(ds,dp);
+ ds->asf_packet=NULL;
+ // continue parsing
+ continue;
+ }
+ // non-last fragment:
+ if(dp->len!=vpkg_offset)
+ mp_msg(MSGT_DEMUX,MSGL_V,"warning! assembled.len=%d offset=%d frag.len=%d total.len=%d \n",dp->len,vpkg_offset,len,vpkg_length);
+ stream_read(demuxer->stream, dp->buffer + dp->len, len);
+ dp->len+=len;
+ break; // no more fragments in this chunk!
+ }
+ }
+ // create new packet!
+ dp = new_demux_packet(vpkg_length+8*5);
+ // the timestamp seems to be in milliseconds
+ dp->pts = timestamp/1000.0f; timestamp=0;
+ dp->pos = demuxer->filepos;
+ dp->flags = (flags & 0x2) ? 0x10 : 0;
+ ds->asf_seq = vpkg_seqnum;
+ extra=(unsigned int*)(dp->buffer+vpkg_length);
+ extra[0]=0; // blocks
+ extra[1]=timestamp;
+ extra[2]=1; // sub-1
+ extra[3]=0;
+ if(0x00==(vpkg_header&0xc0)){
+ // first fragment:
+ dp->len=len;
+ stream_read(demuxer->stream, dp->buffer, dp->len);
+ ds->asf_packet=dp;
+ break;
+ }
+ // whole packet (not fragmented):
+ dp->len=vpkg_length; len-=vpkg_length;
+ stream_read(demuxer->stream, dp->buffer, dp->len);
+ ds_add_packet(ds,dp);
+
+ } // while(len>0)
+
+ } else {
+ // old video stream type
+
+ dp = new_demux_packet(len);
+ stream_read(demuxer->stream, dp->buffer, len);
+ dp->pts = timestamp/90000.0f;
+ dp->pos = demuxer->filepos;
+ dp->flags = (flags & 0x2) ? 0x10 : 0;
+ ds_add_packet(ds, dp);
+ }
+
+ }
}
#endif
@@ -448,7 +604,7 @@ void demux_open_real(demuxer_t* demuxer)
stream_skip(demuxer->stream, 2); /* version */
// stream_skip(demuxer->stream, 4);
i = stream_read_dword(demuxer->stream);
- printf("File version: %d\n", i);
+ mp_msg(MSGT_DEMUX,MSGL_V, "real: File version: %d\n", i);
num_of_headers = stream_read_dword(demuxer->stream);
// stream_skip(demuxer->stream, 4); /* number of headers */
@@ -468,7 +624,7 @@ void demux_open_real(demuxer_t* demuxer)
if (chunk_size < 10)
goto fail;
- printf("Chunk: %.4s (%x) (size: 0x%x, offset: 0x%x)\n",
+ mp_msg(MSGT_DEMUX,MSGL_V, "Chunk: %.4s (%x) (size: 0x%x, offset: 0x%x)\n",
(char *)&chunk_id, chunk_id, chunk_size, chunk_pos);
switch(chunk_id)
@@ -484,9 +640,9 @@ void demux_open_real(demuxer_t* demuxer)
stream_skip(demuxer->stream, 4); /* duration */
stream_skip(demuxer->stream, 4); /* preroll */
priv->index_chunk_offset = stream_read_dword(demuxer->stream);
- printf("First index chunk offset: 0x%x\n", priv->index_chunk_offset);
+ mp_msg(MSGT_DEMUX,MSGL_V,"First index chunk offset: 0x%x\n", priv->index_chunk_offset);
priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10;
- printf("First data chunk offset: 0x%x\n", priv->data_chunk_offset);
+ mp_msg(MSGT_DEMUX,MSGL_V,"First data chunk offset: 0x%x\n", priv->data_chunk_offset);
stream_skip(demuxer->stream, 2); /* nb streams */
#if 0
stream_skip(demuxer->stream, 2); /* flags */
@@ -496,14 +652,14 @@ void demux_open_real(demuxer_t* demuxer)
if (flags)
{
- printf("Flags (%x): ", flags);
+ mp_msg(MSGT_DEMUX,MSGL_V,"Flags (%x): ", flags);
if (flags & 0x1)
- printf("[save allowed] ");
+ mp_msg(MSGT_DEMUX,MSGL_V,"[save allowed] ");
if (flags & 0x2)
- printf("[perfect play (more buffers)] ");
+ mp_msg(MSGT_DEMUX,MSGL_V,"[perfect play (more buffers)] ");
if (flags & 0x4)
- printf("[live broadcast] ");
- printf("\n");
+ mp_msg(MSGT_DEMUX,MSGL_V,"[live broadcast] ");
+ mp_msg(MSGT_DEMUX,MSGL_V,"\n");
}
}
#endif
@@ -565,7 +721,7 @@ void demux_open_real(demuxer_t* demuxer)
int tmp;
stream_id = stream_read_word(demuxer->stream);
- printf("Found new stream (id: %d)\n", stream_id);
+ mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id);
stream_skip(demuxer->stream, 4); /* max bitrate */
bitrate = stream_read_dword(demuxer->stream); /* avg bitrate */
@@ -592,9 +748,9 @@ void demux_open_real(demuxer_t* demuxer)
int frame_size;
int version;
- printf("Found audio stream!\n");
+ mp_msg(MSGT_DEMUX,MSGL_V,"Found audio stream!\n");
version = stream_read_word(demuxer->stream);
- printf("version: %d\n", version);
+ mp_msg(MSGT_DEMUX,MSGL_V,"version: %d\n", version);
// stream_skip(demuxer->stream, 2); /* version (4 or 5) */
stream_skip(demuxer->stream, 2);
stream_skip(demuxer->stream, 4); /* .ra4 or .ra5 */
@@ -609,7 +765,7 @@ void demux_open_real(demuxer_t* demuxer)
stream_skip(demuxer->stream, 2); /* 1 */
// stream_skip(demuxer->stream, 2); /* coded frame size */
frame_size = stream_read_word(demuxer->stream);
- printf("frame_size: %d\n", frame_size);
+ mp_msg(MSGT_DEMUX,MSGL_V,"frame_size: %d\n", frame_size);
stream_skip(demuxer->stream, 4);
if (version == 5)
@@ -618,7 +774,7 @@ void demux_open_real(demuxer_t* demuxer)
sh->samplerate = stream_read_word(demuxer->stream);
stream_skip(demuxer->stream, 4);
sh->channels = stream_read_word(demuxer->stream);
- printf("samplerate: %d, channels: %d\n",
+ mp_msg(MSGT_DEMUX,MSGL_V,"samplerate: %d, channels: %d\n",
sh->samplerate, sh->channels);
if (version == 5)
@@ -649,11 +805,11 @@ void demux_open_real(demuxer_t* demuxer)
switch (MKTAG(buf[0], buf[1], buf[2], buf[3]))
{
case MKTAG('d', 'n', 'e', 't'):
- printf("Audio: DNET -> AC3\n");
+ mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET -> AC3\n");
sh->format = 0x2000;
break;
case MKTAG('s', 'i', 'p', 'r'):
- printf("Audio: SiproLab's ACELP.net\n");
+ mp_msg(MSGT_DEMUX,MSGL_V,"Audio: SiproLab's ACELP.net\n");
sh->format = 0x130;
/* for buggy directshow loader */
sh->wf = realloc(sh->wf, 18+4);
@@ -673,11 +829,11 @@ void demux_open_real(demuxer_t* demuxer)
// sh->wf[sizeof(WAVEFORMATEX)+4] = 0;
break;
case MKTAG('c', 'o', 'o', 'k'):
- printf("Audio: Real's GeneralCooker (?) (RealAudio G2?) (unsupported)\n");
+ mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Real's GeneralCooker (?) (RealAudio G2?) (unsupported)\n");
tmp = 0;
break;
case MKTAG('a', 't', 'r', 'c'):
- printf("Audio: Sony ATRAC3 (RealAudio 8) (unsupported)\n");
+ mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Sony ATRAC3 (RealAudio 8) (unsupported)\n");
sh->format = 0x270;
sh->wf->nAvgBytesPerSec = 16537; // 8268
@@ -688,7 +844,7 @@ void demux_open_real(demuxer_t* demuxer)
sh->wf = realloc(sh->wf, 18+sh->wf->cbSize);
break;
default:
- printf("Audio: Unknown (%s)\n", buf);
+ mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%s)\n", buf);
tmp = 0;
sh->format = MKTAG(buf[0], buf[1], buf[2], buf[3]);
}
@@ -722,7 +878,7 @@ void demux_open_real(demuxer_t* demuxer)
sh_video_t *sh = new_sh_video(demuxer, stream_id);
tmp = stream_read_dword_le(demuxer->stream);
- printf("video: %.4s (%x)\n", (char *)&tmp, tmp);
+ mp_msg(MSGT_DEMUX,MSGL_V,"video: %.4s (%x)\n", (char *)&tmp, tmp);
if (tmp != MKTAG('V', 'I', 'D', 'O'))
{
mp_msg(MSGT_DEMUX, MSGL_ERR, "Not audio/video stream or unsupported!\n");
@@ -730,7 +886,7 @@ void demux_open_real(demuxer_t* demuxer)
}
sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */
- printf("video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);
+ mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);
/* emulate BITMAPINFOHEADER */
sh->bih = malloc(sizeof(BITMAPINFOHEADER));
@@ -753,7 +909,7 @@ void demux_open_real(demuxer_t* demuxer)
/* h263 hack */
tmp = stream_read_dword(demuxer->stream);
- printf("H.263 ID: %x\n", tmp);
+ mp_msg(MSGT_DEMUX,MSGL_V,"H.263 ID: %x\n", tmp);
switch (tmp)
{
case 0x10000000:
@@ -770,9 +926,12 @@ void demux_open_real(demuxer_t* demuxer)
case 0x20100001:
/* codec id: rv20 */
break;
+ case 0x30202002:
+ /* codec id: rv30 */
+ break;
default:
/* codec id: none */
- printf("unknown id: %x\n", tmp);
+ mp_msg(MSGT_DEMUX,MSGL_V,"unknown id: %x\n", tmp);
}
/* insert as stream */
@@ -799,7 +958,7 @@ skip_this_chunk:
goto header_end;
case MKTAG('I', 'N', 'D', 'X'):
default:
- printf("Unknown chunk: %x\n", chunk_id);
+ mp_msg(MSGT_DEMUX,MSGL_V,"Unknown chunk: %x\n", chunk_id);
stream_skip(demuxer->stream, chunk_size - 10);
break;
}
@@ -810,7 +969,7 @@ header_end:
// stream_skip(demuxer->stream, 4); /* number of packets */
stream_skip(demuxer->stream, 4); /* next data header */
- printf("Packets in file: %d\n", priv->num_of_packets);
+ mp_msg(MSGT_DEMUX,MSGL_V,"Packets in file: %d\n", priv->num_of_packets);
if (priv->num_of_packets == 0)
priv->num_of_packets = -10;