# HG changeset patch # User nicodvb # Date 1169294660 0 # Node ID df1d03939216b1fa880b9eb9bf387bf4c6362aef # Parent ea78a2b99651835f7f2aafa8937fed6f82e58637 added function to parse vc1 sequence header diff -r ea78a2b99651 -r df1d03939216 libmpdemux/mpeg_hdr.c --- a/libmpdemux/mpeg_hdr.c Fri Jan 19 23:15:53 2007 +0000 +++ b/libmpdemux/mpeg_hdr.c Sat Jan 20 12:04:20 2007 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #include "config.h" #include "mpeg_hdr.h" @@ -158,7 +159,16 @@ return y; } +static inline unsigned int mp_getbits16(unsigned char *buffer, unsigned int from, unsigned char len) +{ + if(len > 8) + return (mp_getbits(buffer, from, len - 8) << 8) | mp_getbits(buffer, from + len - 8, 8); + else + return mp_getbits(buffer, from, len); +} + #define getbits mp_getbits +#define getbits16 mp_getbits16 static int read_timeinc(mp_mpeg_header_t * picture, unsigned char * buffer, int n) { @@ -409,3 +419,108 @@ free(dest); return n; } + +static int mp_unescape03(unsigned char *buf, int len) +{ + unsigned char *dest; + int i, j, skip; + + dest = malloc(len); + if(! dest) + return 0; + + j = i = skip = 0; + while(i <= len-3) + { + if(buf[i] == 0 && buf[i+1] == 0 && buf[i+2] == 3) + { + dest[j] = dest[j+1] = 0; + j += 2; + i += 3; + skip++; + } + else + { + dest[j] = buf[i]; + j++; + i++; + } + } + dest[j] = buf[len-2]; + dest[j+1] = buf[len-1]; + len -= skip; + memcpy(buf, dest, len); + free(dest); + + return len; +} + +int mp_vc1_decode_sequence_header(mp_mpeg_header_t * picture, unsigned char * buf, int len) +{ + int n, x; + + len = mp_unescape03(buf, len); + + picture->display_picture_width = picture->display_picture_height = 0; + picture->fps = 0; + n = 0; + x = getbits(buf, n, 2); + n += 2; + if(x != 3) //not advanced profile + return 0; + + getbits16(buf, n, 14); + n += 14; + picture->display_picture_width = getbits16(buf, n, 12) * 2 + 2; + n += 12; + picture->display_picture_height = getbits16(buf, n, 12) * 2 + 2; + n += 12; + getbits(buf, n, 6); + n += 6; + x = getbits(buf, n, 1); + n += 1; + if(x) //display info + { + getbits16(buf, n, 14); + n += 14; + getbits16(buf, n, 14); + n += 14; + if(getbits(buf, n++, 1)) //aspect ratio + { + x = getbits(buf, n, 4); + n += 4; + if(x == 15) + { + getbits16(buf, n, 16); + n += 16; + } + } + + if(getbits(buf, n++, 1)) //framerates + { + int frexp=0, frnum=0, frden=0; + + if(getbits(buf, n++, 1)) + { + frexp = getbits16(buf, n, 16); + n += 16; + picture->fps = (double) (frexp+1) / 32.0; + } + else + { + float frates[] = {0, 24000, 25000, 30000, 50000, 60000, 48000, 72000, 0}; + float frdivs[] = {0, 1000, 1001, 0}; + + frnum = getbits(buf, n, 8); + n += 8; + frden = getbits(buf, n, 4); + n += 4; + if((frden == 1 || frden == 2) && (frnum < 8)) + picture->fps = frates[frnum] / frdivs[frden]; + } + } + } + + //free(dest); + return 1; +} diff -r ea78a2b99651 -r df1d03939216 libmpdemux/mpeg_hdr.h --- a/libmpdemux/mpeg_hdr.h Fri Jan 19 23:15:53 2007 +0000 +++ b/libmpdemux/mpeg_hdr.h Sat Jan 20 12:04:20 2007 +0000 @@ -26,3 +26,4 @@ int mp4_header_process_vol(mp_mpeg_header_t * picture, unsigned char * buffer); void mp4_header_process_vop(mp_mpeg_header_t * picture, unsigned char * buffer); int h264_parse_sps(mp_mpeg_header_t * picture, unsigned char * buf, int len); +int mp_vc1_decode_sequence_header(mp_mpeg_header_t * picture, unsigned char * buf, int len);