Commit 5021a98c authored by conrad's avatar conrad

Handle Theora version > 3.2.0 initial granulepos 1|0

Since theora version 3.2.1, the mapping from granules to time
has been shifted by 1, such that the first frame of a newly
encoded file is numbered 1, not 0. Detect that in auto_theora(),
and also report the Theora version in oggz info.
parent 6e924a13
......@@ -80,7 +80,7 @@ oggz_metric_default_granuleshift (OGGZ * oggz, long serialno,
iframe = granulepos >> stream->granuleshift;
pframe = granulepos - (iframe << stream->granuleshift);
granulepos = (iframe + pframe);
granulepos = (iframe + pframe) - stream->first_granule;
units = granulepos * stream->granulerate_d / stream->granulerate_n;
......@@ -200,6 +200,22 @@ oggz_get_granulerate (OGGZ * oggz, long serialno,
return 0;
}
int
oggz_set_first_granule (OGGZ * oggz, long serialno,
ogg_int64_t first_granule)
{
oggz_stream_t * stream;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
stream->first_granule = first_granule;
return oggz_metric_update (oggz, serialno);
}
/** DEPRECATED **/
int
oggz_set_metric_linear (OGGZ * oggz, long serialno,
......
......@@ -347,6 +347,7 @@ oggz_add_stream (OGGZ * oggz, long serialno)
stream->preroll = 0;
stream->granulerate_n = 1;
stream->granulerate_d = 1;
stream->first_granule = 0;
stream->basegranule = 0;
stream->granuleshift = 0;
......
......@@ -134,10 +134,13 @@ static int intlog(int num) {
}
#endif
#define THEORA_VERSION(maj,min,rev) ((maj<<16)+(min<<8)+rev)
static int
auto_theora (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = data;
int version;
ogg_int32_t fps_numerator, fps_denominator;
char keyframe_granule_shift = 0;
int keyframe_shift;
......@@ -145,6 +148,8 @@ auto_theora (OGGZ * oggz, long serialno, unsigned char * data, long length, void
/* TODO: this should check against 42 for the relevant version numbers */
if (length < 41) return 0;
version = THEORA_VERSION(header[7], header[8], header[9]);
fps_numerator = int32_be_at(&header[22]);
fps_denominator = int32_be_at(&header[26]);
......@@ -173,6 +178,8 @@ auto_theora (OGGZ * oggz, long serialno, unsigned char * data, long length, void
OGGZ_AUTO_MULT * (ogg_int64_t)fps_denominator);
oggz_set_granuleshift (oggz, serialno, keyframe_shift);
if (version > THEORA_VERSION(3,2,0))
oggz_set_first_granule (oggz, serialno, 1);
oggz_stream_set_numheaders (oggz, serialno, 3);
......
......@@ -86,6 +86,7 @@ struct _oggz_stream_t {
int preroll;
ogg_int64_t granulerate_n;
ogg_int64_t granulerate_d;
ogg_int64_t first_granule;
ogg_int64_t basegranule;
int granuleshift;
......@@ -282,6 +283,8 @@ oggz_get_granulerate (OGGZ * oggz, long serialno,
int oggz_set_granuleshift (OGGZ * oggz, long serialno, int granuleshift);
int oggz_get_granuleshift (OGGZ * oggz, long serialno);
int oggz_set_first_granule (OGGZ * oggz, long serialno, ogg_int64_t first_granule);
int oggz_set_preroll (OGGZ * oggz, long serialno, int preroll);
int oggz_get_preroll (OGGZ * oggz, long serialno);
......
......@@ -141,8 +141,10 @@ ot_theora_info (unsigned char * data, long len)
height = INT16_BE_AT(&data[18]);
snprintf (buf, 80,
"\tTheora-Version: %d.%d.%d\n"
"\tVideo-Framerate: %.3f fps\n"
"\tVideo-Width: %d\n\tVideo-Height: %d\n",
data[7], data[8], data[9],
(double)INT32_BE_AT(&data[22])/ (double)INT32_BE_AT(&data[26]),
width, height);
......
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