Bug 477899 - Requests for the duration of a media resource are cached by liboggplay - r+sr=roc

This commit is contained in:
Chris Double 2009-03-03 21:35:50 +13:00
Родитель da34fe4fbe
Коммит 9512778100
50 изменённых файлов: 1120 добавлений и 596 удалений

Просмотреть файл

@ -73,6 +73,11 @@ public:
// Resume any downloads that have been suspended.
void Resume();
// Set the duration of the media resource. Call with decoder lock
// obtained so that the decoder thread does not request the duration
// while it is changing.
void SetDuration(PRInt64 aDuration);
nsIPrincipal* GetCurrentPrincipal();
// Implementation of OggPlay Reader API.
@ -81,9 +86,13 @@ public:
size_t io_read(char* aBuffer, size_t aCount);
int io_seek(long aOffset, int aWhence);
long io_tell();
ogg_int64_t duration();
public:
nsMediaStream mStream;
// Duration of the media resource. -1 if not known.
PRInt64 mDuration;
};
#endif

Просмотреть файл

@ -69,6 +69,11 @@ void nsChannelReader::Resume()
mStream.Resume();
}
void nsChannelReader::SetDuration(PRInt64 aDuration)
{
mDuration = aDuration;
}
size_t nsChannelReader::io_read(char* aBuffer, size_t aCount)
{
PRUint32 bytes = 0;
@ -93,6 +98,11 @@ long nsChannelReader::io_tell()
return mStream.Tell();
}
ogg_int64_t nsChannelReader::duration()
{
return mDuration;
}
static OggPlayErrorCode oggplay_channel_reader_initialise(OggPlayReader* aReader, int aBlock)
{
nsChannelReader * me = static_cast<nsChannelReader*>(aReader);
@ -127,6 +137,12 @@ static long oggplay_channel_reader_io_tell(void* aReader)
return me->io_tell();
}
static ogg_int64_t oggplay_channel_reader_duration(struct _OggPlayReader *aReader)
{
nsChannelReader* me = static_cast<nsChannelReader*>(aReader);
return me->duration();
}
nsresult nsChannelReader::Init(nsMediaDecoder* aDecoder, nsIURI* aURI,
nsIChannel* aChannel,
nsIStreamListener** aStreamListener)
@ -139,7 +155,8 @@ nsChannelReader::~nsChannelReader()
MOZ_COUNT_DTOR(nsChannelReader);
}
nsChannelReader::nsChannelReader()
nsChannelReader::nsChannelReader() :
mDuration(-1)
{
MOZ_COUNT_CTOR(nsChannelReader);
OggPlayReader* reader = this;
@ -149,7 +166,7 @@ nsChannelReader::nsChannelReader()
reader->io_read = &oggplay_channel_reader_io_read;
reader->io_seek = &oggplay_channel_reader_io_seek;
reader->io_tell = &oggplay_channel_reader_io_tell;
reader->duration = nsnull;
reader->duration = &oggplay_channel_reader_duration;
}
nsIPrincipal*

Просмотреть файл

@ -653,7 +653,6 @@ private:
nsresult nsHttpStreamStrategy::Seek(PRInt32 aWhence, PRInt64 aOffset)
{
PRInt64 totalBytes = mDecoder->GetStatistics().mTotalBytes;
{
nsAutoLock lock(mLock);
if (!mChannel || !mPipeInput)
@ -719,7 +718,6 @@ nsresult nsHttpStreamStrategy::Seek(PRInt32 aWhence, PRInt64 aOffset)
nsAutoArrayPtr<char> data(new char[bytesAhead]);
if (!data)
return NS_ERROR_OUT_OF_MEMORY;
// Read until the read cursor reaches new seek point. If Cancel() is
// called then the read will fail with an error so we can bail out of
// the blocking call.

Просмотреть файл

@ -674,6 +674,7 @@ void nsOggDecodeStateMachine::PlayFrame() {
// Reset the play start time.
mPlayStartTime = PR_IntervalNow();
mPauseDuration = 0;
frame->mState = OGGPLAY_STREAM_INITIALISED;
}
double time = (PR_IntervalToMilliseconds(PR_IntervalNow()-mPlayStartTime-mPauseDuration)/1000.0);
@ -1228,6 +1229,7 @@ void nsOggDecodeStateMachine::LoadOggHeaders(nsChannelReader* aReader)
// and blocks until these are completed.
mon.Exit();
PRInt64 d = oggplay_get_duration(mPlayer);
oggplay_seek(mPlayer, 0);
mon.Enter();
mDuration = d;
mDecoder->StartProgressUpdates();
@ -1946,6 +1948,10 @@ void nsOggDecoder::SetDuration(PRInt64 aDuration)
if (mDecodeStateMachine) {
nsAutoMonitor mon(mMonitor);
mDecodeStateMachine->SetDuration(mDuration);
if (mReader) {
mReader->SetDuration(mDuration);
}
}
}

Просмотреть файл

@ -5,10 +5,7 @@ the Mozilla build system.
http://svn.annodex.net/liboggplay/trunk/
The svn revision number used was r3774.
The patch from Annodex trac ticket 421 is applied to fix bug 459938:
http://trac.annodex.net/ticket/421
The svn revision number used was r3848.
The patch from Bug 468327 (yuv_disable_optimized.patch) is applied
to disable optimized yuv to rgb routines.

Просмотреть файл

@ -41,6 +41,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DEFINES += -DHAVE_CONFIG_H
MODULE = oggplay
LIBRARY_NAME = oggplay
FORCE_STATIC_LIB= 1

Просмотреть файл

@ -64,6 +64,7 @@ oggplay_new_with_reader(OggPlayReader *reader) {
me->trash = NULL;
me->oggz = NULL;
me->pt_update_valid = 1;
me->duration = -1;
return me;
@ -210,7 +211,7 @@ oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset) {
return E_OGGPLAY_BAD_TRACK;
}
me->decode_data[track]->offset = (offset << 32);
me->decode_data[track]->offset = (offset << 32) / 1000;
return E_OGGPLAY_OK;
@ -509,7 +510,7 @@ read_more_data:
if (r == 0) {
num_records = oggplay_callback_info_prepare(me, &info);
/*
* set all of the tracks to active
* set all of the tracks to inactive
*/
for (i = 0; i < me->num_tracks; i++) {
me->decode_data[i]->active = 0;
@ -574,8 +575,11 @@ oggplay_start_decoding(OggPlay *me) {
int r;
while (1) {
if ((r = oggplay_step_decoding(me)) != E_OGGPLAY_CONTINUE)
return (OggPlayErrorCode)r;
r = oggplay_step_decoding(me);
if (r == E_OGGPLAY_CONTINUE || r == E_OGGPLAY_TIMEOUT) {
continue;
}
return (OggPlayErrorCode)r;
}
}
@ -643,17 +647,30 @@ oggplay_get_duration(OggPlay *me) {
return E_OGGPLAY_BAD_OGGPLAY;
}
if (me->reader->duration)
return me->reader->duration(me->reader);
else {
/* If the reader has a duration function we always call that
* function to find the duration. We never cache the result
* of that function.
*
* If there is no reader duration function we use our cached
* duration value, or do a liboggz seek to find it and cache
* that.
*/
if (me->reader->duration) {
ogg_int64_t d = me->reader->duration(me->reader);
if (d >= 0) {
me->duration = d;
}
}
if (me->duration < 0) {
ogg_int64_t pos;
ogg_int64_t duration;
pos = oggz_tell_units(me->oggz);
duration = oggz_seek_units(me->oggz, 0, SEEK_END);
me->duration = oggz_seek_units(me->oggz, 0, SEEK_END);
oggz_seek_units(me->oggz, pos, SEEK_SET);
oggplay_seek_cleanup(me, pos);
return duration;
}
return me->duration;
}
int

Просмотреть файл

@ -48,7 +48,7 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
int i;
int tcount = 0;
int added_required_record = 1;
int added_required_record = me->num_tracks;
ogg_int64_t diff;
ogg_int64_t latest_first_record = 0x0LL;
//ogg_int64_t lpt = 0;
@ -79,6 +79,7 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
track_info->available_records = track_info->required_records = 0;
track_info->records = NULL;
track_info->stream_info = OGGPLAY_STREAM_UNINITIALISED;
added_required_record --;
continue;
}
@ -144,7 +145,6 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
//lpt = p->presentation_time;
}
}
if (track_info->required_records > 0) {
/*
@ -199,24 +199,30 @@ oggplay_callback_info_prepare(OggPlay *me, OggPlayCallbackInfo ***info) {
* needs to be explicitly required (e.g. by seeking or start of movie), and
* create a new member in the player struct called pt_update_valid
*/
// TODO: I don't think that pt_update_valid is necessary any more, as this will only
// trigger now if there's no data in *ANY* of the tracks. Hence the audio timeslice case
// doesn't apply.
if
(
track->decoded_type != OGGPLAY_CMML
&&
track->decoded_type != OGGPLAY_KATE // TODO: check this is the right thing to do
&&
track_info->required_records == 0
&&
track->active == 1
&&
me->pt_update_valid
track->decoded_type == OGGPLAY_CMML
||
track->decoded_type == OGGPLAY_KATE // TODO: check this is the right thing to do
||
(
track_info->required_records == 0
&&
track->active == 1
&&
me->pt_update_valid
)
) {
added_required_record = 0;
me->pt_update_valid = 0;
added_required_record --;
}
}
me->pt_update_valid = 0;
//printf("\n");
/*
@ -397,7 +403,7 @@ oggplay_callback_info_get_presentation_time(OggPlayDataHeader *header) {
}
/* SGS: is this correct? */
return (header->presentation_time >> 32) & 0xFFFFFFFF;
return (((header->presentation_time >> 16) * 1000) >> 16) & 0xFFFFFFFF;
}
OggPlayVideoData *

Просмотреть файл

@ -59,9 +59,9 @@ oggplay_file_reader_initialise(OggPlayReader * opr, int block) {
return E_OGGPLAY_BAD_INPUT;
}
fseek(me->file, SEEK_END, 0);
fseek(me->file, 0L, SEEK_END);
me->size = ftell(me->file);
fseek(me->file, SEEK_SET, 0);
fseek(me->file, 0L, SEEK_SET);
me->current_position = 0;
@ -146,6 +146,7 @@ oggplay_file_reader_new(char *file_name) {
me->functions.available = &oggplay_file_reader_available;
me->functions.finished_retrieving = &oggplay_file_reader_finished_retrieving;
me->functions.seek = NULL;
me->functions.duration = NULL;
me->functions.io_read = &oggplay_file_reader_io_read;
me->functions.io_seek = &oggplay_file_reader_io_seek;
me->functions.io_tell = &oggplay_file_reader_io_tell;

Просмотреть файл

@ -49,8 +49,8 @@ typedef struct {
OggPlayReader functions;
char * file_name;
FILE * file;
int current_position;
int size;
long current_position;
long size;
} OggPlayFileReader;
#endif

Просмотреть файл

@ -39,11 +39,14 @@
#ifndef __OGGPLAY_PRIVATE_H__
#define __OGGPLAY_PRIVATE_H__
#ifdef HAVE_CONFIG_H
#ifdef WIN32
#include "config_win32.h"
#else
#include <config.h>
#endif
#endif
#include <oggplay/oggplay.h>
#include <oggz/oggz.h>
@ -220,6 +223,7 @@ struct _OggPlay {
OggPlaySeekTrash * trash;
int shutdown;
int pt_update_valid;
ogg_int64_t duration; /**< The value of the duration the last time it was retrieved.*/
};
void

Просмотреть файл

@ -59,7 +59,11 @@
#include <unistd.h>
#endif
#if HAVE_ASSERT
#include <assert.h>
#else
#define assert(x)
#endif
#define PRINT_BUFFER(s,m) \
printf("%s: in_mem: %d size: %d pos: %d stored: %d\n", \

Просмотреть файл

@ -76,6 +76,7 @@ void oggplay_yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
unsigned char * restrict ptry;
unsigned char * restrict ptru;
unsigned char * restrict ptrv;
unsigned char * ptro;
register __m64 *y, *o;
register __m64 zero, ut, vt, imm, imm2;
@ -84,14 +85,15 @@ void oggplay_yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
zero = _mm_setzero_si64();
ptro = rgb->ptro;
ptry = yuv->ptry;
ptru = yuv->ptru;
ptrv = yuv->ptrv;
for (i = 0; i < yuv->y_height; i++) {
int j;
o = (__m64*)rgb->ptro;
rgb->ptro += rgb->rgb_width * 4;
o = (__m64*)ptro;
ptro += rgb->rgb_width * 4;
for (j = 0; j < yuv->y_width; j += 8) {
y = (__m64*)&ptry[j];
@ -206,6 +208,7 @@ void oggplay_yuv2bgr(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
unsigned char * restrict ptry;
unsigned char * restrict ptru;
unsigned char * restrict ptrv;
unsigned char * ptro;
register __m64 *y, *o;
register __m64 zero, ut, vt, imm, imm2;
@ -217,11 +220,12 @@ void oggplay_yuv2bgr(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) {
ptry = yuv->ptry;
ptru = yuv->ptru;
ptrv = yuv->ptrv;
ptro = rgb->ptro;
for (i = 0; i < yuv->y_height; i++) {
int j;
o = (__m64*)rgb->ptro;
rgb->ptro += rgb->rgb_width * 4;
o = (__m64*)ptro;
ptro += rgb->rgb_width * 4;
for (j = 0; j < yuv->y_width; j += 8) {
y = (__m64*)&ptry[j];

Просмотреть файл

@ -35,8 +35,7 @@ sed s/\#include\ \<config.h\>/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\
rm ./src/liboggplay/oggplay_private.h1
sed s/\#ifdef\ HAVE_INTTYPES_H/\#if\ HAVE_INTTYPES_H/g $1/src/liboggplay/oggplay_data.c >./src/liboggplay/oggplay_data.c
cd ./src/liboggplay
patch <../../yuv2rgb-vanilla-fix.patch
patch <../../yuv_disable_optimized.patch
cd ../..
patch -p4 <yuv2argb.patch
patch -p3 <yuv2argb.patch
patch -p3 <bug464007.patch

Просмотреть файл

@ -1,88 +0,0 @@
Index: oggplay_yuv2rgb.c
===================================================================
--- oggplay_yuv2rgb.c (revision 3733)
+++ oggplay_yuv2rgb.c (working copy)
@@ -357,29 +357,27 @@
ptro2 = ptro;
for (j = 0; j < yuv->y_width; j += 2) {
- short pr, pg, pb;
+ short pr, pg, pb, y;
short r, g, b;
- //pr = ((128 + (ptrv[j/2] - 128) * 292) >> 8) - 16; /* 1.14 * 256 */
- pr = (-41344 + ptrv[j/2] * 292) >> 8;
- //pg = ((128 - (ptru[j/2] - 128) * 101 - (ptrv[j/2] - 128) * 149) >> 8)-16;
- // /* 0.395 & 0.581 */
- pg = (28032 - ptru[j/2] * 101 - ptrv[j/2] * 149) >> 8;
- //pb = ((128 + (ptru[j/2] - 128) * 520) >> 8) - 16; /* 2.032 */
- pb = (-70528 + ptru[j/2] * 520) >> 8;
+ pr = (-56992 + ptrv[j/2] * 409) >> 8;
+ pg = (34784 - ptru[j/2] * 100 - ptrv[j/2] * 208) >> 8;
+ pb = (-70688 + ptru[j/2] * 516) >> 8;
- r = ptry[j] + pr;
- g = ptry[j] + pg;
- b = ptry[j] + pb;
+ y = 298*ptry[j] >> 8;
+ r = y + pr;
+ g = y + pg;
+ b = y + pb;
*ptro2++ = CLAMP(r);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(b);
*ptro2++ = 255;
- r = ptry[j + 1] + pr;
- g = ptry[j + 1] + pg;
- b = ptry[j + 1] + pb;
+ y = 298*ptry[j + 1] >> 8;
+ r = y + pr;
+ g = y + pg;
+ b = y + pb;
*ptro2++ = CLAMP(r);
*ptro2++ = CLAMP(g);
@@ -409,29 +407,27 @@
ptro2 = ptro;
for (j = 0; j < yuv->y_width; j += 2) {
- short pr, pg, pb;
+ short pr, pg, pb, y;
short r, g, b;
- //pr = ((128 + (ptrv[j/2] - 128) * 292) >> 8) - 16; /* 1.14 * 256 */
- pr = (-41344 + ptrv[j/2] * 292) >> 8;
- //pg = ((128 - (ptru[j/2] - 128) * 101 - (ptrv[j/2] - 128) * 149) >> 8)-16;
- // /* 0.395 & 0.581 */
- pg = (28032 - ptru[j/2] * 101 - ptrv[j/2] * 149) >> 8;
- //pb = ((128 + (ptru[j/2] - 128) * 520) >> 8) - 16; /* 2.032 */
- pb = (-70528 + ptru[j/2] * 520) >> 8;
+ pr = (-56992 + ptrv[j/2] * 409) >> 8;
+ pg = (34784 - ptru[j/2] * 100 - ptrv[j/2] * 208) >> 8;
+ pb = (-70688 + ptru[j/2] * 516) >> 8;
- r = ptry[j] + pr;
- g = ptry[j] + pg;
- b = ptry[j] + pb;
+ y = 298*ptry[j] >> 8;
+ r = y + pr;
+ g = y + pg;
+ b = y + pb;
*ptro2++ = CLAMP(b);
*ptro2++ = CLAMP(g);
*ptro2++ = CLAMP(r);
*ptro2++ = 255;
- r = ptry[j + 1] + pr;
- g = ptry[j + 1] + pg;
- b = ptry[j + 1] + pb;
+ y = 298*ptry[j + 1] >> 8;
+ r = y + pr;
+ g = y + pg;
+ b = y + pb;
*ptro2++ = CLAMP(b);
*ptro2++ = CLAMP(g);

Просмотреть файл

@ -1,13 +1,17 @@
About Oggz
----------
Oggz comprises liboggz and the command-line tools oggzinfo, oggzdump,
oggzdiff, oggzmerge, oggzrip, oggz-comment, oggz-scan and oggz-validate.
Oggz comprises liboggz and the tool oggz, which provides commands to
inspect, edit and validate Ogg files. The oggz-chop tool can also be
used to serve time ranges of Ogg media over HTTP by any web server that
supports CGI.
liboggz is a C library providing a simple programming interface for reading
and writing Ogg files and streams. Ogg is an interleaving data container
developed by Monty at Xiph.Org, originally to support the Ogg Vorbis audio
format.
liboggz is a C library for reading and writing Ogg files and streams.
It offers various improvements over the reference libogg, including
support for seeking, validation and timestamp interpretation. Ogg is
an interleaving data container developed by Monty at Xiph.Org,
originally to support the Ogg Vorbis audio format but now used for
many free codecs including Dirac, FLAC, Speex and Theora.
Dependencies
------------
@ -16,20 +20,22 @@ Oggz depends only on libogg, available in most free software
distributions, or in source form at: http://xiph.org/downloads/
Support is built-in for parsing the headers of and seeking to time
positions in Ogg Speex, Vorbis, FLAC, Theora, PCM and CMML. Oggz is also
positions in Ogg Dirac, FLAC, Speex, Theora and Vorbis. Oggz is also
compatible with Annodex streams, and supports seeking on all tracks
described in an Ogg Skeleton track.
Installation
------------
This library can be installed using the conventional commands:
Release archives can be installed using the conventional commands:
$ ./configure
$ make check
$ sudo make install
sequence. Full details in the file INSTALL.
sequence. Configuration details are in the file INSTALL. If you obtained
this source by svn, first run "./autogen.sh" to create the configure script,
then run the above commands.
Read the file README.win32 for installing under MS Windows, and
README.symbian for information about building for Symbian devices.
@ -104,26 +110,57 @@ Tools
The Oggz source tarball also contains the following command-line tools,
which are useful for debugging and testing Ogg bitstreams:
* oggzinfo: Display information about one or more Ogg files and
their bitstreams.
* oggzdump: Hexdump packets of an Ogg file, or revert an Ogg file
from such a hexdump.
* oggzdiff: Hexdump the packets of two Ogg files and output
differences.
* oggzmerge: Merge Ogg files together, interleaving pages in order
of presentation time.
* oggzrip: Extract one or more logical bitstreams from an Ogg file.
* oggz-chop: Extract the part of an Ogg file between given start
and/or end times.
* oggz-comment: List or edit comments in an Ogg file.
* oggz-diff: Hexdump the packets of two Ogg files and output
differences.
* oggz-dump: Hexdump packets of an Ogg file, or revert an Ogg file
from such a hexdump.
* oggz-info: Display information about one or more Ogg files and
their bitstreams.
* oggz-merge: Merge Ogg files together, interleaving pages in order
of presentation time.
* oggz-rip: Extract one or more logical bitstreams from an Ogg file.
* oggz-scan: Scan an Ogg file and output characteristic landmarks.
* oggz-sort: Sort the pages of an Ogg file in order of presentation time.
* oggz-validate: Validate the Ogg framing of one or more files.
The script bash-completion/oggz enables completion of tool options and codec
names when using the bash shell. Source it from your .profile, or install it
in /etc/bash_completion.d to enable it system-wide.
oggz-chop: General usage and CGI installation
---------------------------------------------
oggz-chop extracts the part of an Ogg file between given start and/or end
times. The output file contains copies of the headers of the input file, and
all the codec data required to correctly decode the content between the start
and end times specified on the commandline. For codecs with data dependencies
like video keyframes, the keyframe prior to the starting time will be included
in the output.
An Apache server can be configured to use oggz-chop to handle all Ogg files
(or, all Ogg files in a particular directory). An example Apache configuration
is in the liboggz source tree, along with a script for installing it on a
Debian server.
The oggz-chop binary checks if it is being run as a CGI script (by checking
some environment variables), and if so acts based on the CGI query parameter
t=, much like mod_annodex. It accepts all the time specifications that
mod_annodex accepts (npt and various smpte framerates), and start and end
times separated by a /.
License
-------
@ -137,5 +174,4 @@ enjoy :)
--
Conrad Parker
Senior Software Engineer, Continuous Media Web, CSIRO Australia
http://www.annodex.net/ http://www.ict.csiro.au/cmweb/
http://www.annodex.net/

Просмотреть файл

@ -1,21 +1,12 @@
The source from this directory was copied from the liboggz-0.9.7
source distribution using the update.sh script. The only changes made
were those applied by update.sh, which applies a patch from
seek.patch, and the addition/upate of Makefile.in files for the
The source from this directory was copied from the liboggz svn
source repository using the update.sh script. The only changes made
were those applied by update.sh, which applies patches described
below, and the addition/upate of Makefile.in files for the
Mozilla build system.
The seek.patch address a bug in liboggz when a seek call returns an
error. It also addresses an issue where the guess for the seek
position can exceed the file size. These will be upstreamed to liboggz.
The svn revision number used was r3867.
The warning.patch addresses a printf in liboggz that is not wrapped
in a DEBUG #ifdef. See Mozilla bug 450891 and Annodex ticket 431:
http://trac.annodex.net/ticket/431
The oggz_off_t.patch fixes a compile error on Solaris see bug 449754
for details
The wince.patch addresses the lack of posix file IO suppor on windows ce see bug 461844 for details.
The wince.patch addresses the lack of posix file IO support on windows ce,
see bug 461844 for details.
endian.patch is applied to fix bug 452698.

Просмотреть файл

@ -1,6 +1,9 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
@ -8,7 +11,7 @@
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the 'getopt_long' function */
#define HAVE_GETOPT_LONG
#define HAVE_GETOPT_LONG /**/
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
@ -47,6 +50,10 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to build experimental code */
/* #undef OGGZ_CONFIG_EXPERIMENTAL */
@ -101,9 +108,17 @@
/* Version number of package */
#define VERSION "0.9.8"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#define _FILE_OFFSET_BITS 64
@ -114,6 +129,9 @@
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Some systems need _XOPEN_SOURCE for timezone */
/* #undef _XOPEN_SOURCE */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

Просмотреть файл

@ -30,7 +30,7 @@
#define HAVE_SSIZE_T 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
@ -131,4 +131,8 @@
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
#undef DEBUG
/* Define for MSVC as <stdint.h> is unavailable there */
typedef unsigned char uint8_t;
#define inline __inline // MSVC

Просмотреть файл

@ -563,6 +563,15 @@ int oggz_get_numtracks (OGGZ * oggz);
*/
long oggz_serialno_new (OGGZ * oggz);
/**
* Return human-readable string representation of a content type
*
* \retval string the name of the content type
* \retval NULL \a content invalid
*/
const char *
oggz_content_type (OggzStreamContent content);
#include <oggz/oggz_off_t.h>
#include <oggz/oggz_read.h>
#include <oggz/oggz_stream.h>

Просмотреть файл

@ -120,6 +120,7 @@ oggz_comment_get_vendor (OGGZ * oggz, long serialno);
* \retval 0 Success
* \retval OGGZ_ERR_BAD \a oggz is not a valid OGGZ* handle
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
* \note The vendor string should identify the library used to produce
* the stream, e.g. libvorbis 1.0 used "Xiph.Org libVorbis I 20020717".
* If copying a bitstream it should be the same as the source.
@ -190,6 +191,7 @@ oggz_comment_next_byname (OGGZ * oggz, long serialno,
* \retval 0 Success
* \retval OGGZ_ERR_BAD \a oggz is not a valid OGGZ* handle
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
int
oggz_comment_add (OGGZ * oggz, long serialno, OggzComment * comment);
@ -203,6 +205,7 @@ oggz_comment_add (OGGZ * oggz, long serialno, OggzComment * comment);
* \retval 0 Success
* \retval OGGZ_ERR_BAD \a oggz is not a valid OGGZ* handle
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
int
oggz_comment_add_byname (OGGZ * oggz, long serialno,

Просмотреть файл

@ -41,7 +41,7 @@
* Flags to oggz_new(), oggz_open(), and oggz_openfd().
* Can be or'ed together in the following combinations:
* - OGGZ_READ | OGGZ_AUTO
* - OGGZ_WRITE | OGGZ_NONSTRICT
* - OGGZ_WRITE | OGGZ_NONSTRICT | OGGZ_PREFIX | OGGZ_SUFFIX
*/
enum OggzFlags {
/** Read only */
@ -63,12 +63,16 @@ enum OggzFlags {
OGGZ_AUTO = 0x20,
/**
* Prefix
* Write Prefix: Assume that we are only writing the prefix of an
* Ogg stream, ie. disable checking for conformance with end-of-stream
* constraints.
*/
OGGZ_PREFIX = 0x40,
/**
* Suffix
* Write Suffix: Assume that we are only writing the suffix of an
* Ogg stream, ie. disable checking for conformance with
* beginning-of-stream constraints.
*/
OGGZ_SUFFIX = 0x80
@ -112,6 +116,7 @@ typedef enum OggzStreamContent {
OGGZ_CONTENT_ANXDATA,
OGGZ_CONTENT_CELT,
OGGZ_CONTENT_KATE,
OGGZ_CONTENT_DIRAC,
OGGZ_CONTENT_UNKNOWN
} OggzStreamContent;
@ -165,6 +170,12 @@ enum OggzError {
/** no data available from IO, try again */
OGGZ_ERR_IO_AGAIN = -16,
/** Hole (sequence number gap) detected in input data */
OGGZ_ERR_HOLE_IN_DATA = -17,
/** Out of memory */
OGGZ_ERR_OUT_OF_MEMORY = -18,
/** The requested serialno does not exist in this OGGZ */
OGGZ_ERR_BAD_SERIALNO = -20,

Просмотреть файл

@ -125,6 +125,7 @@ typedef int (*OggzIOFlush) (void * user_handle);
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ; \a oggz not
* open for reading.
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
int oggz_io_set_read (OGGZ * oggz, OggzIORead read, void * user_handle);
@ -147,6 +148,7 @@ void * oggz_io_get_read_user_handle (OGGZ * oggz);
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ; \a oggz not
* open for writing.
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
int oggz_io_set_write (OGGZ * oggz, OggzIOWrite write, void * user_handle);
@ -168,6 +170,7 @@ void * oggz_io_get_write_user_handle (OGGZ * oggz);
* \retval 0 Success
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*
* \note If you provide an OggzIOSeek function, you MUST also provide
* an OggzIOTell function, or else all your seeks will fail.
@ -193,6 +196,7 @@ void * oggz_io_get_seek_user_handle (OGGZ * oggz);
* \retval 0 Success
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
int oggz_io_set_tell (OGGZ * oggz, OggzIOTell tell, void * user_handle);
@ -216,6 +220,7 @@ void * oggz_io_get_tell_user_handle (OGGZ * oggz);
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ; \a oggz not
* open for writing.
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
int oggz_io_set_flush (OGGZ * oggz, OggzIOFlush flush, void * user_handle);

Просмотреть файл

@ -94,6 +94,7 @@ typedef int (*OggzReadPacket) (OGGZ * oggz, ogg_packet * op, long serialno,
* logical bitstream in \a oggz.
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*
* \note Values of \a serialno other than -1 allows you to specify different
* callback functions for each logical bitstream.
@ -131,6 +132,7 @@ typedef int (*OggzReadPage) (OGGZ * oggz, const ogg_page * og,
* \retval 0 Success
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*
* \note Values of \a serialno other than -1 allows you to specify different
* callback functions for each logical bitstream.
@ -156,6 +158,7 @@ int oggz_set_read_page (OGGZ * oggz, long serialno,
* returning OGGZ_STOP_OK
* \retval OGGZ_ERR_STOP_ERR Reading was stopped by a user callback
* returning OGGZ_STOP_ERR
* \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
*/
long oggz_read (OGGZ * oggz, long n);

Просмотреть файл

@ -258,6 +258,30 @@ long oggz_seek_packets (OGGZ * oggz, long serialno, long packets, int whence);
* \{
*/
/**
* Retrieve the preroll of a logical bitstream.
* \param oggz An OGGZ handle
* \param serialno Identify the logical bitstream in \a oggz
* \returns The preroll of the specified logical bitstream.
* \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing
* logical bitstream in \a oggz.
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
*/
int oggz_get_preroll (OGGZ * oggz, long serialno);
/**
* Specify the preroll of a logical bitstream.
* \param oggz An OGGZ handle
* \param serialno Identify the logical bitstream in \a oggz to attach
* this preroll to.
* \param preroll The preroll
* \returns 0 Success
* \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing
* logical bitstream in \a oggz.
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
*/
int oggz_set_preroll (OGGZ * oggz, long serialno, int preroll);
/**
* Retrieve the granuleshift of a logical bitstream.
* \param oggz An OGGZ handle
@ -424,6 +448,8 @@ typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target,
* \retval 0 Success
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing
* logical bitstream in \a oggz, and is not -1
*/
int oggz_set_order (OGGZ * oggz, long serialno, OggzOrder order,
void * user_data);

Просмотреть файл

@ -48,6 +48,7 @@ typedef void OggzTable;
/**
* Instantiate a new OggzTable
* \returns A new OggzTable
* \retval NULL Could not allocate memory for table
*/
OggzTable *
oggz_table_new (void);

Просмотреть файл

@ -177,6 +177,7 @@ int oggz_write_set_hungry_callback (OGGZ * oggz,
* 32 bits, ie. within the range (-(2^31), (2^31)-1)
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
* \retval OGGZ_ERR_OUT_OF_MEMORY Unable to allocate memory to queue packet
*
* \note If \a op->b_o_s is initialized to \a -1 before calling
* oggz_write_feed(), Oggz will fill it in with the appropriate

Просмотреть файл

@ -1,12 +0,0 @@
diff -r 070e364189c8 media/liboggz/include/oggz/oggz_off_t_generated.h
--- a/media/liboggz/include/oggz/oggz_off_t_generated.h Wed Nov 26 09:04:13 2008 -0600
+++ b/media/liboggz/include/oggz/oggz_off_t_generated.h Thu Nov 27 17:56:54 2008 +0800
@@ -59,7 +59,7 @@
#include <sys/types.h>
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(SOLARIS)
typedef off_t oggz_off_t;
#else
typedef loff_t oggz_off_t;

Просмотреть файл

@ -46,6 +46,7 @@ LIBRARY_NAME = oggz
FORCE_STATIC_LIB= 1
CSRCS = \
dirac.c \
metric_internal.c \
oggz.c \
oggz_auto.c \

Просмотреть файл

@ -0,0 +1,194 @@
/*
dirac.c
*/
#ifdef WIN32
#include "config_win32.h"
#else
#include "config.h"
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#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)
{
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 int dirac_source_sampling[] = { /* extracted from table C.1 */
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
};
static const int dirac_top_field_first[] = { /* from table C.1 */
0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
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 )) { /* custom_scan_format_flag */
int scan_format = dirac_uint( &bs ); /* scan_format */
if (scan_format < 2) {
info->interlaced = scan_format;
} else { /* other scan_format values are reserved */
info->interlaced = 0;
}
} else { /* no custom scan_format, use the preset value */
info->interlaced = dirac_source_sampling[video_format];
}
/* field order is set by video_format and cannot be custom */
info->top_field_first = dirac_top_field_first[video_format];
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 );
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
/*
* 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

Просмотреть файл

@ -38,6 +38,37 @@
#include "oggz_private.h"
static ogg_int64_t
oggz_metric_dirac (OGGZ * oggz, long serialno,
ogg_int64_t granulepos, void * user_data)
{
oggz_stream_t * stream;
ogg_int64_t iframe, pframe;
ogg_uint32_t pt;
ogg_uint16_t dist;
ogg_uint16_t delay;
ogg_int64_t dt;
ogg_int64_t units;
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) return -1;
iframe = granulepos >> stream->granuleshift;
pframe = granulepos - (iframe << stream->granuleshift);
pt = (iframe + pframe) >> 9;
delay = pframe >> 9;
dt = (ogg_int64_t)pt - delay;
units = dt * stream->granulerate_d / stream->granulerate_n;
#ifdef DEBUG
printf ("oggz_..._granuleshift: serialno %010lu Got frame or field %lld (%lld + %lld): %lld units\n",
serialno, dt, iframe, pframe, units);
#endif
return units;
}
static ogg_int64_t
oggz_metric_default_granuleshift (OGGZ * oggz, long serialno,
ogg_int64_t granulepos, void * user_data)
@ -56,7 +87,7 @@ oggz_metric_default_granuleshift (OGGZ * oggz, long serialno,
units = granulepos * stream->granulerate_d / stream->granulerate_n;
#ifdef DEBUG
printf ("oggz_..._granuleshift: serialno %010ld Got frame %lld (%lld + %lld): %lld units\n",
printf ("oggz_..._granuleshift: serialno %010lu Got frame %lld (%lld + %lld): %lld units\n",
serialno, granulepos, iframe, pframe, units);
#endif
@ -96,6 +127,10 @@ oggz_metric_update (OGGZ * oggz, long serialno)
return oggz_set_metric_internal (oggz, serialno,
oggz_metric_default_linear,
NULL, 1);
} else if (oggz_stream_get_content (oggz, serialno) == OGGZ_CONTENT_DIRAC) {
return oggz_set_metric_internal (oggz, serialno,
oggz_metric_dirac,
NULL, 1);
} else {
return oggz_set_metric_internal (oggz, serialno,
oggz_metric_default_granuleshift,
@ -162,7 +197,7 @@ oggz_get_granulerate (OGGZ * oggz, long serialno,
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
*granulerate_n = stream->granulerate_n;
*granulerate_d = stream->granulerate_d;
*granulerate_d = stream->granulerate_d / OGGZ_AUTO_MULT;
return 0;
}

Просмотреть файл

@ -96,6 +96,10 @@ oggz_new (int flags)
oggz->cb_next = 0;
oggz->streams = oggz_vector_new ();
if (oggz->streams == NULL) {
goto err_oggz_new;
}
oggz->all_at_eos = 0;
oggz->metric = NULL;
@ -106,14 +110,26 @@ oggz_new (int flags)
oggz->order_user_data = NULL;
oggz->packet_buffer = oggz_dlist_new ();
if (oggz->packet_buffer == NULL) {
goto err_streams_new;
}
if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) {
oggz_write_init (oggz);
if (oggz_write_init (oggz) == NULL)
goto err_packet_buffer_new;
} else if (OGGZ_CONFIG_READ) {
oggz_read_init (oggz);
}
return oggz;
err_packet_buffer_new:
oggz_free (oggz->packet_buffer);
err_streams_new:
oggz_free (oggz->streams);
err_oggz_new:
oggz_free (oggz);
return NULL;
}
OGGZ *
@ -325,7 +341,10 @@ oggz_add_stream (OGGZ * oggz, long serialno)
ogg_stream_init (&stream->ogg_stream, (int)serialno);
oggz_comments_init (stream);
if (oggz_comments_init (stream) == -1) {
oggz_free (stream);
return NULL;
}
stream->content = OGGZ_CONTENT_UNKNOWN;
stream->numheaders = 3; /* Default to 3 headers for Ogg logical bitstreams */
@ -598,6 +617,8 @@ oggz_set_order (OGGZ * oggz, long serialno,
oggz->order_user_data = user_data;
} else {
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
stream->order = order;
stream->order_user_data = user_data;
}
@ -621,3 +642,28 @@ oggz_map_return_value_to_error (int cb_ret)
}
}
const char *
oggz_content_type (OggzStreamContent content)
{
/* 20080805:
* Re: http://lists.xiph.org/pipermail/ogg-dev/2008-July/001108.html
*
* "The ISO C standard, in section 6.7.2.2 "enumeration specifiers",
* paragraph 4, says
*
* Each enumerated type shall be compatible with *char*, a signed
* integer type, or an unsigned integer type. The choice of type is
* implementation-defined, but shall be capable of representing the
* values of all the members of the declaration."
*
* -- http://gcc.gnu.org/ml/gcc-bugs/2000-09/msg00271.html
*
* Hence, we cannot remove the (content < 0) guard, even though current
* GCC gives a warning for it -- other compilers (including earlier GCC
* versions) may use a signed type for enum OggzStreamContent.
*/
if (content < 0 || content >= OGGZ_CONTENT_UNKNOWN)
return NULL;
return oggz_auto_codec_ident[content].content_type;
}

Просмотреть файл

@ -47,6 +47,7 @@
#include "oggz_private.h"
#include "oggz_byteorder.h"
#include "dirac.h"
#include <oggz/oggz_stream.h>
@ -66,8 +67,6 @@ int oggz_set_metric_linear (OGGZ * oggz, long serialno,
#define INT32_BE_AT(x) _be_32((*(ogg_int32_t *)(x)))
#define INT64_LE_AT(x) _le_64((*(ogg_int64_t *)(x)))
#define OGGZ_AUTO_MULT 1000Ull
static int
oggz_stream_set_numheaders (OGGZ * oggz, long serialno, int numheaders)
{
@ -84,13 +83,13 @@ oggz_stream_set_numheaders (OGGZ * oggz, long serialno, int numheaders)
}
static int
auto_speex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_speex (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate = 0;
int numheaders;
if (op->bytes < 68) return 0;
if (length < 68) return 0;
granule_rate = (ogg_int64_t) INT32_LE_AT(&header[36]);
#ifdef DEBUG
@ -99,6 +98,8 @@ auto_speex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
oggz_set_granulerate (oggz, serialno, granule_rate, OGGZ_AUTO_MULT);
oggz_set_preroll (oggz, serialno, 3);
numheaders = (ogg_int64_t) INT32_LE_AT(&header[68]) + 2;
oggz_stream_set_numheaders (oggz, serialno, numheaders);
@ -106,12 +107,12 @@ auto_speex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_vorbis (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_vorbis (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate = 0;
if (op->bytes < 30) return 0;
if (length < 30) return 0;
granule_rate = (ogg_int64_t) INT32_LE_AT(&header[12]);
#ifdef DEBUG
@ -120,6 +121,8 @@ auto_vorbis (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
oggz_set_granulerate (oggz, serialno, granule_rate, OGGZ_AUTO_MULT);
oggz_set_preroll (oggz, serialno, 2);
oggz_stream_set_numheaders (oggz, serialno, 3);
return 1;
@ -137,15 +140,15 @@ static int intlog(int num) {
#endif
static int
auto_theora (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_theora (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int32_t fps_numerator, fps_denominator;
char keyframe_granule_shift = 0;
int keyframe_shift;
/* TODO: this should check against 42 for the relevant version numbers */
if (op->bytes < 41) return 0;
if (length < 41) return 0;
fps_numerator = INT32_BE_AT(&header[22]);
fps_denominator = INT32_BE_AT(&header[26]);
@ -175,13 +178,14 @@ auto_theora (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
OGGZ_AUTO_MULT * (ogg_int64_t)fps_denominator);
oggz_set_granuleshift (oggz, serialno, keyframe_shift);
oggz_stream_set_numheaders (oggz, serialno, 3);
return 1;
}
static int
auto_annodex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_annodex (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
/* Apply a zero metric */
oggz_set_granulerate (oggz, serialno, 0, 1);
@ -190,12 +194,12 @@ auto_annodex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_anxdata (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_anxdata (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate_numerator = 0, granule_rate_denominator = 0;
if (op->bytes < 28) return 0;
if (length < 28) return 0;
granule_rate_numerator = INT64_LE_AT(&header[8]);
granule_rate_denominator = INT64_LE_AT(&header[16]);
@ -212,17 +216,17 @@ auto_anxdata (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_flac0 (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_flac0 (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate = 0;
granule_rate = (ogg_int64_t) (header[14] << 12) | (header[15] << 4) |
granule_rate = (ogg_int64_t) (header[14] << 12) | (header[15] << 4) |
((header[16] >> 4)&0xf);
#ifdef DEBUG
printf ("Got flac rate %d\n", (int)granule_rate);
#endif
oggz_set_granulerate (oggz, serialno, granule_rate, OGGZ_AUTO_MULT);
oggz_stream_set_numheaders (oggz, serialno, 3);
@ -231,15 +235,15 @@ auto_flac0 (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_flac (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_flac (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate = 0;
int numheaders;
if (op->bytes < 51) return 0;
if (length < 51) return 0;
granule_rate = (ogg_int64_t) (header[27] << 12) | (header[28] << 4) |
granule_rate = (ogg_int64_t) (header[27] << 12) | (header[28] << 4) |
((header[29] >> 4)&0xf);
#ifdef DEBUG
printf ("Got flac rate %d\n", (int)granule_rate);
@ -258,12 +262,12 @@ auto_flac (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
* http://wiki.xiph.org/index.php/OggPCM2
*/
static int
auto_oggpcm2 (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_oggpcm2 (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate;
if (op->bytes < 28) return 0;
if (length < 28) return 0;
granule_rate = (ogg_int64_t) INT32_BE_AT(&header[16]);
#ifdef DEBUG
@ -278,13 +282,13 @@ auto_oggpcm2 (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_celt (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_celt (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate = 0;
int numheaders;
if (op->bytes < 56) return 0;
if (length < 56) return 0;
granule_rate = (ogg_int64_t) INT32_LE_AT(&header[40]);
#ifdef DEBUG
@ -300,17 +304,17 @@ auto_celt (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_cmml (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_cmml (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int64_t granule_rate_numerator = 0, granule_rate_denominator = 0;
int granuleshift;
if (op->bytes < 28) return 0;
if (length < 28) return 0;
granule_rate_numerator = INT64_LE_AT(&header[12]);
granule_rate_denominator = INT64_LE_AT(&header[20]);
if (op->bytes > 28)
if (length > 28)
granuleshift = (int)header[28];
else
granuleshift = 0;
@ -331,14 +335,14 @@ auto_cmml (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
}
static int
auto_kate (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_kate (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
unsigned char * header = data;
ogg_int32_t gps_numerator, gps_denominator;
unsigned char granule_shift = 0;
int numheaders;
if (op->bytes < 64) return 0;
if (length < 64) return 0;
gps_numerator = INT32_LE_AT(&header[24]);
gps_denominator = INT32_LE_AT(&header[28]);
@ -354,21 +358,49 @@ auto_kate (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
oggz_set_granulerate (oggz, serialno, gps_numerator,
OGGZ_AUTO_MULT * gps_denominator);
oggz_set_granuleshift (oggz, serialno, granule_shift);
oggz_stream_set_numheaders (oggz, serialno, numheaders);
return 1;
}
static int
auto_fisbone (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_dirac (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = op->packet;
int granule_shift = 22; /* not a typo */
dirac_info *info;
info = oggz_malloc(sizeof(dirac_info));
if (info == NULL) return -1;
dirac_parse_info(info, data, length);
#ifdef DEBUG
printf ("Got dirac fps %d/%d granule_shift %d\n",
fps_numerator, fps_denominator, granule_shift);
#endif
/* the granulerate is twice the frame rate (in order to handle interlace) */
oggz_set_granulerate (oggz, serialno,
2 * (ogg_int64_t)info->fps_numerator,
OGGZ_AUTO_MULT * (ogg_int64_t)info->fps_denominator);
oggz_set_granuleshift (oggz, serialno, granule_shift);
oggz_stream_set_numheaders (oggz, serialno, 0);
oggz_free(info);
return 1;
}
static int
auto_fisbone (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
unsigned char * header = data;
long fisbone_serialno; /* The serialno referred to in this fisbone */
ogg_int64_t granule_rate_numerator = 0, granule_rate_denominator = 0;
int granuleshift, numheaders;
if (op->bytes < 48) return 0;
if (length < 48) return 0;
fisbone_serialno = (long) INT32_LE_AT(&header[12]);
@ -380,7 +412,7 @@ auto_fisbone (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
granuleshift = (int)header[48];
#ifdef DEBUG
printf ("Got fisbone granulerate %lld/%lld, granuleshift %d for serialno %010ld\n",
printf ("Got fisbone granulerate %lld/%lld, granuleshift %d for serialno %010lu\n",
granule_rate_numerator, granule_rate_denominator, granuleshift,
fisbone_serialno);
#endif
@ -393,23 +425,18 @@ auto_fisbone (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
/* Increment the number of headers for this stream */
numheaders = oggz_stream_get_numheaders (oggz, serialno);
oggz_stream_set_numheaders (oggz, serialno, numheaders+1);
return 1;
}
static int
auto_fishead (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
auto_fishead (OGGZ * oggz, long serialno, unsigned char * data, long length, void * user_data)
{
if (!op->b_o_s)
{
return auto_fisbone(oggz, op, serialno, user_data);
}
oggz_set_granulerate (oggz, serialno, 0, 1);
/* For skeleton, numheaders will get incremented as each header is seen */
oggz_stream_set_numheaders (oggz, serialno, 1);
return 1;
}
@ -423,27 +450,28 @@ typedef struct {
int encountered_first_data_packet;
} auto_calc_speex_info_t;
static ogg_int64_t
static ogg_int64_t
auto_calc_speex(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
/*
* on the first (b_o_s) packet, set calculate_data to be the number
* of speex frames per packet
*/
auto_calc_speex_info_t *info
auto_calc_speex_info_t *info
= (auto_calc_speex_info_t *)stream->calculate_data;
if (stream->calculate_data == NULL) {
stream->calculate_data = malloc(sizeof(auto_calc_speex_info_t));
stream->calculate_data = oggz_malloc(sizeof(auto_calc_speex_info_t));
if (stream->calculate_data == NULL) return -1;
info = stream->calculate_data;
info->encountered_first_data_packet = 0;
info->packet_size =
info->packet_size =
(*(int *)(op->packet + 64)) * (*(int *)(op->packet + 56));
info->headers_encountered = 1;
return 0;
}
if (info->headers_encountered < 2) {
info->headers_encountered += 1;
} else {
@ -458,7 +486,7 @@ auto_calc_speex(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
if (stream->last_granulepos > 0) {
return stream->last_granulepos + info->packet_size;
}
return -1;
}
@ -476,19 +504,21 @@ typedef struct {
int encountered_first_data_packet;
} auto_calc_celt_info_t;
static ogg_int64_t
static ogg_int64_t
auto_calc_celt (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
/*
* on the first (b_o_s) packet, set calculate_data to be the number
* of celt frames per packet
*/
auto_calc_celt_info_t *info
auto_calc_celt_info_t *info
= (auto_calc_celt_info_t *)stream->calculate_data;
if (stream->calculate_data == NULL) {
stream->calculate_data = malloc(sizeof(auto_calc_celt_info_t));
stream->calculate_data = oggz_malloc(sizeof(auto_calc_celt_info_t));
if (stream->calculate_data == NULL) return -1;
info = stream->calculate_data;
info->encountered_first_data_packet = 0;
@ -501,7 +531,7 @@ auto_calc_celt (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
info->headers_encountered = 1;
return 0;
}
if (info->headers_encountered < 2) {
info->headers_encountered += 1;
} else {
@ -516,7 +546,7 @@ auto_calc_celt (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
if (stream->last_granulepos > 0) {
return stream->last_granulepos + info->packet_size;
}
return -1;
}
@ -527,8 +557,8 @@ auto_calc_celt (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
* Header packets are marked by a set MSB in the first byte. Inter packets
* are marked by a set 2MSB in the first byte. Intra packets (keyframes)
* are any that are left over ;-)
*
* (see http://www.theora.org/doc/Theora_I_spec.pdf for the theora
*
* (see http://www.theora.org/doc/Theora_I_spec.pdf for the theora
* specification)
*/
@ -537,7 +567,7 @@ typedef struct {
} auto_calc_theora_info_t;
static ogg_int64_t
static ogg_int64_t
auto_calc_theora(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
long keyframe_no;
@ -553,13 +583,14 @@ auto_calc_theora(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
if (first_byte & 0x80)
{
if (info == NULL) {
stream->calculate_data = malloc(sizeof(auto_calc_theora_info_t));
stream->calculate_data = oggz_malloc(sizeof(auto_calc_theora_info_t));
if (stream->calculate_data == NULL) return -1;
info = stream->calculate_data;
}
info->encountered_first_data_packet = 0;
return (ogg_int64_t)0;
}
/* known granulepos */
if (now > (ogg_int64_t)(-1)) {
info->encountered_first_data_packet = 1;
@ -586,7 +617,7 @@ auto_calc_theora(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
return stream->last_granulepos + 1;
}
keyframe_shift = stream->granuleshift;
keyframe_shift = stream->granuleshift;
/*
* retrieve last keyframe number
*/
@ -596,12 +627,12 @@ auto_calc_theora(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
*/
keyframe_no += (stream->last_granulepos & ((1 << keyframe_shift) - 1)) + 1;
return ((ogg_int64_t)keyframe_no) << keyframe_shift;
}
static ogg_int64_t
auto_rcalc_theora(ogg_int64_t next_packet_gp, oggz_stream_t *stream,
auto_rcalc_theora(ogg_int64_t next_packet_gp, oggz_stream_t *stream,
ogg_packet *this_packet, ogg_packet *next_packet) {
int keyframe = (int)(next_packet_gp >> stream->granuleshift);
@ -642,9 +673,9 @@ auto_rcalc_theora(ogg_int64_t next_packet_gp, oggz_stream_t *stream,
* (additional information is not required)
*
* The two blocksizes can be determined from the first header packet, by reading
* byte 28. 1 << (packet[28] >> 4) == long_size.
* byte 28. 1 << (packet[28] >> 4) == long_size.
* 1 << (packet[28] & 0xF) == short_size.
*
*
* (see http://xiph.org/vorbis/doc/Vorbis_I_spec.html for specification)
*/
@ -658,13 +689,13 @@ typedef struct {
int log2_num_modes;
int mode_sizes[1];
} auto_calc_vorbis_info_t;
static ogg_int64_t
static ogg_int64_t
auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
auto_calc_vorbis_info_t *info;
if (stream->calculate_data == NULL) {
/*
* on the first (b_o_s) packet, determine the long and short sizes,
@ -672,11 +703,13 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
*/
int short_size;
int long_size;
long_size = 1 << (op->packet[28] >> 4);
short_size = 1 << (op->packet[28] & 0xF);
stream->calculate_data = malloc(sizeof(auto_calc_vorbis_info_t));
stream->calculate_data = oggz_malloc(sizeof(auto_calc_vorbis_info_t));
if (stream->calculate_data == NULL) return -1;
info = (auto_calc_vorbis_info_t *)stream->calculate_data;
info->nln_increments[3] = long_size >> 1;
info->nln_increments[2] = 3 * (long_size >> 2) - (short_size >> 2);
@ -698,10 +731,10 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
/*
* the code pages, a whole bunch of other fairly useless stuff, AND,
* RIGHT AT THE END (of a bunch of variable-length compressed rubbish that
* basically has only one actual set of values that everyone uses BUT YOU
* basically has only one actual set of values that everyone uses BUT YOU
* CAN'T BE SURE OF THAT, OH NO YOU CAN'T) is the only piece of data that's
* actually useful to us - the packet modes (because it's inconceivable to
* think people might want _just that_ and nothing else, you know, for
* think people might want _just that_ and nothing else, you know, for
* seeking and stuff).
*
* Fortunately, because of the mandate that non-used bits must be zero
@ -716,11 +749,12 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
int size_check;
int *mode_size_ptr;
int i;
/*
size_t size_realloc_bytes;
/*
* This is the format of the mode data at the end of the packet for all
* Vorbis Version 1 :
*
*
* [ 6:number_of_modes ]
* [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
* [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
@ -733,7 +767,7 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
* 0 0 0 0 0 1 0 0
* 0 0 1 0 0 0 0 0
* 0 0 1 0 0 0 0 0
* 0 0 1|0 0 0 0 0
* 0 0 1|0 0 0 0 0
* 0 0 0 0|0|0 0 0
* 0 0 0 0 0 0 0 0
* 0 0 0 0|0 0 0 0
@ -743,11 +777,11 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
* 0 0 0 0 0 0 0 0 V
* 0 0 0|0 0 0 0 0
* 0 0 0 0 0 0 0 0
* 0 0 1|0 0 0 0 0
* 0 0|1|0 0 0 0 0
*
*
* i.e. each entry is an important bit, 32 bits of 0, 8 bits of blah, a
* 0 0 1|0 0 0 0 0
* 0 0|1|0 0 0 0 0
*
*
* i.e. each entry is an important bit, 32 bits of 0, 8 bits of blah, a
* bit of 1.
* Let's find our last 1 bit first.
*
@ -765,7 +799,7 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
while (1)
{
/*
* from current_pos-5:(offset+1) to current_pos-1:(offset+1) should
* be zero
@ -773,15 +807,15 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
offset = (offset + 7) % 8;
if (offset == 7)
current_pos -= 1;
if
if
(
((current_pos[-5] & ~((1 << (offset + 1)) - 1)) != 0)
||
current_pos[-4] != 0
||
current_pos[-3] != 0
||
current_pos[-4] != 0
||
current_pos[-3] != 0
||
current_pos[-2] != 0
||
((current_pos[-1] & ((1 << (offset + 1)) - 1)) != 0)
@ -789,12 +823,12 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
{
break;
}
size += 1;
current_pos -= 5;
}
}
if (offset > 4) {
size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
@ -804,10 +838,10 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
/* shift to appropriate position */
size_check <<= (5 - offset);
/* or in part of byte from current_pos - 1 */
size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
(offset + 3);
}
size_check += 1;
#ifdef DEBUG
if (size_check != size)
@ -816,13 +850,16 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
}
#endif
/*
* store mode size information in our info struct
*/
stream->calculate_data = realloc(stream->calculate_data,
sizeof(auto_calc_vorbis_info_t) + (size - 1) * sizeof(int));
info = (auto_calc_vorbis_info_t *)(stream->calculate_data);
/* Check that size to be realloc'd doesn't overflow */
size_realloc_bytes = sizeof(auto_calc_vorbis_info_t) + (size - 1) * sizeof(int);
if (size_realloc_bytes < sizeof (auto_calc_vorbis_info_t)) return -1;
/* Store mode size information in our info struct */
info = realloc(stream->calculate_data, size_realloc_bytes);
if (info == NULL) return -1;
stream->calculate_data = info;
i = -1;
while ((1 << (++i)) < size);
info->log2_num_modes = i;
@ -837,9 +874,9 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
*mode_size_ptr++ = (current_pos[0] >> offset) & 0x1;
current_pos += 5;
}
}
return 0;
}
@ -847,7 +884,7 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
return -1;
{
{
/*
* we're in a data packet! First we need to get the mode of the packet,
* and from the mode, the size
@ -858,7 +895,7 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
mode = (op->packet[0] >> 1) & ((1 << info->log2_num_modes) - 1);
size = info->mode_sizes[mode];
/*
* if we have a working granulepos, we use it, but only if we can't
* calculate a valid gp value.
@ -884,28 +921,28 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
return -1;
}
result = stream->last_granulepos +
result = stream->last_granulepos +
(
(info->last_was_long ? info->long_size : info->short_size)
+
(info->last_was_long ? info->long_size : info->short_size)
+
(size ? info->long_size : info->short_size)
) / 4;
info->last_was_long = size;
return result;
}
}
ogg_int64_t
auto_rcalc_vorbis(ogg_int64_t next_packet_gp, oggz_stream_t *stream,
ogg_packet *this_packet, ogg_packet *next_packet) {
auto_calc_vorbis_info_t *info =
auto_calc_vorbis_info_t *info =
(auto_calc_vorbis_info_t *)stream->calculate_data;
int mode =
int mode =
(this_packet->packet[0] >> 1) & ((1 << info->log2_num_modes) - 1);
int this_size = info->mode_sizes[mode] ? info->long_size : info->short_size;
int next_size;
@ -940,13 +977,15 @@ typedef struct {
int encountered_first_data_packet;
} auto_calc_flac_info_t;
static ogg_int64_t
static ogg_int64_t
auto_calc_flac (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op)
{
auto_calc_flac_info_t *info;
if (stream->calculate_data == NULL) {
stream->calculate_data = malloc(sizeof(auto_calc_flac_info_t));
stream->calculate_data = oggz_malloc(sizeof(auto_calc_flac_info_t));
if (stream->calculate_data == NULL) return -1;
info = (auto_calc_flac_info_t *)stream->calculate_data;
info->previous_gp = 0;
info->encountered_first_data_packet = 0;
@ -1045,31 +1084,32 @@ const oggz_auto_contenttype_t oggz_auto_codec_ident[] = {
{"Annodex", 8, "Annodex", auto_annodex, NULL, NULL},
{"fishead", 7, "Skeleton", auto_fishead, NULL, NULL},
{"fLaC", 4, "Flac0", auto_flac0, auto_calc_flac, NULL},
{"\177FLAC", 4, "Flac", auto_flac, auto_calc_flac, NULL},
{"\177FLAC", 5, "Flac", auto_flac, auto_calc_flac, NULL},
{"AnxData", 7, "AnxData", auto_anxdata, NULL, NULL},
{"CELT ", 8, "CELT", auto_celt, auto_calc_celt, NULL},
{"\200kate\0\0\0", 8, "Kate", auto_kate, NULL, NULL},
{"BBCD\0", 5, "Dirac", auto_dirac, NULL, NULL},
{"", 0, "Unknown", NULL, NULL, NULL}
};
};
static int
oggz_auto_identify (OGGZ * oggz, long serialno, unsigned char * data, long len)
{
int i;
for (i = 0; i < OGGZ_CONTENT_UNKNOWN; i++)
{
const oggz_auto_contenttype_t *codec = oggz_auto_codec_ident + i;
if (len >= codec->bos_str_len &&
memcmp (data, codec->bos_str, codec->bos_str_len) == 0) {
oggz_stream_set_content (oggz, serialno, i);
return 1;
}
}
oggz_stream_set_content (oggz, serialno, OGGZ_CONTENT_UNKNOWN);
return 0;
}
@ -1087,27 +1127,44 @@ oggz_auto_identify_packet (OGGZ * oggz, ogg_packet * op, long serialno)
}
int
oggz_auto_get_granulerate (OGGZ * oggz, ogg_packet * op, long serialno,
void * user_data)
oggz_auto_read_bos_page (OGGZ * oggz, ogg_page * og, long serialno,
void * user_data)
{
int content = 0;
content = oggz_stream_get_content(oggz, serialno);
if (content < 0 || content >= OGGZ_CONTENT_UNKNOWN) {
return 0;
} else if (content == OGGZ_CONTENT_SKELETON && !ogg_page_bos(og)) {
return auto_fisbone(oggz, serialno, og->body, og->body_len, user_data);
} else {
return oggz_auto_codec_ident[content].reader(oggz, serialno, og->body, og->body_len, user_data);
}
oggz_auto_codec_ident[content].reader(oggz, op, serialno, user_data);
return 0;
}
ogg_int64_t
oggz_auto_calculate_granulepos(int content, ogg_int64_t now,
int
oggz_auto_read_bos_packet (OGGZ * oggz, ogg_packet * op, long serialno,
void * user_data)
{
int content = 0;
content = oggz_stream_get_content(oggz, serialno);
if (content < 0 || content >= OGGZ_CONTENT_UNKNOWN) {
return 0;
} else if (content == OGGZ_CONTENT_SKELETON && !op->b_o_s) {
return auto_fisbone(oggz, serialno, op->packet, op->bytes, user_data);
} else {
return oggz_auto_codec_ident[content].reader(oggz, serialno, op->packet, op->bytes, user_data);
}
}
ogg_int64_t
oggz_auto_calculate_granulepos(int content, ogg_int64_t now,
oggz_stream_t *stream, ogg_packet *op) {
if (oggz_auto_codec_ident[content].calculator != NULL) {
ogg_int64_t r = oggz_auto_codec_ident[content].calculator(now, stream, op);
return r;
}
}
return now;
}

Просмотреть файл

@ -429,7 +429,7 @@ This was the Theora header for theora-alpha2:
*/
/**
* Kate bitstream version 0.1
* Kate bitstream version 0.x
*
* Default field type: LITTLE ENDIAN unsigned integer
@ -445,7 +445,7 @@ This was the Theora header for theora-alpha2:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| text encoding | directionality| reserved - 0 | granule shift | 12-15
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| reserved - 0 | 16-19
| cw sh | canvas width | ch sh | canvcas height | 16-19
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| reserved - 0 | 20-23
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@ -470,6 +470,8 @@ This was the Theora header for theora-alpha2:
| category (continued) | 60-63
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
since bitstream 0.3: cw sh, canvas width, ch sh, canvas height
*/
int oggz_auto_identify (OGGZ *oggz, ogg_page *og, long serialno);

Просмотреть файл

@ -39,10 +39,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h> /* ULONG_MAX */
#ifndef WIN32
#include <strings.h>
#endif
#include <assert.h>
#include "oggz_private.h"
#include "oggz_vector.h"
@ -55,12 +58,26 @@
#endif
/* Ensure comment vector length can be expressed in 32 bits */
static unsigned long
oggz_comment_len (const char * s)
{
size_t len;
if (s == NULL) return 0;
len = strlen (s);
return (unsigned long) MIN(len, 0xFFFFFFFF);
}
static char *
oggz_strdup (const char * s)
{
char * ret;
if (s == NULL) return NULL;
ret = oggz_malloc (strlen(s) + 1);
ret = oggz_malloc (oggz_comment_len(s) + 1);
if (ret == NULL) return NULL;
return strcpy (ret, s);
}
@ -93,11 +110,6 @@ oggz_index_len (const char * s, char c, int len)
return NULL;
}
#if 0
static void comment_init(char **comments, int* length, char *vendor_string);
static void comment_add(char **comments, int* length, char *tag, char *val);
#endif
/*
Comments will be stored in the Vorbis style.
It is describled in the "Structure" section of
@ -134,47 +146,6 @@ The comment header is decoded as follows:
buf[base+1]=(char)(((val)>>8)&0xff); \
buf[base+2]=(char)((val)&0xff);
#if 0
static void
comment_init(char **comments, int* length, char *vendor_string)
{
int vendor_length=strlen(vendor_string);
int user_comment_list_length=0;
int len=4+vendor_length+4;
char *p=(char*)oggz_malloc(len);
if(p==NULL){
}
writeint(p, 0, vendor_length);
memcpy(p+4, vendor_string, vendor_length);
writeint(p, 4+vendor_length, user_comment_list_length);
*length=len;
*comments=p;
}
static void
comment_add(char **comments, int* length, char *tag, char *val)
{
char* p=*comments;
int vendor_length=readint(p, 0);
int user_comment_list_length=readint(p, 4+vendor_length);
int tag_len=(tag?strlen(tag):0);
int val_len=strlen(val);
int len=(*length)+4+tag_len+val_len;
p=(char*)oggz_realloc(p, len);
if(p==NULL){
}
writeint(p, *length, tag_len+val_len); /* length of comment */
if(tag) memcpy(p+*length+4, tag, tag_len); /* comment */
memcpy(p+*length+4+tag_len, val, val_len); /* comment */
writeint(p, 4+vendor_length, user_comment_list_length+1);
*comments=p;
*length=len;
}
#endif
static int
oggz_comment_validate_byname (const char * name, const char * value)
{
@ -204,6 +175,8 @@ oggz_comment_new (const char * name, const char * value)
if (!oggz_comment_validate_byname (name, value)) return NULL;
comment = oggz_malloc (sizeof (OggzComment));
if (comment == NULL) return NULL;
comment->name = oggz_strdup (name);
comment->value = oggz_strdup (value);
@ -271,7 +244,10 @@ oggz_comment_set_vendor (OGGZ * oggz, long serialno, const char * vendor_string)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
return OGGZ_ERR_OUT_OF_MEMORY;
if (oggz->flags & OGGZ_WRITE) {
if (OGGZ_CONFIG_WRITE) {
@ -377,7 +353,10 @@ oggz_comment_add (OGGZ * oggz, long serialno, const OggzComment * comment)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
return OGGZ_ERR_OUT_OF_MEMORY;
if (oggz->flags & OGGZ_WRITE) {
if (OGGZ_CONFIG_WRITE) {
@ -408,7 +387,10 @@ oggz_comment_add_byname (OGGZ * oggz, long serialno,
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
return OGGZ_ERR_OUT_OF_MEMORY;
if (oggz->flags & OGGZ_WRITE) {
if (OGGZ_CONFIG_WRITE) {
@ -523,6 +505,8 @@ oggz_comments_init (oggz_stream_t * stream)
{
stream->vendor = NULL;
stream->comments = oggz_vector_new ();
if (stream->comments == NULL) return -1;
oggz_vector_set_cmp (stream->comments, (OggzCmpFunc) oggz_comment_cmp, NULL);
return 0;
@ -618,6 +602,26 @@ oggz_comments_decode (OGGZ * oggz, long serialno,
return 0;
}
/*
* Pre-condition: at least one of accum, delta are non-zero,
* ie. don't call accum_length (0, 0);
* \retval 0 Failure: integer overflow
*/
static unsigned long
accum_length (unsigned long * accum, unsigned long delta)
{
/* Pre-condition: don't call accum_length (0, 0) */
assert (*accum != 0 || delta != 0);
/* Check for integer overflow */
if (delta > ULONG_MAX - (*accum))
return 0;
*accum += delta;
return *accum;
}
long
oggz_comments_encode (OGGZ * oggz, long serialno,
unsigned char * buf, long length)
@ -625,16 +629,20 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
oggz_stream_t * stream;
char * c = (char *)buf;
const OggzComment * comment;
int nb_fields = 0, vendor_length = 0, field_length;
long actual_length, remaining = length;
int nb_fields = 0, vendor_length = 0;
unsigned long actual_length = 0, remaining = length, field_length;
/* Deal with sign of length first */
if (length < 0) return 0;
stream = oggz_get_stream (oggz, serialno);
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
/* Vendor string */
if (stream->vendor)
vendor_length = strlen (stream->vendor);
actual_length = 4 + vendor_length;
vendor_length = oggz_comment_len (stream->vendor);
if (accum_length (&actual_length, 4 + vendor_length) == 0)
return 0;
#ifdef DEBUG
printf ("oggz_comments_encode: vendor = %s\n", stream->vendor);
#endif
@ -644,9 +652,14 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
for (comment = oggz_comment_first (oggz, serialno); comment;
comment = oggz_comment_next (oggz, serialno, comment)) {
actual_length += 4 + strlen (comment->name); /* [size]"name" */
if (comment->value)
actual_length += 1 + strlen (comment->value); /* "=value" */
/* [size]"name" */
if (accum_length (&actual_length, 4 + oggz_comment_len (comment->name)) == 0)
return 0;
if (comment->value) {
/* "=value" */
if (accum_length (&actual_length, 1 + oggz_comment_len (comment->value)) == 0)
return 0;
}
#ifdef DEBUG
printf ("oggz_comments_encode: %s = %s\n",
@ -656,7 +669,11 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
nb_fields++;
}
actual_length++; /* framing bit */
/* framing bit */
if (accum_length (&actual_length, 1) == 0)
return 0;
/* NB. actual_length is not modified from here onwards */
if (buf == NULL) return actual_length;
@ -666,7 +683,7 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
c += 4;
if (stream->vendor) {
field_length = strlen (stream->vendor);
field_length = oggz_comment_len (stream->vendor);
memcpy (c, stream->vendor, MIN (field_length, remaining));
c += field_length; remaining -= field_length;
if (remaining <= 0 ) return actual_length;
@ -680,16 +697,16 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
for (comment = oggz_comment_first (oggz, serialno); comment;
comment = oggz_comment_next (oggz, serialno, comment)) {
field_length = strlen (comment->name); /* [size]"name" */
field_length = oggz_comment_len (comment->name); /* [size]"name" */
if (comment->value)
field_length += 1 + strlen (comment->value); /* "=value" */
field_length += 1 + oggz_comment_len (comment->value); /* "=value" */
remaining -= 4;
if (remaining <= 0) return actual_length;
writeint (c, 0, field_length);
c += 4;
field_length = strlen (comment->name);
field_length = oggz_comment_len (comment->name);
memcpy (c, comment->name, MIN (field_length, remaining));
c += field_length; remaining -= field_length;
if (remaining <= 0) return actual_length;
@ -700,7 +717,7 @@ oggz_comments_encode (OGGZ * oggz, long serialno,
*c = '=';
c++;
field_length = strlen (comment->value);
field_length = oggz_comment_len (comment->value);
memcpy (c, comment->value, MIN (field_length, remaining));
c += field_length; remaining -= field_length;
if (remaining <= 0) return actual_length;
@ -779,11 +796,11 @@ oggz_comment_generate(OGGZ * oggz, long serialno,
return NULL;
}
c_packet = malloc(sizeof *c_packet);
c_packet = oggz_malloc(sizeof *c_packet);
if(c_packet) {
memset(c_packet, 0, sizeof *c_packet);
c_packet->packetno = 1;
c_packet->packet = malloc(buf_size);
c_packet->packet = oggz_malloc(buf_size);
}
if(c_packet && c_packet->packet) {
@ -811,7 +828,7 @@ oggz_comment_generate(OGGZ * oggz, long serialno,
c_packet->bytes -= 1;
}
} else {
free(c_packet);
oggz_free(c_packet);
c_packet = 0;
}
@ -836,9 +853,9 @@ void oggz_packet_destroy(ogg_packet *packet) {
if(packet) {
if(packet->packet)
{
free(packet->packet);
oggz_free(packet->packet);
}
free(packet);
oggz_free(packet);
}
return;
}

Просмотреть файл

@ -38,6 +38,7 @@
#include <stdlib.h>
#include "oggz_dlist.h"
#include "oggz_macros.h"
typedef struct OggzDListElem {
struct OggzDListElem * next;
@ -53,11 +54,25 @@ struct _OggzDList {
OggzDList *
oggz_dlist_new (void) {
OggzDList *dlist = malloc(sizeof(OggzDList));
OggzDListElem * dummy_front = malloc(sizeof(OggzDListElem));
OggzDListElem * dummy_back = malloc(sizeof(OggzDListElem));
OggzDList *dlist;
OggzDListElem *dummy_front, *dummy_back;
dlist = oggz_malloc(sizeof(OggzDList));
if (dlist == NULL) return NULL;
dummy_front = oggz_malloc(sizeof(OggzDListElem));
if (dummy_front == NULL) {
oggz_free (dlist);
return NULL;
}
dummy_back = oggz_malloc(sizeof(OggzDListElem));
if (dummy_back == NULL) {
oggz_free (dummy_front);
oggz_free (dlist);
return NULL;
}
dummy_front->next = dummy_back;
dummy_front->prev = NULL;
@ -68,7 +83,6 @@ oggz_dlist_new (void) {
dlist->tail = dummy_back;
return dlist;
}
void
@ -77,11 +91,11 @@ oggz_dlist_delete(OggzDList *dlist) {
OggzDListElem *p;
for (p = dlist->head->next; p != NULL; p = p->next) {
free(p->prev);
oggz_free(p->prev);
}
free(dlist->tail);
free(dlist);
oggz_free(dlist->tail);
oggz_free(dlist);
}
@ -90,22 +104,34 @@ oggz_dlist_is_empty(OggzDList *dlist) {
return (dlist->head->next == dlist->tail);
}
void
int
oggz_dlist_append(OggzDList *dlist, void *elem) {
OggzDListElem *new_elem = malloc(sizeof(OggzDListElem));
OggzDListElem *new_elem;
if (dlist == NULL) return -1;
new_elem = oggz_malloc(sizeof(OggzDListElem));
if (new_elem == NULL) return -1;
new_elem->data = elem;
new_elem->next = dlist->tail;
new_elem->prev = dlist->tail->prev;
new_elem->prev->next = new_elem;
new_elem->next->prev = new_elem;
return 0;
}
void
int
oggz_dlist_prepend(OggzDList *dlist, void *elem) {
OggzDListElem *new_elem = malloc(sizeof(OggzDListElem));
OggzDListElem *new_elem;
if (dlist == NULL) return -1;
new_elem = oggz_malloc(sizeof(OggzDListElem));
if (new_elem == NULL) return -1;
new_elem->data = elem;
new_elem->prev = dlist->head;
@ -113,6 +139,7 @@ oggz_dlist_prepend(OggzDList *dlist, void *elem) {
new_elem->prev->next = new_elem;
new_elem->next->prev = new_elem;
return 0;
}
void
@ -154,7 +181,7 @@ oggz_dlist_deliter(OggzDList *dlist, OggzDListIterFunc func) {
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
oggz_free(p);
}
}
@ -173,7 +200,7 @@ oggz_dlist_reverse_deliter(OggzDList *dlist, OggzDListIterFunc func) {
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
oggz_free(p);
}
}

Просмотреть файл

@ -49,10 +49,10 @@ oggz_dlist_delete(OggzDList *dlist);
int
oggz_dlist_is_empty(OggzDList *dlist);
void
int
oggz_dlist_append(OggzDList *dlist, void *elem);
void
int
oggz_dlist_prepend(OggzDList *dlist, void *elem);
void

Просмотреть файл

@ -180,11 +180,15 @@ oggz_io_flush (OGGZ * oggz)
/* get/set functions */
static void
static int
oggz_io_init (OGGZ * oggz)
{
oggz->io = (OggzIO *) oggz_malloc (sizeof (OggzIO));
if (oggz->io == NULL) return -1;
memset (oggz->io, 0, sizeof (OggzIO));
return 0;
}
int
@ -193,7 +197,10 @@ oggz_io_set_read (OGGZ * oggz, OggzIORead read, void * user_handle)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
if (oggz->io == NULL) oggz_io_init (oggz);
if (oggz->io == NULL) {
if (oggz_io_init (oggz) == -1)
return OGGZ_ERR_OUT_OF_MEMORY;
}
oggz->io->read = read;
oggz->io->read_user_handle = user_handle;
@ -218,7 +225,10 @@ oggz_io_set_write (OGGZ * oggz, OggzIOWrite write, void * user_handle)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
if (oggz->io == NULL) oggz_io_init (oggz);
if (oggz->io == NULL) {
if (oggz_io_init (oggz) == -1)
return OGGZ_ERR_OUT_OF_MEMORY;
}
oggz->io->write = write;
oggz->io->write_user_handle = user_handle;
@ -243,7 +253,10 @@ oggz_io_set_seek (OGGZ * oggz, OggzIOSeek seek, void * user_handle)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
if (oggz->io == NULL) oggz_io_init (oggz);
if (oggz->io == NULL) {
if (oggz_io_init (oggz) == -1)
return OGGZ_ERR_OUT_OF_MEMORY;
}
oggz->io->seek = seek;
oggz->io->seek_user_handle = user_handle;
@ -268,7 +281,10 @@ oggz_io_set_tell (OGGZ * oggz, OggzIOTell tell, void * user_handle)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
if (oggz->io == NULL) oggz_io_init (oggz);
if (oggz->io == NULL) {
if (oggz_io_init (oggz) == -1)
return OGGZ_ERR_OUT_OF_MEMORY;
}
oggz->io->tell = tell;
oggz->io->tell_user_handle = user_handle;
@ -293,7 +309,10 @@ oggz_io_set_flush (OGGZ * oggz, OggzIOFlush flush, void * user_handle)
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
if (oggz->io == NULL) oggz_io_init (oggz);
if (oggz->io == NULL) {
if (oggz_io_init (oggz) == -1)
return OGGZ_ERR_OUT_OF_MEMORY;
}
oggz->io->flush = flush;
oggz->io->flush_user_handle = user_handle;

Просмотреть файл

@ -44,6 +44,8 @@
#include "oggz_vector.h"
#include "oggz_dlist.h"
#define OGGZ_AUTO_MULT 1000Ull
typedef struct _OGGZ OGGZ;
typedef struct _OggzComment OggzComment;
typedef struct _OggzIO OggzIO;
@ -277,13 +279,18 @@ oggz_get_granulerate (OGGZ * oggz, long serialno,
ogg_int64_t * granulerate_d);
int oggz_set_granuleshift (OGGZ * oggz, long serialno, int granuleshift);
int oggz_get_granuleshift (OGGZ * oggz, long serialno);
int oggz_set_preroll (OGGZ * oggz, long serialno, int preroll);
int oggz_get_preroll (OGGZ * oggz, long serialno);
/* oggz_auto */
int
oggz_auto_get_granulerate (OGGZ * oggz, ogg_packet * op, long serialno,
oggz_auto_read_bos_page (OGGZ * oggz, ogg_page * og, long serialno,
void * user_data);
int
oggz_auto_read_bos_packet (OGGZ * oggz, ogg_packet * op, long serialno,
void * user_data);
int

Просмотреть файл

@ -124,12 +124,10 @@ oggz_set_read_callback (OGGZ * oggz, long serialno,
reader->read_user_data = user_data;
} else {
stream = oggz_get_stream (oggz, serialno);
#if 0
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
#else
if (stream == NULL)
stream = oggz_add_stream (oggz, serialno);
#endif
if (stream == NULL)
return OGGZ_ERR_OUT_OF_MEMORY;
stream->read_packet = read_packet;
stream->read_user_data = user_data;
@ -158,12 +156,10 @@ oggz_set_read_page (OGGZ * oggz, long serialno, OggzReadPage read_page,
reader->read_page_user_data = user_data;
} else {
stream = oggz_get_stream (oggz, serialno);
#if 0
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
#else
if (stream == NULL)
stream = oggz_add_stream (oggz, serialno);
#endif
if (stream == NULL)
return OGGZ_ERR_OUT_OF_MEMORY;
stream->read_page = read_page;
stream->read_page_user_data = user_data;
@ -173,9 +169,10 @@ oggz_set_read_page (OGGZ * oggz, long serialno, OggzReadPage read_page,
}
/*
* oggz_get_next_page_7 (oggz, og, do_read)
* oggz_read_get_next_page (oggz, og, do_read)
*
* MODIFIED COPY OF CODE FROM BELOW SEEKING STUFF
* This differs from oggz_get_next_page() in oggz_seek.c in that it
* does not attempt to call oggz_io_read() if the sync buffer is empty.
*
* retrieves the next page.
* returns >= 0 if found; return value is offset of page start
@ -183,12 +180,9 @@ oggz_set_read_page (OGGZ * oggz, long serialno, OggzReadPage read_page,
* returns -2 if EOF was encountered
*/
static oggz_off_t
oggz_get_next_page_7 (OGGZ * oggz, ogg_page * og)
oggz_read_get_next_page (OGGZ * oggz, ogg_page * og)
{
OggzReader * reader = &oggz->x.reader;
#if _UNMODIFIED
char * buffer;
#endif
long bytes = 0, more;
oggz_off_t page_offset = 0, ret;
int found = 0;
@ -198,25 +192,7 @@ oggz_get_next_page_7 (OGGZ * oggz, ogg_page * og)
if (more == 0) {
page_offset = 0;
#if _UMMODIFIED_
buffer = ogg_sync_buffer (&reader->ogg_sync, CHUNKSIZE);
if ((bytes = oggz_io_read (oggz, buffer, CHUNKSIZE)) == 0) {
#if 0
if (ferror (oggz->file)) {
oggz_set_error (oggz, OGGZ_ERR_SYSTEM);
return -1;
}
#endif
}
if (bytes == 0) {
return -2;
}
ogg_sync_wrote(&reader->ogg_sync, bytes);
#else
return -2;
#endif
} else if (more < 0) {
#ifdef DEBUG_VERBOSE
printf ("get_next_page: skipped %ld bytes\n", -more);
@ -258,9 +234,11 @@ oggz_read_new_pbuffer_entry(OGGZ *oggz, ogg_packet *packet,
ogg_int64_t granulepos, long serialno, oggz_stream_t * stream,
OggzReader *reader) {
OggzBufferedPacket *p = malloc(sizeof(OggzBufferedPacket));
OggzBufferedPacket *p = oggz_malloc(sizeof(OggzBufferedPacket));
if (p == NULL) return NULL;
memcpy(&(p->packet), packet, sizeof(ogg_packet));
p->packet.packet = malloc(packet->bytes);
p->packet.packet = oggz_malloc(packet->bytes);
memcpy(p->packet.packet, packet->packet, packet->bytes);
p->calced_granulepos = granulepos;
@ -275,8 +253,8 @@ oggz_read_new_pbuffer_entry(OGGZ *oggz, ogg_packet *packet,
void
oggz_read_free_pbuffer_entry(OggzBufferedPacket *p) {
free(p->packet.packet);
free(p);
oggz_free(p->packet.packet);
oggz_free(p);
}
@ -371,30 +349,36 @@ oggz_read_sync (OGGZ * oggz)
/* new stream ... check bos etc. */
if ((stream = oggz_add_stream (oggz, serialno)) == NULL) {
/* error -- could not add stream */
return -7;
return OGGZ_ERR_OUT_OF_MEMORY;
}
}
os = &stream->ogg_stream;
result = ogg_stream_packetout(os, op);
/*
* libogg flags "holes in the data" (which are really inconsistencies
* in the page sequence number) by returning -1.
*/
if(result == -1) {
#ifdef DEBUG
printf ("oggz_read_sync: hole in the data\n");
#endif
/* We can't tolerate holes in headers, so bail out. */
if (stream->packetno < 3) return OGGZ_ERR_HOLE_IN_DATA;
/* Holes in content occur in some files and pretty much don't matter,
* so we silently swallow the notification and reget the packet.
*/
result = ogg_stream_packetout(os, op);
if (result == -1) {
#ifdef DEBUG
/*
* libogg flags "holes in the data" (which are really
* inconsistencies in the page sequence number) by returning
* -1. This occurs in some files and pretty much doesn't matter,
* so we silently swallow the notification and reget the packet.
* If the result is *still* -1 then something strange is happening.
/* If the result is *still* -1 then something strange is
* happening.
*/
printf ("shouldn't get here");
#ifdef DEBUG
printf ("Multiple holes in data!");
#endif
return -7;
return OGGZ_ERR_HOLE_IN_DATA;
}
}
@ -418,7 +402,7 @@ oggz_read_sync (OGGZ * oggz)
(oggz->flags & OGGZ_AUTO)
)
{
oggz_auto_get_granulerate (oggz, op, serialno, NULL);
oggz_auto_read_bos_packet (oggz, op, serialno, NULL);
}
/* attempt to determine granulepos for this packet */
@ -511,7 +495,7 @@ oggz_read_sync (OGGZ * oggz)
/* If we've got a stop already, don't read more data in */
if (cb_ret == OGGZ_STOP_OK || cb_ret == OGGZ_STOP_ERR) return cb_ret;
if(oggz_get_next_page_7 (oggz, &og) < 0)
if(oggz_read_get_next_page (oggz, &og) < 0)
return OGGZ_READ_EMPTY; /* eof. leave uninitialized */
serialno = ogg_page_serialno (&og);
@ -523,11 +507,15 @@ oggz_read_sync (OGGZ * oggz)
/* new stream ... check bos etc. */
if ((stream = oggz_add_stream (oggz, serialno)) == NULL) {
/* error -- could not add stream */
return -7;
return OGGZ_ERR_OUT_OF_MEMORY;
}
/* identify stream type */
oggz_auto_identify_page (oggz, &og, serialno);
/* read bos data */
if (oggz->flags & OGGZ_AUTO)
oggz_auto_read_bos_page (oggz, &og, serialno, NULL);
}
else if (oggz_stream_get_content(oggz, serialno) == OGGZ_CONTENT_ANXDATA)
{
@ -560,12 +548,6 @@ oggz_read_sync (OGGZ * oggz)
reader->read_page (oggz, &og, serialno, reader->read_page_user_data);
}
#if 0
/* bitrate tracking; add the header's bytes here, the body bytes
are done by packet above */
vf->bittrack+=og.header_len*8;
#endif
ogg_stream_pagein(os, &og);
}
@ -594,28 +576,14 @@ oggz_read (OGGZ * oggz, long n)
reader = &oggz->x.reader;
cb_ret = oggz_read_sync (oggz);
#if 0
if (cb_ret == OGGZ_READ_EMPTY) {
/* If there's nothing to read yet, don't return 0 (eof) */
if (reader->current_unit == 0) cb_ret = 0;
else {
#if 0
printf ("oggz_read: EMPTY, current_unit %ld != 0\n",
reader->current_unit);
return 0;
#endif
}
}
#endif
if (cb_ret == OGGZ_ERR_OUT_OF_MEMORY)
return cb_ret;
while (cb_ret != OGGZ_STOP_ERR && cb_ret != OGGZ_STOP_OK &&
bytes_read > 0 && remaining > 0) {
bytes = MIN (remaining, CHUNKSIZE);
buffer = ogg_sync_buffer (&reader->ogg_sync, bytes);
if ((bytes_read = (long) oggz_io_read (oggz, buffer, bytes)) == 0) {
/* schyeah! */
}
bytes_read = (long) oggz_io_read (oggz, buffer, bytes);
if (bytes_read == OGGZ_ERR_SYSTEM) {
return OGGZ_ERR_SYSTEM;
}
@ -627,6 +595,8 @@ oggz_read (OGGZ * oggz, long n)
nread += bytes_read;
cb_ret = oggz_read_sync (oggz);
if (cb_ret == OGGZ_ERR_OUT_OF_MEMORY)
return cb_ret;
}
}
@ -678,14 +648,8 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
reader = &oggz->x.reader;
cb_ret = oggz_read_sync (oggz);
#if 0
if (cb_ret == OGGZ_READ_EMPTY) {
/* If there's nothing to read yet, don't return 0 (eof) */
if (reader->current_unit == 0) cb_ret = 0;
else return 0;
}
#endif
if (cb_ret == OGGZ_ERR_OUT_OF_MEMORY)
return cb_ret;
while (cb_ret != OGGZ_STOP_ERR && cb_ret != OGGZ_STOP_OK &&
/* !oggz->eos && */ remaining > 0) {
@ -699,6 +663,8 @@ oggz_read_input (OGGZ * oggz, unsigned char * buf, long n)
nread += bytes;
cb_ret = oggz_read_sync (oggz);
if (cb_ret == OGGZ_ERR_OUT_OF_MEMORY)
return cb_ret;
}
if (cb_ret == OGGZ_STOP_ERR) oggz_purge (oggz);

Просмотреть файл

@ -234,14 +234,6 @@ oggz_get_next_page (OGGZ * oggz, ogg_page * og)
printf ("get_next_page: bytes == 0, returning -2\n");
#endif
return -2;
#if 0
} else if (oggz->file && feof (oggz->file)) {
#ifdef DEBUG_VERBOSE
printf ("get_next_page: feof (oggz->file), returning -2\n");
#endif
clearerr (oggz->file);
return -2;
#endif
}
ogg_sync_wrote(&reader->ogg_sync, bytes);
@ -632,7 +624,7 @@ oggz_offset_end (OGGZ * oggz)
static ogg_int64_t
oggz_seek_set (OGGZ * oggz, ogg_int64_t unit_target)
{
OggzReader * reader = &oggz->x.reader;
OggzReader * reader;
oggz_off_t offset_orig, offset_at, offset_guess;
oggz_off_t offset_begin, offset_end = -1, offset_next;
ogg_int64_t granule_at;
@ -659,6 +651,8 @@ oggz_seek_set (OGGZ * oggz, ogg_int64_t unit_target)
return -1;
}
reader = &oggz->x.reader;
if (unit_target == reader->current_unit) {
#ifdef DEBUG
printf ("oggz_seek_set: unit_target == reader->current_unit, SKIP\n");
@ -843,7 +837,7 @@ oggz_seek_end (OGGZ * oggz, ogg_int64_t unit_offset)
off_t
oggz_seek (OGGZ * oggz, oggz_off_t offset, int whence)
{
OggzReader * reader = &oggz->x.reader;
OggzReader * reader;
ogg_int64_t units = -1;
if (oggz == NULL) return -1;
@ -853,7 +847,9 @@ oggz_seek (OGGZ * oggz, oggz_off_t offset, int whence)
}
if (offset == 0 && whence == SEEK_SET) units = 0;
reader = &oggz->x.reader;
if (!(offset == 0 && whence == SEEK_CUR)) {
/* Invalidate current_unit */
reader->current_unit = -1;
@ -865,7 +861,7 @@ oggz_seek (OGGZ * oggz, oggz_off_t offset, int whence)
ogg_int64_t
oggz_seek_units (OGGZ * oggz, ogg_int64_t units, int whence)
{
OggzReader * reader = &oggz->x.reader;
OggzReader * reader;
ogg_int64_t r;
@ -890,6 +886,8 @@ oggz_seek_units (OGGZ * oggz, ogg_int64_t units, int whence)
return -1;
}
reader = &oggz->x.reader;
switch (whence) {
case SEEK_SET:
r = oggz_seek_set (oggz, units);

Просмотреть файл

@ -90,3 +90,30 @@ oggz_stream_get_numheaders (OGGZ * oggz, long serialno)
return stream->numheaders;
}
int
oggz_set_preroll (OGGZ * oggz, long serialno, int preroll)
{
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->preroll = preroll;
return 0;
}
int
oggz_get_preroll (OGGZ * oggz, long serialno)
{
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;
return stream->preroll;
}

Просмотреть файл

@ -35,11 +35,15 @@
typedef struct _oggz_stream_t oggz_stream_t;
typedef int (*OggzReadBOS) (OGGZ * oggz, long serialno,
unsigned char * data, long length,
void * user_data);
typedef struct {
const char *bos_str;
int bos_str_len;
const char *content_type;
OggzReadPacket reader;
OggzReadBOS reader;
ogg_int64_t (*calculator)(ogg_int64_t now, oggz_stream_t *stream,
ogg_packet *op);
ogg_int64_t (*r_calculator)(ogg_int64_t next_packet_gp,

Просмотреть файл

@ -53,6 +53,8 @@ oggz_table_new (void)
OggzTable * table;
table = oggz_malloc (sizeof (OggzTable));
if (table == NULL) return NULL;
table->keys = oggz_vector_new ();
table->data = oggz_vector_new ();
@ -74,6 +76,8 @@ oggz_table_lookup (OggzTable * table, long key)
{
int i, size;
if (table == NULL) return NULL;
size = oggz_vector_size (table->keys);
for (i = 0; i < size; i++) {
if (oggz_vector_nth_l (table->keys, i) == key) {

Просмотреть файл

@ -82,6 +82,7 @@ oggz_vector_new (void)
OggzVector * vector;
vector = oggz_malloc (sizeof (OggzVector));
if (vector == NULL) return NULL;
vector->max_elements = 0;
vector->nr_elements = 0;
@ -270,7 +271,6 @@ oggz_vector_grow (OggzVector * vector)
if (new_elements == NULL) {
vector->nr_elements--;
vector->data = NULL;
return NULL;
}
@ -363,8 +363,7 @@ oggz_vector_remove_nth (OggzVector * vector, int n)
oggz_realloc (vector->data,
(size_t)new_max_elements * sizeof (oggz_data_t));
if (new_elements == NULL)
{
if (new_elements == NULL) {
vector->data = NULL;
return NULL;
}
@ -409,52 +408,13 @@ void *
oggz_vector_pop (OggzVector * vector)
{
void * data;
#if 0
void * new_elements;
int new_max_elements;
#endif
if (!vector || vector->data == NULL) return NULL;
if (vector == NULL || vector->data == NULL) return NULL;
data = vector->data[0].p;
#if 0
vector->nr_elements--;
if (vector->nr_elements == 0) {
oggz_vector_clear (vector);
} else {
#if 0
memmove (vector->data, &vector->data[1],
vector->nr_elements * sizeof (void *));
#else
{
int i;
for (i = 0; i < vector->nr_elements; i++) {
vector->data[i].p = vector->data[i+1].p;
}
}
#endif
if (vector->nr_elements < vector->max_elements/2) {
new_max_elements = vector->max_elements/2;
new_elements =
oggz_realloc (vector->data,
(size_t)new_max_elements * sizeof (oggz_data_t));
if (new_elements != NULL) {
vector->max_elements = new_max_elements;
vector->data = new_elements;
}
}
}
#else
oggz_vector_remove_nth (vector, 0);
#endif
return data;
}

Просмотреть файл

@ -40,9 +40,17 @@ typedef int (*OggzFunc1) (void * data, void *arg);
typedef int (*OggzFindFunc) (void * data, long serialno);
typedef int (*OggzCmpFunc) (const void * a, const void * b, void * user_data);
/**
* Create a new vector object.
* \retval a pointer to the new vector.
* \retval NULL on failure.
*/
OggzVector *
oggz_vector_new (void);
/**
* Destroy a vector object.
*/
void
oggz_vector_delete (OggzVector * vector);
@ -61,19 +69,41 @@ oggz_vector_nth_p (OggzVector * vector, int n);
long
oggz_vector_nth_l (OggzVector * vector, int n);
/**
* Call a function on each element of a vector, in order.
* \param vector The OggzVector to iterate over
* \param func The OggzFunc to be called on each element
* \retval 0 on success
*/
int
oggz_vector_foreach (OggzVector * vector, OggzFunc func);
/**
* Call a function with a userdata pointer on each element
* of a vector, in order. This allows the function to access
* shared data when operating on the element sequence.
* \param vector The OggzVector to iterate over
* \param func The OggzFunc1 to be called on each element
* \param arg The userdata pointer to be passed to the function
* along with the vector member
* \retval 0 on success
*/
int
oggz_vector_foreach1 (OggzVector * vector, OggzFunc1 func, void *arg);
/**
* Return the number of elements in a vector.
* \param vector The vector to query
* \retval The number of elements
*/
int
oggz_vector_size (OggzVector * vector);
/**
* Add an element to a vector. If the vector has a comparison function,
* the new element is inserted in sorted order, otherwise it is appended
* to the tail.
* to the tail. Use this function to add pointer elements to the vector.
* Use ogg_vector_insert_l for long values.
* \param vector An OggzVector
* \param data The new element to add
* \retval data If the element was successfully added
@ -82,6 +112,16 @@ oggz_vector_size (OggzVector * vector);
void *
oggz_vector_insert_p (OggzVector * vector, void * data);
/**
* Add an element to a vector. If the vector has a comparison function,
* the new element is inserted in sorted order, otherwise it is appended
* to the tail. Use this function to add long value elements to the
* vector. Use ogg_vector_insert_p for pointer values.
* \param vector An OggzVector
* \param ldata The new element to add
* \retval ldata If the element was successfully added
* \retval -1L If adding the element failed
*/
long
oggz_vector_insert_l (OggzVector * vector, long ldata);
@ -101,10 +141,29 @@ oggz_vector_remove_p (OggzVector * vector, void * data);
OggzVector *
oggz_vector_remove_l (OggzVector * vector, long ldata);
/**
* Set a comparison function for a vector.
* Vectors can be sorted, or stored in append order, depending on
* whether they have a comparison function defined. When a comparison
* function is first set, it will be used to sort the entire vector,
* and subsequence insertions will maintain the sort. If no comparison
* function is set, new elements are appended at the end of the vector.
* Call oggz_vector_set_cmp(vector, NULL, NULL) to remove the current
* comparison function. This does not affect the member order.
* \param vector the vector to associate the comparison function with
* \param compare the OggzCmpFunc to use for comparisons
* \param user_data private data pointer for the compare function
* \retval 0 on success
*/
int
oggz_vector_set_cmp (OggzVector * vector, OggzCmpFunc compare,
void * user_data);
/**
* Pop a member off a vector.
* \retval pointer to the popped member
* \retval NULL if the vector is empty
*/
void *
oggz_vector_pop (OggzVector * vector);

Просмотреть файл

@ -95,6 +95,7 @@ oggz_write_init (OGGZ * oggz)
writer->next_zpacket = NULL;
writer->packet_queue = oggz_vector_new ();
if (writer->packet_queue == NULL) return NULL;
#ifdef ZPACKET_CMP
/* XXX: comparison function should only kick in when a metric is set */
@ -209,7 +210,7 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
oggz_stream_t * stream;
oggz_writer_packet_t * packet;
ogg_packet * new_op;
unsigned char * new_buf;
unsigned char * new_buf = NULL;
int b_o_s, e_o_s, bos_auto;
int strict, prefix, suffix;
@ -231,13 +232,13 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
* ie. that it fits within 32 bits and does not equal the special value -1 */
if ((long)((ogg_int32_t)serialno) != serialno || serialno == -1) {
#ifdef DEBUG
printf ("oggz_write_feed: serialno %010ld\n", serialno);
printf ("oggz_write_feed: serialno %010lu\n", serialno);
#endif
return OGGZ_ERR_BAD_SERIALNO;
}
#ifdef DEBUG
printf ("oggz_write_feed: (%010ld) FLUSH: %d\n", serialno, flush);
printf ("oggz_write_feed: (%010lu) FLUSH: %d\n", serialno, flush);
#endif
/* Cache strict, prefix, suffix */
@ -260,6 +261,8 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
if (b_o_s || !strict || suffix) {
stream = oggz_add_stream (oggz, serialno);
if (stream == NULL)
return OGGZ_ERR_OUT_OF_MEMORY;
oggz_auto_identify_packet (oggz, op, serialno);
} else {
return OGGZ_ERR_BAD_SERIALNO;
@ -275,7 +278,9 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
if (strict) {
if (op->bytes < 0) return OGGZ_ERR_BAD_BYTES;
if (!suffix && b_o_s != stream->b_o_s) return OGGZ_ERR_BAD_B_O_S;
if (op->granulepos != -1 && op->granulepos < stream->granulepos)
if (op->granulepos != -1 && op->granulepos < stream->granulepos &&
/* Allow negative granulepos immediately after headers, for Dirac: */
!(stream->granulepos == 0 && op->granulepos < 0))
return OGGZ_ERR_BAD_GRANULEPOS;
/* Allow packetno == -1 to indicate oggz should fill it in; otherwise:
@ -294,7 +299,7 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
/* OK -- Update stream's memory of packet details */
if (!stream->metric && (oggz->flags & OGGZ_AUTO)) {
oggz_auto_get_granulerate (oggz, op, serialno, NULL);
oggz_auto_read_bos_packet (oggz, op, serialno, NULL);
}
stream->b_o_s = 0; /* The stream is henceforth no longer at bos */
@ -308,12 +313,18 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
/* Now set up the packet and add it to the queue */
if (guard == NULL) {
new_buf = oggz_malloc ((size_t)op->bytes);
if (new_buf == NULL) return OGGZ_ERR_OUT_OF_MEMORY;
memcpy (new_buf, op->packet, (size_t)op->bytes);
} else {
new_buf = op->packet;
}
packet = oggz_malloc (sizeof (oggz_writer_packet_t));
if (packet == NULL) {
if (guard == NULL && new_buf != NULL) oggz_free (new_buf);
return OGGZ_ERR_OUT_OF_MEMORY;
}
new_op = &packet->op;
new_op->packet = new_buf;
@ -375,13 +386,14 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
static long
oggz_page_init (OGGZ * oggz)
{
OggzWriter * writer = &oggz->x.writer;
OggzWriter * writer;
ogg_stream_state * os;
ogg_page * og;
int ret;
if (oggz == NULL) return -1;
writer = &oggz->x.writer;
os = writer->current_stream;
og = &oggz->current_page;
@ -416,13 +428,14 @@ oggz_page_init (OGGZ * oggz)
static long
oggz_packet_init (OGGZ * oggz, oggz_writer_packet_t * next_zpacket)
{
OggzWriter * writer = &oggz->x.writer;
OggzWriter * writer;
oggz_stream_t * stream;
ogg_stream_state * os;
ogg_packet * op;
if (oggz == NULL) return -1L;
writer = &oggz->x.writer;
writer->current_zpacket = next_zpacket;
op = &next_zpacket->op;
@ -451,12 +464,13 @@ oggz_packet_init (OGGZ * oggz, oggz_writer_packet_t * next_zpacket)
static long
oggz_page_copyout (OGGZ * oggz, unsigned char * buf, long n)
{
OggzWriter * writer = &oggz->x.writer;
OggzWriter * writer;
long h, b;
ogg_page * og;
if (oggz == NULL) return -1L;
writer = &oggz->x.writer;
og = &oggz->current_page;
h = MIN (n, og->header_len - writer->page_offset);
@ -493,7 +507,7 @@ oggz_page_copyout (OGGZ * oggz, unsigned char * buf, long n)
static long
oggz_page_writeout (OGGZ * oggz, long n)
{
OggzWriter * writer = &oggz->x.writer;
OggzWriter * writer;
long h, b, nwritten;
ogg_page * og;
@ -503,6 +517,7 @@ oggz_page_writeout (OGGZ * oggz, long n)
if (oggz == NULL) return -1L;
writer = &oggz->x.writer;
og = &oggz->current_page;
#ifdef OGGZ_WRITE_DIRECT
@ -654,7 +669,7 @@ oggz_writer_make_packet (OGGZ * oggz)
#ifdef DEBUG
printf("oggz_writer_make_packet: cb_ret is %d\n", cb_ret);
#endif
if (cb_ret == 0 && next_zpacket == NULL) return OGGZ_WRITE_EMPTY;
return cb_ret;
@ -668,7 +683,7 @@ oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
int active = 1, cb_ret = 0;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
writer = &oggz->x.writer;
if (!(oggz->flags & OGGZ_WRITE)) {
@ -820,7 +835,7 @@ oggz_write (OGGZ * oggz, long n)
* if we're out of packets because we're at the end of the file,
* we can't finish just yet. Instead we need to force a page flush,
* and write the page out. So we set flushing and no_more_packets to
* 1. This causes oggz_page_init to flush the page, then we
* 1. This causes oggz_page_init to flush the page, then we
* will switch the state to OGGZ_WRITING_PAGES, which will trigger
* the writing code below.
*/
@ -903,11 +918,13 @@ oggz_write (OGGZ * oggz, long n)
long
oggz_write_get_next_page_size (OGGZ * oggz)
{
OggzWriter * writer = &oggz->x.writer;
OggzWriter * writer;
ogg_page * og;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
writer = &oggz->x.writer;
if (!(oggz->flags & OGGZ_WRITE)) {
return OGGZ_ERR_INVALID;
}

Просмотреть файл

@ -40,9 +40,9 @@ sed s/\#include\ \"config.h\"/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\
sed s/\#include\ \"config.h\"/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\#else\\n\#include\ \"config.h\"\\n\#endif/g $1/src/liboggz/oggz_seek.c >./src/liboggz/oggz_seek.c
cp $1/src/liboggz/oggz_dlist.h ./src/liboggz/oggz_dlist.h
sed s/\#include\ \"config.h\"/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\#else\\n\#include\ \"config.h\"\\n\#endif/g $1/src/liboggz/metric_internal.c >./src/liboggz/metric_internal.c
cp $1/src/liboggz/dirac.h ./src/liboggz/dirac.h
sed s/\#include\ \"config.h\"/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\#else\\n\#include\ \"config.h\"\\n\#endif/g $1/src/liboggz/dirac.c >./src/liboggz/dirac.c
cp $1/AUTHORS ./AUTHORS
patch -p4 <seek.patch
patch -p4 <warning.patch
patch -p3 <oggz_off_t.patch
patch -p3 <wince.patch
patch -p4 <endian.patch
patch -p3 <endian.patch
patch -p4 <seek.patch

Просмотреть файл

@ -1,17 +0,0 @@
diff --git a/media/liboggz/src/liboggz/oggz_auto.c b/media/liboggz/src/liboggz/oggz_auto.c
index 6d83fa9..95ffe6c 100644
--- a/media/liboggz/src/liboggz/oggz_auto.c
+++ b/media/liboggz/src/liboggz/oggz_auto.c
@@ -809,10 +809,12 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
}
size_check += 1;
+#ifdef DEBUG
if (size_check != size)
{
printf("WARNING: size parsing failed for VORBIS mode packets\n");
}
+#endif
/*
* store mode size information in our info struct