|
Packit |
a38265 |
/*
|
|
Packit |
a38265 |
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
|
Packit |
a38265 |
Organisation (CSIRO) Australia
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
a38265 |
modification, are permitted provided that the following conditions
|
|
Packit |
a38265 |
are met:
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions of source code must retain the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Redistributions in binary form must reproduce the above copyright
|
|
Packit |
a38265 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
a38265 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
- Neither the name of CSIRO Australia nor the names of its
|
|
Packit |
a38265 |
contributors may be used to endorse or promote products derived from
|
|
Packit |
a38265 |
this software without specific prior written permission.
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
a38265 |
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
a38265 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
Packit |
a38265 |
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
|
Packit |
a38265 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
Packit |
a38265 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
Packit |
a38265 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
a38265 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
a38265 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit |
a38265 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
a38265 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
a38265 |
*/
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "config.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "oggz_private.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#include "oggz/oggz_stream.h"
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static ogg_int64_t
|
|
Packit |
a38265 |
oggz_metric_dirac (OGGZ * oggz, long serialno,
|
|
Packit |
a38265 |
ogg_int64_t granulepos, void * user_data)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
ogg_int64_t iframe, pframe;
|
|
Packit |
a38265 |
ogg_uint32_t pt;
|
|
Packit |
a38265 |
ogg_uint16_t dist;
|
|
Packit |
a38265 |
ogg_uint16_t delay;
|
|
Packit |
a38265 |
ogg_int64_t dt;
|
|
Packit |
a38265 |
ogg_int64_t units;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return -1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
iframe = granulepos >> stream->granuleshift;
|
|
Packit |
a38265 |
pframe = granulepos - (iframe << stream->granuleshift);
|
|
Packit |
a38265 |
pt = (iframe + pframe) >> 9;
|
|
Packit |
a38265 |
delay = pframe >> 9;
|
|
Packit |
a38265 |
dt = (ogg_int64_t)pt - delay;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
units = dt * stream->granulerate_d / stream->granulerate_n;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#ifdef DEBUG
|
|
Packit |
a38265 |
printf ("oggz_..._granuleshift: serialno %010lu Got frame or field %lld (%lld + %lld): %lld units\n",
|
|
Packit |
a38265 |
serialno, dt, iframe, pframe, units);
|
|
Packit |
a38265 |
#endif
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return units;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static ogg_int64_t
|
|
Packit |
a38265 |
oggz_metric_default_granuleshift (OGGZ * oggz, long serialno,
|
|
Packit |
a38265 |
ogg_int64_t granulepos, void * user_data)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
ogg_int64_t iframe, pframe;
|
|
Packit |
a38265 |
ogg_int64_t units;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return -1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
iframe = granulepos >> stream->granuleshift;
|
|
Packit |
a38265 |
pframe = granulepos - (iframe << stream->granuleshift);
|
|
Packit |
a38265 |
granulepos = iframe + pframe;
|
|
Packit |
a38265 |
if (granulepos > 0) granulepos -= stream->first_granule;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
units = granulepos * stream->granulerate_d / stream->granulerate_n;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
#ifdef DEBUG
|
|
Packit |
a38265 |
printf ("oggz_..._granuleshift: serialno %010lu Got frame %lld (%lld + %lld): %lld units\n",
|
|
Packit |
a38265 |
serialno, granulepos, iframe, pframe, units);
|
|
Packit |
a38265 |
#endif
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return units;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static ogg_int64_t
|
|
Packit |
a38265 |
oggz_metric_default_linear (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
|
|
Packit |
a38265 |
void * user_data)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return -1;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return (stream->granulerate_d * granulepos / stream->granulerate_n);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
static int
|
|
Packit |
a38265 |
oggz_metric_update (OGGZ * oggz, long serialno)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/* we divide by the granulerate, ie. mult by gr_d/gr_n, so ensure
|
|
Packit |
a38265 |
* numerator is non-zero */
|
|
Packit |
a38265 |
if (stream->granulerate_n == 0) {
|
|
Packit |
a38265 |
stream->granulerate_n= 1;
|
|
Packit |
a38265 |
stream->granulerate_d = 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (stream->granuleshift == 0) {
|
|
Packit |
a38265 |
return oggz_set_metric_internal (oggz, serialno,
|
|
Packit |
a38265 |
oggz_metric_default_linear,
|
|
Packit |
a38265 |
NULL, 1);
|
|
Packit |
a38265 |
} else if (oggz_stream_get_content (oggz, serialno) == OGGZ_CONTENT_DIRAC) {
|
|
Packit |
a38265 |
return oggz_set_metric_internal (oggz, serialno,
|
|
Packit |
a38265 |
oggz_metric_dirac,
|
|
Packit |
a38265 |
NULL, 1);
|
|
Packit |
a38265 |
} else {
|
|
Packit |
a38265 |
return oggz_set_metric_internal (oggz, serialno,
|
|
Packit |
a38265 |
oggz_metric_default_granuleshift,
|
|
Packit |
a38265 |
NULL, 1);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_set_granuleshift (OGGZ * oggz, long serialno, int granuleshift)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream->granuleshift = granuleshift;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz_metric_update (oggz, serialno);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_get_granuleshift (OGGZ * oggz, long serialno)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return stream->granuleshift;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_set_granulerate (OGGZ * oggz, long serialno,
|
|
Packit |
a38265 |
ogg_int64_t granule_rate_numerator,
|
|
Packit |
a38265 |
ogg_int64_t granule_rate_denominator)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream->granulerate_n = granule_rate_numerator;
|
|
Packit |
a38265 |
stream->granulerate_d = granule_rate_denominator;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz_metric_update (oggz, serialno);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_get_granulerate (OGGZ * oggz, long serialno,
|
|
Packit |
a38265 |
ogg_int64_t * granulerate_n,
|
|
Packit |
a38265 |
ogg_int64_t * granulerate_d)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
*granulerate_n = stream->granulerate_n;
|
|
Packit |
a38265 |
*granulerate_d = stream->granulerate_d / OGGZ_AUTO_MULT;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return 0;
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_set_first_granule (OGGZ * oggz, long serialno,
|
|
Packit |
a38265 |
ogg_int64_t first_granule)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream->first_granule = first_granule;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz_metric_update (oggz, serialno);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
/** DEPRECATED **/
|
|
Packit |
a38265 |
int
|
|
Packit |
a38265 |
oggz_set_metric_linear (OGGZ * oggz, long serialno,
|
|
Packit |
a38265 |
ogg_int64_t granule_rate_numerator,
|
|
Packit |
a38265 |
ogg_int64_t granule_rate_denominator)
|
|
Packit |
a38265 |
{
|
|
Packit |
a38265 |
oggz_stream_t * stream;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream = oggz_get_stream (oggz, serialno);
|
|
Packit |
a38265 |
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
stream->granulerate_n = granule_rate_numerator;
|
|
Packit |
a38265 |
stream->granulerate_d = granule_rate_denominator;
|
|
Packit |
a38265 |
stream->granuleshift = 0;
|
|
Packit |
a38265 |
|
|
Packit |
a38265 |
return oggz_metric_update (oggz, serialno);
|
|
Packit |
a38265 |
}
|
|
Packit |
a38265 |
|