Mercurial > mplayer.hg
changeset 9579:89d27a306886
*signed int vlc (needs only 5 lines of code so its no increase of complexity)
*moving subpacket shuffle type to the header
*encoding packet timestamps as signed difference from the msb_timestamp this is more flexible & cleaner
*optionally storing the keyframe flag for subpackets (in RLE)
*storing the timestamps differences for subpackets (in RLE)
*storing the signed differences of subpacket sizes instead of unsigned diff from some base size
*more compact encoding of common name/type for info packets
*removing fixed entries at the start of info packets (simpler)
*removing stuffing packet (uneeded, vlc itself allows padding)
*fixing sample code
author | michael |
---|---|
date | Thu, 13 Mar 2003 15:32:48 +0000 |
parents | 0c5454233dcf |
children | 88eabd7a3b3b |
files | DOCS/tech/mpcf.txt |
diffstat | 1 files changed, 135 insertions(+), 62 deletions(-) [+] |
line wrap: on
line diff
--- a/DOCS/tech/mpcf.txt Thu Mar 13 14:09:49 2003 +0000 +++ b/DOCS/tech/mpcf.txt Thu Mar 13 15:32:48 2003 +0000 @@ -42,6 +42,12 @@ data u(7) value= 128*value + data }while(more_data) + +s + temp v + temp++ + if(temp&1) value= -(temp>>1) + else value= (temp>>1) b (binary data or string) length v @@ -88,7 +94,8 @@ language_code b time_base_nom v time_base_denom v - lsb_timestamp_length v + msb_timestamp_shift v + shuffle_type v fixed_fps u(1) index_flag u(1) reserved u(6) @@ -111,7 +118,7 @@ audio_stream_header: stream_header - samplerate v + samplerate_mul v channel_count v reserved_bytes checksum u(32) @@ -127,19 +134,25 @@ msb_timestamp_flag u(1) subpacket_type u(2) reserved u(1) - lsb_timestamp v stream_id v if(msb_timestamp_flag) msb_timestamp v - if(sub_packet_type==00) + lsb_timestamp s + if(sub_packet_type==01) sub_packet[0] else{ subpacket_count v - shuffle_type v - if(subpacket_type==10){ - subpacket_base_size v - for(i=0; i<subpacket_count; i++) - subpacket_size_diff[i] v + if(sub_packet_type&01) + for(i=0; ; i++) + keyframe_run[i] v + for(i=0; ; i++){ + timestamp_diff[i] v + if(timestamp_diff[i] & 1) + timestamp_diff_run[i] v + } + if(sub_packet_type&10){ + for(i=0; i<subpacket_count-1; i++) + subpacket_size_diff[i] s } for(i=0; i<subpacket_count; i++) subpacket[i] @@ -163,25 +176,25 @@ info_packet: (optional) packet header info_startcode f(64) - start_time v - end_time v - start_stream_id v - end_stream_id v for(;;){ - type b - if(type=="") break; - name b - value b + id v + if(id==0) break + name= info_table[id][0] + type= info_table[id][1] + if(type==NULL) + type b + if(name==NULL) + name b + if(type=="v") + value v + else if(type=="s") + value s + else + value b } reserved_bytes checksum u(32) -stuffing_packet: (optional) - packet_header - stuffing_startcode f(64) - for(i=0; i<forward_ptr - length_of_non_reserved; i++) - stuffing f(8) - forward_ptr backward_ptr @@ -252,15 +265,21 @@ if the fixed_fps is 1 time_base_denom MUST not be 0 time_base_nom and time_base_denom MUST be relative prime - time_base_nom MUST be < 2^15 + time_base_nom MUST be < 2^16 examples: fps time_base_nom time_base_denom 30 30 1 29.97 30000 1001 23.976 24000 1001 + sample_rate sample_rate_mul time_base_nom time_base_denom + 44100 1 44100 1 + 44100 64 11025 16 + 48000 1024 375 8 + Note: the advantage to using a large sample_rate_mul is that the + timestamps need fewer bits -lsb_timestamp_length - length in bits of the lsb_timestamp +msb_timestamp_shift + amount of bits msb_timestamp is shifted left before adding lsb_timestamp MUST be <16 fixed_fps @@ -284,11 +303,12 @@ MUST be 1 for keyframes subpacket_type - 00 1 subpacket per packet (video, ...) - 01 subpacket_count fixed length subpackets per packet - 10 subpacket_count variable length subpackets per packet - 11 reserved - the only legal subpacket_type for video streams is 00, so video streams + subpacket_count subpacket_size keyframe_flag + 00 >1 constant constant + 01 1 NA NA + 10 >1 variable constant + 11 >1 variable variable + the only legal subpacket_type for video streams is 01, so video streams MUST NOT contain multiple subpackets per packet Note, if there are multiple subpackets then the timestamp of the packet is the timestamp of the first subpacket @@ -296,28 +316,37 @@ framesize SHOULD be < 16kbyte and not more then 0.5 sec of data SHOULD be put in a single packet -subpacket_base_size - an offset which should be added to the subpacket_size_diff of each - subpacket to get the actual size, so its normally the size of the - smallest subpacket - for fixed length subpackets, the size is calculated from the - subpacket_count - subpacket_count the number of subpackets, if not pressent then 1 +keyframe_run[i] + the number of subpackets with an identical keyframe_flag + Note, the value of first flag is stored in the packet header + is equal to subpacket count if not coded + +timestamp_diff[i] + the difference from the last subpacket timestamp to the current one in + time_base precission + the lowwest bit is used to indicate if timestamp_diff_run[i] is coded + +timestamp_diff_run[i] + the number of subpackets which have the same timestamp_diff + if not coded than 1 + 0 is forbidden + subpacket_size_diff - the (allways positive) difference from the subpacket_base_size to the - actual size of the current subpacket, if its not coded - (subpacket_type != 10) then its 0 + the difference between the predicted size of this subpacket and the + actual size + the predicted size is 64 for the first subpacket in a packet + otherwise it is MAX(64, last_subpacket_size) + the size of the last subpacket is not coded and is simply the space left Note a subpacket MUST be in exactly one packet, it cannot be split msb_timestamp most significant bits of the timestamp, SHOULD be 0 for the first frame lsb_timestamp - most significant bits of the timestamp in time_base precission, with - lsb_timestamp_length bits + difference from the msb_timestamp in time_base precission Example: IBBP display order keyframe msb_timestamp=0 lsb_timestamp=0 -> timestamp=0 frame lsb_timestamp=3 -> timestamp=3 @@ -325,8 +354,8 @@ frame lsb_timestamp=2 -> timestamp=2 ... keyframe msb_timestamp=1 lsb_timestamp=1 -> timestamp=257 - frame msb_timestamp=0 lsb_timestamp=255->timestamp=255 - frame msb_timestamp=1 lsb_timestamp=0 -> timestamp=256 + frame lsb_timestamp=-1-> timestamp=255 + frame lsb_timestamp=0 -> timestamp=256 frame lsb_timestamp=4 -> timestamp=260 frame lsb_timestamp=2 -> timestamp=258 frame lsb_timestamp=3 -> timestamp=259 @@ -341,6 +370,10 @@ depth for compatibility with some win32 codecs + +samplerate_mul + the number of samples per second in one time_base unit + samplerate = time_base*samplerate_mul zero_bit MUST be 0, its there to distinguish non keyframes from other packets, @@ -377,20 +410,21 @@ position in bytes of the first byte of the keyframe header, relative to the last index_position -start_time, stop_time - the time range in msecs to which the info applies - Note: can be used to mark chapters - -start_stream_id / end_stream_id - the stream(s) to which the info packet applies - +id + the id of the type/name pair, so its more compact + 0 means end + type - the fourcc of the type for example: "UTF8" -> String or "JPEG" -> jpeg image - 0 length means end + Note: nonstandard fields should be prefixed by "X-" + Note: MUST be less than 6 byte long (might be increased to 64 later) name the name of the info entry, valid names are + "StreamId" the stream(s) to which the info packet applies + "StartTimestamp" + "EndTimestamp" the time range in msecs to which the info applies + "SegmentId" a unique id for the streams + time specified "Author" "Description" "Copyright" @@ -408,11 +442,34 @@ Note: if someone needs some others, please tell us about them, so we can add them to the official standard (if they are sane) Note: nonstandard fields should be prefixed by "X-" + Note: MUST be less than 64 bytes long value + value of this name/type pair stuffing - 0xFF + 0x80 can be placed infront of any type v entry for stuffing + purposes + +info_table[][2]={ + {NULL , NULL }, // end + {NULL , NULL }, + {NULL , "UTF8"}, + {NULL , "v"}, + {NULL , "s"}, + {"StreamId" , "v"}, + {"SegmentId" , "v"}, + {"StartTimestamp" , "v"}, + {"EndTimestamp" , "v"}, + {"Author" , "UTF8"}, + {"Titel" , "UTF8"}, + {"Description" , "UTF8"}, + {"Copyright" , "UTF8"}, + {"Encoder" , "UTF8"}, + {"Keyword" , "UTF8"}, + {"Cover" , "JPEG"}, + {"Cover" , "PNG"}, +}; Structure: @@ -481,31 +538,47 @@ return val; } -static inline uint64_t get_v(BufferContext *bc){ +static inline uint64_t get_v(ByteStream *bc){ uint64_t val= 0; - for(;;){ + for(; spaceLeft(bc) > 0; ){ int tmp= *(bc->buf_ptr++); if(tmp&0x80) val= (val<<7) + tmp - 0x80; else return (val<<7) + tmp; } + + return -1; } -static inline void put_v(BufferContext *bc, uint64_t val){ +static inline int put_v(ByteStream *bc, uint64_t val){ int i; - assert(val); + if(spaceLeft(bc) < 9) return -1; - for(i=56;; i-=8){ - if(val>>i) break; + val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently + for(i=7; ; i+=7){ + if(val>>i == 0) break; } - for(;i>0; i-=8){ + for(i-=7; i>0; i-=8){ *(bc->buf_ptr++)= 0x80 | (val>>i); } *(bc->buf_ptr++)= val&0x7F; + + return 0; +} + +static inline int put_s(ByteStream *bc, uint64_t val){ + if(val<=0) return put_v(bc, -2*val ); + else return put_v(bc, 2*val-1); +} + +static inline int64_t get_s(ByteStream *bc){ + int64_t v= get_v(bc) + 1; + if(v&1) return -(v>>1); + else return (v>>1); }