summaryrefslogtreecommitdiffstats
path: root/DOCS/OUTDATED-tech/realcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'DOCS/OUTDATED-tech/realcodecs')
-rw-r--r--DOCS/OUTDATED-tech/realcodecs/TODO22
-rw-r--r--DOCS/OUTDATED-tech/realcodecs/audio-codecs.txt155
-rw-r--r--DOCS/OUTDATED-tech/realcodecs/streaming.txt58
-rw-r--r--DOCS/OUTDATED-tech/realcodecs/video-codecs.txt185
4 files changed, 420 insertions, 0 deletions
diff --git a/DOCS/OUTDATED-tech/realcodecs/TODO b/DOCS/OUTDATED-tech/realcodecs/TODO
new file mode 100644
index 0000000000..5ba035bfdd
--- /dev/null
+++ b/DOCS/OUTDATED-tech/realcodecs/TODO
@@ -0,0 +1,22 @@
+TODO:
+
+- more docs are coming as I find the time to write them down
+- use RV20toYUV420Free()
+- audio support - nearly DONE (look below)
+- internet streaming support
+- searching - we need to take care of the audio interleaving -
+ haven't taken steps to locate audio key frames (does such thing
+ exist?)
+- some media files can't be played (mplayer crashes/fails) because
+ it asks for decoded audio data, but the buffer in the audio
+ demuxer packets are empty/missing. It seems that the necessary
+ audio packets haven't been decoded completely (incomplete interleaving)
+ the audio stream packets may get mixed with video stream packet - DONE ???
+- put variables for audio streaming inside real_priv_t
+- audio support for other formats than COOK - use a switch
+ (like -forcereal) to activate it - no switch needed, win32 codecs
+ doens't work (it was a nonworking attempt)
+- postprocessing support (see rp8 preferences->performance->cpu usage,
+ also statistics->streams->video->POST FILTER: ON
+ (i've found that custommessage calls differ wiht pp on/off, but adding
+ these calls to mplayer didn't make a pixel difference between outputs)
diff --git a/DOCS/OUTDATED-tech/realcodecs/audio-codecs.txt b/DOCS/OUTDATED-tech/realcodecs/audio-codecs.txt
new file mode 100644
index 0000000000..fd28ab2a16
--- /dev/null
+++ b/DOCS/OUTDATED-tech/realcodecs/audio-codecs.txt
@@ -0,0 +1,155 @@
+all audio codecs (cook,atrk,14_4,28_8,dnet,sipr) have the same interface,
+but i have only analyzed the cook codec
+
+
+audio properties (hex)
+
+00 short text/description of the format (bitrate, when to use)
+01 bitrate (bits/s) //avg. bytes/sec output
+02 ulong: ?
+ ulong: samples per second
+ ushort: bits/sample
+ ushort: number of channels
+03 same as 02 //constant 2
+04 long description
+05 constant 1 (always?)
+06 ulong: block align (input frame size for RADecode)
+07 string: minimum player version
+08 n/a
+09 n/a
+0A n/a
+0B n/a
+0C n/a
+0D ?
+0E ? leaf size
+0F ?
+10 ?
+11 ?
+12 ?
+13 min. output buffer size? max. number of samples?
+14 ?
+
+
+
+
+functions:
+
+ulong result=RAOpenCodec2(ra_main_t *raMain);
+
+ulong result=RAInitDecoder(ra_main_t *raMain, ra_init_struct *raInit);
+struct ra_init_struct {
+ ulong sample_rate;
+ ushort bits_per_sample; // unused by RAInitDecoder
+ ushort number_of_channels;
+ ushort unknown1; // 0
+ ushort unknown2; // also unused (100)
+ ulong leaf_size; // leaf size (used for interleaving, but
+ // exists in audio stream description header (ASDH))
+ ulong block_align; // packet size
+ ulong bits_per_sample; // unused (always 16)
+ char *ext_data; // 16 bytes located at the end of the
+ // ASDH
+};
+
+There are some information missing that you usually need for playback,
+like bits per sample (the fileds aren't read by RAInitDecoder()). These
+are hard coded in the "flavors", i.e. the sub formats. A flavor is an entry
+in the list of available format variations like bitrate, number of channels,
+decoding algorithm, and so on.We can get those information with the
+following command:
+
+
+
+void *GetRAFlavorProperty(ra_main_t *raMain, ulong flavor, ulong property,
+ short *property_length_in_bytes);
+returns property data for a specific data
+
+This is not important, because it's just a read only function.
+These flavor properties don't seem to exist in
+
+
+ulong RADecode(ra_main_t *raMain, char *input_buffer,
+ ulong input_buffer_size, char *output_buffer,
+ ulong *decoded_bytes, ulong p6=-1);
+
+RAFreeDecoder(ra_main_t *);
+
+RACloseCodec(ra_main_t *);
+
+
+ulong RASetFlavor(ra_main_t *ra_main, ulong flavor);
+
+Set the flavor of the stream.
+
+a flavor is an entry in the list of available format variations like
+bitrate, number of channels, decoding algorithm, and so on
+
+
+audio data storage:
+-------------------
+
+With Real Audio V5 (or earlier?), the audio streams can be interleaved,
+i.e. the stream is striped amongst several data packets. The packets
+(which have a fixed size packet_len) are split up into a fixed number
+of num_parts equally sized parts - I call them leaves in lack of
+better name. The leaves have the size leaf_size = packet_len / num_parts.
+
+To create a bunch of packets, you need 2*num_parts stream packets.
+The first part of the first stream packet is stored in leaf number 0,
+the first part of the second into leaf number num_parts, the one of the
+next one into leaf number 1 etc. The following part of a stream packet
+is stored 2*num_packets behind the current part of the same stream packet.
+
+In short words: when you have a matrix with the leaves as the values,
+it's a transposition in conjunction with a permutation.
+
+packet | leaf | stream packet, part no.
+-------+---------------+------------------------
+0 | 0 | (0,0)
+0 | 1 | (2,0)
+. | . | .
+. | . | .
+0 | num_parts-1 | (2*num_parts-2,0)
+0 | num_parts | (1,0)
+0 | num_parts+1 | (3,0)
+. | . | .
+. | . | .
+0 | 2*num_parts-1 | (2*num_parts-1,0)
+1 | 0 | (0,1)
+. | . | .
+. | . | .
+
+
+sequence of calls:
+------------------
+
+RAOpenCodec2()
+
+RAInitDecoder()
+
+RASetFlavor()
+
+RAGetFlavorProperty(0xE)
+
+sequence of RADecode()s
+
+once a RAGetFlavorProperty(0xE) after some RADecode()s
+
+and occasionally the following sequence:
+RAGetFlavorProperty(0)
+RAGetFlavorProperty(7)
+which is rather pointless because they only return
+cleartext audio descriptions
+
+RAFreeDecoder()
+
+RACloseCodec()
+
+
+
+RAFlush(ra_main_t *raMain, char *output_buffer, ulong *retval)
+will be called when seeking
+output_buffer points to the output buffer from the last
+decode operation.
+retval is unknown, returning always 0x18 in a specific sample
+-> further investigation needed
diff --git a/DOCS/OUTDATED-tech/realcodecs/streaming.txt b/DOCS/OUTDATED-tech/realcodecs/streaming.txt
new file mode 100644
index 0000000000..a4af485b9b
--- /dev/null
+++ b/DOCS/OUTDATED-tech/realcodecs/streaming.txt
@@ -0,0 +1,58 @@
+In the RV30 format, another encapsulated data layer for the video stream
+has been introduced. In lack of a name I'll call them sub packets, the
+normal packets which exist in RV10 I'll call - well - packets. The stream
+of bytes which is put in one memory block is named block.
+
+The format extension has been * by wild guessing and comparing the
+received data between the original viewer and the demuxer.
+
+
+
+Every packet may contain one or more sub packets, and one block may
+be contained inside one or more adjacent (sub) packets.
+A sub packet (fragment) starts with a small header (two letters are one byte):
+
+
+aa(bb)[cccc{gggg}dddd{eeee}ff]
+
+aa: indicates the type of header
+ the 2MSB indicate the header type (mask C0)
+ C0: the [] part exists, but not () -> whole packet (not fragmented)
+ 00, 80: the data block is encapsulated inside multiple packets.
+ bb contains the sequence number, beginning with 1.
+ 80 indicates the last sub packet containing data for the
+ current block. no C0 or 40 sub packet follows until
+ the block has been finished with a 80 sub packet.
+ No packet with another stream than the current video stream
+ is inside the sub packet chain, at least I haven't seen
+ such case - the demuxer will shout in this case.
+ 40: [] does not exist, the meaning of bb is unknown to me
+ data follows to the end of the packet
+ mask 3F: unknown
+bb: sub-seq - mask 0x7f: the sequence number of the _fragment_
+ mask 0x80: unknown, seems to alternating between 00 and 80
+cccc: mask 3FFF: _total_ length of the packet
+ mask C000: unknown, seems to be always 4000
+ when it's all 0000, it indicates value >=0x4000, you should read {gggg}
+ and use all 16 bits of it. dunno what happens when length>=65536...
+dddd: when it's 0, {} exists (only in this case)
+ mask 3FFF: offset of fragment inside the whole packet. it's counted
+ from the beginning of the packet, except when hdr&0x80,
+ hten it's relative to the _end_ of the packet, so it's
+ equal to fragment size!
+ mask C000: like cccc, except the first case (always 4000)
+ when it's all 0000, it indicates value >=0x4000, you should read {eeee}
+ and use all 16 bits of it. dunno what happens when length>=65536...
+ff: sequence number of the assembled (defragmented) packets, beginning with 0
+
+NOTE: the demuxer should build a table of the subpacket offsets relative to the
+start of whole packet, it's required by the rv20/rv30 video decoders.
+
+
+packet header:
+
+ushort unknown
+ulong blocksize
+ushort streamid
+uchar reserved
+uchar flags 1=reliable, 2=keyframe
diff --git a/DOCS/OUTDATED-tech/realcodecs/video-codecs.txt b/DOCS/OUTDATED-tech/realcodecs/video-codecs.txt
new file mode 100644
index 0000000000..af2152061a
--- /dev/null
+++ b/DOCS/OUTDATED-tech/realcodecs/video-codecs.txt
@@ -0,0 +1,185 @@
+The work has been based on the RV30 codec, but since RV20 has the same
+interface, it might work for it as well.
+
+
+
+
+error codes (the software uses redmond originated error codes)
+
+1. internal code (1-10)
+2. result
+
+0 00000000 success
+1 80004005 E_FAIL
+2 8007000E E_OUTOFMEMORY
+3,9 80004001 E_NOTIMPL
+4,5 80070005 E_ACCESSDENIED
+6 80004003 E_POINTER
+7,10 80070057 E_INVALIDREG
+8 80040FC1 (or 1FC?: CO_E_OBJISREG) - never occurred here
+
+
+
+
+
+I think the only relevant file is the decoder drv[23].so.6.0
+The rv[23]0 ones are just for streaming. We do this ourselves.
+
+
+The codec consists of several functions. The relevant ones are:
+
+RV20toYUV420Init()
+RV20toYUV420Transform()
+RV20toYUV420CustomMessage()
+RV20toYUV420Free()
+
+
+The others are irrelevant (seems to me). HiveMessage doesn't manipulate
+anything and is only called in the beginning.
+
+result=RV20toYUV420Init(struct init_data *, struct rvyuvMain **);
+
+struct init_data {
+ short constant=0xb;
+ short width, height;
+ short 0, 0, 0;
+ ulong format1;
+ long 1;
+ ulong format2;
+};
+
+format1 and format2 are stored in the .rm file's stream headers.
+(format1>>16)&3 seems to be a sub-codec id/selector, at least for rv30
+it's the only difference between low and high bitrate files.
+
+result=RV20toYUV420Transform(char *input_stream, char *output_data,
+ struct transin *, struct transout *, struct rvyuvMain *);
+
+struct transin {
+ ulong length_of_input_data;
+ ulong null;
+ ulong num_sub_packets_in_block_minus_one;
+ ulong *sub_packets_list;
+ ulong another_null;
+ ulong timestamp_from_stream;
+};
+
+struct transout {
+ ulong flag1; // ((var_94&2!=0)&&(result==0))?1:0
+ ulong flag2; // 4 LBS from var_94
+ ulong zero;
+ ulong width, height;
+};
+
+The length of output_stream is 1.5*width*height (I420 planar yuv 4:2:0).
+input_stream is the exact data from the data block for one frame.
+
+sub_packets_list is a list of num_sub_packets pairs of long values, in form:
+1, 0,
+1, offset_2nd,
+1, offset_3rd,
+1, offset_4th,
+...
+
+where offset_* are the offsets or sub-packets relative to input_stream.
+
+
+result=RV20toYUV420CustomMessage(ulong *msg, struct rvyuvMain *);
+
+Messages used by RV30:
+
+A message is a triplet (cmd,val,ext) of ulong.
+
+NOTE:
+rv30 only requires the (0x24,2|3,{w,h,w,h}) message. others can be left out!
+rv20 only requires the (0x11,2,0) message in rp8, before each transform call.
+
+(3,2,0)
+returns always(?) an error, since a global variable inside the codec
+(which points to a function similar to custommessage), is always NULL
+
+(0x11,0|1|2,0)
+val=0|1: sets intern2 to val, when intern1 is non-zero
+ return 3 when intern1 is zero and val is 1
+ else returns 0
+val=2: return intern2
+what does intern[1,2] mean?
+
+(0x12,...)
+used by rv20, function unknown, can be ignored
+
+(0x1e,2|3,1)
+calls a subroutine and returns the result, purpose has to be detemined
+
+(0x24,subcodec,{...})
+copies 4 dwords to rvyuvMain+07c: { width, height, 0, 0 }
+subcodec must be 2 (low-bitrate) or 3 (high-bitrate) for rv30.
+the codec type (low vs high) can be determined from 1+((format1>>16)&3)
+for rv20, this call should be ignored! (makes codec crashing)
+
+(0x1c,a,b) - called inside transform
+to be analyzed
+
+(105,...)
+used by rv20, function unknown, can be ignored
+
+
+structure of rvyuvMain:
+-----------------------
+
+DWORDS (the entries are not always constant)
+there are two w/h pairs at 05C. the first is the size of the
+unscaled video stream, the second possibly image size
+
+000 1 6 3 1
+010 1 0 AEBFC0D1(magic) 0
+020 0 ptr->? 0 0
+030 0 0 ->rvyuvMain+0x050 ?
+040 width height 0x17 0x479
+050 ->rvyuvMain 0x17 0x17 width
+060 height width height 0
+070 0 1 0 0
+080 0 0xb w h
+090 w h 0 0
+0A0 1 0xb0(w?) 0x58 0x58
+0B0 ptr->? 0 0 1
+0C0 0x32 1 0 0
+0D0 0 0 0 0
+0E0 0 0 0 0
+0F0 0 0 0 0
+100 0 0 0 0
+110 p p p p p are pointers to several function, for
+120 p p p p example to the actual public functions
+130 p p p p (except init, the others are some kind of
+140 p p p p interfaces)
+150 p 0 0 0
+160 0 0x2000 1 0
+170 0 0 0 0
+180 1 1 0 0
+190 0 0 0 0
+1A0 0 0 0 0
+1B0 1 0 ptr->? ptr->?
+1C0 1 0 0 0
+1D0 0 0 0 0
+1E0 0 0 0 0
+...
+
+
+
+
+Order of calls:
+---------------
+
+Init
+(0x11,0,0)
+(0x24,2,{...})
+
+[
+(3,2,0)->80004001
+(0x11,1,0)
+(0x1e,3,1)
+Transform (internally calls (0x1c,x,y))
+(11,2,0)
+]
+
+Free