mirror of
https://github.com/mpv-player/mpv
synced 2025-04-24 12:24:21 +00:00
initial version from Florian Schneider <flo-mplayer-dev@gmx.net>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6350 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
c047d8b1df
commit
56ae80d6e4
18
DOCS/tech/realcodecs/TODO
Normal file
18
DOCS/tech/realcodecs/TODO
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
TODO:
|
||||||
|
|
||||||
|
- more docs are coming as I find the time to write them down
|
||||||
|
- USE_REALCODECS is needed in config.h -> configure
|
||||||
|
- the original player is doing something I don't know of:
|
||||||
|
I compare the input and output data of the original and mplayer.
|
||||||
|
While the input is the same, the ouput differs.
|
||||||
|
- the frame rate is incorrect
|
||||||
|
- use RV20toYUV420Free()
|
||||||
|
- rvyuvMain and the two format dwords should be stored inside
|
||||||
|
st_context, so we don't use constants in the demuxer and the
|
||||||
|
wrapper
|
||||||
|
- audio support (mainly for COOK)
|
||||||
|
- RV20 support
|
||||||
|
- internet streaming support
|
||||||
|
- searching
|
||||||
|
- get it to work before (they stream) the Bizarre festival
|
||||||
|
|
58
DOCS/tech/realcodecs/audio-codecs.txt
Normal file
58
DOCS/tech/realcodecs/audio-codecs.txt
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
00 short text/description of the format (bitrate, when to use)
|
||||||
|
01 avg. bytes/sec output
|
||||||
|
02 ulong: ?
|
||||||
|
ulong: samples per second
|
||||||
|
ushort: bits/sample
|
||||||
|
ushort: number of channels
|
||||||
|
03 constant 2
|
||||||
|
04 long description
|
||||||
|
05 constant 1 (always?)
|
||||||
|
06 ulong: block align (input frame for RADecode)
|
||||||
|
07 string: minimum player version
|
||||||
|
08 n/a
|
||||||
|
09 n/a
|
||||||
|
0A n/a
|
||||||
|
0B n/a
|
||||||
|
0C n/a
|
||||||
|
0D ?
|
||||||
|
0E ?
|
||||||
|
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, p2);
|
||||||
|
p2=?
|
||||||
|
|
||||||
|
|
||||||
|
void *GetRAFlavorProperty(ra_main_t *raMain, ulong flavor, ulong property,
|
||||||
|
short *property_length_in_bytes);
|
||||||
|
returns property data for a specific data
|
||||||
|
|
||||||
|
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);
|
||||||
|
a flavor is an entry in the list of available format variations like
|
||||||
|
bitrate, number of channels, decoding algorithm, and so on
|
55
DOCS/tech/realcodecs/streaming.txt
Normal file
55
DOCS/tech/realcodecs/streaming.txt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
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 starts with a small header (two letters are one byte):
|
||||||
|
|
||||||
|
|
||||||
|
aa(bb)[ccccdddd{eeee}ff]
|
||||||
|
|
||||||
|
aa: indicates the type of header
|
||||||
|
the 2MSB indicate the header type (mask C0)
|
||||||
|
C0: the [] part exists, but not ()
|
||||||
|
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: unknown
|
||||||
|
cccc: mask 3FFF: length of data
|
||||||
|
mask C000: unknown, seems to be always 4000
|
||||||
|
dddd: when it's 0, {} exists (only in this case)
|
||||||
|
mask 3FFF: I thought it would have been the offset inside the
|
||||||
|
block, is not correct in every case. Just appending the
|
||||||
|
data works better, ignoring it.
|
||||||
|
mask C000: like cccc, except the first case
|
||||||
|
eeee: only exists when dddd exists and is zero. contains the data
|
||||||
|
dddd should contain in the second case. don't know what the developers
|
||||||
|
had in mind.
|
||||||
|
ff: sequence number for the data blocks, beginning with 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
packet header:
|
||||||
|
|
||||||
|
ushort unknown
|
||||||
|
ulong blocksize
|
||||||
|
ushort streamid
|
||||||
|
uchar reserved
|
||||||
|
uchar flags 1=reliable, 2=keyframe
|
||||||
|
|
||||||
|
|
177
DOCS/tech/realcodecs/video-codecs.txt
Normal file
177
DOCS/tech/realcodecs/video-codecs.txt
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
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 occured 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
struct transin1 *ptr;
|
||||||
|
ulong another_null;
|
||||||
|
ulong timestamp_from_stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct transin1 {
|
||||||
|
ulong 1, 0;
|
||||||
|
// ... more data? the codec's behaviour changed sometimes
|
||||||
|
// when I changed the data following the first to ulongs
|
||||||
|
// i.e. it crashed. I've set it to 0
|
||||||
|
// TODO: understand (the purpose of) these values
|
||||||
|
// often contains 0x28, 0x19
|
||||||
|
// sometimes 0x28, 0x11
|
||||||
|
// sometimes even other data (e.g. pointers)
|
||||||
|
// a breakpoint didn't reveal a read operation. weird.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
input_stream is the exact data from the data block for one frame.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result=RV20toYUV420CustomMessage(ulong *msg, struct rvyuvMain *);
|
||||||
|
|
||||||
|
Messages used by RV30:
|
||||||
|
|
||||||
|
A message is a triplet (cmd,val,ext) of ulong.
|
||||||
|
|
||||||
|
(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?
|
||||||
|
|
||||||
|
(0x1e,2|3,1)
|
||||||
|
calls a subroutine and returns the result, purpose has to be detemined
|
||||||
|
|
||||||
|
(0x24,2,{...})
|
||||||
|
copies 4 dwords to rvyuvMain+07c: { width, height, 0, 0 }
|
||||||
|
|
||||||
|
(0x1c,a,b) - called inside transform
|
||||||
|
to be analyzed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user