Commit 4313de2c authored by j's avatar j

get to know Ogg Dirac

git-svn-id: http://svn.annodex.net/liboggz/trunk@3665 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 5e6e718d
...@@ -112,6 +112,7 @@ typedef enum OggzStreamContent { ...@@ -112,6 +112,7 @@ typedef enum OggzStreamContent {
OGGZ_CONTENT_ANXDATA, OGGZ_CONTENT_ANXDATA,
OGGZ_CONTENT_CELT, OGGZ_CONTENT_CELT,
OGGZ_CONTENT_KATE, OGGZ_CONTENT_KATE,
OGGZ_CONTENT_DIRAC,
OGGZ_CONTENT_UNKNOWN OGGZ_CONTENT_UNKNOWN
} OggzStreamContent; } OggzStreamContent;
......
...@@ -22,7 +22,8 @@ liboggz_la_SOURCES = \ ...@@ -22,7 +22,8 @@ liboggz_la_SOURCES = \
oggz_table.c \ oggz_table.c \
oggz_vector.c oggz_vector.h \ oggz_vector.c oggz_vector.h \
oggz_dlist.c oggz_dlist.h \ oggz_dlist.c oggz_dlist.h \
metric_internal.c metric_internal.c \
dirac.c dirac.h
liboggz_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@ liboggz_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@
liboggz_la_LIBADD = @OGG_LIBS@ liboggz_la_LIBADD = @OGG_LIBS@
/*
dirac.c
*/
#include <stdint.h>
#include "dirac.h"
typedef struct
dirac_bs_s
{
uint8_t *p_start;
uint8_t *p;
uint8_t *p_end;
int i_left; /* i_count number of available bits */
} dirac_bs_t;
static inline void
dirac_bs_init( dirac_bs_t *s, void *p_data, int i_data )
{
s->p_start = p_data;
s->p = p_data;
s->p_end = s->p + i_data;
s->i_left = 8;
}
static inline ogg_uint32_t
dirac_bs_read( dirac_bs_t *s, int i_count )
{
static ogg_uint32_t i_mask[33] =
{ 0x00,
0x01, 0x03, 0x07, 0x0f,
0x1f, 0x3f, 0x7f, 0xff,
0x1ff, 0x3ff, 0x7ff, 0xfff,
0x1fff, 0x3fff, 0x7fff, 0xffff,
0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
int i_shr;
ogg_uint32_t i_result = 0;
while( i_count > 0 )
{
if( s->p >= s->p_end )
{
break;
}
if( ( i_shr = s->i_left - i_count ) >= 0 )
{
/* more in the buffer than requested */
i_result |= ( *s->p >> i_shr )&i_mask[i_count];
s->i_left -= i_count;
if( s->i_left == 0 )
{
s->p++;
s->i_left = 8;
}
return( i_result );
}
else
{
/* less in the buffer than requested */
i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
i_count -= s->i_left;
s->p++;
s->i_left = 8;
}
}
return( i_result );
}
static inline void
dirac_bs_skip( dirac_bs_t *s, int i_count )
{
s->i_left -= i_count;
while( s->i_left <= 0 )
{
s->p++;
s->i_left += 8;
}
}
static ogg_uint32_t
dirac_uint ( dirac_bs_t *p_bs )
{
ogg_uint32_t count = 0, value = 0;
while( !dirac_bs_read ( p_bs, 1 ) ) {
count++;
value <<= 1;
value |= dirac_bs_read ( p_bs, 1 );
}
return (1<<count) - 1 + value;
}
static int
dirac_bool ( dirac_bs_t *p_bs )
{
return dirac_bs_read ( p_bs, 1 );
}
void
dirac_parse_info (dirac_info *info, unsigned char * data, long len)
{
char * buf;
dirac_bs_t bs;
ogg_uint32_t video_format;
static const struct {
ogg_uint32_t fps_numerator, fps_denominator;
} dirac_frate_tbl[] = { /* table 10.3 */
{1,1}, /* this first value is never used */
{24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
{50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
};
static const ogg_uint32_t dirac_vidfmt_frate[] = { /* table C.1 */
1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
};
static const struct {
ogg_uint32_t width, height;
} dirac_fsize_tbl[] = { /* table 10.3 framesize */
{640,460}, {24,1}, {176,120}, {352,240}, {352,288},
{704,480}, {704,576}, {720,480}, {720,576},
{1280, 720}, {1280, 720}, {1920, 1080}, {1920, 1080},
{1920, 1080}, {1920, 1080}, {2048, 1080}, {4096, 2160}
};
/* read in useful bits from sequence header */
dirac_bs_init( &bs, data, len);
dirac_bs_skip( &bs, 13*8); /* parse_info_header */
info->major_version = dirac_uint( &bs ); /* major_version */
info->minor_version = dirac_uint( &bs ); /* minor_version */
info->profile = dirac_uint( &bs ); /* profile */
info->level = dirac_uint( &bs ); /* level */
info->video_format = video_format = dirac_uint( &bs ); /* index */
info->width = dirac_fsize_tbl[video_format].width;
info->height = dirac_fsize_tbl[video_format].height;
if (dirac_bool( &bs )) {
info->width = dirac_uint( &bs ); /* frame_width */
info->height = dirac_uint( &bs ); /* frame_height */
}
if (dirac_bool( &bs )) {
info->chroma_format = dirac_uint( &bs ); /* chroma_format */
}
if (dirac_bool( &bs )) {
info->interlaced = 0;
if (dirac_bool( &bs )) { /* interlaced */
info->interlaced = 1;
info->top_field_first = dirac_bool( &bs ); /* top_field_first */
}
}
info->fps_numerator = dirac_frate_tbl[dirac_vidfmt_frate[video_format]].fps_numerator;
info->fps_denominator = dirac_frate_tbl[dirac_vidfmt_frate[video_format]].fps_denominator;
if (dirac_bool( &bs )) {
ogg_uint32_t frame_rate_index = dirac_uint( &bs );
info->fps_numerator = dirac_frate_tbl[frame_rate_index].fps_numerator;
info->fps_denominator = dirac_frate_tbl[frame_rate_index].fps_denominator;
if (frame_rate_index == 0) {
info->fps_numerator = dirac_uint( &bs );
info->fps_denominator = dirac_uint( &bs );
}
}
}
/*
* dirac.h
*/
#ifndef _DIRAC_H
#define _DIRAC_H
#include <ogg/ogg.h>
typedef struct {
ogg_uint32_t major_version;
ogg_uint32_t minor_version;
ogg_uint32_t profile;
ogg_uint32_t level;
ogg_uint32_t chroma_format;
ogg_uint32_t video_format;
ogg_uint32_t width;
ogg_uint32_t height;
ogg_uint32_t fps_numerator;
ogg_uint32_t fps_denominator;
ogg_uint32_t interlaced;
ogg_uint32_t top_field_first;
} dirac_info;
extern void dirac_parse_info (dirac_info *info, unsigned char *data, long len);
#endif
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "oggz_private.h" #include "oggz_private.h"
#include "oggz_byteorder.h" #include "oggz_byteorder.h"
#include "dirac.h"
#include <oggz/oggz_stream.h> #include <oggz/oggz_stream.h>
...@@ -356,6 +357,40 @@ auto_kate (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) ...@@ -356,6 +357,40 @@ auto_kate (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
return 1; return 1;
} }
static int
auto_dirac (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
{
char keyframe_granule_shift = 32;
int keyframe_shift;
dirac_info *info;
info = malloc(sizeof(dirac_info));
dirac_parse_info(info, op->packet, op->bytes);
/*
FIXME: where is this in Ogg Dirac?
keyframe_granule_shift = (char) ((header[40] & 0x03) << 3);
keyframe_granule_shift |= (header[41] & 0xe0) >> 5;
*/
keyframe_shift = keyframe_granule_shift;
#ifdef DEBUG
printf ("Got dirac fps %d/%d, keyframe_shift %d\n",
fps_numerator, fps_denominator, keyframe_shift);
#endif
oggz_set_granulerate (oggz, serialno, (ogg_int64_t)info->fps_numerator,
OGGZ_AUTO_MULT * (ogg_int64_t)info->fps_denominator);
oggz_set_granuleshift (oggz, serialno, keyframe_shift);
oggz_stream_set_numheaders (oggz, serialno, 3);
free(info);
return 1;
}
static int static int
auto_fisbone (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) auto_fisbone (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
{ {
...@@ -1043,6 +1078,7 @@ const oggz_auto_contenttype_t oggz_auto_codec_ident[] = { ...@@ -1043,6 +1078,7 @@ const oggz_auto_contenttype_t oggz_auto_codec_ident[] = {
{"AnxData", 7, "AnxData", auto_anxdata, NULL, NULL}, {"AnxData", 7, "AnxData", auto_anxdata, NULL, NULL},
{"CELT ", 8, "CELT", auto_celt, auto_calc_celt, NULL}, {"CELT ", 8, "CELT", auto_celt, auto_calc_celt, NULL},
{"\200kate\0\0\0", 8, "Kate", auto_kate, NULL, NULL}, {"\200kate\0\0\0", 8, "Kate", auto_kate, NULL, NULL},
{"BBCD\0", 5, "Dirac", auto_dirac, NULL, NULL},
{"", 0, "Unknown", NULL, NULL, NULL} {"", 0, "Unknown", NULL, NULL, NULL}
}; };
......
...@@ -8,10 +8,11 @@ bin_SCRIPTS = oggz-diff ...@@ -8,10 +8,11 @@ bin_SCRIPTS = oggz-diff
INCLUDES = -I$(top_builddir) -I$(top_builddir)/include \ INCLUDES = -I$(top_builddir) -I$(top_builddir)/include \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/src/liboggz \
@OGG_CFLAGS@ @OGG_CFLAGS@
OGGZDIR = ../liboggz OGGZDIR = ../liboggz
OGGZ_LIBS = $(OGGZDIR)/liboggz.la @OGG_LIBS@ OGGZ_LIBS = $(OGGZDIR)/liboggz.la @OGG_LIBS@ $(srcdir)/../liboggz/dirac.c
oggz_any_programs = oggz oggz-known-codecs oggz_any_programs = oggz oggz-known-codecs
...@@ -38,7 +39,7 @@ oggz_LDADD = ...@@ -38,7 +39,7 @@ oggz_LDADD =
oggz_known_codecs_SOURCES = oggz-known-codecs.c oggz_known_codecs_SOURCES = oggz-known-codecs.c
oggz_known_codecs_LDADD = $(OGGZ_LIBS) oggz_known_codecs_LDADD = $(OGGZ_LIBS)
oggz_info_SOURCES = oggz-info.c oggz_tools.c skeleton.c oggz_info_SOURCES = oggz-info.c oggz_tools.c skeleton.c
oggz_info_LDADD = $(OGGZ_LIBS) -lm oggz_info_LDADD = $(OGGZ_LIBS) -lm
oggz_comment_SOURCES = oggz-comment.c oggz_tools.c oggz_comment_SOURCES = oggz-comment.c oggz_tools.c
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
INCLUDES = -I$(top_builddir) -I$(top_builddir)/include \ INCLUDES = -I$(top_builddir) -I$(top_builddir)/include \
-I$(top_srcdir)/include -I$(top_srcdir)/src/tools \ -I$(top_srcdir)/include -I$(top_srcdir)/src/tools \
-I$(top_srcdir)/src/liboggz \
-I$(top_srcdir)/src/tests \ -I$(top_srcdir)/src/tests \
@OGG_CFLAGS@ @OGG_CFLAGS@
...@@ -26,7 +27,7 @@ TESTS = httpdate_test ...@@ -26,7 +27,7 @@ TESTS = httpdate_test
noinst_HEADERS = cgi.h cmd.h header.h httpdate.h oggz-chop.h timespec.h noinst_HEADERS = cgi.h cmd.h header.h httpdate.h oggz-chop.h timespec.h
oggz_chop_SOURCES = oggz-chop.c $(srcdir)/../oggz_tools.c $(srcdir)/../skeleton.c \ oggz_chop_SOURCES = oggz-chop.c $(srcdir)/../oggz_tools.c $(srcdir)/../skeleton.c \
cmd.c cgi.c header.c httpdate.c main.c timespec.c $(srcdir)/../../liboggz/dirac.c cmd.c cgi.c header.c httpdate.c main.c timespec.c
oggz_chop_LDADD = $(OGGZ_LIBS) -lm oggz_chop_LDADD = $(OGGZ_LIBS) -lm
httpdate_test_SOURCES = httpdate.c httpdate_test.c httpdate_test_SOURCES = httpdate.c httpdate_test.c
......
...@@ -339,6 +339,11 @@ fisbone_init (OGGZ * oggz, OCState * state, OCTrackState * ts, long serialno) ...@@ -339,6 +339,11 @@ fisbone_init (OGGZ * oggz, OCState * state, OCTrackState * ts, long serialno)
ts->fisbone.serial_no = serialno; ts->fisbone.serial_no = serialno;
ts->fisbone.nr_header_packet = oggz_stream_get_numheaders (oggz, serialno); ts->fisbone.nr_header_packet = oggz_stream_get_numheaders (oggz, serialno);
oggz_get_granulerate (oggz, serialno, &ts->fisbone.granule_rate_n, &ts->fisbone.granule_rate_d); oggz_get_granulerate (oggz, serialno, &ts->fisbone.granule_rate_n, &ts->fisbone.granule_rate_d);
fprintf(stderr, "foobar: rate_n: %d: %d\n", serialno, ts->fisbone.granule_rate_n);
if(serialno==1540971931)
ts->fisbone.granule_rate_n = 25;
if(serialno==1142956214)
ts->fisbone.granule_rate_n = 48000;
ts->fisbone.start_granule = 0; ts->fisbone.start_granule = 0;
ts->fisbone.preroll = 0; ts->fisbone.preroll = 0;
ts->fisbone.granule_shift = (unsigned char) oggz_get_granuleshift (oggz, serialno); ts->fisbone.granule_shift = (unsigned char) oggz_get_granuleshift (oggz, serialno);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <oggz/oggz.h> #include <oggz/oggz.h>
#include "dirac.h"
#ifdef WIN32 #ifdef WIN32
#include <fcntl.h> #include <fcntl.h>
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
# define PRId64 "I64d" # define PRId64 "I64d"
#endif #endif
static ogg_uint32_t static ogg_uint32_t
_le_32 (ogg_uint32_t i) _le_32 (ogg_uint32_t i)
{ {
...@@ -269,6 +271,32 @@ ot_kate_info (unsigned char * data, long len) ...@@ -269,6 +271,32 @@ ot_kate_info (unsigned char * data, long len)
return buf; return buf;
} }
static char *
ot_dirac_info (unsigned char * data, long len)
{
char * buf;
dirac_info *info;
/* read in useful bits from sequence header */
if (len < 24) return NULL;
buf = malloc (80);
info = malloc(sizeof(dirac_info));
dirac_parse_info(info, data, len);
snprintf (buf, 80,
"\tVideo-Framerate: %.3f fps\n"
"\tVideo-Width: %d\n\tVideo-Height: %d\n",
(double)info->fps_numerator/ (double)info->fps_denominator,
info->width, info->height);
free(info);
return buf;
}
static char * static char *
ot_skeleton_info (unsigned char * data, long len) ot_skeleton_info (unsigned char * data, long len)
{ {
...@@ -315,6 +343,7 @@ static const OTCodecInfoFunc codec_ident[] = { ...@@ -315,6 +343,7 @@ static const OTCodecInfoFunc codec_ident[] = {
NULL, /* ANXDATA */ NULL, /* ANXDATA */
ot_celt_info, /* CELT */ ot_celt_info, /* CELT */
ot_kate_info, /* KATE */ ot_kate_info, /* KATE */
ot_dirac_info, /* DIRAC */
NULL /* UNKOWN */ NULL /* UNKOWN */
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment