diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 7e741e92f1..d61008fe6a 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -141,10 +141,8 @@ SYSTEM_ADD_ONS_MEDIA = cortex_audioadapter.media_addon ; SYSTEM_ADD_ONS_MEDIA_PLUGINS = $(GPL_ONLY)ac3_decoder aiff_reader asf_reader au_reader $(X86_ONLY)ffmpeg - mov_reader musepack ogg raw_decoder speex - $(X86_ONLY)ape_reader - # theora - vorbis wav_reader + mov_reader musepack raw_decoder $(X86_ONLY)ape_reader + wav_reader ; SYSTEM_ADD_ONS_PRINT = Canon\ LIPS3\ Compatible Canon\ LIPS4\ Compatible PCL5\ Compatible PCL6\ Compatible PDF\ Writer PS\ Compatible Preview diff --git a/src/add-ons/media/plugins/Jamfile b/src/add-ons/media/plugins/Jamfile index 3e6b93bfae..552bfcc3b3 100644 --- a/src/add-ons/media/plugins/Jamfile +++ b/src/add-ons/media/plugins/Jamfile @@ -12,11 +12,7 @@ SubInclude HAIKU_TOP src add-ons media plugins matroska ; SubInclude HAIKU_TOP src add-ons media plugins mov_reader ; SubInclude HAIKU_TOP src add-ons media plugins mp4_reader ; SubInclude HAIKU_TOP src add-ons media plugins musepack ; -SubInclude HAIKU_TOP src add-ons media plugins ogg ; SubInclude HAIKU_TOP src add-ons media plugins raw_decoder ; -SubInclude HAIKU_TOP src add-ons media plugins speex ; -#SubInclude HAIKU_TOP src add-ons media plugins theora ; -SubInclude HAIKU_TOP src add-ons media plugins vorbis ; SubInclude HAIKU_TOP src add-ons media plugins wav_reader ; # The following add-ons are GPL licensed, and can only be used with diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index baa495abab..3df5d581e6 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -446,6 +446,31 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex) description.family = B_WAV_FORMAT_FAMILY; codecTag = ' DTS'; break; + case CODEC_ID_THEORA: + // Use the same format description as the native Ogg + // reader and decoder did. + description.family = B_MISC_FORMAT_FAMILY; +// TODO: The rest of this plugin (Decoders/Encoders) does not support +// this yet, specifying it would throw off the format matching. +// description.u.misc.file_format = 'OggS'; + codecTag = 'theo'; + break; + case CODEC_ID_SPEEX: + // Use the same format description as the native Ogg + // reader and decoder did. + description.family = B_MISC_FORMAT_FAMILY; +// TODO: See above. +// description.u.misc.file_format = 'OggS'; + codecTag = 'spex'; + break; + case CODEC_ID_VORBIS: + // Use the same format description as the native Ogg + // reader and decoder did. + description.family = B_MISC_FORMAT_FAMILY; +// TODO: See above. +// description.u.misc.file_format = 'OggS'; + codecTag = 'vorb'; + break; default: fprintf(stderr, "ffmpeg codecTag is null, codec_id " "unknown 0x%x\n", codecContext->codec_id); @@ -627,6 +652,8 @@ if (format->u.encoded_video.output.field_rate == 50.0f) = codecContext->width; format->u.encoded_video.output.display.line_count = codecContext->height; + TRACE(" width/height: %d/%d\n", codecContext->width, + codecContext->height); format->u.encoded_video.output.display.bytes_per_row = 0; format->u.encoded_video.output.display.pixel_offset = 0; format->u.encoded_video.output.display.line_offset = 0; @@ -647,10 +674,10 @@ if (format->u.encoded_video.output.field_rate == 50.0f) } TRACE(" extradata_size: %d\n", codecContext->extradata_size); - TRACE(" intra_matrix: %p\n", codecContext->intra_matrix); - TRACE(" inter_matrix: %p\n", codecContext->inter_matrix); - TRACE(" get_buffer(): %p\n", codecContext->get_buffer); - TRACE(" release_buffer(): %p\n", codecContext->release_buffer); +// TRACE(" intra_matrix: %p\n", codecContext->intra_matrix); +// TRACE(" inter_matrix: %p\n", codecContext->inter_matrix); +// TRACE(" get_buffer(): %p\n", codecContext->get_buffer); +// TRACE(" release_buffer(): %p\n", codecContext->release_buffer); #ifdef TRACE_AVFORMAT_READER char formatString[512]; diff --git a/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp b/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp index 5c87860418..2c92c51be1 100644 --- a/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp +++ b/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp @@ -214,6 +214,10 @@ const struct codec_table gCodecTable[] = { {CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('IV31'), "Indeo 3"}, {CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('IV32'), "Indeo 3"}, + {CODEC_ID_THEORA, B_MEDIA_ENCODED_VIDEO, B_MISC_FORMAT_FAMILY, 'theo', "Theora"}, + {CODEC_ID_VORBIS, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'vorb', "Vorbis"}, + {CODEC_ID_SPEEX, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'spex', "Speex"}, + {CODEC_ID_VP3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'VP31', "On2 VP3"}, {CODEC_ID_VP6F, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'VP6F', "On2 VP6"}, diff --git a/src/add-ons/media/plugins/ffmpeg/DemuxerTable.cpp b/src/add-ons/media/plugins/ffmpeg/DemuxerTable.cpp index ec1dbdb46e..88351fa2f9 100644 --- a/src/add-ons/media/plugins/ffmpeg/DemuxerTable.cpp +++ b/src/add-ons/media/plugins/ffmpeg/DemuxerTable.cpp @@ -84,6 +84,13 @@ static const DemuxerFormat gDemuxerTable[] = { "nsv", "NSV (NullSoft Video File)", "video/nsv", B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY }, + { + // Works fine, expect for seeking in clips generated by + // native software when the video and audio stream are + // not interleaved. + "ogg", "Ogg", "video/ogg", + B_MISC_FORMAT_FAMILY, B_MISC_FORMAT_FAMILY + }, { // TODO: untested! "rm", "RM (RealVideo Clip)", "video/vnd.rn-realvideo", diff --git a/src/add-ons/media/plugins/ffmpeg/Jamfile b/src/add-ons/media/plugins/ffmpeg/Jamfile index 8b935e5d35..96fc5686fa 100644 --- a/src/add-ons/media/plugins/ffmpeg/Jamfile +++ b/src/add-ons/media/plugins/ffmpeg/Jamfile @@ -34,6 +34,7 @@ Addon ffmpeg : libswscale.a libvorbis_ffmpeg.a + libspeex_ffmpeg.a libtheora_ffmpeg.a libogg_ffmpeg.a @@ -109,5 +110,6 @@ SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavformat ; SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavutil ; SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libogg ; SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libswscale ; +SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libspeex ; SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libtheora ; SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libvorbis ; diff --git a/src/add-ons/media/plugins/ffmpeg/config.h b/src/add-ons/media/plugins/ffmpeg/config.h index c975c4c495..7749793455 100644 --- a/src/add-ons/media/plugins/ffmpeg/config.h +++ b/src/add-ons/media/plugins/ffmpeg/config.h @@ -195,7 +195,7 @@ #define CONFIG_LIBOPENJPEG 0 #define CONFIG_LIBRTMP 0 #define CONFIG_LIBSCHROEDINGER 0 -#define CONFIG_LIBSPEEX 0 +#define CONFIG_LIBSPEEX 1 #define CONFIG_LIBTHEORA 1 #define CONFIG_LIBVORBIS 1 #define CONFIG_LIBVPX 0 @@ -487,7 +487,7 @@ #define CONFIG_LIBOPENCORE_AMRWB_DECODER 0 #define CONFIG_LIBOPENJPEG_DECODER 0 #define CONFIG_LIBSCHROEDINGER_DECODER 0 -#define CONFIG_LIBSPEEX_DECODER 0 +#define CONFIG_LIBSPEEX_DECODER 1 #define CONFIG_LIBVPX_DECODER 0 #define CONFIG_ASV1_ENCODER 0 #define CONFIG_ASV2_ENCODER 0 diff --git a/src/add-ons/media/plugins/ffmpeg/libavcodec/Jamfile b/src/add-ons/media/plugins/ffmpeg/libavcodec/Jamfile index fc97c90d99..f73d6aca91 100644 --- a/src/add-ons/media/plugins/ffmpeg/libavcodec/Jamfile +++ b/src/add-ons/media/plugins/ffmpeg/libavcodec/Jamfile @@ -7,6 +7,7 @@ SubDirHdrs [ FDirName $(SUBDIR) .. libswscale ] ; SubDirSysHdrs [ FDirName $(SUBDIR) .. libogg include ] ; SubDirSysHdrs [ FDirName $(SUBDIR) .. libtheora include ] ; SubDirSysHdrs [ FDirName $(SUBDIR) .. libvorbis include ] ; +SubDirSysHdrs [ FDirName $(SUBDIR) .. libspeex include ] ; UseLibraryHeaders zlib ; @@ -188,6 +189,7 @@ StaticLibrary libavcodec.a : kmvc.c lcldec.c # lclenc.c + libspeexdec.c libtheoraenc.c libvorbis.c # ljpegenc.c @@ -373,6 +375,7 @@ StaticLibrary libavcodec.a : # per individual file. SourceHdrs libvorbis.c : [ FDirName $(SUBDIR) .. libvorbis include vorbis ] ; SourceHdrs libtheoraenc.c : [ FDirName $(SUBDIR) .. libtheora include theora ] ; +SourceHdrs libspeexdec.c : [ FDirName $(SUBDIR) .. libspeex include speex ] ; SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavcodec $(TARGET_ARCH) ; diff --git a/src/add-ons/media/plugins/ogg/Jamfile b/src/add-ons/media/plugins/ogg/Jamfile deleted file mode 100644 index 44da15b653..0000000000 --- a/src/add-ons/media/plugins/ogg/Jamfile +++ /dev/null @@ -1,24 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins ogg ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -UsePrivateHeaders media ; - -SubDirSysHdrs [ FDirName $(SUBDIR) libogg ] ; - -Addon ogg : - OggReaderPlugin.cpp - OggTrack.cpp - OggStream.cpp - OggSeekable.cpp - OggSpeexStream.cpp - OggSpeexSeekable.cpp - OggTheoraStream.cpp - OggTobiasStream.cpp - OggTobiasSeekable.cpp - OggVorbisStream.cpp - OggVorbisSeekable.cpp - : libogg.a be libmedia.so $(TARGET_LIBSTDC++) -; - -SubInclude HAIKU_TOP src add-ons media plugins ogg libogg ; diff --git a/src/add-ons/media/plugins/ogg/OggFormats.h b/src/add-ons/media/plugins/ogg/OggFormats.h deleted file mode 100644 index da537f01d2..0000000000 --- a/src/add-ons/media/plugins/ogg/OggFormats.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _OGG_FORMATS_H -#define _OGG_FORMATS_H - -//! for use in media_misc_description.file_format -const uint32 OGG_FILE_FORMAT = 'OggS'; - -//! for use in media_header.user_data_type -const uint32 OGG_PACKET_DATA_TYPE = 'OggP'; - -#endif // _OGG_FORMATS_H diff --git a/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp b/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp deleted file mode 100644 index 0e4983bba0..0000000000 --- a/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp +++ /dev/null @@ -1,418 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "OggReaderPlugin.h" -#include "OggStream.h" -#include "OggSeekable.h" - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -OggReader::OggReader() -{ - TRACE("OggReader::OggReader\n"); - ogg_sync_init(&fSync); - fSeekable = NULL; - fFile = NULL; - fPosition = 0; -} - - -OggReader::~OggReader() -{ - TRACE("OggReader::~OggReader\n"); - serialno_OggTrack_map::iterator i = fTracks.begin(); - while (i != fTracks.end()) { - serialno_OggTrack_map::iterator j = i; - i++; - delete j->second; - } - ogg_sync_clear(&fSync); -} - - -const char * -OggReader::Copyright() -{ - return "ogg reader, " B_UTF8_COPYRIGHT " by Andrew Bachmann"; -} - - -// the main page reading hook (stream friendly) -ssize_t -OggReader::ReadPage(bool first_page) -{ -// TRACE("OggReader::ReadPage\n"); - int read_size = (first_page ? 4096 : 4*B_PAGE_SIZE); - BAutolock autolock(fSyncLock); - ogg_page page; -retry: - int result = ogg_sync_pageout(&fSync, &page); // first read leftovers - while (result == 0) { - char * buffer = ogg_sync_buffer(&fSync, read_size); - ssize_t bytes = Source()->Read(buffer, read_size); - if (bytes == 0) { - TRACE("OggReader::GetPage: Read: no data\n"); - return B_LAST_BUFFER_ERROR; - } - if (bytes < 0) { - TRACE("OggReader::GetPage: Read: error\n"); - return bytes; - } - if (ogg_sync_wrote(&fSync, bytes) != 0) { - TRACE("OggReader::GetPage: ogg_sync_wrote failed?: error\n"); - return B_ERROR; - } - result = ogg_sync_pageout(&fSync, &page); - if (first_page && (result != 1)) { - TRACE("OggReader::GetPage: short first page not found: error\n"); - return B_ERROR; - } - } - if (result == -1) { - TRACE("OggReader::GetPage: ogg_sync_pageout: not synced: error\n"); - return B_ERROR; - } - if (ogg_page_version(&page) != 0) { - TRACE("OggReader::GetPage: ogg_page_version: error in page encoding: error\n"); - return B_ERROR; - } - long serialno = ogg_page_serialno(&page); - bool new_serialno = fTracks.find(serialno) == fTracks.end(); - if (new_serialno) { - // this is an unknown serialno - if (ogg_page_bos(&page) == 0) { - TRACE("OggReader::GetPage: non-bos page with unknown serialno\n"); -#ifdef STRICT_OGG - return B_ERROR; -#else - // silently discard non-bos packets with unknown serialno - goto retry; -#endif - } -#ifdef STRICT_OGG - if (ogg_page_continued(&page) != 0) { - TRACE("oggReader::GetPage: ogg_page_continued: continued page: not ogg\n"); - return B_ERROR; - } -#endif //STRICT_OGG - // this is a beginning of stream page - ogg_stream_state stream; - if (ogg_stream_init(&stream, serialno) != 0) { - TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n"); - return B_ERROR; - } - if (ogg_stream_pagein(&stream, &page) != 0) { - TRACE("oggReader::GetPage: ogg_stream_pagein: failed: error\n"); - return B_ERROR; - } - ogg_packet packet; - if (ogg_stream_packetout(&stream, &packet) != 1) { -#ifdef STRICT_OGG - return B_ERROR; -#endif //STRICT_OGG - } - if (fSeekable) { - fTracks[serialno] = OggSeekable::makeOggSeekable(fSeekable, &fSeekableLock, serialno, packet); - } else { - class Interface : public StreamInterface { - private: - OggReader * reader; - public: - Interface(OggReader * reader) { - this->reader = reader; - } - virtual ssize_t ReadPage() { - return reader->ReadPage(); - } - }; - fTracks[serialno] = OggStream::makeOggStream(new Interface(this), serialno, packet); - } - fCookies.push_back(serialno); - } - // this check ensures that we only push the initial pages into OggSeekables. - if (!fSeekable || new_serialno) { - status_t status = fTracks[serialno]->AddPage(fPosition, page); - if (status != B_OK) { - return status; - } - fPosition += page.header_len + page.body_len; - } - return page.header_len + page.body_len; -} - - -static BPositionIO * -get_seekable(BDataIO * data) -{ - // try to cast to BPositionIO then perform a series of - // sanity checks to ensure that seeking is reliable - BPositionIO * seekable = dynamic_cast(data); - if (seekable == 0) { - return 0; - } - // first try to get our current location - off_t current = seekable->Seek(0, SEEK_CUR); - if (current < 0) { - return 0; - } - // check it against position - if (current != seekable->Position()) { - return 0; - } - // next try to seek to our current location (absolutely) - if (seekable->Seek(current, SEEK_SET) < 0) { - return 0; - } - // next try to seek to the start of the stream (absolutely) - if (seekable->Seek(0, SEEK_SET) < 0) { - return 0; - } - // then seek back to where we started - if (seekable->Seek(current, SEEK_SET) < 0) { - // really screwed - return 0; - } - // next try to seek to the end of the stream (absolutely) - if (seekable->Seek(0, SEEK_END) < 0) { - return 0; - } - // then seek back to where we started - if (seekable->Seek(current, SEEK_SET) < 0) { - // really screwed - return 0; - } - return seekable; -} - - -static BFile * -get_file(BDataIO * data) -{ - // try to cast to BFile then perform a series of - // sanity checks to ensure that the file is okay - BFile * file = dynamic_cast(data); - if (file == 0) { - return 0; - } - if (file->InitCheck() != B_OK) { - return 0; - } - return file; -} - - -status_t -OggReader::Sniff(int32 *streamCount) -{ - TRACE("OggReader::Sniff\n"); -#ifdef STRICT_OGG - bool first_page = true; -#else - bool first_page = false; -#endif - fSeekable = get_seekable(Source()); - fFile = get_file(Source()); - - ssize_t bytes = ReadPage(first_page); - if (bytes < 0) { - return bytes; - } - uint count = 1; - while (count++ == fCookies.size()) { - ssize_t bytes = ReadPage(); - if (bytes < 0) { - return bytes; - } - } - if (fSeekable) { - status_t status = FindLastPages(); - if (status != B_OK) { - return status; - } - } - *streamCount = fCookies.size(); - return B_OK; -} - - -void -OggReader::GetFileFormatInfo(media_file_format *mff) -{ - TRACE("OggReader::GetFileFormatInfo\n"); - mff->capabilities = media_file_format::B_READABLE - | media_file_format::B_IMPERFECTLY_SEEKABLE - | media_file_format::B_KNOWS_ENCODED_VIDEO - | media_file_format::B_KNOWS_ENCODED_AUDIO - | media_file_format::B_KNOWS_OTHER; - mff->family = B_MISC_FORMAT_FAMILY; - mff->version = 100; - strcpy(mff->mime_type, "application/ogg"); - strcpy(mff->file_extension, "ogg"); - strcpy(mff->short_name, "Ogg"); - strcpy(mff->pretty_name, "Ogg bitstream"); -} - - -status_t -OggReader::AllocateCookie(int32 streamNumber, void **cookie) -{ - TRACE("OggReader::AllocateCookie %ld\n", streamNumber); - if (streamNumber < 0 || streamNumber > (signed)fCookies.size()) { - TRACE("OggReader::AllocateCookie: invalid streamNumber: bail\n"); - return B_ERROR; - } - OggTrack * track = fTracks[fCookies[streamNumber]]; - // store the cookie - *cookie = track; - return B_OK; -} - - -status_t -OggReader::FreeCookie(void *cookie) -{ - TRACE("OggReader::FreeCookie\n"); - return B_OK; -} - - -status_t -OggReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration, - media_format *format, const void **infoBuffer, size_t *infoSize) -{ - TRACE("OggReader::GetStreamInfo\n"); - *infoBuffer = 0; - *infoSize = 0; - OggTrack * track = static_cast(cookie); - status_t status = track->GetStreamInfo(frameCount, duration, format); - TRACE("OggReader::GetStreamInfo: cookie=%x, frame count = %lld, duration = %lld.%lld seconds\n", - *(int*)cookie, *frameCount, (*duration)/1000000, (*duration)%1000000); - return status; -} - - -status_t -OggReader::Seek(void *cookie, - uint32 seekTo, - int64 *frame, bigtime_t *time) -{ - TRACE("OggReader::Seek to %lld : %lld\n", *frame, *time); - OggTrack * track = static_cast(cookie); - return track->Seek(seekTo, frame, time); -} - - -status_t -OggReader::GetNextChunk(void *cookie, - const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ -// TRACE("OggReader::GetNextChunk\n"); - OggTrack * track = static_cast(cookie); - return track->GetNextChunk(chunkBuffer, chunkSize, mediaHeader); -} - - -status_t -OggReader::FindLastPages() -{ - TRACE("OggReader::FindLastPages\n"); - - status_t result = B_ERROR; - - const int read_size = 256*256; - - ogg_page page; - ogg_sync_state sync; - ogg_sync_init(&sync); - - off_t right = fSeekable->Seek(0, SEEK_END); - off_t left = right; - // we assume the common case is that the last pages are near the end - uint serial_count = 0; - while (serial_count < fCookies.size()) { - int offset; - ssize_t bytes = 0; - while ((offset = ogg_sync_pageseek(&sync, &page)) <= 0) { - left += -offset; - if (offset == 0) { - off_t pos = fSeekable->Position(); - if (pos >= right || bytes == 0) { - if (left == 0) { - TRACE("OggReader::FindLastPages: couldn't find some stream's page!!!\n"); - goto done; - } - left = max_c(0, left - read_size); - result = fSeekable->Seek(left, SEEK_SET); - if (result < 0) { - goto done; - } - ogg_sync_reset(&sync); - } - char * buffer = ogg_sync_buffer(&sync, read_size); - bytes = fSeekable->Read(buffer, read_size); - if (bytes < 0) { - TRACE("OggReader::FindLastPages: Read: error\n"); - result = bytes; - goto done; - } - if (ogg_sync_wrote(&sync, bytes) != 0) { - TRACE("OggReader::FindLastPages: ogg_sync_wrote failed?: error\n"); - goto done; - } - } - } - off_t current = left; - do { - // found a page at "current" - long serialno = ogg_page_serialno(&page); - OggSeekable * track = dynamic_cast(fTracks[serialno]); - if (track == 0) { - TRACE("OggReader::FindLastPages: unknown serialno == TODO: chaining?\n"); - } else { - if (track->GetLastPagePosition() == 0) { - serial_count++; - } - track->SetLastPagePosition(current); - } - current += page.header_len + page.body_len; - } while ((current < right) && (ogg_sync_pageout(&sync, &page) == 1)); - right = left; - ogg_sync_reset(&sync); - } - result = B_OK; -done: - ogg_sync_clear(&sync); - TRACE("OggReader::FindLastPages took %lld microseconds\n", system_time() - start_time); - - return result; -} - -/* - * OggReaderPlugin - */ - -Reader * -OggReaderPlugin::NewReader() -{ - return new OggReader; -} - - -MediaPlugin * -instantiate_plugin() -{ - return new OggReaderPlugin; -} diff --git a/src/add-ons/media/plugins/ogg/OggReaderPlugin.h b/src/add-ons/media/plugins/ogg/OggReaderPlugin.h deleted file mode 100644 index 46ea486a52..0000000000 --- a/src/add-ons/media/plugins/ogg/OggReaderPlugin.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _OGG_READER_PLUGIN_H -#define _OGG_READER_PLUGIN_H - -#include "ReaderPlugin.h" -#include "ogg/ogg.h" - -#include -#include - -class BFile; - -namespace BPrivate { namespace media { - -class OggTrack; - -typedef std::map serialno_OggTrack_map; -typedef std::vector serialno_vector; - -class OggReader : public Reader { -public: - OggReader(); - ~OggReader(); - - const char *Copyright(); - - status_t Sniff(int32 *streamCount); - - void GetFileFormatInfo(media_file_format *mff); - - status_t AllocateCookie(int32 streamNumber, void **cookie); - status_t FreeCookie(void *cookie); - - // delegated to OggTrack - status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration, - media_format *format, const void **infoBuffer, size_t *infoSize); - status_t Seek(void *cookie, uint32 seekTo, int64 *frame, bigtime_t *time); - status_t GetNextChunk(void *cookie, const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - -private: - status_t FindLastPages(); - - ogg_sync_state fSync; - BLocker fSyncLock; - serialno_OggTrack_map fTracks; - serialno_vector fCookies; - - BPositionIO * fSeekable; - BLocker fSeekableLock; - BFile * fFile; - - off_t fPosition; - - // interface for OggStreams - ssize_t ReadPage(bool first_page = false); - -public: - class StreamInterface { - public: - virtual ~StreamInterface() {}; - virtual ssize_t ReadPage() = 0; - }; -}; - -class OggReaderPlugin : public ReaderPlugin { -public: - Reader *NewReader(); -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_READER_PLUGIN_H diff --git a/src/add-ons/media/plugins/ogg/OggSeekable.cpp b/src/add-ons/media/plugins/ogg/OggSeekable.cpp deleted file mode 100644 index cbe5b5e40c..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSeekable.cpp +++ /dev/null @@ -1,506 +0,0 @@ -#include "OggSeekable.h" -#include "OggSpeexSeekable.h" -#include "OggTobiasSeekable.h" -#include "OggVorbisSeekable.h" -#include "OggFormats.h" -#include -#include -#include -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -/* - * OggSeekable codec identification and instantiation - */ - -/* static */ OggSeekable * -OggSeekable::makeOggSeekable(BPositionIO * positionIO, BLocker * positionLock, - long serialno, const ogg_packet & packet) -{ - TRACE("OggSeekable::makeOggSeekable\n"); - OggSeekable * stream; - if (OggVorbisSeekable::IsValidHeader(packet)) { - stream = new OggVorbisSeekable(serialno); - } else if (OggTobiasSeekable::IsValidHeader(packet)) { - stream = new OggTobiasSeekable(serialno); - } else if (OggSpeexSeekable::IsValidHeader(packet)) { - stream = new OggSpeexSeekable(serialno); -// } else if (OggTheoraSeekable::IsValidHeader(packet)) { -// stream = new OggTheoraSeekable(serialno); - } else { - stream = new OggSeekable(serialno); - } - stream->fPositionIO = positionIO; - stream->fPositionLock = positionLock; - return stream; -} - - -/* - * OggSeekable generic functions - */ - -OggSeekable::OggSeekable(long serialno) - : OggTrack(serialno) -{ - TRACE("OggSeekable::OggSeekable\n"); - ogg_sync_init(&fSync); - ogg_stream_init(&fStreamState,serialno); - fPosition = 0; - fLastPagePosition = 0; - - fCurrentFrame = 0; - fCurrentTime = 0; - fFirstGranulepos = 0; - fFrameRate = 0; -} - - -OggSeekable::~OggSeekable() -{ - // free internal stream state storage - ogg_sync_clear(&fSync); - ogg_stream_clear(&fStreamState); -} - - -static void -insert_position(std::vector & positions, off_t position) -{ - positions.push_back(position); -} - - -status_t -OggSeekable::AddPage(off_t position, const ogg_page & page) -{ - TRACE("OggSeekable::AddPage\n"); - insert_position(fPagePositions, position); - char * buffer; - // copy the header to our local sync - buffer = ogg_sync_buffer(&fSync, page.header_len); - memcpy(buffer, page.header, page.header_len); - ogg_sync_wrote(&fSync, page.header_len); - // copy the body to our local sync - buffer = ogg_sync_buffer(&fSync, page.body_len); - memcpy(buffer, page.body, page.body_len); - ogg_sync_wrote(&fSync, page.body_len); - fPosition = position + page.header_len + page.body_len; - return B_OK; -} - - -void -OggSeekable::SetLastPagePosition(off_t position) -{ - fLastPagePosition = max_c(fLastPagePosition, position); -} - - -off_t -OggSeekable::GetLastPagePosition() -{ - return fLastPagePosition; -} - - -off_t -OggSeekable::Seek(off_t position, int32 mode) -{ - BAutolock autolock(fPositionLock); - off_t result = fPositionIO->Seek(position, mode); - if (result >= 0) { - fPosition = result; - ogg_sync_reset(&fSync); - ogg_stream_reset(&fStreamState); - } - return result; -} - - -off_t -OggSeekable::Position(void) const -{ - return fPosition; -} - - -status_t -OggSeekable::GetSize(off_t * size) -{ - BAutolock autolock(fPositionLock); - off_t prior = fPositionIO->Position(); - off_t result = fPositionIO->Seek(0, SEEK_END); - fPositionIO->Seek(prior, SEEK_SET); - if (result >= 0) { - *size = result; - result = B_OK; - } - return result; -} - - -status_t -OggSeekable::ReadPage(ogg_page * page, int read_size) -{ -// TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - int result; - while ((result = ogg_sync_pageout(&fSync, page)) == 1) { - if (ogg_page_serialno(page) == GetSerial()) { - return B_OK; - } - } - BAutolock autolock(fPositionLock); - // align to page boundary -align: - int offset; - while ((offset = ogg_sync_pageseek(&fSync, page)) <= 0) { - if (offset == 0) { - char * buffer = ogg_sync_buffer(&fSync, read_size); - ssize_t bytes = fPositionIO->ReadAt(fPosition, buffer, read_size); - if (bytes == 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ReadAt: no data\n"); - return B_LAST_BUFFER_ERROR; - } - if (bytes < 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ReadAt: error\n"); - return bytes; - } - fPosition += bytes; - if (ogg_sync_wrote(&fSync, bytes) != 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ogg_sync_wrote failed?: error\n"); - return B_ERROR; - } - } - } - // repeat until this is one of our pages - while (ogg_page_serialno(page) != GetSerial()) { - int result; - // read the page - while ((result = ogg_sync_pageout(&fSync, page)) == 0) { - char * buffer = ogg_sync_buffer(&fSync, read_size); - ssize_t bytes = fPositionIO->ReadAt(fPosition, buffer, read_size); - if (bytes == 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ReadAt 2: no data\n"); - return B_LAST_BUFFER_ERROR; - } - if (bytes < 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ReadAt 2: error\n"); - return bytes; - } - fPosition += bytes; - if (ogg_sync_wrote(&fSync, bytes) != 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ogg_sync_wrote 2 failed?: error\n"); - return B_ERROR; - } - } - if (result == -1) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ogg_sync_pageout: not synced... attempt resync\n"); - goto align; - } - if (ogg_page_version(page) != 0) { - TRACE("OggSeekable::ReadPage (%llu)\n", fPosition); - TRACE("OggSeekable::ReadPage: ogg_page_version: error in page encoding??\n"); -#ifdef STRICT_OGG - return B_ERROR; -#endif - } - } - return B_OK; -} - - -status_t -OggSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggSeekable::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - TRACE("OggSeekable::GetStreamInfo failed to get header packet\n"); - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - TRACE("OggSeekable::GetStreamInfo failed : not beginning of stream\n"); - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet - uint32 four_bytes = *(uint32*)(&packet); - - // get the format for the description - media_format_description description; - description.family = B_MISC_FORMAT_FAMILY; - description.u.misc.file_format = OGG_FILE_FORMAT; - description.u.misc.codec = four_bytes; - BMediaFormats formats; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - // ignore the error, allow the user to use ReadChunk interface - } - - // fill out format from header packet - format->user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format->user_data, (char*)(&packet), 4); - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - *duration = 140000000; - *frameCount = 60000; - return B_OK; -} - -status_t -OggSeekable::Seek(uint32 seekTo, int64 *frame, bigtime_t *time) -{ - status_t status; - int64 granulepos; - if (seekTo & B_MEDIA_SEEK_TO_TIME) { - TRACE("OggSeekable::Seek: seek to time: %lld\n", *time); - if ((fFrameRate == 0) && (*time != 0)) { - TRACE("OggSeekable::Seek: fFrameRate unset, seek to non-zero time unsupported\n"); - return B_UNSUPPORTED; - } - granulepos = fFirstGranulepos + (int64) (*time * (long long)fFrameRate) / 1000000LL; - } else if (seekTo & B_MEDIA_SEEK_TO_FRAME) { - granulepos = fFirstGranulepos + *frame; - } else { - TRACE("OggSeekable::Seek: bad seekTo"); - return B_BAD_VALUE; - } - TRACE("OggSeekable::Seek: seek to granulepos: %lld\n", granulepos); - - // find the first packet with data in it - ogg_page page; - off_t left = 0; - BAutolock autolock(fPositionLock); - off_t pos = Seek(0, SEEK_SET); - if (pos < 0) { - TRACE("OggSeekable::Seek: Seek = %s\n", strerror(pos)); - return pos; - } - uint header_packets_left = GetHeaderPackets().size(); - while (header_packets_left > 0) { - status = ReadPage(&page, B_PAGE_SIZE); - if (status != B_OK) { - TRACE("OggSeekable::Seek: ReadPage = %s\n", strerror(status)); - return status; - } - header_packets_left -= ogg_page_packets(&page); - left += page.header_len + page.body_len; - } - TRACE("OggSeekable::Seek: header packets end after = %llu\n", left); - pos = Seek(left, SEEK_SET); - if (pos < 0) { - TRACE("OggSeekable::Seek: Seek2 = %s\n", strerror(pos)); - return pos; - } - status = ReadPage(&page, B_PAGE_SIZE); - if (status != B_OK) { - TRACE("OggSeekable::Seek: ReadPage2 = %s\n", strerror(status)); - return status; - } - if (ogg_page_continued(&page)) { - TRACE("OggSeekable::Seek: warning: data packet began in header page!\n"); - // how to handle this? - } - - int64 left_granulepos = 0; - int64 right_granulepos = 0; - // if not the first, perform a binary search - if (granulepos != fFirstGranulepos) { - // binary search to find our place - off_t right = GetLastPagePosition(); - // uint width = (uint)log10(max_c(1, fFirstGranulepos + right)) + 2; - while (true) { - ogg_sync_reset(&fSync); - ogg_stream_reset(&fStreamState); - if (right - left > B_PAGE_SIZE) { - TRACE(" Seek: [%*lld,%*lld]: ", width, left, width, right); - fPosition = (right + left) / 2; - } else { - TRACE(" Seek: [%*lld,...]\n", width, left); - fPosition = left; - break; - } - do { - status = ReadPage(&page, B_PAGE_SIZE); - if (status != B_OK) { - TRACE("OggSeekable::Seek: ReadPage = %s\n", strerror(status)); - return status; - } - if (ogg_stream_pagein(&fStreamState, &page) != 0) { - TRACE("OggSeekable::Seek: ogg_stream_pagein: failed??\n"); - return B_ERROR; - } - } while (ogg_page_granulepos(&page) == -1); - TRACE("granulepos = %*lld, ", width, ogg_page_granulepos(&page)); - TRACE("fPosition = %*llu\n", width, fPosition); - // check the granulepos of the page against the requested frame - if (ogg_page_granulepos(&page) < granulepos) { - // The packet that the frame is in is someplace after - // the last complete packet in this page. (It may yet - // be in this page, but in a packet completed on the - // next page.) - left = (right + left) / 2; - left_granulepos = ogg_page_granulepos(&page); - continue; - } else { - right = (right + left) / 2; - right_granulepos = ogg_page_granulepos(&page); - continue; - } - } - } - - // if not the first, look for a granulepos in a packet - if (granulepos != fFirstGranulepos) { - ogg_packet packet; - do { - status = GetPacket(&packet); - if (status != B_OK) { - TRACE("OggSeekable::Seek: GetPacket = %s\n", strerror(status)); - return status; - } - } while (packet.granulepos == -1); - granulepos = packet.granulepos; - fCurrentFrame = granulepos - fFirstGranulepos; - fCurrentTime = (1000000LL * fCurrentFrame) / (long long)fFrameRate; - } else { - fCurrentFrame = 0; - fCurrentTime = 0; - Seek(left, SEEK_SET); - } - TRACE("OggSeekable::Seek done: "); - TRACE("[%lld,%lld] => ", left_granulepos, right_granulepos); - TRACE("found frame %lld at time %llu\n", fCurrentFrame, fCurrentTime); - *frame = fCurrentFrame; - *time = fCurrentTime; - return B_OK; -} - - // The packet that the frame is in is someplace before or - // in the last complete packet in this page. (It may be in - // a prior page) -/* ogg_packet packet; - do { - switch (ogg_stream_packetpeek(&fStreamState, &packet)) { - case 1: // a packet found - break; - case 0: { // no packets found - status_t status = ReadPage(&page, B_PAGE_SIZE); - if (status != B_OK) { - TRACE("OggSeekable::Seek: ReadPage = %s\n", strerror(status)); - return status; - } - if (ogg_stream_pagein(&fStreamState, &page) != 0) { - TRACE("OggSeekable::Seek: ogg_stream_pagein: failed??\n"); - return B_ERROR; - } - continue; - default: // error condition - TRACE("OggSeekable::Seek: error peeking for packet\n"); - continue; - } - if (packet.granulepos == -1) { - // useless packet with no seek info, eat it - ogg_stream_packetout(&fStreamState, &packet); - } - } while (packet.granulepos == -1); - if (packet.granulepos -*/ -/* if (ogg_page_granulepos(&page) == *frame) { - // The frame is in the last packet to end on this page. - // If the last packet on this page was continued from - // the prior page, we might need to go back farther to - // get the whole packet. - if ((ogg_page_packets(&page) == 1) && - (ogg_page_continued(&page)) && - (ogg_stream_packetpeek(&fStreamState, NULL) != 1)) { - right = (right + left) / 2; - continue; - } - // The frame is the last frame in the last packet on - // this page. If there are more than 1 packet, discard - // all but the last and return. - for (int i = 0 ; i < packets - 1 ; i++) { - ogg_packet packet; - GetPacket(&packet); - } - return B_OK; - }*/ - -status_t -OggSeekable::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ - ogg_packet packet; - BAutolock autolock(fPositionLock); - status_t result = GetPacket(&packet); - *chunkBuffer = packet.packet; - *chunkSize = packet.bytes; - packet.packet = NULL; - assert(sizeof(ogg_packet) <= sizeof(mediaHeader->user_data)); - mediaHeader->user_data_type = OGG_PACKET_DATA_TYPE; - memcpy(mediaHeader->user_data, &packet, sizeof(ogg_packet)); - if (result != B_OK) { - TRACE("OggSeekable::GetNextChunk failed: GetPacket = %s\n", strerror(result)); - return result; - } - if (packet.granulepos > 0) { - fCurrentFrame = packet.granulepos - fFirstGranulepos; - fCurrentTime = (bigtime_t)((fCurrentFrame * 1000000LL) / fFrameRate); - mediaHeader->start_time = fCurrentTime; - } else { - mediaHeader->start_time = -1; - } - mediaHeader->file_pos = fPosition; - return B_OK; -} - - -// subclass pull input function -status_t -OggSeekable::GetPacket(ogg_packet * packet) -{ - // at the end, pull the packet - while (ogg_stream_packetpeek(&fStreamState, NULL) != 1) { - ogg_page page; - status_t status = ReadPage(&page); - if (status != B_OK) { - TRACE("OggSeekable::GetPacket: ReadPage = %s\n", strerror(status)); - return status; - } - if (ogg_stream_pagein(&fStreamState, &page) != 0) { - TRACE("OggSeekable::GetPacket: ogg_stream_pagein: failed??\n"); - return B_ERROR; - } - } - if (ogg_stream_packetout(&fStreamState, packet) != 1) { - TRACE("OggSeekable::GetPacket: ogg_stream_packetout failed\n"); - return B_ERROR; - } - return B_OK; -} - diff --git a/src/add-ons/media/plugins/ogg/OggSeekable.h b/src/add-ons/media/plugins/ogg/OggSeekable.h deleted file mode 100644 index 6df8de3945..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSeekable.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _OGG_SEEKABLE_H -#define _OGG_SEEKABLE_H - -#include "OggTrack.h" -#include "OggReaderPlugin.h" -#include - -namespace BPrivate { namespace media { - -class OggSeekable : public OggTrack { -public: - static OggSeekable * makeOggSeekable(BPositionIO * positionIO, BLocker * positionLock, - long serialno, const ogg_packet & packet); - - // interface for OggReader - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - virtual status_t Seek(uint32 seekTo, int64 *frame, bigtime_t *time); - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - -protected: - OggSeekable(long serialno); -public: - virtual ~OggSeekable(); - - // reader push input function - status_t AddPage(off_t position, const ogg_page & page); - - void SetLastPagePosition(off_t position); - off_t GetLastPagePosition(); -private: - off_t fLastPagePosition; - -protected: - off_t Seek(off_t position, int32 mode); - off_t Position(void) const; - status_t GetSize(off_t * size); - status_t ReadPage(ogg_page * page, int read_size = 4*B_PAGE_SIZE); - - // subclass pull input function - status_t GetPacket(ogg_packet * packet); - -protected: - int64 fCurrentFrame; - bigtime_t fCurrentTime; - - int64 fFirstGranulepos; - float fFrameRate; - -private: - off_t fPosition; - std::vector fPagePositions; - -private: - ogg_sync_state fSync; - ogg_stream_state fStreamState; - BPositionIO * fPositionIO; - BLocker fPositionLock; -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_SEEKABLE_H diff --git a/src/add-ons/media/plugins/ogg/OggSpeexFormats.h b/src/add-ons/media/plugins/ogg/OggSpeexFormats.h deleted file mode 100644 index a2e80c6913..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSpeexFormats.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _OGG_SPEEX_FORMATS_H -#define _OGG_SPEEX_FORMATS_H - -#include -#include -#include -#include "OggFormats.h" - -/* - * speex descriptions/formats - */ - - -static media_format_description -speex_description() -{ - media_format_description description; - description.family = B_MISC_FORMAT_FAMILY; - description.u.misc.file_format = OGG_FILE_FORMAT; - description.u.misc.codec = 'Spee'; - return description; -} - - -static void -init_speex_media_raw_audio_format(media_raw_audio_format * output) -{ - output->format = media_raw_audio_format::B_AUDIO_FLOAT; - output->byte_order = B_MEDIA_HOST_ENDIAN; -} - - -static media_format -speex_encoded_media_format() -{ - media_format format; - format.type = B_MEDIA_ENCODED_AUDIO; - format.user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format.user_data, "Spee", 4); - format.u.encoded_audio.frame_size = sizeof(ogg_packet); - init_speex_media_raw_audio_format(&format.u.encoded_audio.output); - return format; -} - - -#endif //_OGG_SPEEX_FORMATS_H diff --git a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp b/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp deleted file mode 100644 index 4defff8ae0..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "OggSpeexFormats.h" -#include "OggSpeexSeekable.h" -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * speex header from libspeex/speex_header.h - * also documented at http://www.speex.org/manual/node7.html#SECTION00073000000000000000 - */ - -typedef struct SpeexHeader { - char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */ - char speex_version[20]; /**< Speex version */ - int speex_version_id; /**< Version for Speex (for checking compatibility) */ - int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ - int rate; /**< Sampling rate used */ - int mode; /**< Mode used (0 for narrowband, 1 for wideband) */ - int mode_bitstream_version; /**< Version ID of the bit-stream */ - int nb_channels; /**< Number of channels encoded */ - int bitrate; /**< Bit-rate used */ - int frame_size; /**< Size of frames */ - int vbr; /**< 1 for a VBR encoding, 0 otherwise */ - int frames_per_packet; /**< Number of frames stored per Ogg packet */ - int extra_headers; /**< Number of additional headers after the comments */ - int reserved1; /**< Reserved for future use, must be zero */ - int reserved2; /**< Reserved for future use, must be zero */ -} SpeexHeader; - - -/* - * OggSpeexSeekable implementations - */ - -/* static */ bool -OggSpeexSeekable::IsValidHeader(const ogg_packet & packet) -{ - return findIdentifier(packet,"Speex ",0); -} - -OggSpeexSeekable::OggSpeexSeekable(long serialno) - : OggSeekable(serialno) -{ - TRACE("OggSpeexSeekable::OggSpeexSeekable\n"); -} - -OggSpeexSeekable::~OggSpeexSeekable() -{ - -} - -status_t -OggSpeexSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggSpeexSeekable::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - - // get header packet - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet, check size against struct minus optional fields - if (packet.bytes < 1 + (signed)sizeof(SpeexHeader) - 2*(signed)sizeof(int)) { - return B_ERROR; - } - void * data = &(packet.packet[0]); - SpeexHeader * header = (SpeexHeader *)data; - - // get the format for the description - media_format_description description = speex_description(); - BMediaFormats formats; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = speex_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - if (header->bitrate > 0) { - format->u.encoded_audio.bit_rate = header->bitrate; - } else { - // TODO: manually compute it where possible - } - if (header->nb_channels == 1) { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT; - } else { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; - } - fFrameRate = format->u.encoded_audio.output.frame_rate = header->rate; - format->u.encoded_audio.output.channel_count = header->nb_channels; - // allocate buffer, round up to nearest speex output_length size - int buffer_size = AudioBufferSize(&format->u.encoded_audio.output); - int output_length = header->frame_size * header->nb_channels * - (format->u.encoded_audio.output.format & 0xf); - buffer_size = ((buffer_size - 1) / output_length + 1) * output_length; - format->u.encoded_audio.output.buffer_size = buffer_size; - - // get comment packet - if (GetHeaderPackets().size() < 2) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - // get extra headers - while ((signed)GetHeaderPackets().size() < header->extra_headers) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - - // TODO: count the frames in the first page.. somehow.. :-/ - int64 frames = 0; - - ogg_page page; - // read the first page - result = ReadPage(&page); - if (result != B_OK) { - return result; - } - int64 fFirstGranulepos = ogg_page_granulepos(&page); - TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos); - // read our last page - off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET); - if (last < 0) { - return last; - } - result = ReadPage(&page); - if (result != B_OK) { - return result; - } - int64 last_granulepos = ogg_page_granulepos(&page); - - // seek back to the start - int64 frame = 0; - bigtime_t time = 0; - result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time); - if (result != B_OK) { - return result; - } - - // compute frame count and duration from sample count - frames = last_granulepos - fFirstGranulepos; - - *frameCount = frames; - *duration = (1000000LL * frames) / (long long)fFrameRate; - - return B_OK; -} diff --git a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h b/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h deleted file mode 100644 index cbe42466c5..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _OGG_SPEEX_SEEKABLE_H -#define _OGG_SPEEX_SEEKABLE_H - -#include "OggSeekable.h" - -namespace BPrivate { namespace media { - -class OggSpeexSeekable : public OggSeekable { -private: - typedef OggSeekable inherited; -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggSpeexSeekable(long serialno); - virtual ~OggSpeexSeekable(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_SPEEX_SEEKABLE_H diff --git a/src/add-ons/media/plugins/ogg/OggSpeexStream.cpp b/src/add-ons/media/plugins/ogg/OggSpeexStream.cpp deleted file mode 100644 index 58b3b23ed7..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSpeexStream.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "OggSpeexFormats.h" -#include "OggSpeexStream.h" -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * speex header from libspeex/speex_header.h - * also documented at http://www.speex.org/manual/node7.html#SECTION00073000000000000000 - */ - -typedef struct SpeexHeader { - char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */ - char speex_version[20]; /**< Speex version */ - int speex_version_id; /**< Version for Speex (for checking compatibility) */ - int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ - int rate; /**< Sampling rate used */ - int mode; /**< Mode used (0 for narrowband, 1 for wideband) */ - int mode_bitstream_version; /**< Version ID of the bit-stream */ - int nb_channels; /**< Number of channels encoded */ - int bitrate; /**< Bit-rate used */ - int frame_size; /**< Size of frames */ - int vbr; /**< 1 for a VBR encoding, 0 otherwise */ - int frames_per_packet; /**< Number of frames stored per Ogg packet */ - int extra_headers; /**< Number of additional headers after the comments */ - int reserved1; /**< Reserved for future use, must be zero */ - int reserved2; /**< Reserved for future use, must be zero */ -} SpeexHeader; - - -/* - * OggSpeexStream implementations - */ - -/* static */ bool -OggSpeexStream::IsValidHeader(const ogg_packet & packet) -{ - return findIdentifier(packet,"Speex ",0); -} - -OggSpeexStream::OggSpeexStream(long serialno) - : OggStream(serialno) -{ - TRACE("OggSpeexStream::OggSpeexStream\n"); -} - -OggSpeexStream::~OggSpeexStream() -{ - -} - -status_t -OggSpeexStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggSpeexStream::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - - // get header packet - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet, check size against struct minus optional fields - if (packet.bytes < 1 + (signed)sizeof(SpeexHeader) - 2*(signed)sizeof(int)) { - return B_ERROR; - } - void * data = &(packet.packet[0]); - SpeexHeader * header = (SpeexHeader *)data; - - // get the format for the description - media_format_description description = speex_description(); - BMediaFormats formats; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = speex_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - if (header->bitrate > 0) { - format->u.encoded_audio.bit_rate = header->bitrate; - } else { - // TODO: manually compute it where possible - } - if (header->nb_channels == 1) { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT; - } else { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; - } - format->u.encoded_audio.output.frame_rate = header->rate; - format->u.encoded_audio.output.channel_count = header->nb_channels; - // allocate buffer, round up to nearest speex output_length size - int buffer_size = AudioBufferSize(&format->u.encoded_audio.output); - int output_length = header->frame_size * header->nb_channels * - (format->u.encoded_audio.output.format & 0xf); - buffer_size = ((buffer_size - 1) / output_length + 1) * output_length; - format->u.encoded_audio.output.buffer_size = buffer_size; - - // get comment packet - if (GetHeaderPackets().size() < 2) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - // get extra headers - while ((signed)GetHeaderPackets().size() < header->extra_headers) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - *duration = 100000000; - *frameCount = 60000; - return B_OK; -} - - -status_t -OggSpeexStream::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ - status_t result = GetPacket(&fChunkPacket); - if (result != B_OK) { - TRACE("OggSpeexStream::GetNextChunk failed: GetPacket = %s\n", strerror(result)); - return result; - } - *chunkBuffer = fChunkPacket.packet; - *chunkSize = fChunkPacket.bytes; - return B_OK; -} diff --git a/src/add-ons/media/plugins/ogg/OggSpeexStream.h b/src/add-ons/media/plugins/ogg/OggSpeexStream.h deleted file mode 100644 index c74ab2a70d..0000000000 --- a/src/add-ons/media/plugins/ogg/OggSpeexStream.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _OGG_SPEEX_STREAM_H -#define _OGG_SPEEX_STREAM_H - -#include "OggStream.h" - -namespace BPrivate { namespace media { - -class OggSpeexStream : public OggStream { -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggSpeexStream(long serialno); - virtual ~OggSpeexStream(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_SPEEX_STREAM_H diff --git a/src/add-ons/media/plugins/ogg/OggStream.cpp b/src/add-ons/media/plugins/ogg/OggStream.cpp deleted file mode 100644 index 0fe267d711..0000000000 --- a/src/add-ons/media/plugins/ogg/OggStream.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "OggStream.h" -#include "OggSpeexStream.h" -#include "OggTheoraStream.h" -#include "OggTobiasStream.h" -#include "OggVorbisStream.h" -#include "OggFormats.h" -#include -#include -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -/* - * OggStream codec identification and instantiation - */ - -/* static */ OggStream * -OggStream::makeOggStream(OggReader::StreamInterface * interface, - long serialno, const ogg_packet & packet) -{ - TRACE("OggStream::makeOggStream\n"); - OggStream * stream; - if (OggVorbisStream::IsValidHeader(packet)) { - stream = new OggVorbisStream(serialno); - } else if (OggTobiasStream::IsValidHeader(packet)) { - stream = new OggTobiasStream(serialno); - } else if (OggSpeexStream::IsValidHeader(packet)) { - stream = new OggSpeexStream(serialno); - } else if (OggTheoraStream::IsValidHeader(packet)) { - stream = new OggTheoraStream(serialno); - } else { - stream = new OggStream(serialno); - } - stream->fReaderInterface = interface; - return stream; -} - - -/* - * OggStream generic functions - */ - -OggStream::OggStream(long serialno) - : OggTrack(serialno) -{ - TRACE("OggStream::OggStream\n"); - fCurrentFrame = 0; - fCurrentTime = 0; - ogg_sync_init(&fSync); - ogg_stream_init(&fStreamState,serialno); -} - - -OggStream::~OggStream() -{ - // free internal stream state storage - ogg_sync_clear(&fSync); - ogg_stream_clear(&fStreamState); -} - - -status_t -OggStream::AddPage(off_t position, const ogg_page & page) -{ -// TRACE("OggStream::AddPage\n"); - BAutolock autolock(fSyncLock); - char * buffer; - // copy the header to our local sync - buffer = ogg_sync_buffer(&fSync, page.header_len); - memcpy(buffer, page.header, page.header_len); - ogg_sync_wrote(&fSync, page.header_len); - // copy the body to our local sync - buffer = ogg_sync_buffer(&fSync, page.body_len); - memcpy(buffer, page.body, page.body_len); - ogg_sync_wrote(&fSync, page.body_len); - return B_OK; -} - - -status_t -OggStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggStream::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - TRACE("OggStream::GetStreamInfo failed to get header packet\n"); - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - TRACE("OggStream::GetStreamInfo failed : not beginning of stream\n"); - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet - uint32 four_bytes = *(uint32*)(&packet); - - // get the format for the description - media_format_description description; - description.family = B_MISC_FORMAT_FAMILY; - description.u.misc.file_format = OGG_FILE_FORMAT; - description.u.misc.codec = four_bytes; - BMediaFormats formats; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - // ignore the error, allow the user to use ReadChunk interface - } - - // fill out format from header packet - format->user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format->user_data, (char*)(&packet), 4); - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - *duration = 140000000; - *frameCount = 60000; - return B_OK; -} - - -// the default chunk is an ogg packet -status_t -OggStream::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ - status_t result = GetPacket(&fChunkPacket); - if (result != B_OK) { - TRACE("OggStream::GetNextChunk failed: GetPacket = %s\n", strerror(result)); - return result; - } - *chunkBuffer = &fChunkPacket; - *chunkSize = sizeof(fChunkPacket); - return B_OK; -} - - -// subclass pull input function -status_t -OggStream::GetPacket(ogg_packet * packet) -{ - // at the end, pull the packet - while (ogg_stream_packetpeek(&fStreamState, NULL) != 1) { - BAutolock autolock(fSyncLock); - int result; - ogg_page page; - while ((result = ogg_sync_pageout(&fSync,&page)) == 0) { - result = fReaderInterface->ReadPage(); - if (result < 0) { - TRACE("OggStream::GetPacket: GetNextPage = %s\n", strerror(result)); - return result; - } - } - if (result == -1) { - TRACE("OggStream::GetPacket: ogg_sync_pageout: not synced??\n"); - return B_ERROR; - } - if (ogg_stream_pagein(&fStreamState,&page) != 0) { - TRACE("OggStream::GetPacket: ogg_stream_pagein: failed??\n"); - return B_ERROR; - } - } - if (ogg_stream_packetout(&fStreamState, packet) != 1) { - TRACE("OggStream::GetPacket: ogg_stream_packetout failed\n"); - return B_ERROR; - } - return B_OK; -} - diff --git a/src/add-ons/media/plugins/ogg/OggStream.h b/src/add-ons/media/plugins/ogg/OggStream.h deleted file mode 100644 index 69f8c7956a..0000000000 --- a/src/add-ons/media/plugins/ogg/OggStream.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _OGG_STREAM_H -#define _OGG_STREAM_H - -#include "OggTrack.h" -#include "OggReaderPlugin.h" -#include - -namespace BPrivate { namespace media { - -class OggStream : public OggTrack { -public: - static OggStream * makeOggStream(OggReader::StreamInterface * interface, - long serialno, const ogg_packet & packet); - - // interface for OggReader - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - -protected: - OggStream(long serialno); -public: - virtual ~OggStream(); - - // reader push input function - virtual status_t AddPage(off_t position, const ogg_page & page); - -protected: - // subclass pull input function - status_t GetPacket(ogg_packet * packet); - ogg_packet fChunkPacket; - -protected: - int64 fCurrentFrame; - bigtime_t fCurrentTime; - -private: - ogg_sync_state fSync; - BLocker fSyncLock; - ogg_stream_state fStreamState; - OggReader::StreamInterface * fReaderInterface; -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_STREAM_H diff --git a/src/add-ons/media/plugins/ogg/OggTheoraFormats.h b/src/add-ons/media/plugins/ogg/OggTheoraFormats.h deleted file mode 100644 index b791bcd453..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTheoraFormats.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _OGG_THEORA_FORMATS_H -#define _OGG_THEORA_FORMATS_H - -#include -#include -#include -#include "OggFormats.h" - -/* - * theora descriptions/formats - */ - - -static media_format_description -theora_description() -{ - media_format_description description; - description.family = B_MISC_FORMAT_FAMILY; - description.u.misc.file_format = OGG_FILE_FORMAT; - description.u.misc.codec = 'theo'; - return description; -} - - -static void -init_theora_media_raw_video_format(media_raw_video_format * output) -{ -} - - -static media_format -theora_encoded_media_format() -{ - media_format format; - format.type = B_MEDIA_ENCODED_AUDIO; - format.user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format.user_data, "theo", 4); - init_theora_media_raw_video_format(&format.u.encoded_video.output); - return format; -} - - -#endif //_OGG_THEORA_FORMATS_H diff --git a/src/add-ons/media/plugins/ogg/OggTheoraStream.cpp b/src/add-ons/media/plugins/ogg/OggTheoraStream.cpp deleted file mode 100644 index 5e15289d8c..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTheoraStream.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include "OggTheoraFormats.h" -#include "OggTheoraStream.h" -#include -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * theora header parsing code from theora/theara.h - */ - -typedef enum { - OC_CS_UNSPECIFIED, - OC_CS_ITU_REC_470M, - OC_CS_ITU_REC_470BG, -} theora_colorspace; - -typedef struct { - ogg_uint32_t width; - ogg_uint32_t height; - ogg_uint32_t frame_width; - ogg_uint32_t frame_height; - ogg_uint32_t offset_x; - ogg_uint32_t offset_y; - ogg_uint32_t fps_numerator; - ogg_uint32_t fps_denominator; - ogg_uint32_t aspect_numerator; - ogg_uint32_t aspect_denominator; - theora_colorspace colorspace; - int target_bitrate; - int quality; - int quick_p; /* quick encode/decode */ - - /* decode only */ - unsigned char version_major; - unsigned char version_minor; - unsigned char version_subminor; - - void *codec_setup; - - /* encode only */ - int dropframes_p; - int keyframe_auto_p; - ogg_uint32_t keyframe_frequency; - ogg_uint32_t keyframe_frequency_force; /* also used for decode init to - get granpos shift correct */ - ogg_uint32_t keyframe_data_target_bitrate; - ogg_int32_t keyframe_auto_threshold; - ogg_uint32_t keyframe_mindistance; - ogg_int32_t noise_sensitivity; - ogg_int32_t sharpness; - -} theora_info; - -// based on theora/lib/toplevel.c _theora_unpack_info - -#define theora_read(x,y,z) ( *z = oggpack_read(x,y) ) - -#define OC_BADHEADER -1 - -static int _theora_unpack_info(theora_info *ci, oggpack_buffer *opb){ - long ret; - - theora_read(opb,8,&ret); - ci->version_major=(unsigned char)ret; - theora_read(opb,8,&ret); - ci->version_minor=(unsigned char)ret; - theora_read(opb,8,&ret); - ci->version_subminor=(unsigned char)ret; - -// if(ci->version_major!=VERSION_MAJOR)return(OC_VERSION); -// if(ci->version_minor>VERSION_MINOR)return(OC_VERSION); - - theora_read(opb,16,&ret); - ci->width=ret<<4; - theora_read(opb,16,&ret); - ci->height=ret<<4; - theora_read(opb,24,&ret); - ci->frame_width=ret; - theora_read(opb,24,&ret); - ci->frame_height=ret; - theora_read(opb,8,&ret); - ci->offset_x=ret; - theora_read(opb,8,&ret); - ci->offset_y=ret; - - theora_read(opb,32,&ret); - ci->fps_numerator=ret; - theora_read(opb,32,&ret); - ci->fps_denominator=ret; - theora_read(opb,24,&ret); - ci->aspect_numerator=ret; - theora_read(opb,24,&ret); - ci->aspect_denominator=ret; - - theora_read(opb,8,&ret); - ci->colorspace=(theora_colorspace)ret; - theora_read(opb,24,&ret); - ci->target_bitrate=ret; - theora_read(opb,6,&ret); - ci->quality=ret=ret; - - theora_read(opb,5,&ret); - ci->keyframe_frequency_force=1<u.encoded_video.frame_size = info.frame_width * info.frame_height ; - format->u.encoded_video.output.display.line_width = info.frame_width; - format->u.encoded_video.output.display.line_count = info.frame_height; - // TODO: wring more info out of the headers - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - *duration = 80000000; - *frameCount = 60000; - return B_OK; -} diff --git a/src/add-ons/media/plugins/ogg/OggTheoraStream.h b/src/add-ons/media/plugins/ogg/OggTheoraStream.h deleted file mode 100644 index 338fec39ef..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTheoraStream.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _OGG_THEORA_STREAM_H -#define _OGG_THEORA_STREAM_H - -#include "OggStream.h" - -namespace BPrivate { namespace media { - -class OggTheoraStream : public OggStream { -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggTheoraStream(long serialno); - virtual ~OggTheoraStream(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_THEORA_STREAM_H diff --git a/src/add-ons/media/plugins/ogg/OggTobiasFormats.h b/src/add-ons/media/plugins/ogg/OggTobiasFormats.h deleted file mode 100644 index b31e3f0635..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTobiasFormats.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _OGG_TOBIAS_FORMATS_H -#define _OGG_TOBIAS_FORMATS_H - -#include -#include -#include -#include "OggFormats.h" - -/* - * tobias descriptions/formats - */ - - -// video - -static media_format_description -tobias_video_description() -{ - media_format_description description; - description.family = B_AVI_FORMAT_FAMILY; - return description; -} - - -static void -init_tobias_media_raw_video_format(media_raw_video_format * output) -{ - -} - - -static media_format -tobias_video_encoded_media_format() -{ - media_format format; - format.type = B_MEDIA_ENCODED_VIDEO; - init_tobias_media_raw_video_format(&format.u.encoded_video.output); - return format; -} - -// audio - -static media_format_description -tobias_audio_description() -{ - media_format_description description; - description.family = B_WAV_FORMAT_FAMILY; - return description; -} - - -static void -init_tobias_media_raw_audio_format(media_raw_audio_format * output) -{ -} - - -static media_format -tobias_audio_encoded_media_format() -{ - media_format format; - format.type = B_MEDIA_ENCODED_AUDIO; - init_tobias_media_raw_audio_format(&format.u.encoded_audio.output); - return format; -} - - -// text - -static media_format_description -tobias_text_description() -{ - media_format_description description; - description.family = B_MISC_FORMAT_FAMILY; - description.u.misc.file_format = OGG_FILE_FORMAT; - description.u.misc.codec = 'text'; - return description; -} - - -static media_format -tobias_text_encoded_media_format() -{ - media_format format; - format.type = B_MEDIA_HTML; - format.user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format.user_data, "text", 4); - return format; -} - - -#endif // _OGG_TOBIAS_FORMATS_H diff --git a/src/add-ons/media/plugins/ogg/OggTobiasSeekable.cpp b/src/add-ons/media/plugins/ogg/OggTobiasSeekable.cpp deleted file mode 100644 index 2c5d73bdd1..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTobiasSeekable.cpp +++ /dev/null @@ -1,318 +0,0 @@ -#include "OggTobiasFormats.h" -#include "OggTobiasSeekable.h" -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * tobias header structs from http://tobias.everwicked.com/packfmt.htm - */ - -typedef struct tobias_stream_header_video -{ - ogg_int32_t width; - ogg_int32_t height; -} tobias_stream_header_video; - -typedef struct tobias_stream_header_audio -{ - ogg_int16_t channels; - ogg_int16_t blockalign; - ogg_int32_t avgbytespersec; -} tobias_stream_header_audio; - -typedef struct tobias_stream_header -{ - char streamtype[8]; - char subtype[4]; - - ogg_int32_t size; // size of the structure - - ogg_int64_t time_unit; // in reference time (100 ns units) - ogg_int64_t samples_per_unit; - ogg_int32_t default_len; // in media time - - ogg_int32_t buffersize; - ogg_int16_t bits_per_sample; - - union { - // Video specific - tobias_stream_header_video video; - // Audio specific - tobias_stream_header_audio audio; - }; -} tobias_stream_header; - -/* - * OggTobiasSeekable implementations - */ - -/* static */ bool -OggTobiasSeekable::IsValidHeader(const ogg_packet & packet) -{ - return findIdentifier(packet,"video",1) - || findIdentifier(packet,"audio",1) - || findIdentifier(packet,"text",1); -} - - -OggTobiasSeekable::OggTobiasSeekable(long serialno) - : OggSeekable(serialno) -{ - TRACE("OggTobiasSeekable::OggTobiasSeekable\n"); - fMicrosecPerFrame = 0; -} - - -OggTobiasSeekable::~OggTobiasSeekable() -{ - TRACE("OggTobiasSeekable::~OggTobiasSeekable\n"); -} - - -static status_t -get_video_format(tobias_stream_header * header, media_format * format) -{ - TRACE(" get_video_format\n"); - // get the format for the description - media_format_description description = tobias_video_description(); - description.u.avi.codec = header->subtype[3] << 24 | header->subtype[2] << 16 - | header->subtype[1] << 8 | header->subtype[0]; - BMediaFormats formats; - status_t result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = tobias_video_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - format->user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format->user_data, header->subtype, 4); - format->u.encoded_video.frame_size - = header->video.width * header->video.height; - format->u.encoded_video.output.field_rate = 10000000.0 / header->time_unit; - format->u.encoded_video.output.interlace = 1; - format->u.encoded_video.output.first_active = 0; - format->u.encoded_video.output.last_active = header->video.height - 1; - format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT; - format->u.encoded_video.output.pixel_width_aspect = 1; - format->u.encoded_video.output.pixel_height_aspect = 1; - format->u.encoded_video.output.display.line_width = header->video.width; - format->u.encoded_video.output.display.line_count = header->video.height; - format->u.encoded_video.output.display.bytes_per_row = 0; - format->u.encoded_video.output.display.pixel_offset = 0; - format->u.encoded_video.output.display.line_offset = 0; - format->u.encoded_video.output.display.flags = 0; - - // TODO: wring more info out of the headers - return B_OK; -} - - -static status_t -get_audio_format(tobias_stream_header * header, media_format * format) -{ - TRACE(" get_audio_format\n"); - // get the format for the description - media_format_description description = tobias_audio_description(); - unsigned int wav_id = 0; - sscanf(header->subtype, "%04x", &wav_id); - description.u.wav.codec = wav_id; - BMediaFormats formats; - status_t result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = tobias_audio_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - format->user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format->user_data, header->subtype, 4); - format->u.encoded_audio.bit_rate = header->audio.avgbytespersec * 8; - if (header->audio.channels == 1) { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT; - } else { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; - } - format->u.encoded_audio.output.frame_rate = header->samples_per_unit * 10000000.0 / header->time_unit; - format->u.encoded_audio.output.channel_count = header->audio.channels; - format->u.encoded_audio.output.buffer_size - = AudioBufferSize(&format->u.encoded_audio.output); - - // TODO: wring more info out of the headers - - return B_OK; -} - - -static status_t -get_text_format(tobias_stream_header * header, media_format * format) -{ - TRACE(" get_text_format\n"); - // get the format for the description - media_format_description description = tobias_text_description(); - BMediaFormats formats; - status_t result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = tobias_text_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - - return B_OK; -} - - -status_t -OggTobiasSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggTobiasSeekable::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - - // get header packet - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet - if (packet.bytes < 1+(signed)sizeof(tobias_stream_header)) { - return B_ERROR; - } - void * data = &(packet.packet[1]); - tobias_stream_header * header = (tobias_stream_header *)data; - - if (strcmp(header->streamtype, "video") == 0) { - result = get_video_format(header, format); - if (result != B_OK) { - return result; - } - } else if (strcmp(header->streamtype, "audio") == 0) { - result = get_audio_format(header, format); - if (result != B_OK) { - return result; - } - } else if (strcmp(header->streamtype, "text") == 0) { - result = get_text_format(header, format); - if (result != B_OK) { - return result; - } - } else { - *frameCount = 0; - // unknown streamtype - return B_BAD_VALUE; - } - - // get comment packet - if (GetHeaderPackets().size() < 2) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - fMediaFormat = *format; - fMicrosecPerFrame = header->time_unit / 10.0; - fFrameRate = header->samples_per_unit * 1000000.0 / fMicrosecPerFrame; - - // TODO: count the frames in the first page.. somehow.. :-/ - int64 frames = 0; - - ogg_page page; - // read the first page - result = ReadPage(&page); - if (result != B_OK) { - return result; - } - int64 fFirstGranulepos = ogg_page_granulepos(&page); - TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos); - // read our last page - off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET); - if (last < 0) { - return last; - } - result = ReadPage(&page); - if (result != B_OK) { - return result; - } - int64 last_granulepos = ogg_page_granulepos(&page); - - // seek back to the start - int64 frame = 0; - bigtime_t time = 0; - result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time); - if (result != B_OK) { - return result; - } - - // compute frame count and duration from sample count - frames = last_granulepos - fFirstGranulepos; - - *frameCount = frames; - *duration = (long long)((1000000LL * frames) / (double)fFrameRate); - return B_OK; -} - - -status_t -OggTobiasSeekable::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ - status_t result = inherited::GetNextChunk(chunkBuffer, chunkSize, mediaHeader); - if (result != B_OK) { - TRACE("OggTobiasSeekable::GetNextChunk failed: GetNextChunk = %s\n", strerror(result)); - return result; - } - bool keyframe = ((uint*)chunkBuffer)[0] & (1 << 3); // ?? - if (fMediaFormat.type == B_MEDIA_ENCODED_VIDEO) { - mediaHeader->type = fMediaFormat.type; - mediaHeader->u.encoded_video.field_flags = (keyframe ? B_MEDIA_KEY_FRAME : 0); - mediaHeader->u.encoded_video.first_active_line - = fMediaFormat.u.encoded_video.output.first_active; - mediaHeader->u.encoded_video.line_count - = fMediaFormat.u.encoded_video.output.display.line_count; - } - if (fMediaFormat.type == B_MEDIA_ENCODED_AUDIO) { - mediaHeader->type = fMediaFormat.type; - } - if (mediaHeader->start_time < 0) { - fCurrentFrame++; - fCurrentTime = (bigtime_t)((fCurrentFrame * 1000000LL) / fFrameRate); - mediaHeader->start_time = fCurrentTime; - } -// fprintf(stderr, "current frame = %lld, time = %lld\n", fCurrentFrame, fCurrentTime); - return B_OK; -} diff --git a/src/add-ons/media/plugins/ogg/OggTobiasSeekable.h b/src/add-ons/media/plugins/ogg/OggTobiasSeekable.h deleted file mode 100644 index d7688d5e09..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTobiasSeekable.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _OGG_TOBIAS_SEEKABLE_H -#define _OGG_TOBIAS_SEEKABLE_H - -#include "OggSeekable.h" - -namespace BPrivate { namespace media { - -class OggTobiasSeekable : public OggSeekable { -private: - typedef OggSeekable inherited; -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggTobiasSeekable(long serialno); - virtual ~OggTobiasSeekable(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - -private: - media_format fMediaFormat; - double fMicrosecPerFrame; -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_TOBIAS_SEEKABLE_H diff --git a/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp b/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp deleted file mode 100644 index 277d262b49..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "OggTobiasFormats.h" -#include "OggTobiasStream.h" -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * tobias header structs from http://tobias.everwicked.com/packfmt.htm - */ - -typedef struct tobias_stream_header_video -{ - ogg_int32_t width; - ogg_int32_t height; -} tobias_stream_header_video; - -typedef struct tobias_stream_header_audio -{ - ogg_int16_t channels; - ogg_int16_t blockalign; - ogg_int32_t avgbytespersec; -} tobias_stream_header_audio; - -typedef struct tobias_stream_header -{ - char streamtype[8]; - char subtype[4]; - - ogg_int32_t size; // size of the structure - - ogg_int64_t time_unit; // in reference time (100 ns units) - ogg_int64_t samples_per_unit; - ogg_int32_t default_len; // in media time - - ogg_int32_t buffersize; - ogg_int16_t bits_per_sample; - - union { - // Video specific - tobias_stream_header_video video; - // Audio specific - tobias_stream_header_audio audio; - }; -} tobias_stream_header; - -/* - * OggTobiasStream implementations - */ - -/* static */ bool -OggTobiasStream::IsValidHeader(const ogg_packet & packet) -{ - return findIdentifier(packet,"video",1) - || findIdentifier(packet,"audio",1) - || findIdentifier(packet,"text",1); -} - - -OggTobiasStream::OggTobiasStream(long serialno) - : OggStream(serialno) -{ - TRACE("OggTobiasStream::OggTobiasStream\n"); - fMicrosecPerFrame = 0; -} - - -OggTobiasStream::~OggTobiasStream() -{ - TRACE("OggTobiasStream::~OggTobiasStream\n"); -} - - -static status_t -get_video_format(tobias_stream_header * header, media_format * format) -{ - TRACE(" get_video_format\n"); - // get the format for the description - media_format_description description = tobias_video_description(); - description.u.avi.codec = header->subtype[3] << 24 | header->subtype[2] << 16 - | header->subtype[1] << 8 | header->subtype[0]; - BMediaFormats formats; - status_t result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = tobias_video_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - format->user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format->user_data, header->subtype, 4); - format->u.encoded_video.frame_size - = header->video.width * header->video.height; - format->u.encoded_video.output.field_rate = 10000000.0 / header->time_unit; - format->u.encoded_video.output.interlace = 1; - format->u.encoded_video.output.first_active = 0; - format->u.encoded_video.output.last_active = header->video.height - 1; - format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT; - format->u.encoded_video.output.pixel_width_aspect = 1; - format->u.encoded_video.output.pixel_height_aspect = 1; - format->u.encoded_video.output.display.line_width = header->video.width; - format->u.encoded_video.output.display.line_count = header->video.height; - format->u.encoded_video.output.display.bytes_per_row = 0; - format->u.encoded_video.output.display.pixel_offset = 0; - format->u.encoded_video.output.display.line_offset = 0; - format->u.encoded_video.output.display.flags = 0; - - // TODO: wring more info out of the headers - return B_OK; -} - - -static status_t -get_audio_format(tobias_stream_header * header, media_format * format) -{ - TRACE(" get_audio_format\n"); - debugger("get_audio_format"); - return B_UNSUPPORTED; -} - - -static status_t -get_text_format(tobias_stream_header * header, media_format * format) -{ - TRACE(" get_text_format\n"); - // get the format for the description - media_format_description description = tobias_text_description(); - BMediaFormats formats; - status_t result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = tobias_text_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - - return B_OK; -} - - -status_t -OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggTobiasStream::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - - // get header packet - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet - if (packet.bytes < 1+(signed)sizeof(tobias_stream_header)) { - return B_ERROR; - } - void * data = &(packet.packet[1]); - tobias_stream_header * header = (tobias_stream_header *)data; - - if (strcmp(header->streamtype, "video") == 0) { - result = get_video_format(header, format); - if (result != B_OK) { - return result; - } - *frameCount = (bigtime_t)(3 * 3600 * format->u.encoded_video.output.field_rate); - } else if (strcmp(header->streamtype, "audio") == 0) { - result = get_audio_format(header, format); - if (result != B_OK) { - return result; - } - *frameCount = 2000000; - } else if (strcmp(header->streamtype, "text") == 0) { - result = get_text_format(header, format); - if (result != B_OK) { - return result; - } - *frameCount = 2000000; - } else { - *frameCount = 0; - // unknown streamtype - return B_BAD_VALUE; - } - - // get comment packet - if (GetHeaderPackets().size() < 2) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - fMediaFormat = *format; - fMicrosecPerFrame = header->time_unit / 10.0; - *duration = (bigtime_t)(*frameCount * fMicrosecPerFrame); - return B_OK; -} - - -status_t -OggTobiasStream::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ - status_t result = GetPacket(&fChunkPacket); - if (result != B_OK) { - TRACE("OggTobiasStream::GetNextChunk failed: GetPacket = %s\n", strerror(result)); - return result; - } - *chunkBuffer = fChunkPacket.packet; - *chunkSize = fChunkPacket.bytes; - bool keyframe = fChunkPacket.packet[0] & (1 << 3); // ?? - if (fMediaFormat.type == B_MEDIA_ENCODED_VIDEO) { - mediaHeader->type = fMediaFormat.type; - mediaHeader->start_time = fCurrentTime; - mediaHeader->u.encoded_video.field_flags = (keyframe ? B_MEDIA_KEY_FRAME : 0); - mediaHeader->u.encoded_video.first_active_line - = fMediaFormat.u.encoded_video.output.first_active; - mediaHeader->u.encoded_video.line_count - = fMediaFormat.u.encoded_video.output.display.line_count; - } - fCurrentFrame++; - fCurrentTime = (bigtime_t)(fCurrentFrame * fMicrosecPerFrame); - return B_OK; -} - - -status_t -OggTobiasStream::AddPage(off_t position, const ogg_page & page) -{ - status_t status = OggStream::AddPage(position, page); - if (fMediaFormat.type == B_MEDIA_HTML) { - ogg_packet packet; - GetPacket(&packet); - if (packet.bytes > 4) { - fprintf(stderr, "%s\n", &(packet.packet[3])); - } - } - return status; -} diff --git a/src/add-ons/media/plugins/ogg/OggTobiasStream.h b/src/add-ons/media/plugins/ogg/OggTobiasStream.h deleted file mode 100644 index e3ed0b7504..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTobiasStream.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _OGG_TOBIAS_STREAM_H -#define _OGG_TOBIAS_STREAM_H - -#include "OggStream.h" - -namespace BPrivate { namespace media { - -class OggTobiasStream : public OggStream { -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggTobiasStream(long serialno); - virtual ~OggTobiasStream(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - - // reader push input function - virtual status_t AddPage(off_t position, const ogg_page & page); - -private: - media_format fMediaFormat; - double fMicrosecPerFrame; -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_TOBIAS_STREAM_H diff --git a/src/add-ons/media/plugins/ogg/OggTrack.cpp b/src/add-ons/media/plugins/ogg/OggTrack.cpp deleted file mode 100644 index 525ba6d232..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTrack.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "OggTrack.h" -#include -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -/* static */ bool -OggTrack::findIdentifier(const ogg_packet & packet, const char * id, uint pos) -{ - uint length = strlen(id); - if ((unsigned)packet.bytes < pos+length) { - return false; - } - return !memcmp(&packet.packet[pos], id, length); -} - - -OggTrack::OggTrack(long serialno) -{ - TRACE("OggTrack::OggTrack\n"); - fSerialno = serialno; -} - - -OggTrack::~OggTrack() -{ - // free internal header packet storage - std::vector::iterator iter = fHeaderPackets.begin(); - while (iter != fHeaderPackets.end()) { - delete iter->packet; - iter++; - } -} - - -long -OggTrack::GetSerial() const -{ - return fSerialno; -} - - -status_t -OggTrack::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - *frameCount = 0; - *duration = 0; - media_format f; - *format = f; - return B_UNSUPPORTED; -} - - -status_t -OggTrack::Seek(uint32 seekTo, int64 *frame, bigtime_t *time) -{ - *frame = 0; - *time = 0; - return B_UNSUPPORTED; -} - - -status_t -OggTrack::GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) -{ - *chunkBuffer = 0; - *chunkSize = 0; - media_header mh; - *mediaHeader = mh; - return B_UNSUPPORTED; -} - - -// GetStreamInfo helpers -void -OggTrack::SaveHeaderPacket(ogg_packet packet) -{ - uint8 * buffer = new uint8[packet.bytes]; - memcpy(buffer, packet.packet, packet.bytes); - packet.packet = buffer; - fHeaderPackets.push_back(packet); -} - - -const std::vector & -OggTrack::GetHeaderPackets() -{ - return fHeaderPackets; -} diff --git a/src/add-ons/media/plugins/ogg/OggTrack.h b/src/add-ons/media/plugins/ogg/OggTrack.h deleted file mode 100644 index aa53a33ab5..0000000000 --- a/src/add-ons/media/plugins/ogg/OggTrack.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _OGG_TRACK_H -#define _OGG_TRACK_H - -#include -#include -#include "ogg/ogg.h" -#include - -namespace BPrivate { namespace media { - -class OggTrack { -protected: - static bool findIdentifier(const ogg_packet & packet, - const char * id, uint pos); - OggTrack(long serialno); -public: - virtual ~OggTrack(); - long GetSerial() const; - - // push interface - virtual status_t AddPage(off_t position, const ogg_page & page) = 0; - - // interface for OggReader - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); - virtual status_t Seek(uint32 seekTo, int64 *frame, bigtime_t *time); - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); - -protected: - // GetStreamInfo helpers - void SaveHeaderPacket(ogg_packet packet); - const std::vector & GetHeaderPackets(); - -private: - std::vector fHeaderPackets; - long fSerialno; -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_TRACK_H diff --git a/src/add-ons/media/plugins/ogg/OggVorbisFormats.h b/src/add-ons/media/plugins/ogg/OggVorbisFormats.h deleted file mode 100644 index 083e3f21d3..0000000000 --- a/src/add-ons/media/plugins/ogg/OggVorbisFormats.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _OGG_VORBIS_FORMATS_H -#define _OGG_VORBIS_FORMATS_H - -#include -#include -#include -#include "OggFormats.h" - -/* - * vorbis descriptions/formats - */ - - -static media_format_description -vorbis_description() -{ - media_format_description description; - description.family = B_MISC_FORMAT_FAMILY; - description.u.misc.file_format = OGG_FILE_FORMAT; - description.u.misc.codec = 'vorb'; - return description; -} - - -static void -init_vorbis_media_raw_audio_format(media_raw_audio_format * output) -{ - output->format = media_raw_audio_format::B_AUDIO_FLOAT; - output->byte_order = B_MEDIA_HOST_ENDIAN; -} - - -static media_format -vorbis_encoded_media_format() -{ - media_format format; - format.type = B_MEDIA_ENCODED_AUDIO; - format.user_data_type = B_CODEC_TYPE_INFO; - strncpy((char*)format.user_data, "vorb", 4); - format.u.encoded_audio.frame_size = sizeof(ogg_packet); - init_vorbis_media_raw_audio_format(&format.u.encoded_audio.output); - return format; -} - - -#endif //_OGG_VORBIS_FORMATS_H diff --git a/src/add-ons/media/plugins/ogg/OggVorbisSeekable.cpp b/src/add-ons/media/plugins/ogg/OggVorbisSeekable.cpp deleted file mode 100644 index 2e0d488c1b..0000000000 --- a/src/add-ons/media/plugins/ogg/OggVorbisSeekable.cpp +++ /dev/null @@ -1,230 +0,0 @@ -#include "OggVorbisFormats.h" -#include "OggVorbisSeekable.h" -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * vorbis header parsing code from libvorbis/info.c - */ - -typedef struct vorbis_info{ - int version; - int channels; - long rate; - - /* The below bitrate declarations are *hints*. - Combinations of the three values carry the following implications: - - all three set to the same value: - implies a fixed rate bitstream - only nominal set: - implies a VBR stream that averages the nominal bitrate. No hard - upper/lower limit - upper and or lower set: - implies a VBR bitstream that obeys the bitrate limits. nominal - may also be set to give a nominal rate. - none set: - the coder does not care to speculate. - */ - - long bitrate_upper; - long bitrate_nominal; - long bitrate_lower; - long bitrate_window; - - void *codec_setup; -} vorbis_info; - - -// based on libvorbis/info.c _vorbis_unpack_info -static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ - vi->version = oggpack_read(opb, 32); - if (vi->version != 0) { - return -1; - } - vi->channels = oggpack_read(opb, 8); - vi->rate = oggpack_read(opb, 32); - vi->bitrate_upper = oggpack_read(opb, 32); - vi->bitrate_nominal = oggpack_read(opb, 32); - vi->bitrate_lower = oggpack_read(opb, 32); - long blocksizes0 = oggpack_read(opb, 4); - long blocksizes1 = oggpack_read(opb, 4); - if (vi->rate < 1) { - return -1; - } - if (vi->channels < 1) { - return -1; - } - if (blocksizes0 < 8) { - return -1; - } - if (blocksizes1 < blocksizes0) { - return -1; - } - if (oggpack_read(opb, 1) != 1) { - return -1; - } /* EOP check */ - return 0; -} - - -/* - * OggVorbisSeekable implementations - */ - -/* static */ bool -OggVorbisSeekable::IsValidHeader(const ogg_packet & packet) -{ - return findIdentifier(packet,"vorbis",1); -} - -OggVorbisSeekable::OggVorbisSeekable(long serialno) - : OggSeekable(serialno) -{ - TRACE("OggVorbisSeekable::OggVorbisSeekable\n"); -} - -OggVorbisSeekable::~OggVorbisSeekable() -{ - TRACE("OggVorbisSeekable::~OggVorbisSeekable\n"); -} - -status_t -OggVorbisSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggVorbisSeekable::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - - // get header packet - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet - // based on libvorbis/info.c vorbis_synthesis_headerin(...) - oggpack_buffer opb; - oggpack_readinit(&opb, packet.packet, packet.bytes); - int packtype = oggpack_read(&opb, 8); - if (packtype != 0x01) { - return B_ERROR; // first packet was not an info packet - } - // discard vorbis string - for (uint i = 0 ; i < sizeof("vorbis") - 1 ; i++) { - oggpack_read(&opb, 8); - } - vorbis_info info; - if (_vorbis_unpack_info(&info, &opb) != 0) { - return B_ERROR; // couldn't unpack info - } - - // get the format for the description - media_format_description description = vorbis_description(); - BMediaFormats formats; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = vorbis_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - if (info.bitrate_nominal > 0) { - format->u.encoded_audio.bit_rate = info.bitrate_nominal; - } else if (info.bitrate_upper > 0) { - format->u.encoded_audio.bit_rate = info.bitrate_upper; - } else if (info.bitrate_lower > 0) { - format->u.encoded_audio.bit_rate = info.bitrate_lower; - } - if (info.channels == 1) { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT; - } else { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; - } - fFrameRate = format->u.encoded_audio.output.frame_rate = (float)info.rate; - format->u.encoded_audio.output.channel_count = info.channels; - format->u.encoded_audio.output.buffer_size - = AudioBufferSize(&format->u.encoded_audio.output); - - // get comment packet - if (GetHeaderPackets().size() < 2) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - // get codebook packet - if (GetHeaderPackets().size() < 3) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - - // TODO: count the frames in the first page.. somehow.. :-/ - int64 frames = 0; - - ogg_page page; - // read the first page - result = ReadPage(&page); - if (result != B_OK) { - return result; - } - int64 fFirstGranulepos = ogg_page_granulepos(&page); - TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos); - // read our last page - off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET); - if (last < 0) { - return last; - } - result = ReadPage(&page); - if (result != B_OK) { - return result; - } - int64 last_granulepos = ogg_page_granulepos(&page); - - // seek back to the start - int64 frame = 0; - bigtime_t time = 0; - result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time); - if (result != B_OK) { - return result; - } - - // compute frame count and duration from sample count - frames = last_granulepos - fFirstGranulepos; - - *frameCount = frames; - *duration = (1000000LL * frames) / (long long)fFrameRate; - - return B_OK; -} diff --git a/src/add-ons/media/plugins/ogg/OggVorbisSeekable.h b/src/add-ons/media/plugins/ogg/OggVorbisSeekable.h deleted file mode 100644 index 76081c71ef..0000000000 --- a/src/add-ons/media/plugins/ogg/OggVorbisSeekable.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _OGG_VORBIS_SEEKABLE_H -#define _OGG_VORBIS_SEEKABLE_H - -#include "OggSeekable.h" - -namespace BPrivate { namespace media { - -class OggVorbisSeekable : public OggSeekable { -private: - typedef OggSeekable inherited; -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggVorbisSeekable(long serialno); - virtual ~OggVorbisSeekable(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_VORBIS_SEEKABLE_H diff --git a/src/add-ons/media/plugins/ogg/OggVorbisStream.cpp b/src/add-ons/media/plugins/ogg/OggVorbisStream.cpp deleted file mode 100644 index c240492106..0000000000 --- a/src/add-ons/media/plugins/ogg/OggVorbisStream.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "OggVorbisFormats.h" -#include "OggVorbisStream.h" -#include - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) ((void)0) -#endif - -inline size_t -AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - return (raf->format & 0xf) * (raf->channel_count) - * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); -} - -/* - * vorbis header parsing code from libvorbis/info.c - */ - -typedef struct vorbis_info{ - int version; - int channels; - long rate; - - /* The below bitrate declarations are *hints*. - Combinations of the three values carry the following implications: - - all three set to the same value: - implies a fixed rate bitstream - only nominal set: - implies a VBR stream that averages the nominal bitrate. No hard - upper/lower limit - upper and or lower set: - implies a VBR bitstream that obeys the bitrate limits. nominal - may also be set to give a nominal rate. - none set: - the coder does not care to speculate. - */ - - long bitrate_upper; - long bitrate_nominal; - long bitrate_lower; - long bitrate_window; - - void *codec_setup; -} vorbis_info; - -// based on libvorbis/info.c _vorbis_unpack_info -static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ - vi->version = oggpack_read(opb, 32); - if (vi->version != 0) { - return -1; - } - vi->channels = oggpack_read(opb, 8); - vi->rate = oggpack_read(opb, 32); - vi->bitrate_upper = oggpack_read(opb, 32); - vi->bitrate_nominal = oggpack_read(opb, 32); - vi->bitrate_lower = oggpack_read(opb, 32); - long blocksizes0 = oggpack_read(opb, 4); - long blocksizes1 = oggpack_read(opb, 4); - if (vi->rate < 1) { - return -1; - } - if (vi->channels < 1) { - return -1; - } - if (blocksizes0 < 8) { - return -1; - } - if (blocksizes1 < blocksizes0) { - return -1; - } - if (oggpack_read(opb, 1) != 1) { - return -1; - } /* EOP check */ - return 0; -} - -/* - * OggVorbisStream implementations - */ - -/* static */ bool -OggVorbisStream::IsValidHeader(const ogg_packet & packet) -{ - return findIdentifier(packet,"vorbis",1); -} - -OggVorbisStream::OggVorbisStream(long serialno) - : OggStream(serialno) -{ - TRACE("OggVorbisStream::OggVorbisStream\n"); -} - -OggVorbisStream::~OggVorbisStream() -{ - TRACE("OggVorbisStream::~OggVorbisStream\n"); -} - -status_t -OggVorbisStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format) -{ - TRACE("OggVorbisStream::GetStreamInfo\n"); - status_t result = B_OK; - ogg_packet packet; - - // get header packet - if (GetHeaderPackets().size() < 1) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - packet = GetHeaderPackets()[0]; - if (!packet.b_o_s) { - return B_ERROR; // first packet was not beginning of stream - } - - // parse header packet - // based on libvorbis/info.c vorbis_synthesis_headerin(...) - oggpack_buffer opb; - oggpack_readinit(&opb, packet.packet, packet.bytes); - int packtype = oggpack_read(&opb, 8); - if (packtype != 0x01) { - return B_ERROR; // first packet was not an info packet - } - // discard vorbis string - for (uint i = 0 ; i < sizeof("vorbis") - 1 ; i++) { - oggpack_read(&opb, 8); - } - vorbis_info info; - if (_vorbis_unpack_info(&info, &opb) != 0) { - return B_ERROR; // couldn't unpack info - } - - // get the format for the description - media_format_description description = vorbis_description(); - BMediaFormats formats; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } - if (result != B_OK) { - *format = vorbis_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface - } - - // fill out format from header packet - if (info.bitrate_nominal > 0) { - format->u.encoded_audio.bit_rate = info.bitrate_nominal; - } else if (info.bitrate_upper > 0) { - format->u.encoded_audio.bit_rate = info.bitrate_upper; - } else if (info.bitrate_lower > 0) { - format->u.encoded_audio.bit_rate = info.bitrate_lower; - } - if (info.channels == 1) { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT; - } else { - format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; - } - format->u.encoded_audio.output.frame_rate = (float)info.rate; - format->u.encoded_audio.output.channel_count = info.channels; - format->u.encoded_audio.output.buffer_size - = AudioBufferSize(&format->u.encoded_audio.output); - - // get comment packet - if (GetHeaderPackets().size() < 2) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - // get codebook packet - if (GetHeaderPackets().size() < 3) { - result = GetPacket(&packet); - if (result != B_OK) { - return result; - } - SaveHeaderPacket(packet); - } - - format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - - // compute frame count and duration from sample count - *duration = 5 * 60 * 1000000; - *frameCount = *duration * (long long)format->u.encoded_audio.output.frame_rate; - - return B_OK; -} diff --git a/src/add-ons/media/plugins/ogg/OggVorbisStream.h b/src/add-ons/media/plugins/ogg/OggVorbisStream.h deleted file mode 100644 index 7d13c7712a..0000000000 --- a/src/add-ons/media/plugins/ogg/OggVorbisStream.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _OGG_VORBIS_STREAM_H -#define _OGG_VORBIS_STREAM_H - -#include "OggStream.h" - -namespace BPrivate { namespace media { - -class OggVorbisStream : public OggStream { -public: - static bool IsValidHeader(const ogg_packet & packet); -public: - OggVorbisStream(long serialno); - virtual ~OggVorbisStream(); - - virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration, - media_format *format); -}; - -} } // namespace BPrivate::media - -using namespace BPrivate::media; - -#endif // _OGG_VORBIS_STREAM_H diff --git a/src/add-ons/media/plugins/ogg/libogg/AUTHORS b/src/add-ons/media/plugins/ogg/libogg/AUTHORS deleted file mode 100644 index 80c787cb8d..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -Monty - -and the rest of the Xiph.Org Foundation. - diff --git a/src/add-ons/media/plugins/ogg/libogg/CHANGES b/src/add-ons/media/plugins/ogg/libogg/CHANGES deleted file mode 100644 index 965e795a10..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/CHANGES +++ /dev/null @@ -1,2 +0,0 @@ -- Sat Sep 02 2000 Jack Moffitt - + separated from vorbis diff --git a/src/add-ons/media/plugins/ogg/libogg/COPYING b/src/add-ons/media/plugins/ogg/libogg/COPYING deleted file mode 100644 index 6111c6c5a6..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2002, Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/add-ons/media/plugins/ogg/libogg/Jamfile b/src/add-ons/media/plugins/ogg/libogg/Jamfile deleted file mode 100644 index 0c78b265e5..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins ogg libogg ; - -SubDirSysHdrs $(SUBDIR) ; - -StaticLibrary libogg.a : - bitwise.c - framing.c -; diff --git a/src/add-ons/media/plugins/ogg/libogg/bitwise.c b/src/add-ons/media/plugins/ogg/libogg/bitwise.c deleted file mode 100644 index 151e42bd4a..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/bitwise.c +++ /dev/null @@ -1,782 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: packing variable sized words into an octet stream - last mod: $Id: bitwise.c 6729 2004-02-24 13:52:39Z shatty $ - - ********************************************************************/ - -/* We're 'LSb' endian; if we write a word but read individual bits, - then we'll read the lsb first */ - -#include -#include -#include - -#define BUFFER_INCREMENT 256 - -static unsigned long mask[]= -{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, - 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, - 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, - 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, - 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, - 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, - 0x3fffffff,0x7fffffff,0xffffffff }; - -static unsigned int mask8B[]= -{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; - -void oggpack_writeinit(oggpack_buffer *b){ - memset(b,0,sizeof(*b)); - b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); - b->buffer[0]='\0'; - b->storage=BUFFER_INCREMENT; -} - -void oggpackB_writeinit(oggpack_buffer *b){ - oggpack_writeinit(b); -} - -void oggpack_writetrunc(oggpack_buffer *b,long bits){ - long bytes=bits>>3; - bits-=bytes*8; - b->ptr=b->buffer+bytes; - b->endbit=bits; - b->endbyte=bytes; - *b->ptr&=mask[bits]; -} - -void oggpackB_writetrunc(oggpack_buffer *b,long bits){ - long bytes=bits>>3; - bits-=bytes*8; - b->ptr=b->buffer+bytes; - b->endbit=bits; - b->endbyte=bytes; - *b->ptr&=mask8B[bits]; -} - -/* Takes only up to 32 bits. */ -void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ - if(b->endbyte+4>=b->storage){ - b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); - b->storage+=BUFFER_INCREMENT; - b->ptr=b->buffer+b->endbyte; - } - - value&=mask[bits]; - bits+=b->endbit; - - b->ptr[0]|=value<endbit; - - if(bits>=8){ - b->ptr[1]=value>>(8-b->endbit); - if(bits>=16){ - b->ptr[2]=value>>(16-b->endbit); - if(bits>=24){ - b->ptr[3]=value>>(24-b->endbit); - if(bits>=32){ - if(b->endbit) - b->ptr[4]=value>>(32-b->endbit); - else - b->ptr[4]=0; - } - } - } - } - - b->endbyte+=bits/8; - b->ptr+=bits/8; - b->endbit=bits&7; -} - -/* Takes only up to 32 bits. */ -void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ - if(b->endbyte+4>=b->storage){ - b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); - b->storage+=BUFFER_INCREMENT; - b->ptr=b->buffer+b->endbyte; - } - - value=(value&mask[bits])<<(32-bits); - bits+=b->endbit; - - b->ptr[0]|=value>>(24+b->endbit); - - if(bits>=8){ - b->ptr[1]=value>>(16+b->endbit); - if(bits>=16){ - b->ptr[2]=value>>(8+b->endbit); - if(bits>=24){ - b->ptr[3]=value>>(b->endbit); - if(bits>=32){ - if(b->endbit) - b->ptr[4]=value<<(8-b->endbit); - else - b->ptr[4]=0; - } - } - } - } - - b->endbyte+=bits/8; - b->ptr+=bits/8; - b->endbit=bits&7; -} - -void oggpack_writealign(oggpack_buffer *b){ - int bits=8-b->endbit; - if(bits<8) - oggpack_write(b,0,bits); -} - -void oggpackB_writealign(oggpack_buffer *b){ - int bits=8-b->endbit; - if(bits<8) - oggpackB_write(b,0,bits); -} - -static void oggpack_writecopy_helper(oggpack_buffer *b, - void *source, - long bits, - void (*w)(oggpack_buffer *, - unsigned long, - int), - int msb){ - unsigned char *ptr=(unsigned char *)source; - - long bytes=bits/8; - bits-=bytes*8; - - if(b->endbit){ - int i; - /* unaligned copy. Do it the hard way. */ - for(i=0;iendbyte+bytes+1>=b->storage){ - b->storage=b->endbyte+bytes+BUFFER_INCREMENT; - b->buffer=_ogg_realloc(b->buffer,b->storage); - b->ptr=b->buffer+b->endbyte; - } - - memmove(b->ptr,source,bytes); - b->ptr+=bytes; - b->buffer+=bytes; - *b->ptr=0; - - } - if(bits){ - if(msb) - w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); - else - w(b,(unsigned long)(ptr[bytes]),bits); - } -} - -void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ - oggpack_writecopy_helper(b,source,bits,oggpack_write,0); -} - -void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ - oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); -} - -void oggpack_reset(oggpack_buffer *b){ - b->ptr=b->buffer; - b->buffer[0]=0; - b->endbit=b->endbyte=0; -} - -void oggpackB_reset(oggpack_buffer *b){ - oggpack_reset(b); -} - -void oggpack_writeclear(oggpack_buffer *b){ - _ogg_free(b->buffer); - memset(b,0,sizeof(*b)); -} - -void oggpackB_writeclear(oggpack_buffer *b){ - oggpack_writeclear(b); -} - -void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ - memset(b,0,sizeof(*b)); - b->buffer=b->ptr=buf; - b->storage=bytes; -} - -void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ - oggpack_readinit(b,buf,bytes); -} - -/* Read in bits without advancing the bitptr; bits <= 32 */ -long oggpack_look(oggpack_buffer *b,int bits){ - unsigned long ret; - unsigned long m=mask[bits]; - - bits+=b->endbit; - - if(b->endbyte+4>=b->storage){ - /* not the main path */ - if(b->endbyte*8+bits>b->storage*8)return(-1); - } - - ret=b->ptr[0]>>b->endbit; - if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); - if(bits>32 && b->endbit) - ret|=b->ptr[4]<<(32-b->endbit); - } - } - } - return(m&ret); -} - -/* Read in bits without advancing the bitptr; bits <= 32 */ -long oggpackB_look(oggpack_buffer *b,int bits){ - unsigned long ret; - int m=32-bits; - - bits+=b->endbit; - - if(b->endbyte+4>=b->storage){ - /* not the main path */ - if(b->endbyte*8+bits>b->storage*8)return(-1); - } - - ret=b->ptr[0]<<(24+b->endbit); - if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); - if(bits>32 && b->endbit) - ret|=b->ptr[4]>>(8-b->endbit); - } - } - } - return (ret>>(m>>1))>>((m+1)>>1); -} - -long oggpack_look1(oggpack_buffer *b){ - if(b->endbyte>=b->storage)return(-1); - return((b->ptr[0]>>b->endbit)&1); -} - -long oggpackB_look1(oggpack_buffer *b){ - if(b->endbyte>=b->storage)return(-1); - return((b->ptr[0]>>(7-b->endbit))&1); -} - -void oggpack_adv(oggpack_buffer *b,int bits){ - bits+=b->endbit; - b->ptr+=bits/8; - b->endbyte+=bits/8; - b->endbit=bits&7; -} - -void oggpackB_adv(oggpack_buffer *b,int bits){ - oggpack_adv(b,bits); -} - -void oggpack_adv1(oggpack_buffer *b){ - if(++(b->endbit)>7){ - b->endbit=0; - b->ptr++; - b->endbyte++; - } -} - -void oggpackB_adv1(oggpack_buffer *b){ - oggpack_adv1(b); -} - -/* bits <= 32 */ -long oggpack_read(oggpack_buffer *b,int bits){ - unsigned long ret; - unsigned long m=mask[bits]; - - bits+=b->endbit; - - if(b->endbyte+4>=b->storage){ - /* not the main path */ - ret=-1UL; - if(b->endbyte*8+bits>b->storage*8)goto overflow; - } - - ret=b->ptr[0]>>b->endbit; - if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); - if(bits>32 && b->endbit){ - ret|=b->ptr[4]<<(32-b->endbit); - } - } - } - } - ret&=m; - - overflow: - - b->ptr+=bits/8; - b->endbyte+=bits/8; - b->endbit=bits&7; - return(ret); -} - -/* bits <= 32 */ -long oggpackB_read(oggpack_buffer *b,int bits){ - unsigned long ret; - long m=32-bits; - - bits+=b->endbit; - - if(b->endbyte+4>=b->storage){ - /* not the main path */ - ret=-1UL; - if(b->endbyte*8+bits>b->storage*8)goto overflow; - } - - ret=b->ptr[0]<<(24+b->endbit); - if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); - if(bits>32 && b->endbit) - ret|=b->ptr[4]>>(8-b->endbit); - } - } - } - ret=(ret>>(m>>1))>>((m+1)>>1); - - overflow: - - b->ptr+=bits/8; - b->endbyte+=bits/8; - b->endbit=bits&7; - return(ret); -} - -long oggpack_read1(oggpack_buffer *b){ - unsigned long ret; - - if(b->endbyte>=b->storage){ - /* not the main path */ - ret=-1UL; - goto overflow; - } - - ret=(b->ptr[0]>>b->endbit)&1; - - overflow: - - b->endbit++; - if(b->endbit>7){ - b->endbit=0; - b->ptr++; - b->endbyte++; - } - return(ret); -} - -long oggpackB_read1(oggpack_buffer *b){ - unsigned long ret; - - if(b->endbyte>=b->storage){ - /* not the main path */ - ret=-1UL; - goto overflow; - } - - ret=(b->ptr[0]>>(7-b->endbit))&1; - - overflow: - - b->endbit++; - if(b->endbit>7){ - b->endbit=0; - b->ptr++; - b->endbyte++; - } - return(ret); -} - -long oggpack_bytes(oggpack_buffer *b){ - return(b->endbyte+(b->endbit+7)/8); -} - -long oggpack_bits(oggpack_buffer *b){ - return(b->endbyte*8+b->endbit); -} - -long oggpackB_bytes(oggpack_buffer *b){ - return oggpack_bytes(b); -} - -long oggpackB_bits(oggpack_buffer *b){ - return oggpack_bits(b); -} - -unsigned char *oggpack_get_buffer(oggpack_buffer *b){ - return(b->buffer); -} - -unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ - return oggpack_get_buffer(b); -} - -/* Self test of the bitwise routines; everything else is based on - them, so they damned well better be solid. */ - -#ifdef _V_SELFTEST -#include - -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -oggpack_buffer o; -oggpack_buffer r; - -void report(char *in){ - fprintf(stderr,"%s",in); - exit(1); -} - -void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ - long bytes,i; - unsigned char *buffer; - - oggpack_reset(&o); - for(i=0;i -#include -#include - -/* A complete description of Ogg framing exists in docs/framing.html */ - -int ogg_page_version(ogg_page *og){ - return((int)(og->header[4])); -} - -int ogg_page_continued(ogg_page *og){ - return((int)(og->header[5]&0x01)); -} - -int ogg_page_bos(ogg_page *og){ - return((int)(og->header[5]&0x02)); -} - -int ogg_page_eos(ogg_page *og){ - return((int)(og->header[5]&0x04)); -} - -ogg_int64_t ogg_page_granulepos(ogg_page *og){ - unsigned char *page=og->header; - ogg_int64_t granulepos=page[13]&(0xff); - granulepos= (granulepos<<8)|(page[12]&0xff); - granulepos= (granulepos<<8)|(page[11]&0xff); - granulepos= (granulepos<<8)|(page[10]&0xff); - granulepos= (granulepos<<8)|(page[9]&0xff); - granulepos= (granulepos<<8)|(page[8]&0xff); - granulepos= (granulepos<<8)|(page[7]&0xff); - granulepos= (granulepos<<8)|(page[6]&0xff); - return(granulepos); -} - -int ogg_page_serialno(ogg_page *og){ - return(og->header[14] | - (og->header[15]<<8) | - (og->header[16]<<16) | - (og->header[17]<<24)); -} - -long ogg_page_pageno(ogg_page *og){ - return(og->header[18] | - (og->header[19]<<8) | - (og->header[20]<<16) | - (og->header[21]<<24)); -} - - - -/* returns the number of packets that are completed on this page (if - the leading packet is begun on a previous page, but ends on this - page, it's counted */ - -/* NOTE: -If a page consists of a packet begun on a previous page, and a new -packet begun (but not completed) on this page, the return will be: - ogg_page_packets(page) ==1, - ogg_page_continued(page) !=0 - -If a page happens to be a single packet that was begun on a -previous page, and spans to the next page (in the case of a three or -more page packet), the return will be: - ogg_page_packets(page) ==0, - ogg_page_continued(page) !=0 -*/ - -int ogg_page_packets(ogg_page *og){ - int i,n=og->header[26],count=0; - for(i=0;iheader[27+i]<255)count++; - return(count); -} - - -#if 0 -/* helper to initialize lookup for direct-table CRC (illustrative; we - use the static init below) */ - -static ogg_uint32_t _ogg_crc_entry(unsigned long index){ - int i; - unsigned long r; - - r = index << 24; - for (i=0; i<8; i++) - if (r & 0x80000000UL) - r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator - polynomial, although we use an - unreflected alg and an init/final - of 0, not 0xffffffff */ - else - r<<=1; - return (r & 0xffffffffUL); -} -#endif - -static ogg_uint32_t crc_lookup[256]={ - 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9, - 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005, - 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61, - 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd, - 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9, - 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, - 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011, - 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd, - 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039, - 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5, - 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81, - 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, - 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49, - 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95, - 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1, - 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d, - 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae, - 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, - 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16, - 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca, - 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde, - 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02, - 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066, - 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, - 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e, - 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692, - 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6, - 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a, - 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e, - 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, - 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686, - 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a, - 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637, - 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb, - 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f, - 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, - 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47, - 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b, - 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff, - 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623, - 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7, - 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, - 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f, - 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3, - 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7, - 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b, - 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f, - 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, - 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640, - 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c, - 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8, - 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24, - 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30, - 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, - 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088, - 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654, - 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0, - 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c, - 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18, - 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, - 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0, - 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c, - 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668, - 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4}; - -/* init the encode/decode logical stream state */ - -int ogg_stream_init(ogg_stream_state *os,int serialno){ - if(os){ - memset(os,0,sizeof(*os)); - os->body_storage=16*1024; - os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data)); - - os->lacing_storage=1024; - os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals)); - os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals)); - - os->serialno=serialno; - - return(0); - } - return(-1); -} - -/* _clear does not free os, only the non-flat storage within */ -int ogg_stream_clear(ogg_stream_state *os){ - if(os){ - if(os->body_data)_ogg_free(os->body_data); - if(os->lacing_vals)_ogg_free(os->lacing_vals); - if(os->granule_vals)_ogg_free(os->granule_vals); - - memset(os,0,sizeof(*os)); - } - return(0); -} - -int ogg_stream_destroy(ogg_stream_state *os){ - if(os){ - ogg_stream_clear(os); - _ogg_free(os); - } - return(0); -} - -/* Helpers for ogg_stream_encode; this keeps the structure and - what's happening fairly clear */ - -static void _os_body_expand(ogg_stream_state *os,int needed){ - if(os->body_storage<=os->body_fill+needed){ - os->body_storage+=(needed+1024); - os->body_data=_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data)); - } -} - -static void _os_lacing_expand(ogg_stream_state *os,int needed){ - if(os->lacing_storage<=os->lacing_fill+needed){ - os->lacing_storage+=(needed+32); - os->lacing_vals=_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals)); - os->granule_vals=_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals)); - } -} - -/* checksum the page */ -/* Direct table CRC; note that this will be faster in the future if we - perform the checksum silmultaneously with other copies */ - -void ogg_page_checksum_set(ogg_page *og){ - if(og){ - ogg_uint32_t crc_reg=0; - int i; - - /* safety; needed for API behavior, but not framing code */ - og->header[22]=0; - og->header[23]=0; - og->header[24]=0; - og->header[25]=0; - - for(i=0;iheader_len;i++) - crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]]; - for(i=0;ibody_len;i++) - crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]]; - - og->header[22]=crc_reg&0xff; - og->header[23]=(crc_reg>>8)&0xff; - og->header[24]=(crc_reg>>16)&0xff; - og->header[25]=(crc_reg>>24)&0xff; - } -} - -/* submit data to the internal buffer of the framing engine */ -int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ - int lacing_vals=op->bytes/255+1,i; - - if(os->body_returned){ - /* advance packet data according to the body_returned pointer. We - had to keep it around to return a pointer into the buffer last - call */ - - os->body_fill-=os->body_returned; - if(os->body_fill) - memmove(os->body_data,os->body_data+os->body_returned, - os->body_fill); - os->body_returned=0; - } - - /* make sure we have the buffer storage */ - _os_body_expand(os,op->bytes); - _os_lacing_expand(os,lacing_vals); - - /* Copy in the submitted packet. Yes, the copy is a waste; this is - the liability of overly clean abstraction for the time being. It - will actually be fairly easy to eliminate the extra copy in the - future */ - - memcpy(os->body_data+os->body_fill,op->packet,op->bytes); - os->body_fill+=op->bytes; - - /* Store lacing vals for this packet */ - for(i=0;ilacing_vals[os->lacing_fill+i]=255; - os->granule_vals[os->lacing_fill+i]=os->granulepos; - } - os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255; - os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos; - - /* flag the first segment as the beginning of the packet */ - os->lacing_vals[os->lacing_fill]|= 0x100; - - os->lacing_fill+=lacing_vals; - - /* for the sake of completeness */ - os->packetno++; - - if(op->e_o_s)os->e_o_s=1; - - return(0); -} - -/* This will flush remaining packets into a page (returning nonzero), - even if there is not enough data to trigger a flush normally - (undersized page). If there are no packets or partial packets to - flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will - try to flush a normal sized page like ogg_stream_pageout; a call to - ogg_stream_flush does not guarantee that all packets have flushed. - Only a return value of 0 from ogg_stream_flush indicates all packet - data is flushed into pages. - - since ogg_stream_flush will flush the last page in a stream even if - it's undersized, you almost certainly want to use ogg_stream_pageout - (and *not* ogg_stream_flush) unless you specifically need to flush - an page regardless of size in the middle of a stream. */ - -int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ - int i; - int vals=0; - int maxvals=(os->lacing_fill>255?255:os->lacing_fill); - int bytes=0; - long acc=0; - ogg_int64_t granule_pos=os->granule_vals[0]; - - if(maxvals==0)return(0); - - /* construct a page */ - /* decide how many segments to include */ - - /* If this is the initial header case, the first page must only include - the initial header packet */ - if(os->b_o_s==0){ /* 'initial header page' case */ - granule_pos=0; - for(vals=0;valslacing_vals[vals]&0x0ff)<255){ - vals++; - break; - } - } - }else{ - for(vals=0;vals4096)break; - acc+=os->lacing_vals[vals]&0x0ff; - granule_pos=os->granule_vals[vals]; - } - } - - /* construct the header in temp storage */ - memcpy(os->header,"OggS",4); - - /* stream structure version */ - os->header[4]=0x00; - - /* continued packet flag? */ - os->header[5]=0x00; - if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01; - /* first page flag? */ - if(os->b_o_s==0)os->header[5]|=0x02; - /* last page flag? */ - if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04; - os->b_o_s=1; - - /* 64 bits of PCM position */ - for(i=6;i<14;i++){ - os->header[i]=(granule_pos&0xff); - granule_pos>>=8; - } - - /* 32 bits of stream serial number */ - { - long serialno=os->serialno; - for(i=14;i<18;i++){ - os->header[i]=(serialno&0xff); - serialno>>=8; - } - } - - /* 32 bits of page counter (we have both counter and page header - because this val can roll over) */ - if(os->pageno==-1)os->pageno=0; /* because someone called - stream_reset; this would be a - strange thing to do in an - encode stream, but it has - plausible uses */ - { - long pageno=os->pageno++; - for(i=18;i<22;i++){ - os->header[i]=(pageno&0xff); - pageno>>=8; - } - } - - /* zero for computation; filled in later */ - os->header[22]=0; - os->header[23]=0; - os->header[24]=0; - os->header[25]=0; - - /* segment table */ - os->header[26]=vals&0xff; - for(i=0;iheader[i+27]=(os->lacing_vals[i]&0xff); - - /* set pointers in the ogg_page struct */ - og->header=os->header; - og->header_len=os->header_fill=vals+27; - og->body=os->body_data+os->body_returned; - og->body_len=bytes; - - /* advance the lacing data and set the body_returned pointer */ - - os->lacing_fill-=vals; - memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals)); - memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals)); - os->body_returned+=bytes; - - /* calculate the checksum */ - - ogg_page_checksum_set(og); - - /* done */ - return(1); -} - - -/* This constructs pages from buffered packet segments. The pointers -returned are to static buffers; do not free. The returned buffers are -good only until the next call (using the same ogg_stream_state) */ - -int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){ - - if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ - os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */ - os->lacing_fill>=255 || /* 'segment table full' case */ - (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */ - - return(ogg_stream_flush(os,og)); - } - - /* not enough data to construct a page and not end of stream */ - return(0); -} - -int ogg_stream_eos(ogg_stream_state *os){ - return os->e_o_s; -} - -/* DECODING PRIMITIVES: packet streaming layer **********************/ - -/* This has two layers to place more of the multi-serialno and paging - control in the application's hands. First, we expose a data buffer - using ogg_sync_buffer(). The app either copies into the - buffer, or passes it directly to read(), etc. We then call - ogg_sync_wrote() to tell how many bytes we just added. - - Pages are returned (pointers into the buffer in ogg_sync_state) - by ogg_sync_pageout(). The page is then submitted to - ogg_stream_pagein() along with the appropriate - ogg_stream_state* (ie, matching serialno). We then get raw - packets out calling ogg_stream_packetout() with a - ogg_stream_state. See the 'frame-prog.txt' docs for details and - example code. */ - -/* initialize the struct to a known state */ -int ogg_sync_init(ogg_sync_state *oy){ - if(oy){ - memset(oy,0,sizeof(*oy)); - } - return(0); -} - -/* clear non-flat storage within */ -int ogg_sync_clear(ogg_sync_state *oy){ - if(oy){ - if(oy->data)_ogg_free(oy->data); - ogg_sync_init(oy); - } - return(0); -} - -int ogg_sync_destroy(ogg_sync_state *oy){ - if(oy){ - ogg_sync_clear(oy); - _ogg_free(oy); - } - return(0); -} - -char *ogg_sync_buffer(ogg_sync_state *oy, long size){ - - /* first, clear out any space that has been previously returned */ - if(oy->returned){ - oy->fill-=oy->returned; - if(oy->fill>0) - memmove(oy->data,oy->data+oy->returned,oy->fill); - oy->returned=0; - } - - if(size>oy->storage-oy->fill){ - /* We need to extend the internal buffer */ - long newsize=size+oy->fill+4096; /* an extra page to be nice */ - - if(oy->data) - oy->data=_ogg_realloc(oy->data,newsize); - else - oy->data=_ogg_malloc(newsize); - oy->storage=newsize; - } - - /* expose a segment at least as large as requested at the fill mark */ - return((char *)oy->data+oy->fill); -} - -int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ - if(oy->fill+bytes>oy->storage)return(-1); - oy->fill+=bytes; - return(0); -} - -/* sync the stream. This is meant to be useful for finding page - boundaries. - - return values for this: - -n) skipped n bytes - 0) page not ready; more data (no bytes skipped) - n) page synced at current location; page length n bytes - -*/ - -long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ - unsigned char *page=oy->data+oy->returned; - unsigned char *next; - long bytes=oy->fill-oy->returned; - - if(oy->headerbytes==0){ - int headerbytes,i; - if(bytes<27)return(0); /* not enough for a header */ - - /* verify capture pattern */ - if(memcmp(page,"OggS",4))goto sync_fail; - - headerbytes=page[26]+27; - if(bytesbodybytes+=page[27+i]; - oy->headerbytes=headerbytes; - } - - if(oy->bodybytes+oy->headerbytes>bytes)return(0); - - /* The whole test page is buffered. Verify the checksum */ - { - /* Grab the checksum bytes, set the header field to zero */ - char chksum[4]; - ogg_page log; - - memcpy(chksum,page+22,4); - memset(page+22,0,4); - - /* set up a temp page struct and recompute the checksum */ - log.header=page; - log.header_len=oy->headerbytes; - log.body=page+oy->headerbytes; - log.body_len=oy->bodybytes; - ogg_page_checksum_set(&log); - - /* Compare */ - if(memcmp(chksum,page+22,4)){ - /* D'oh. Mismatch! Corrupt page (or miscapture and not a page - at all) */ - /* replace the computed checksum with the one actually read in */ - memcpy(page+22,chksum,4); - - /* Bad checksum. Lose sync */ - goto sync_fail; - } - } - - /* yes, have a whole page all ready to go */ - { - unsigned char *page=oy->data+oy->returned; - long bytes; - - if(og){ - og->header=page; - og->header_len=oy->headerbytes; - og->body=page+oy->headerbytes; - og->body_len=oy->bodybytes; - } - - oy->unsynced=0; - oy->returned+=(bytes=oy->headerbytes+oy->bodybytes); - oy->headerbytes=0; - oy->bodybytes=0; - return(bytes); - } - - sync_fail: - - oy->headerbytes=0; - oy->bodybytes=0; - - /* search for possible capture */ - next=memchr(page+1,'O',bytes-1); - if(!next) - next=oy->data+oy->fill; - - oy->returned=next-oy->data; - return(-(next-page)); -} - -/* sync the stream and get a page. Keep trying until we find a page. - Supress 'sync errors' after reporting the first. - - return values: - -1) recapture (hole in data) - 0) need more data - 1) page returned - - Returns pointers into buffered data; invalidated by next call to - _stream, _clear, _init, or _buffer */ - -int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ - - /* all we need to do is verify a page at the head of the stream - buffer. If it doesn't verify, we look for the next potential - frame */ - - while(1){ - long ret=ogg_sync_pageseek(oy,og); - if(ret>0){ - /* have a page */ - return(1); - } - if(ret==0){ - /* need more data */ - return(0); - } - - /* head did not start a synced page... skipped some bytes */ - if(!oy->unsynced){ - oy->unsynced=1; - return(-1); - } - - /* loop. keep looking */ - - } -} - -/* add the incoming page to the stream state; we decompose the page - into packet segments here as well. */ - -int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ - unsigned char *header=og->header; - unsigned char *body=og->body; - long bodysize=og->body_len; - int segptr=0; - - int version=ogg_page_version(og); - int continued=ogg_page_continued(og); - int bos=ogg_page_bos(og); - int eos=ogg_page_eos(og); - ogg_int64_t granulepos=ogg_page_granulepos(og); - int serialno=ogg_page_serialno(og); - long pageno=ogg_page_pageno(og); - int segments=header[26]; - - /* clean up 'returned data' */ - { - long lr=os->lacing_returned; - long br=os->body_returned; - - /* body data */ - if(br){ - os->body_fill-=br; - if(os->body_fill) - memmove(os->body_data,os->body_data+br,os->body_fill); - os->body_returned=0; - } - - if(lr){ - /* segment table */ - if(os->lacing_fill-lr){ - memmove(os->lacing_vals,os->lacing_vals+lr, - (os->lacing_fill-lr)*sizeof(*os->lacing_vals)); - memmove(os->granule_vals,os->granule_vals+lr, - (os->lacing_fill-lr)*sizeof(*os->granule_vals)); - } - os->lacing_fill-=lr; - os->lacing_packet-=lr; - os->lacing_returned=0; - } - } - - /* check the serial number */ - if(serialno!=os->serialno)return(-1); - if(version>0)return(-1); - - _os_lacing_expand(os,segments+1); - - /* are we in sequence? */ - if(pageno!=os->pageno){ - int i; - - /* unroll previous partial packet (if any) */ - for(i=os->lacing_packet;ilacing_fill;i++) - os->body_fill-=os->lacing_vals[i]&0xff; - os->lacing_fill=os->lacing_packet; - - /* make a note of dropped data in segment table */ - if(os->pageno!=-1){ - os->lacing_vals[os->lacing_fill++]=0x400; - os->lacing_packet++; - } - - /* are we a 'continued packet' page? If so, we'll need to skip - some segments */ - if(continued){ - bos=0; - for(;segptrbody_data+os->body_fill,body,bodysize); - os->body_fill+=bodysize; - } - - { - int saved=-1; - while(segptrlacing_vals[os->lacing_fill]=val; - os->granule_vals[os->lacing_fill]=-1; - - if(bos){ - os->lacing_vals[os->lacing_fill]|=0x100; - bos=0; - } - - if(val<255)saved=os->lacing_fill; - - os->lacing_fill++; - segptr++; - - if(val<255)os->lacing_packet=os->lacing_fill; - } - - /* set the granulepos on the last granuleval of the last full packet */ - if(saved!=-1){ - os->granule_vals[saved]=granulepos; - } - - } - - if(eos){ - os->e_o_s=1; - if(os->lacing_fill>0) - os->lacing_vals[os->lacing_fill-1]|=0x200; - } - - os->pageno=pageno+1; - - return(0); -} - -/* clear things to an initial state. Good to call, eg, before seeking */ -int ogg_sync_reset(ogg_sync_state *oy){ - oy->fill=0; - oy->returned=0; - oy->unsynced=0; - oy->headerbytes=0; - oy->bodybytes=0; - return(0); -} - -int ogg_stream_reset(ogg_stream_state *os){ - os->body_fill=0; - os->body_returned=0; - - os->lacing_fill=0; - os->lacing_packet=0; - os->lacing_returned=0; - - os->header_fill=0; - - os->e_o_s=0; - os->b_o_s=0; - os->pageno=-1; - os->packetno=0; - os->granulepos=0; - - return(0); -} - -int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){ - ogg_stream_reset(os); - os->serialno=serialno; - return(0); -} - -static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){ - - /* The last part of decode. We have the stream broken into packet - segments. Now we need to group them into packets (or return the - out of sync markers) */ - - int ptr=os->lacing_returned; - - if(os->lacing_packet<=ptr)return(0); - - if(os->lacing_vals[ptr]&0x400){ - /* we need to tell the codec there's a gap; it might need to - handle previous packet dependencies. */ - os->lacing_returned++; - os->packetno++; - return(-1); - } - - if(!op && !adv)return(1); /* just using peek as an inexpensive way - to ask if there's a whole packet - waiting */ - - /* Gather the whole packet. We'll have no holes or a partial packet */ - { - int size=os->lacing_vals[ptr]&0xff; - int bytes=size; - int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */ - int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */ - - while(size==255){ - int val=os->lacing_vals[++ptr]; - size=val&0xff; - if(val&0x200)eos=0x200; - bytes+=size; - } - - if(op){ - op->e_o_s=eos; - op->b_o_s=bos; - op->packet=os->body_data+os->body_returned; - op->packetno=os->packetno; - op->granulepos=os->granule_vals[ptr]; - op->bytes=bytes; - } - - if(adv){ - os->body_returned+=bytes; - os->lacing_returned=ptr+1; - os->packetno++; - } - } - return(1); -} - -int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){ - return _packetout(os,op,1); -} - -int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){ - return _packetout(os,op,0); -} - -void ogg_packet_clear(ogg_packet *op) { - _ogg_free(op->packet); - memset(op, 0, sizeof(*op)); -} - -#ifdef _V_SELFTEST -#include - -ogg_stream_state os_en, os_de; -ogg_sync_state oy; - -void checkpacket(ogg_packet *op,int len, int no, int pos){ - long j; - static int sequence=0; - static int lastno=0; - - if(op->bytes!=len){ - fprintf(stderr,"incorrect packet length!\n"); - exit(1); - } - if(op->granulepos!=pos){ - fprintf(stderr,"incorrect packet position!\n"); - exit(1); - } - - /* packet number just follows sequence/gap; adjust the input number - for that */ - if(no==0){ - sequence=0; - }else{ - sequence++; - if(no>lastno+1) - sequence++; - } - lastno=no; - if(op->packetno!=sequence){ - fprintf(stderr,"incorrect packet sequence %ld != %d\n", - (long)(op->packetno),sequence); - exit(1); - } - - /* Test data */ - for(j=0;jbytes;j++) - if(op->packet[j]!=((j+no)&0xff)){ - fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n", - j,op->packet[j],(j+no)&0xff); - exit(1); - } -} - -void check_page(unsigned char *data,const int *header,ogg_page *og){ - long j; - /* Test data */ - for(j=0;jbody_len;j++) - if(og->body[j]!=data[j]){ - fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n", - j,data[j],og->body[j]); - exit(1); - } - - /* Test header */ - for(j=0;jheader_len;j++){ - if(og->header[j]!=header[j]){ - fprintf(stderr,"header content mismatch at pos %ld:\n",j); - for(j=0;jheader[j]); - fprintf(stderr,"\n"); - exit(1); - } - } - if(og->header_len!=header[26]+27){ - fprintf(stderr,"header length incorrect! (%ld!=%d)\n", - og->header_len,header[26]+27); - exit(1); - } -} - -void print_header(ogg_page *og){ - int j; - fprintf(stderr,"\nHEADER:\n"); - fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n", - og->header[0],og->header[1],og->header[2],og->header[3], - (int)og->header[4],(int)og->header[5]); - - fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n", - (og->header[9]<<24)|(og->header[8]<<16)| - (og->header[7]<<8)|og->header[6], - (og->header[17]<<24)|(og->header[16]<<16)| - (og->header[15]<<8)|og->header[14], - ((long)(og->header[21])<<24)|(og->header[20]<<16)| - (og->header[19]<<8)|og->header[18]); - - fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (", - (int)og->header[22],(int)og->header[23], - (int)og->header[24],(int)og->header[25], - (int)og->header[26]); - - for(j=27;jheader_len;j++) - fprintf(stderr,"%d ",(int)og->header[j]); - fprintf(stderr,")\n\n"); -} - -void copy_page(ogg_page *og){ - unsigned char *temp=_ogg_malloc(og->header_len); - memcpy(temp,og->header,og->header_len); - og->header=temp; - - temp=_ogg_malloc(og->body_len); - memcpy(temp,og->body,og->body_len); - og->body=temp; -} - -void error(void){ - fprintf(stderr,"error!\n"); - exit(1); -} - -/* 17 only */ -const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0x15,0xed,0xec,0x91, - 1, - 17}; - -/* 17, 254, 255, 256, 500, 510, 600 byte, pad */ -const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0x59,0x10,0x6c,0x2c, - 1, - 17}; -const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x89,0x33,0x85,0xce, - 13, - 254,255,0,255,1,255,245,255,255,0, - 255,255,90}; - -/* nil packets; beginning,middle,end */ -const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; -const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x5c,0x3f,0x66,0xcb, - 17, - 17,254,255,0,0,255,1,0,255,245,255,255,0, - 255,255,90,0}; - -/* large initial packet */ -const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0x01,0x27,0x31,0xaa, - 18, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,10}; - -const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x7f,0x4e,0x8a,0xd2, - 4, - 255,4,255,0}; - - -/* continuing packet test */ -const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x34,0x24,0xd5,0x29, - 17, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255}; - -const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05, - 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0xc8,0xc3,0xcb,0xed, - 5, - 10,255,4,255,0}; - - -/* page with the 255 segment limit */ -const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0xed,0x2a,0x2e,0xa7, - 255, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10}; - -const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0x6c,0x3b,0x82,0x3d, - 1, - 50}; - - -/* packet that overspans over an entire page */ -const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x3c,0xd9,0x4d,0x3f, - 17, - 100,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255}; - -const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01, - 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0xbd,0xd5,0xb5,0x8b, - 17, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255}; - -const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05, - 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,3,0,0,0, - 0xef,0xdd,0x88,0xde, - 7, - 255,255,75,255,4,255,0}; - -/* packet that overspans over an entire page */ -const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x3c,0xd9,0x4d,0x3f, - 17, - 100,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255}; - -const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05, - 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0xd4,0xe0,0x60,0xe5, - 1,0}; - -void test_pack(const int *pl, const int **headers){ - unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ - long inptr=0; - long outptr=0; - long deptr=0; - long depacket=0; - long granule_pos=7,pageno=0; - int i,j,packets,pageout=0; - int eosflag=0; - int bosflag=0; - - ogg_stream_reset(&os_en); - ogg_stream_reset(&os_de); - ogg_sync_reset(&oy); - - for(packets=0;;packets++)if(pl[packets]==-1)break; - - for(i=0;i0){ - /* got a page. Happy happy. Verify that it's good. */ - - check_page(data+deptr,headers[pageout],&og_de); - deptr+=og_de.body_len; - pageout++; - - /* submit it to deconstitution */ - ogg_stream_pagein(&os_de,&og_de); - - /* packets out? */ - while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ - ogg_stream_packetpeek(&os_de,NULL); - ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ - - /* verify peek and out match */ - if(memcmp(&op_de,&op_de2,sizeof(op_de))){ - fprintf(stderr,"packetout != packetpeek! pos=%ld\n", - depacket); - exit(1); - } - - /* verify the packet! */ - /* check data */ - if(memcmp(data+depacket,op_de.packet,op_de.bytes)){ - fprintf(stderr,"packet data mismatch in decode! pos=%ld\n", - depacket); - exit(1); - } - /* check bos flag */ - if(bosflag==0 && op_de.b_o_s==0){ - fprintf(stderr,"b_o_s flag not set on packet!\n"); - exit(1); - } - if(bosflag && op_de.b_o_s){ - fprintf(stderr,"b_o_s flag incorrectly set on packet!\n"); - exit(1); - } - bosflag=1; - depacket+=op_de.bytes; - - /* check eos flag */ - if(eosflag){ - fprintf(stderr,"Multiple decoded packets with eos flag!\n"); - exit(1); - } - - if(op_de.e_o_s)eosflag=1; - - /* check granulepos flag */ - if(op_de.granulepos!=-1){ - fprintf(stderr," granule:%ld ",(long)op_de.granulepos); - } - } - } - } - } - } - } - _ogg_free(data); - if(headers[pageno]!=NULL){ - fprintf(stderr,"did not write last page!\n"); - exit(1); - } - if(headers[pageout]!=NULL){ - fprintf(stderr,"did not decode last page!\n"); - exit(1); - } - if(inptr!=outptr){ - fprintf(stderr,"encoded page data incomplete!\n"); - exit(1); - } - if(inptr!=deptr){ - fprintf(stderr,"decoded page data incomplete!\n"); - exit(1); - } - if(inptr!=depacket){ - fprintf(stderr,"decoded packet data incomplete!\n"); - exit(1); - } - if(!eosflag){ - fprintf(stderr,"Never got a packet with EOS set!\n"); - exit(1); - } - fprintf(stderr,"ok.\n"); -} - -int main(void){ - - ogg_stream_init(&os_en,0x04030201); - ogg_stream_init(&os_de,0x04030201); - ogg_sync_init(&oy); - - /* Exercise each code path in the framing code. Also verify that - the checksums are working. */ - - { - /* 17 only */ - const int packets[]={17, -1}; - const int *headret[]={head1_0,NULL}; - - fprintf(stderr,"testing single page encoding... "); - test_pack(packets,headret); - } - - { - /* 17, 254, 255, 256, 500, 510, 600 byte, pad */ - const int packets[]={17, 254, 255, 256, 500, 510, 600, -1}; - const int *headret[]={head1_1,head2_1,NULL}; - - fprintf(stderr,"testing basic page encoding... "); - test_pack(packets,headret); - } - - { - /* nil packets; beginning,middle,end */ - const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1}; - const int *headret[]={head1_2,head2_2,NULL}; - - fprintf(stderr,"testing basic nil packets... "); - test_pack(packets,headret); - } - - { - /* large initial packet */ - const int packets[]={4345,259,255,-1}; - const int *headret[]={head1_3,head2_3,NULL}; - - fprintf(stderr,"testing initial-packet lacing > 4k... "); - test_pack(packets,headret); - } - - { - /* continuing packet test */ - const int packets[]={0,4345,259,255,-1}; - const int *headret[]={head1_4,head2_4,head3_4,NULL}; - - fprintf(stderr,"testing single packet page span... "); - test_pack(packets,headret); - } - - /* page with the 255 segment limit */ - { - - const int packets[]={0,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,50,-1}; - const int *headret[]={head1_5,head2_5,head3_5,NULL}; - - fprintf(stderr,"testing max packet segments... "); - test_pack(packets,headret); - } - - { - /* packet that overspans over an entire page */ - const int packets[]={0,100,9000,259,255,-1}; - const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; - - fprintf(stderr,"testing very large packets... "); - test_pack(packets,headret); - } - - { - /* term only page. why not? */ - const int packets[]={0,100,4080,-1}; - const int *headret[]={head1_7,head2_7,head3_7,NULL}; - - fprintf(stderr,"testing zero data page (1 nil packet)... "); - test_pack(packets,headret); - } - - - - { - /* build a bunch of pages for testing */ - unsigned char *data=_ogg_malloc(1024*1024); - int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1}; - int inptr=0,i,j; - ogg_page og[5]; - - ogg_stream_reset(&os_en); - - for(i=0;pl[i]!=-1;i++){ - ogg_packet op; - int len=pl[i]; - - op.packet=data+inptr; - op.bytes=len; - op.e_o_s=(pl[i+1]<0?1:0); - op.granulepos=(i+1)*1000; - - for(j=0;j0)error(); - - /* Test fractional page inputs: incomplete fixed header */ - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3, - 20); - ogg_sync_wrote(&oy,20); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - /* Test fractional page inputs: incomplete header */ - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23, - 5); - ogg_sync_wrote(&oy,5); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - /* Test fractional page inputs: incomplete body */ - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28, - og[1].header_len-28); - ogg_sync_wrote(&oy,og[1].header_len-28); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000); - ogg_sync_wrote(&oy,1000); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000, - og[1].body_len-1000); - ogg_sync_wrote(&oy,og[1].body_len-1000); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - - /* Test fractional page inputs: page + incomplete capture */ - { - ogg_page og_de; - fprintf(stderr,"Testing sync on 1+partial inputs... "); - ogg_sync_reset(&oy); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - og[1].header_len); - ogg_sync_wrote(&oy,og[1].header_len); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - 20); - ogg_sync_wrote(&oy,20); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20, - og[1].header_len-20); - ogg_sync_wrote(&oy,og[1].header_len-20); - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - - /* Test recapture: garbage + page */ - { - ogg_page og_de; - fprintf(stderr,"Testing search for capture... "); - ogg_sync_reset(&oy); - - /* 'garbage' */ - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - og[1].header_len); - ogg_sync_wrote(&oy,og[1].header_len); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, - 20); - ogg_sync_wrote(&oy,20); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20, - og[2].header_len-20); - ogg_sync_wrote(&oy,og[2].header_len-20); - memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, - og[2].body_len); - ogg_sync_wrote(&oy,og[2].body_len); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - - /* Test recapture: page + garbage + page */ - { - ogg_page og_de; - fprintf(stderr,"Testing recapture... "); - ogg_sync_reset(&oy); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - og[1].header_len); - ogg_sync_wrote(&oy,og[1].header_len); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, - og[2].header_len); - ogg_sync_wrote(&oy,og[2].header_len); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, - og[2].header_len); - ogg_sync_wrote(&oy,og[2].header_len); - - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, - og[2].body_len-5); - ogg_sync_wrote(&oy,og[2].body_len-5); - - memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header, - og[3].header_len); - ogg_sync_wrote(&oy,og[3].header_len); - - memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body, - og[3].body_len); - ogg_sync_wrote(&oy,og[3].body_len); - - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - } - - return(0); -} - -#endif - - - - diff --git a/src/add-ons/media/plugins/ogg/libogg/ogg/ogg.h b/src/add-ons/media/plugins/ogg/libogg/ogg/ogg.h deleted file mode 100644 index 908981d0c7..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/ogg/ogg.h +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: toplevel libogg include - last mod: $Id: ogg.h 6729 2004-02-24 13:52:39Z shatty $ - - ********************************************************************/ -#ifndef _OGG_H -#define _OGG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef struct { - long endbyte; - int endbit; - - unsigned char *buffer; - unsigned char *ptr; - long storage; -} oggpack_buffer; - -/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ - -typedef struct { - unsigned char *header; - long header_len; - unsigned char *body; - long body_len; -} ogg_page; - -/* ogg_stream_state contains the current encode/decode state of a logical - Ogg bitstream **********************************************************/ - -typedef struct { - unsigned char *body_data; /* bytes from packet bodies */ - long body_storage; /* storage elements allocated */ - long body_fill; /* elements stored; fill mark */ - long body_returned; /* elements of fill returned */ - - - int *lacing_vals; /* The values that will go to the segment table */ - ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact - this way, but it is simple coupled to the - lacing fifo */ - long lacing_storage; - long lacing_fill; - long lacing_packet; - long lacing_returned; - - unsigned char header[282]; /* working space for header encode */ - int header_fill; - - int e_o_s; /* set when we have buffered the last packet in the - logical bitstream */ - int b_o_s; /* set after we've written the initial page - of a logical bitstream */ - long serialno; - long pageno; - ogg_int64_t packetno; /* sequence number for decode; the framing - knows where there's a hole in the data, - but we need coupling so that the codec - (which is in a seperate abstraction - layer) also knows about the gap */ - ogg_int64_t granulepos; - -} ogg_stream_state; - -/* ogg_packet is used to encapsulate the data and metadata belonging - to a single raw Ogg/Vorbis packet *************************************/ - -typedef struct { - unsigned char *packet; - long bytes; - long b_o_s; - long e_o_s; - - ogg_int64_t granulepos; - - ogg_int64_t packetno; /* sequence number for decode; the framing - knows where there's a hole in the data, - but we need coupling so that the codec - (which is in a seperate abstraction - layer) also knows about the gap */ -} ogg_packet; - -typedef struct { - unsigned char *data; - int storage; - int fill; - int returned; - - int unsynced; - int headerbytes; - int bodybytes; -} ogg_sync_state; - -/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ - -extern void oggpack_writeinit(oggpack_buffer *b); -extern void oggpack_writetrunc(oggpack_buffer *b,long bits); -extern void oggpack_writealign(oggpack_buffer *b); -extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); -extern void oggpack_reset(oggpack_buffer *b); -extern void oggpack_writeclear(oggpack_buffer *b); -extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); -extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); -extern long oggpack_look(oggpack_buffer *b,int bits); -extern long oggpack_look1(oggpack_buffer *b); -extern void oggpack_adv(oggpack_buffer *b,int bits); -extern void oggpack_adv1(oggpack_buffer *b); -extern long oggpack_read(oggpack_buffer *b,int bits); -extern long oggpack_read1(oggpack_buffer *b); -extern long oggpack_bytes(oggpack_buffer *b); -extern long oggpack_bits(oggpack_buffer *b); -extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); - -extern void oggpackB_writeinit(oggpack_buffer *b); -extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); -extern void oggpackB_writealign(oggpack_buffer *b); -extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); -extern void oggpackB_reset(oggpack_buffer *b); -extern void oggpackB_writeclear(oggpack_buffer *b); -extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); -extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); -extern long oggpackB_look(oggpack_buffer *b,int bits); -extern long oggpackB_look1(oggpack_buffer *b); -extern void oggpackB_adv(oggpack_buffer *b,int bits); -extern void oggpackB_adv1(oggpack_buffer *b); -extern long oggpackB_read(oggpack_buffer *b,int bits); -extern long oggpackB_read1(oggpack_buffer *b); -extern long oggpackB_bytes(oggpack_buffer *b); -extern long oggpackB_bits(oggpack_buffer *b); -extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); - -/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ - -extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); -extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); -extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); - -/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ - -extern int ogg_sync_init(ogg_sync_state *oy); -extern int ogg_sync_clear(ogg_sync_state *oy); -extern int ogg_sync_reset(ogg_sync_state *oy); -extern int ogg_sync_destroy(ogg_sync_state *oy); - -extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); -extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); -extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); -extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); -extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); -extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); -extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); - -/* Ogg BITSTREAM PRIMITIVES: general ***************************/ - -extern int ogg_stream_init(ogg_stream_state *os,int serialno); -extern int ogg_stream_clear(ogg_stream_state *os); -extern int ogg_stream_reset(ogg_stream_state *os); -extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); -extern int ogg_stream_destroy(ogg_stream_state *os); -extern int ogg_stream_eos(ogg_stream_state *os); - -extern void ogg_page_checksum_set(ogg_page *og); - -extern int ogg_page_version(ogg_page *og); -extern int ogg_page_continued(ogg_page *og); -extern int ogg_page_bos(ogg_page *og); -extern int ogg_page_eos(ogg_page *og); -extern ogg_int64_t ogg_page_granulepos(ogg_page *og); -extern int ogg_page_serialno(ogg_page *og); -extern long ogg_page_pageno(ogg_page *og); -extern int ogg_page_packets(ogg_page *og); - -extern void ogg_packet_clear(ogg_packet *op); - - -#ifdef __cplusplus -} -#endif - -#endif /* _OGG_H */ - - - - - - diff --git a/src/add-ons/media/plugins/ogg/libogg/ogg/os_types.h b/src/add-ons/media/plugins/ogg/libogg/ogg/os_types.h deleted file mode 100644 index dbbb68578f..0000000000 --- a/src/add-ons/media/plugins/ogg/libogg/ogg/os_types.h +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: #ifdef jail to whip a few platforms into the UNIX ideal. - last mod: $Id: os_types.h 28305 2008-10-23 21:46:26Z bonefish $ - - ********************************************************************/ -#ifndef _OS_TYPES_H -#define _OS_TYPES_H - -/* make it easy on the folks that want to compile the libs with a - different malloc than stdlib */ -#define _ogg_malloc malloc -#define _ogg_calloc calloc -#define _ogg_realloc realloc -#define _ogg_free free - -#ifdef _WIN32 - -# ifndef __GNUC__ - /* MSVC/Borland */ - typedef __int64 ogg_int64_t; - typedef __int32 ogg_int32_t; - typedef unsigned __int32 ogg_uint32_t; - typedef __int16 ogg_int16_t; - typedef unsigned __int16 ogg_uint16_t; -# else - /* Cygwin */ - #include <_G_config.h> - typedef _G_int64_t ogg_int64_t; - typedef _G_int32_t ogg_int32_t; - typedef _G_uint32_t ogg_uint32_t; - typedef _G_int16_t ogg_int16_t; - typedef _G_uint16_t ogg_uint16_t; -# endif - -#elif defined(__MACOS__) - -# include - typedef SInt16 ogg_int16_t; - typedef UInt16 ogg_uint16_t; - typedef SInt32 ogg_int32_t; - typedef UInt32 ogg_uint32_t; - typedef SInt64 ogg_int64_t; - -#elif defined(__MACOSX__) /* MacOS X Framework build */ - -# include - typedef int16_t ogg_int16_t; - typedef u_int16_t ogg_uint16_t; - typedef int32_t ogg_int32_t; - typedef u_int32_t ogg_uint32_t; - typedef int64_t ogg_int64_t; - -#elif (defined(__BEOS__) || defined(__HAIKU__)) - - /* Be */ -# include - typedef int16_t ogg_int16_t; - typedef u_int16_t ogg_uint16_t; - typedef int32_t ogg_int32_t; - typedef u_int32_t ogg_uint32_t; - typedef int64_t ogg_int64_t; - -#elif defined (__EMX__) - - /* OS/2 GCC */ - typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - -#elif defined (DJGPP) - - /* DJGPP */ - typedef short ogg_int16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - -#elif defined(R5900) - - /* PS2 EE */ - typedef long ogg_int64_t; - typedef int ogg_int32_t; - typedef unsigned ogg_uint32_t; - typedef short ogg_int16_t; - -#else - -# include -# include - -#endif - -#endif /* _OS_TYPES_H */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/AUTHORS b/src/add-ons/media/plugins/ogg/liboggz/AUTHORS deleted file mode 100644 index 0b1f6b403f..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/AUTHORS +++ /dev/null @@ -1,11 +0,0 @@ -Conrad Parker - - Design, general implementation - -Silvia Pfeiffer - - Design, MS Windows porting - -Andre Pang - - Design, Mac OS X porting - -Zentaro Kavanagh - - MS Windows Porting and packaging. Windows specific bugfixes. diff --git a/src/add-ons/media/plugins/ogg/liboggz/COPYING b/src/add-ons/media/plugins/ogg/liboggz/COPYING deleted file mode 100644 index 0be71ec661..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/COPYING +++ /dev/null @@ -1,29 +0,0 @@ - Copyright (C) 2003 CSIRO Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the CSIRO nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/src/add-ons/media/plugins/ogg/liboggz/ChangeLog b/src/add-ons/media/plugins/ogg/liboggz/ChangeLog deleted file mode 100644 index e8ba589cbf..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/ChangeLog +++ /dev/null @@ -1,17 +0,0 @@ -Fri May 21 16:48:34 EST 2004 Conrad Parker - - * Version 0.8.3 - * fixes for win32 build procedure - * improved API documentation for seeking, OGGZ_AUTO and OggzIO - -Thu Mar 11 11:00:00 EST 2004 Silvia Pfeiffer - * Version 0.8.2 - * fixed up the Makefiles to not include the CVS subdirectories - -Sun Mar 07 16:00:00 EST 2004 Silvia Pfeiffer - * Version 0.8.1 - * includes Windows port with Makefile & VC6 workspace & .NET solution - -Thu Oct 16 21:55:07 EST 2003 Conrad Parker - - * split liboggz out from libannodex sources, started ChangeLog diff --git a/src/add-ons/media/plugins/ogg/liboggz/Jamfile b/src/add-ons/media/plugins/ogg/liboggz/Jamfile deleted file mode 100644 index 83587964e6..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/Jamfile +++ /dev/null @@ -1,14 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins ogg liboggz ; - -SubDirHdrs [ FDirName $(SUBDIR) .. libogg ] ; -SubDirCcFlags -Wno-missing-prototypes ; - -StaticLibrary liboggz.a : - oggz.c - oggz_auto.c - oggz_io.c - oggz_read.c - oggz_table.c - oggz_vector.c - oggz_write.c -; diff --git a/src/add-ons/media/plugins/ogg/liboggz/config.h b/src/add-ons/media/plugins/ogg/liboggz/config.h deleted file mode 100644 index e81dc759a1..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/config.h +++ /dev/null @@ -1,97 +0,0 @@ -/* config.h. Generated by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the 'getopt_long' function */ -#define HAVE_GETOPT_LONG - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `random' function. */ -#define HAVE_RANDOM 1 - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#define HAVE_REALLOC 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to build experimental code */ -/* #undef OGGZ_CONFIG_EXPERIMENTAL */ - -/* Do not build reading support */ -#define OGGZ_CONFIG_READ 1 - -/* Do not build writing support */ -#define OGGZ_CONFIG_WRITE 1 - -/* Name of package */ -#define PACKAGE "liboggz" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.8.3" - -/* 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 to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `long' if does not define. */ -/* #undef off_t */ - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define to `unsigned' if does not define. */ -/* #undef size_t */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz.c b/src/add-ons/media/plugins/ogg/liboggz/oggz.c deleted file mode 100644 index 4bef0a7daf..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "config.h" - -#include -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#include -#include - -#include - -#include "oggz_compat.h" -#include "oggz_private.h" -#include "oggz_vector.h" - -/*#define DEBUG*/ - -static int -oggz_flags_disabled (int flags) -{ - if (flags & OGGZ_WRITE) { - if (!OGGZ_CONFIG_WRITE) return OGGZ_ERR_DISABLED; - } else { - if (!OGGZ_CONFIG_READ) return OGGZ_ERR_DISABLED; - } - - return 0; -} - -OGGZ * -oggz_new (int flags) -{ - OGGZ * oggz; - - if (oggz_flags_disabled (flags)) return NULL; - - oggz = (OGGZ *) oggz_malloc (sizeof (OGGZ)); - if (oggz == NULL) return NULL; - - oggz->flags = flags; - oggz->file = NULL; - oggz->io = NULL; - - oggz->offset = 0; - oggz->offset_data_begin = 0; - - oggz->streams = oggz_vector_new (); - oggz->all_at_eos = 0; - - oggz->metric = NULL; - oggz->metric_user_data = NULL; - oggz->metric_internal = 0; - - oggz->order = NULL; - oggz->order_user_data = NULL; - - if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) { - oggz_write_init (oggz); - } else if (OGGZ_CONFIG_READ) { - oggz_read_init (oggz); - } - - return oggz; -} - -OGGZ * -oggz_open (char * filename, int flags) -{ - OGGZ * oggz = NULL; - FILE * file = NULL; - - if (oggz_flags_disabled (flags)) return NULL; - - if (flags & OGGZ_WRITE) { - file = fopen (filename, "wb"); - } else { - file = fopen (filename, "rb"); - } - if (file == NULL) return NULL; - - oggz = oggz_new (flags); - oggz->file = file; - - return oggz; -} - -OGGZ * -oggz_open_stdio (FILE * file, int flags) -{ - OGGZ * oggz = NULL; - - if (oggz_flags_disabled (flags)) return NULL; - - oggz = oggz_new (flags); - oggz->file = file; - - return oggz; -} - -int -oggz_flush (OGGZ * oggz) -{ - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - return oggz_io_flush (oggz); -} - -static int -oggz_stream_clear (void * data) -{ - oggz_stream_t * stream = (oggz_stream_t *) data; - - if (stream->ogg_stream.serialno != -1) - ogg_stream_clear (&stream->ogg_stream); - - if (stream->metric_internal) - oggz_free (stream->metric_user_data); - - return 0; -} - -int -oggz_close (OGGZ * oggz) -{ - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - oggz_vector_foreach (oggz->streams, oggz_stream_clear); - oggz_vector_delete (oggz->streams); - - if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) { - oggz_write_close (oggz); - } else if (OGGZ_CONFIG_READ) { - oggz_read_close (oggz); - } - - if (oggz->file != NULL) { - if (fclose (oggz->file) == EOF) { - return OGGZ_ERR_SYSTEM; - } - } - - oggz_free (oggz); - - return 0; -} - -off_t -oggz_tell (OGGZ * oggz) -{ - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - return oggz->offset; -} - -ogg_int64_t -oggz_tell_units (OGGZ * oggz) -{ - OggzReader * reader; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (oggz->flags & OGGZ_WRITE) { - return OGGZ_ERR_INVALID; - } - - reader = &oggz->x.reader; - - if (OGGZ_CONFIG_READ) { - return reader->current_unit; - } else { - return OGGZ_ERR_DISABLED; - } -} - -/******** oggz_stream management ********/ - -static int -oggz_find_stream (void * data, long serialno) -{ - oggz_stream_t * stream = (oggz_stream_t *) data; - - return (stream->ogg_stream.serialno == serialno); -} - -oggz_stream_t * -oggz_get_stream (OGGZ * oggz, long serialno) -{ - if (serialno < 0) return NULL; - - return oggz_vector_find (oggz->streams, oggz_find_stream, serialno); -} - -oggz_stream_t * -oggz_add_stream (OGGZ * oggz, long serialno) -{ - oggz_stream_t * stream; - - stream = oggz_malloc (sizeof (oggz_stream_t)); - if (stream == NULL) return NULL; - - ogg_stream_init (&stream->ogg_stream, (int)serialno); - - stream->delivered_non_b_o_s = 0; - stream->b_o_s = 1; - stream->e_o_s = 0; - stream->granulepos = 0; - stream->packetno = -1; /* will be incremented on first write */ - - stream->metric = NULL; - stream->metric_user_data = NULL; - stream->metric_internal = 0; - stream->order = NULL; - stream->order_user_data = NULL; - stream->read_packet = NULL; - stream->read_user_data = NULL; - - oggz_vector_insert_p (oggz->streams, stream); - - return stream; -} - -int -oggz_get_bos (OGGZ * oggz, long serialno) -{ - oggz_stream_t * stream; - int i, size; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (serialno == -1) { - size = oggz_vector_size (oggz->streams); - for (i = 0; i < size; i++) { - stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i); -#if 1 - /* If this stream has delivered a non bos packet, return FALSE */ - if (stream->delivered_non_b_o_s) return 0; -#else - /* If this stream has delivered its bos packet, return FALSE */ - if (!stream->b_o_s) return 0; -#endif - } - return 1; - } else { - stream = oggz_get_stream (oggz, serialno); - if (stream == NULL) - return OGGZ_ERR_BAD_SERIALNO; - - return stream->b_o_s; - } -} - -int -oggz_get_eos (OGGZ * oggz, long serialno) -{ - oggz_stream_t * stream; - int i, size; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (serialno == -1) { - size = oggz_vector_size (oggz->streams); - for (i = 0; i < size; i++) { - stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i); - if (!stream->e_o_s) return 0; - } - return 1; - } else { - stream = oggz_get_stream (oggz, serialno); - if (stream == NULL) - return OGGZ_ERR_BAD_SERIALNO; - - return stream->e_o_s; - } -} - -int -oggz_set_eos (OGGZ * oggz, long serialno) -{ - oggz_stream_t * stream; - int i, size; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (serialno == -1) { - size = oggz_vector_size (oggz->streams); - for (i = 0; i < size; i++) { - stream = (oggz_stream_t *) oggz_vector_nth_p (oggz->streams, i); - stream->e_o_s = 1; - } - oggz->all_at_eos = 1; - } else { - stream = oggz_get_stream (oggz, serialno); - if (stream == NULL) - return OGGZ_ERR_BAD_SERIALNO; - - stream->e_o_s = 1; - - if (oggz_get_eos (oggz, -1)) - oggz->all_at_eos = 1; - } - - return 0; -} - -long -oggz_serialno_new (OGGZ * oggz) -{ - long serialno; - - do { - serialno = oggz_random(); - } while (oggz_get_stream (oggz, serialno) != NULL); - - return serialno; -} - -/******** OggzMetric management ********/ - -typedef struct { - ogg_int64_t gr_n; - ogg_int64_t gr_d; -} oggz_metric_linear_t; - -static ogg_int64_t -oggz_metric_default_linear (OGGZ * oggz, long serialno, ogg_int64_t granulepos, - void * user_data) -{ - oggz_metric_linear_t * ldata = (oggz_metric_linear_t *)user_data; - - return (ldata->gr_d * granulepos / ldata->gr_n); -} - -int -oggz_set_metric_internal (OGGZ * oggz, long serialno, - OggzMetric metric, void * user_data, int internal) -{ - oggz_stream_t * stream; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (serialno == -1) { - if (oggz->metric_internal) - oggz_free (oggz->metric_user_data); - oggz->metric = metric; - oggz->metric_user_data = user_data; - oggz->metric_internal = internal; - } else { - stream = oggz_get_stream (oggz, serialno); - if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO; - - if (stream->metric_internal) - oggz_free (stream->metric_user_data); - stream->metric = metric; - stream->metric_user_data = user_data; - stream->metric_internal = internal; - } - - return 0; -} - -int -oggz_set_metric (OGGZ * oggz, long serialno, - OggzMetric metric, void * user_data) -{ - return oggz_set_metric_internal (oggz, serialno, metric, user_data, 0); -} - -int -oggz_set_metric_linear (OGGZ * oggz, long serialno, - ogg_int64_t granule_rate_numerator, - ogg_int64_t granule_rate_denominator) -{ - oggz_metric_linear_t * linear_data; - - /* we divide by the granulerate, ie. mult by gr_d/gr_n, so ensure - * numerator is non-zero */ - if (granule_rate_numerator == 0) { - granule_rate_numerator = 1; - granule_rate_denominator = 0; - } - - linear_data = oggz_malloc (sizeof (oggz_metric_linear_t)); - linear_data->gr_n = granule_rate_numerator; - linear_data->gr_d = granule_rate_denominator; - - return oggz_set_metric_internal (oggz, serialno, oggz_metric_default_linear, - linear_data, 1); -} - -/* - * Check if an oggz has metrics for all streams - */ -int -oggz_has_metrics (OGGZ * oggz) -{ - int i, size; - oggz_stream_t * stream; - - if (oggz->metric != NULL) return 1; - - size = oggz_vector_size (oggz->streams); - for (i = 0; i < size; i++) { - stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i); - if (stream->metric == NULL) return 0; - } - - return 1; -} - -ogg_int64_t -oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos) -{ - oggz_stream_t * stream; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (granulepos == -1) return -1; - - if (serialno == -1) { - if (oggz->metric) - return oggz->metric (oggz, serialno, granulepos, - oggz->metric_user_data); - } else { - stream = oggz_get_stream (oggz, serialno); - if (!stream) return -1; - - if (stream->metric) { - return stream->metric (oggz, serialno, granulepos, - stream->metric_user_data); - } else if (oggz->metric) { - return oggz->metric (oggz, serialno, granulepos, - oggz->metric_user_data); - } - } - - return -1; -} - -int -oggz_set_order (OGGZ * oggz, long serialno, - OggzOrder order, void * user_data) -{ - oggz_stream_t * stream; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (oggz->flags & OGGZ_WRITE) { - return OGGZ_ERR_INVALID; - } - - if (serialno == -1) { - oggz->order = order; - oggz->order_user_data = user_data; - } else { - stream = oggz_get_stream (oggz, serialno); - stream->order = order; - stream->order_user_data = user_data; - } - - return 0; -} - diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz.h b/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz.h deleted file mode 100644 index 0cf42beda8..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz.h +++ /dev/null @@ -1,1153 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_H__ -#define __OGGZ_H__ - -#include -#include - -#include -#include -#include - -/** \mainpage - * - * \section intro Oggz makes programming with Ogg easy! - * - * This is the documentation for the Oggz C API. Oggz provides 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 supports the flexibility afforded by the Ogg file format while - * presenting the following API niceties: - * - * - Strict adherence to the formatting requirements of Ogg - * \link basics bitstreams \endlink, to ensure that only valid bitstreams - * are generated - * - A simple, callback based open/read/close or open/write/close - * \link oggz.h interface \endlink to raw Ogg files - * - A customisable \link seek_api seeking \endlink abstraction for - * seeking on multitrack Ogg data - * - A packet queue for feeding incoming packets for writing, with callback - * based notification when this queue is empty - * - A means of overriding the \link oggz_io.h IO functions \endlink used by - * Oggz, for easier integration with media frameworks and similar systems. - * - A handy \link oggz_table.h table \endlink structure for storing - * information on each logical bitstream - * - * \subsection contents Contents - * - * - \link basics Basics \endlink: - * Information about Ogg required to understand liboggz - * - * - \link oggz.h oggz.h \endlink: - * Documentation of the Oggz C API - * - * - \link configuration Configuration \endlink: - * Customizing liboggz to only read or write. - * - * - \link building Building \endlink: - * Information related to building software that uses liboggz. - * - * \section Licensing - * - * liboggz is provided under the following BSD-style open source license: - * - * \include COPYING - * - */ - -/** \defgroup basics Ogg basics - * - * \section Scope - * - * This section provides a minimal introduction to Ogg concepts, covering - * only that which is required to use liboggz. - * - * For more detailed information, see the - * Ogg homepage - * or IETF RFC 3533 - * The Ogg File Format version 0. - * - * \section Terminology - * - * The monospace text below is quoted directly from RFC 3533. - * For each concept introduced, tips related to liboggz are provided - * in bullet points. - * - * \subsection bitstreams Physical and Logical Bitstreams - * - * The raw data of an Ogg stream, as read directly from a file or network - * socket, is called a physical bitstream. - * -
-   The result of an Ogg encapsulation is called the "Physical (Ogg)
-   Bitstream".  It encapsulates one or several encoder-created
-   bitstreams, which are called "Logical Bitstreams".  A logical
-   bitstream, provided to the Ogg encapsulation process, has a
-   structure, i.e., it is split up into a sequence of so-called
-   "Packets".  The packets are created by the encoder of that logical
-   bitstream and represent meaningful entities for that encoder only
-   (e.g., an uncompressed stream may use video frames as packets).
-
- * - * \subsection pages Packets and Pages - * - * Within the Ogg format, packets are written into \a pages. You can think - * of pages like pages in a book, and packets as items of the actual text. - * Consider, for example, individual poems or short stories as the packets. - * Pages are of course all the same size, and a few very short packets could - * be written into a single page. On the other hand, a very long packet will - * use many pages. - * - * - liboggz handles the details of writing packets into pages, and of - * reading packets from pages; your application deals only with - * ogg_packet structures. - * - Each ogg_packet structure contains a block of data and its - * length in bytes, plus other information related to the stream structure - * as explained below. - * - * \subsection serialno - * - * Each logical bitstream is uniquely identified by a serial number or - * \a serialno. - * - * - Packets are always associated with a \a serialno. This is not actually - * part of the ogg_packet structure, so wherever you see an - * ogg_packet in the liboggz API, you will see an accompanying - * \a serialno. - * -
-   This unique serial number is created randomly and does not have any
-   connection to the content or encoder of the logical bitstream it
-   represents.
-
- * - * - Use oggz_serialno_new() to generate a new serial number for each - * logical bitstream you write. - * - Use an \link oggz_table.h OggzTable \endlink, keyed by \a serialno, - * to store and retrieve data related to each logical bitstream. - * - * \subsection boseos b_o_s and e_o_s -
-   bos page: The initial page (beginning of stream) of a logical
-      bitstream which contains information to identify the codec type
-      and other decoding-relevant information.
-
-   eos page: The final page (end of stream) of a logical bitstream.
-
- * - * - Every ogg_packet contains \a b_o_s and \a e_o_s flags. - * Of course each of these will be set only once per logical bitstream. - * See the Structuring section below for rules on setting \a b_o_s and - * \a e_o_s when interleaving logical bitstreams. - * - This documentation will refer to \a bos and \a eos packets - * (not pages) as that is more closely represented by the API. - * The \a bos packet is the only packet on the \a bos page, and the - * \a eos packet is the last packet on the \a eos page. - * - * \subsection granulepos -
-   granule position: An increasing position number for a specific
-      logical bitstream stored in the page header.  Its meaning is
-      dependent on the codec for that logical bitstream
-
- * - * - Every ogg_packet contains a \a granulepos. The \a granulepos - * of each packet is used mostly for \link seek_api seeking. \endlink - * - * \section Structuring - * - * The general structure of an Ogg stream is governed by various rules. - * - * \subsection secondaries Secondary header packets - * - * Some data sources require initial setup information such as comments - * and codebooks to be present near the beginning of the stream (directly - * following the b_o_s packets. - * -
-   Ogg also allows but does not require secondary header packets after
-   the bos page for logical bitstreams and these must also precede any
-   data packets in any logical bitstream.  These subsequent header
-   packets are framed into an integral number of pages, which will not
-   contain any data packets.  So, a physical bitstream begins with the
-   bos pages of all logical bitstreams containing one initial header
-   packet per page, followed by the subsidiary header packets of all
-   streams, followed by pages containing data packets.
-
- * - * - liboggz handles the framing of \a packets into low-level \a pages. To - * ensure that the pages used by secondary headers contain no data packets, - * set the \a flush parameter of oggz_write_feed() to \a OGGZ_FLUSH_AFTER - * when queueing the last of the secondary headers. - * - or, equivalently, set \a flush to \a OGGZ_FLUSH_BEFORE when queueing - * the first of the data packets. - * - * \subsection boseosseq Sequencing b_o_s and e_o_s packets - * - * The following rules apply for sequencing \a bos and \a eos packets in - * a physical bitstream: -
-   ... All bos pages of all logical bitstreams MUST appear together at
-   the beginning of the Ogg bitstream.
-
-   ... eos pages for the logical bitstreams need not all occur
-   contiguously.  Eos pages may be 'nil' pages, that is, pages
-   containing no content but simply a page header with position
-   information and the eos flag set in the page header.
-
- * - * - oggz_write_feed() will fail with a return value of - * \a OGGZ_ERR_BOS if an attempt is made to queue a late \a bos packet - * - * \subsection interleaving Interleaving logical bitstreams -
-   It is possible to consecutively chain groups of concurrently
-   multiplexed bitstreams.  The groups, when unchained, MUST stand on
-   their own as a valid concurrently multiplexed bitstream.  The
-   following diagram shows a schematic example of such a physical
-   bitstream that obeys all the rules of both grouped and chained
-   multiplexed bitstreams.
-   
-               physical bitstream with pages of 
-          different logical bitstreams grouped and chained
-      -------------------------------------------------------------
-      |*A*|*B*|*C*|A|A|C|B|A|B|#A#|C|...|B|C|#B#|#C#|*D*|D|...|#D#|
-      -------------------------------------------------------------
-       bos bos bos             eos           eos eos bos       eos
-   
-   In this example, there are two chained physical bitstreams, the first
-   of which is a grouped stream of three logical bitstreams A, B, and C.
-   The second physical bitstream is chained after the end of the grouped
-   bitstream, which ends after the last eos page of all its grouped
-   logical bitstreams.  As can be seen, grouped bitstreams begin
-   together - all of the bos pages MUST appear before any data pages.
-   It can also be seen that pages of concurrently multiplexed bitstreams
-   need not conform to a regular order.  And it can be seen that a
-   grouped bitstream can end long before the other bitstreams in the
-   group end.
-
- * - * - oggz_write_feed() will fail, returning an explicit error value, if - * an attempt is made to queue a packet in violation of these rules. - * - * \section References - * - * This introduction to the Ogg format is derived from - * IETF RFC 3533 - * The Ogg File Format version 0 in accordance with the - * following copyright statement pertaining to the text of RFC 3533: - * -
-   Copyright (C) The Internet Society (2003).  All Rights Reserved.
-
-   This document and translations of it may be copied and furnished to
-   others, and derivative works that comment on or otherwise explain it
-   or assist in its implementation may be prepared, copied, published
-   and distributed, in whole or in part, without restriction of any
-   kind, provided that the above copyright notice and this paragraph are
-   included on all such copies and derivative works.  However, this
-   document itself may not be modified in any way, such as by removing
-   the copyright notice or references to the Internet Society or other
-   Internet organizations, except as needed for the purpose of
-   developing Internet standards in which case the procedures for
-   copyrights defined in the Internet Standards process must be
-   followed, or as required to translate it into languages other than
-   English.
-
-   The limited permissions granted above are perpetual and will not be
-   revoked by the Internet Society or its successors or assigns.
-
-   This document and the information contained herein is provided on an
-   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
-   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
-   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
-   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
- * - */ - -/** \defgroup configuration Configuration - * \section ./configure ./configure - * - * It is possible to customize the functionality of liboggz - * by using various ./configure flags when - * building it from source. You can build a smaller - * version of liboggz to only read or write. - * By default, both reading and writing support is built. - * - * For general information about using ./configure, see the file - * \link install INSTALL \endlink - * - * \subsection no_encode Removing writing support - * - * Configuring with \a --disable-write will remove all support for writing: - * - All internal write related functions will not be built - * - Any attempt to call oggz_new(), oggz_open() or oggz_open_stdio() - * with \a flags == OGGZ_WRITE will fail, returning NULL - * - Any attempt to call oggz_write(), oggz_write_output(), oggz_write_feed(), - * oggz_write_set_hungry_callback(), or oggz_write_get_next_page_size() - * will return OGGZ_ERR_DISABLED - * - * \subsection no_decode Removing reading support - * - * Configuring with \a --disable-read will remove all support for reading: - * - All internal reading related functions will not be built - * - Any attempt to call oggz_new(), oggz_open() or oggz_open_stdio() - * with \a flags == OGGZ_READ will fail, returning NULL - * - Any attempt to call oggz_read(), oggz_read_input(), - * oggz_set_read_callback(), oggz_seek(), or oggz_seek_units() will return - * OGGZ_ERR_DISABLED - * - */ - -/** \defgroup install Installation - * \section install INSTALL - * - * \include INSTALL - */ - -/** \defgroup building Building against liboggz - * - * - * \section autoconf Using GNU autoconf - * - * If you are using GNU autoconf, you do not need to call pkg-config - * directly. Use the following macro to determine if liboggz is - * available: - * -
- PKG_CHECK_MODULES(OGGZ, oggz >= 0.6.0,
-                   HAVE_OGGZ="yes", HAVE_OGGZ="no")
- if test "x$HAVE_OGGZ" = "xyes" ; then
-   AC_SUBST(OGGZ_CFLAGS)
-   AC_SUBST(OGGZ_LIBS)
- fi
- 
- * - * If liboggz is found, HAVE_OGGZ will be set to "yes", and - * the autoconf variables OGGZ_CFLAGS and OGGZ_LIBS will - * be set appropriately. - * - * \section pkg-config Determining compiler options with pkg-config - * - * If you are not using GNU autoconf in your project, you can use the - * pkg-config tool directly to determine the correct compiler options. - * -
- OGGZ_CFLAGS=`pkg-config --cflags oggz`
-
- OGGZ_LIBS=`pkg-config --libs oggz`
- 
- * - */ - -/** \file - * The liboggz C API. - * - * \section general Generic semantics - * - * All access is managed via an OGGZ handle. This can be instantiated - * in one of three ways: - * - * - oggz_open() - Open a full pathname - * - oggz_open_stdio() - Use an already opened FILE * - * - oggz_new() - Create an anonymous OGGZ object, which you can later - * handle via memory buffers - * - * To finish using an OGGZ handle, it should be closed with oggz_close(). - * - * \section reading Reading Ogg data - * - * To read from Ogg files or streams you must instantiate an OGGZ handle - * with flags set to OGGZ_READ, and provide an OggzReadPacket - * callback with oggz_set_read_callback(). - * See the \ref read_api section for details. - * - * \section writing Writing Ogg data - * - * To write to Ogg files or streams you must instantiate an OGGZ handle - * with flags set to OGGZ_WRITE, and provide an OggzWritePacket - * callback with oggz_set_write_callback(). - * See the \ref write_api section for details. - * - * \section seeking Seeking on Ogg data - * - * To seek while reading Ogg files or streams you must instantiate an OGGZ - * handle for reading, and ensure that an \link metric OggzMetric \endlink - * function is defined to translate packet positions into units such as time. - * See the \ref seek_api section for details. - * - * \section io Overriding the IO methods - * - * When an OGGZ handle is instantiated by oggz_open() or oggz_open_stdio(), - * Oggz uses stdio functions internally to access the raw data. However for - * some applications, the raw data cannot be accessed via stdio -- this - * commonly occurs when integrating with media frameworks. For such - * applications, you can provide Oggz with custom IO methods that it should - * use to access the raw data. Oggz will then use these custom methods, - * rather than using stdio methods, to access the raw data internally. - * - * For details, see \link oggz_io.h \endlink. - * - * \section headers Headers - * - * oggz.h provides direct access to libogg types such as ogg_packet, defined - * in . - */ - -/** - * An opaque handle to an Ogg file. This is returned by oggz_open() or - * oggz_new(), and is passed to all other oggz_* functions. - */ -typedef void OGGZ; - -/** - * Create a new OGGZ object - * \param flags OGGZ_READ or OGGZ_WRITE - * \returns A new OGGZ object - * \retval NULL on system error; check errno for details - */ -OGGZ * oggz_new (int flags); - -/** - * Open an Ogg file, creating an OGGZ handle for it - * \param filename The file to open - * \param flags OGGZ_READ or OGGZ_WRITE - * \return A new OGGZ handle - * \retval NULL System error; check errno for details - */ -OGGZ * oggz_open (char * filename, int flags); - -/** - * Create an OGGZ handle associated with a stdio stream - * \param file An open FILE handle - * \param flags OGGZ_READ or OGGZ_WRITE - * \returns A new OGGZ handle - * \retval NULL System error; check errno for details - */ -OGGZ * oggz_open_stdio (FILE * file, int flags); - -/** - * Ensure any associated io streams are flushed. - * \param oggz An OGGZ handle - * \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_SYSTEM System error; check errno for details - */ -int oggz_flush (OGGZ * oggz); - -/** - * Close an OGGZ handle - * \param oggz An OGGZ handle - * \retval 0 Success - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_SYSTEM System error; check errno for details - */ -int oggz_close (OGGZ * oggz); - -/** - * Determine if a given logical bitstream is at bos (beginning of stream). - * \param oggz An OGGZ handle - * \param serialno Identify a logical bitstream within \a oggz, or -1 to - * query if all logical bitstreams in \a oggz are at bos - * \retval 1 The given stream is at bos - * \retval 0 The given stream is not at bos - * \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing - * logical bitstream in \a oggz. - */ -int oggz_get_bos (OGGZ * oggz, long serialno); - -/** - * Determine if a given logical bitstream is at eos (end of stream). - * \param oggz An OGGZ handle - * \param serialno Identify a logical bitstream within \a oggz, or -1 to - * query if all logical bitstreams in \a oggz are at eos - * \retval 1 The given stream is at eos - * \retval 0 The given stream is not at eos - * \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing - * logical bitstream in \a oggz. - */ -int oggz_get_eos (OGGZ * oggz, long serialno); - -/** \defgroup read_api OGGZ Read API - * - * OGGZ parses Ogg bitstreams, forming ogg_packet structures, and calling - * your OggzReadPacket callback(s). - * - * You provide Ogg data to OGGZ with oggz_read() or oggz_read_input(), and - * independently process it in OggzReadPacket callbacks. - * It is possible to set a different callback per \a serialno (ie. for each - * logical bitstream in the Ogg bitstream - see the \ref basics section for - * more detail). - * - * See \ref seek_api for information on seeking on interleaved Ogg data. - * - * \{ - */ - -/** - * This is the signature of a callback which you must provide for Oggz - * to call whenever it finds a new packet in the Ogg stream associated - * with \a oggz. - * - * \param oggz The OGGZ handle - * \param op The full ogg_packet (see ) - * \param serialno Identify the logical bistream in \a oggz that contains - * \a op - * \param user_data A generic pointer you have provided earlier - * \returns 0 to continue, non-zero to instruct OGGZ to stop. - * - * \note It is possible to provide different callbacks per logical - * bitstream -- see oggz_set_read_callback() for more information. - */ -typedef int (*OggzReadPacket) (OGGZ * oggz, ogg_packet * op, long serialno, - void * user_data); - -/** - * Set a callback for Oggz to call when a new Ogg packet is found in the - * stream. - * - * \param oggz An OGGZ handle previously opened for reading - * \param serialno Identify the logical bitstream in \a oggz to attach - * this callback to, or -1 to attach this callback to all unattached - * logical bitstreams in \a oggz. - * \param read_packet Your callback function - * \param user_data Arbitrary data you wish to pass to your callback - * \retval 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 - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - * - * \note Values of \a serialno other than -1 allows you to specify different - * callback functions for each logical bitstream. - * - * \note It is safe to call this callback from within an OggzReadPacket - * function, in order to specify that subsequent packets should be handled - * by a different OggzReadPacket function. - */ -int oggz_set_read_callback (OGGZ * oggz, long serialno, - OggzReadPacket read_packet, void * user_data); - -/** - * Read n bytes into \a oggz, calling any read callbacks on the fly. - * \param oggz An OGGZ handle previously opened for reading - * \param n A count of bytes to ingest - * \retval "> 0" The number of bytes successfully ingested. - * \retval 0 End of file - * \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_SYSTEM System error; check errno for details - */ -long oggz_read (OGGZ * oggz, long n); - -/** - * Input data into \a oggz. - * \param oggz An OGGZ handle previously opened for reading - * \param buf A memory buffer - * \param n A count of bytes to input - * \retval "> 0" The number of bytes successfully ingested. - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - */ -long oggz_read_input (OGGZ * oggz, unsigned char * buf, long n); - -/** \} - */ - -/** \defgroup force_feed Writing by force feeding OGGZ - * - * Force feeding involves synchronously: - * - Creating an \a ogg_packet structure - * - Adding it to the packet queue with oggz_write_feed() - * - Calling oggz_write() or oggz_write_output(), repeatedly as necessary, - * to generate the Ogg bitstream. - * - * This process is illustrated in the following diagram: - * - * \image html forcefeed.png - * \image latex forcefeed.eps "Force Feeding OGGZ" width=10cm - * - * The following example code generates a stream of ten packets, each - * containing a single byte ('A', 'B', ... , 'J'): - * - * \include write-feed.c - */ - -/** \defgroup hungry Writing with OggzHungry callbacks - * - * You can add packets to the OGGZ packet queue only when it is "hungry" - * by providing an OggzHungry callback. - * - * An OggzHungry callback will: - * - Create an \a ogg_packet structure - * - Add it to the packet queue with oggz_write_feed() - * - * Once you have set such a callback with oggz_write_set_hungry_callback(), - * simply call oggz_write() or oggz_write_output() repeatedly, and OGGZ - * will call your callback to provide packets when it is hungry. - * - * This process is illustrated in the following diagram: - * - * \image html hungry.png - * \image latex hungry.eps "Using OggzHungry" width=10cm - * - * The following example code generates a stream of ten packets, each - * containing a single byte ('A', 'B', ... , 'J'): - * - * \include write-hungry.c - */ - -/** \defgroup write_api OGGZ Write API - * - * OGGZ maintains a packet queue, such that you can independently add - * packets to the queue and write an Ogg bitstream. - * There are two complementary methods for adding packets to the - * packet queue. - * - * - by \link force_feed force feeding OGGZ \endlink - * - by using \link hungry OggzHungry \endlink callbacks - * - * As each packet is enqueued, its validity is checked against the framing - * constraints outlined in the \link basics Ogg basics \endlink section. - * If it does not pass these constraints, oggz_write_feed() will fail with - * an appropriate error code. - * - * \note - * - When writing, you can ensure that a packet starts on a new page - * by setting the \a flush parameter of oggz_write_feed() to - * \a OGGZ_FLUSH_BEFORE when enqueuing it. - * Similarly you can ensure that the last page a packet is written into - * won't contain any following packets by setting the \a flush parameter - * of oggz_write_feed() to \a OGGZ_FLUSH_AFTER. - * - The \a OGGZ_FLUSH_BEFORE and \a OGGZ_FLUSH_AFTER flags can be bitwise - * OR'd together to ensure that the packet will not share any pages with - * any other packets, either before or after. - * - * \{ - */ - -/** - * This is the signature of a callback which Oggz will call when \a oggz - * is \link hungry hungry \endlink. - * - * \param oggz The OGGZ handle - * \param empty A value of 1 indicates that the packet queue is currently - * empty. A value of 0 indicates that the packet queue is not empty. - * \param user_data A generic pointer you have provided earlier - * \retval 0 Continue - * \retval non-zero Instruct OGGZ to stop. - */ -typedef int (*OggzWriteHungry) (OGGZ * oggz, int empty, void * user_data); - -/** - * Set a callback for Oggz to call when \a oggz - * is \link hungry hungry \endlink. - * - * \param oggz An OGGZ handle previously opened for writing - * \param hungry Your callback function - * \param only_when_empty When to call: a value of 0 indicates that - * OGGZ should call \a hungry() after each and every packet is written; - * a value of 1 indicates that OGGZ should call \a hungry() only when - * its packet queue is empty - * \param user_data Arbitrary data you wish to pass to your callback - * \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 - * \note Passing a value of 0 for \a only_when_empty allows you to feed - * new packets into \a oggz's packet queue on the fly. - */ -int oggz_write_set_hungry_callback (OGGZ * oggz, - OggzWriteHungry hungry, - int only_when_empty, - void * user_data); -/** - * Add a packet to \a oggz's packet queue. - * \param oggz An OGGZ handle previously opened for writing - * \param op An ogg_packet with all fields filled in - * \param serialno Identify the logical bitstream in \a oggz to add the - * packet to - * \param flush Bitmask of OGGZ_FLUSH_BEFORE, OGGZ_FLUSH_AFTER - * \param guard A guard for nocopy, NULL otherwise - * \retval 0 Success - * \retval OGGZ_ERR_BAD_GUARD \a guard specified has non-zero initialization - * \retval OGGZ_ERR_BOS Packet would be bos packet of a new logical bitstream, - * but oggz has already written one or more non-bos packets in - * other logical bitstreams, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_EOS The logical bitstream identified by \a serialno is - * already at eos, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_BAD_BYTES \a op->bytes is invalid, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_BAD_B_O_S \a op->b_o_s is invalid, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_BAD_GRANULEPOS \a op->granulepos is less than that of - * an earlier packet within this logical bitstream, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_BAD_PACKETNO \a op->packetno is less than that of an - * earlier packet within this logical bitstream, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing - * logical bitstream in \a oggz, - * and \a oggz is not flagged OGGZ_NONSTRICT - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - * - * \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 - * value; ie. 1 for the first packet of a new stream, and 0 otherwise. - */ -int oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, - int * guard); - -/** - * Output data from an OGGZ handle. Oggz will call your write callback - * as needed. - * - * \param oggz An OGGZ handle previously opened for writing - * \param buf A memory buffer - * \param n A count of bytes to output - * \retval "> 0" The number of bytes successfully output - * \retval 0 End of stream - * \retval OGGZ_ERR_RECURSIVE_WRITE Attempt to initiate writing from - * within an OggzHungry callback - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - */ -long oggz_write_output (OGGZ * oggz, unsigned char * buf, long n); - -/** - * Write n bytes from an OGGZ handle. Oggz will call your write callback - * as needed. - * - * \param oggz An OGGZ handle previously opened for writing - * \param n A count of bytes to be written - * \retval "> 0" The number of bytes successfully output - * \retval 0 End of stream - * \retval OGGZ_ERR_RECURSIVE_WRITE Attempt to initiate writing from - * within an OggzHungry callback - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - */ -long oggz_write (OGGZ * oggz, long n); - -/** - * Query the number of bytes in the next page to be written. - * - * \param oggz An OGGZ handle previously opened for writing - * \retval ">= 0" The number of bytes in the next page - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - */ -long oggz_write_get_next_page_size (OGGZ * oggz); - -/** \} - */ - -/** \defgroup auto OGGZ_AUTO - * - * \section auto Automatic Metrics - * - * Oggz can automatically provide \link metric metrics \endlink for the - * common media codecs - * Speex, - * Vorbis, - * and Theora, - * as well as all Annodex streams. - * You need do nothing more than open the file with the OGGZ_AUTO flag set. - * - * - Create an OGGZ handle for reading with \a flags = OGGZ_READ | OGGZ_AUTO - * - Read data, ensuring that you have received all b_o_s pages before - * attempting to seek. - * - * Oggz will silently parse known codec headers and associate metrics - * appropriately; if you attempt to seek before you have received all - * b_o_s pages, Oggz will not have had a chance to parse the codec headers - * and associate metrics. - * It is safe to seek once you have received a packet with \a b_o_s == 0; - * see the \link basics Ogg basics \endlink section for more details. - * - * \note This functionality is provided for convenience. Oggz parses - * these codec headers internally, and so liboggz is \b not linked to - * libspeex, libvorbis, libtheora or libannodex. - */ - -/** \defgroup metric Using OggzMetric - * - * \section metric_intro Introduction - * - * An OggzMetric is a helper function for Oggz's seeking mechanism. - * - * If every position in an Ogg stream can be described by a metric such as - * time, then it is possible to define a function that, given a serialno and - * granulepos, returns a measurement in units such as milliseconds. Oggz - * will use this function repeatedly while seeking in order to navigate - * through the Ogg stream. - * - * The meaning of the units is arbitrary, but must be consistent across all - * logical bitstreams. This allows Oggz to seek accurately through Ogg - * bitstreams containing multiple logical bitstreams such as tracks of media. - * - * \section setting How to set metrics - * - * You don't need to set metrics for Vorbis, Speex, Theora or Annodex. - * These can be handled \link auto automatically \endlink by Oggz. - * - * For most others it is simply a matter of providing a linear multiplication - * factor (such as a sampling rate, if each packet's granulepos represents a - * sample number). For non-linear data streams, you will need to explicitly - * provide your own OggzMetric function. - * - * \subsection linear Linear Metrics - * - * - Set the \a granule_rate_numerator and \a granule_rate_denominator - * appropriately using oggz_set_metric_linear() - * - * \subsection custom Custom Metrics - * - * For streams with non-linear granulepos, you need to set a custom metric: - * - * - Implement an OggzMetric callback - * - Set the OggzMetric callback using oggz_set_metric() - * - * \section using Seeking with OggzMetrics - * - * To seek, use oggz_seek_units(). Oggz will perform a ratio search - * through the Ogg bitstream, using the OggzMetric callback to determine - * its position relative to the desired unit. - * - * \note - * - * Many data streams begin with headers describing such things as codec - * setup parameters. One of the assumptions Monty makes is: - * - * - Given pre-cached decode headers, a player may seek into a stream at - * any point and begin decode. - * - * Thus, the first action taken by applications dealing with such data is - * to read in and cache the decode headers; thereafter the application can - * safely seek to arbitrary points in the data. - * - * This impacts seeking because the portion of the bitstream containing - * decode headers should not be considered part of the metric space. To - * inform Oggz not to seek earlier than the end of the decode headers, - * use oggz_set_data_start(). - * - */ - -/** \defgroup seek_semantics Semantics of seeking in Ogg bitstreams - * - * \section seek_semantics_intro Introduction - * - * The seeking semantics of the Ogg file format were outlined by Monty in - * a - * post to theora-dev in September 2002. Quoting from that post, we - * have the following assumptions: - * - * - Ogg is not a non-linear format. ... It is a media transport format - * designed to do nothing more than deliver content, in a stream, and - * have all the pieces arrive on time and in sync. - * - The Ogg layer does not know the specifics of the codec data it's - * multiplexing into a stream. It knows nothing beyond 'Oooo, packets!', - * that the packets belong to different buckets, that the packets go in - * order, and that packets have position markers. Ogg does not even have - * a concept of 'time'; it only knows about the sequentially increasing, - * unitless position markers. It is up to higher layers which have - * access to the codec APIs to assign and convert units of framing or - * time. - * - * (For more details on the structure of Ogg streams, see the - * \link basics Ogg Basics \endlink section). - * - * For data such as media, for which it is possible to provide a mapping - * such as 'time', OGGZ can efficiently navigate through an Ogg stream - * by use of an OggzMetric callback, thus allowing automatic seeking to - * points in 'time'. - * - * For common codecs you can ask Oggz to set this for you automatically by - * instantiating the OGGZ handle with the OGGZ_AUTO flag set. For others - * you can specify a multiplier with oggz_set_metric_linear(), or a generic - * non-linear metric with oggz_set_metric(). - * - */ - -/** \defgroup seek_api OGGZ Seek API - * - * Oggz can seek on multitrack, multicodec bitstreams. - * - * - If you are expecting to only handle - * Annodex bitstreams, - * or any combination of Vorbis, - * Speex and - * Theora logical bitstreams, seeking - * is built-in to Oggz. See \link auto OGGZ_AUTO \endlink for details. - * - * - For other data streams, you will need to provide a metric function; - * see the section on \link metric Using OggzMetrics \endlink for details - * of setting up and seeking with metrics. - * - * - It is always possible to seek to exact byte positions using oggz_seek(). - * - * - A mechanism to aid seeking across non-metric spaces for which a partial - * order exists (ie. data that is not synchronised by a measure such as time, - * but is nevertheless somehow seekably structured), is also planned. - * - * For a full description of the seeking methods possible in Ogg, see - * \link seek_semantics Semantics of seeking in Ogg bitstreams \endlink. - * - * \{ - */ - -/** - * Specify that a logical bitstream has a linear metric - * \param oggz An OGGZ handle - * \param serialno Identify the logical bitstream in \a oggz to attach - * this linear metric to. A value of -1 indicates that the metric should - * be attached to all unattached logical bitstreams in \a oggz. - * \param granule_rate_numerator The numerator of the granule rate - * \param granule_rate_denominator The denominator of the granule rate - * \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_metric_linear (OGGZ * oggz, long serialno, - ogg_int64_t granule_rate_numerator, - ogg_int64_t granule_rate_denominator); - -/** - * This is the signature of a function to correlate Ogg streams. - * If every position in an Ogg stream can be described by a metric (eg. time) - * then define this function that returns some arbitrary unit value. - * This is the normal use of OGGZ for media streams. The meaning of units is - * arbitrary, but must be consistent across all logical bitstreams; for - * example a conversion of the time offset of a given packet into nanoseconds - * or a similar stream-specific subdivision may be appropriate. - * - * \param oggz An OGGZ handle - * \param serialno Identifies a logical bitstream within \a oggz - * \param granulepos A granulepos within the logical bitstream identified - * by \a serialno - * \param user_data Arbitrary data you wish to pass to your callback - * \returns A conversion of the (serialno, granulepos) pair into a measure - * in units which is consistent across all logical bitstreams within \a oggz - */ -typedef ogg_int64_t (*OggzMetric) (OGGZ * oggz, long serialno, - ogg_int64_t granulepos, void * user_data); - -/** - * Set the OggzMetric to use for an OGGZ handle - * - * \param oggz An OGGZ handle - * \param serialno Identify the logical bitstream in \a oggz to attach - * this metric to. A value of -1 indicates that this metric - * should be attached to all unattached logical bitstreams - * in \a oggz. - * \param metric An OggzMetric callback - * \param user_data arbitrary data to pass to the metric callback - * - * \returns 0 Success - * \retval OGGZ_ERR_BAD_SERIALNO \a serialno does not identify an existing - * logical bitstream in \a oggz, and is not -1 - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * - * \note Specifying values of \a serialno other than -1 allows you to pass - * logical bitstream specific user_data to the same metric. - * \note Alternatively, you may use a different \a metric for each - * \a serialno, but all metrics used must return mutually consistent - * unit measurements. - */ -int oggz_set_metric (OGGZ * oggz, long serialno, OggzMetric metric, - void * user_data); - -/** - * Query the current offset in units corresponding to the Metric function - * \param oggz An OGGZ handle - * \returns the offset in units - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - */ -ogg_int64_t oggz_tell_units (OGGZ * oggz); - -/** - * Seek to a number of units corresponding to the Metric function - * \param oggz An OGGZ handle - * \param units A number of units - * \param whence As defined in : SEEK_SET, SEEK_CUR or SEEK_END - * \returns the new file offset, or -1 on failure. - */ -ogg_int64_t oggz_seek_units (OGGZ * oggz, ogg_int64_t units, int whence); - -#ifdef _UNIMPLEMENTED -/** \defgroup order OggzOrder - * - * \subsection OggzOrder - * - * Suppose there is a partial order < and a corresponding equivalence - * relation = defined on the space of packets in the Ogg stream of 'OGGZ'. - * An OggzOrder simply provides a comparison in terms of '<' and '=' for - * ogg_packets against a target. - * - * To use OggzOrder: - * - * - Implement an OggzOrder callback - * - Set the OggzOrder callback for an OGGZ handle with oggz_set_order() - * - To seek, use oggz_seek_byorder(). Oggz will use a combination bisection - * search and scan of the Ogg bitstream, using the OggzOrder callback to - * match against the desired 'target'. - * - * Otherwise, for more general ogg streams for which a partial order can be - * defined, define a function matching this specification. - * - * Parameters: - * - * OGGZ: the OGGZ object - * op: an ogg packet in the stream - * target: a user defined object - * - * Return values: - * - * -1 , if 'op' would occur before the position represented by 'target' - * 0 , if the position of 'op' is equivalent to that of 'target' - * 1 , if 'op' would occur after the position represented by 'target' - * 2 , if the relationship between 'op' and 'target' is undefined. - * - * Symbolically: - * - * Suppose there is a partial order < and a corresponding equivalence - * relation = defined on the space of packets in the Ogg stream of 'OGGZ'. - * Let p represent the position of the packet 'op', and t be the position - * represented by 'target'. - * - * Then a function implementing OggzPacketOrder should return as follows: - * - * -1 , p < t - * 0 , p = t - * 1 , t < p - * 2 , otherwise - * - * Hacker's hint: if there are no circumstances in which you would return - * a value of 2, there is a linear order; it may be possible to define a - * Metric rather than an Order. - * - */ -typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target, - void * user_data); -/** - * \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 - */ -int oggz_set_order (OGGZ * oggz, long serialno, OggzOrder order, - void * user_data); - -long oggz_seek_byorder (OGGZ * oggz, void * target); - -#endif /* _UNIMPLEMENTED */ - -/** - * Erase any input buffered in OGGZ. This discards any input read from the - * underlying IO system but not yet delivered as ogg_packets. - * - * \param oggz An OGGZ handle - * \retval 0 Success - * \retval OGGZ_ERR_SYSTEM Error seeking on underlying IO. - * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ - * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ - */ -int oggz_purge (OGGZ * oggz); - -/** - * Tell OGGZ to remember the given offset as the start of data. - * This informs the seeking mechanism that when seeking back to unit 0, - * go to the given offset, not to the start of the file, which is usually - * codec headers. - * The usual usage is: -
-    oggz_set_data_start (oggz, oggz_tell (oggz));
-
- * \param oggz An OGGZ handle previously opened for reading - * \param offset The offset of the start of data - * \returns 0 on success, -1 on failure. - */ -int oggz_set_data_start (OGGZ * oggz, off_t offset); - -/** - * Provide the file offset in bytes corresponding to the data read. - * \param oggz An OGGZ handle - * \returns The current offset of oggz. - * - * \note When reading, the value returned by oggz_tell() reflects the - * data offset of the start of the most recent packet processed, so that - * when called from an OggzReadPacket callback it reflects the byte - * offset of the start of the packet. As OGGZ may have internally read - * ahead, this may differ from the current offset of the associated file - * descriptor. - */ -off_t oggz_tell (OGGZ * oggz); - -/** - * Seek to a specific byte offset - * \param oggz An OGGZ handle - * \param offset a byte offset - * \param whence As defined in : SEEK_SET, SEEK_CUR or SEEK_END - * \returns the new file offset, or -1 on failure. - */ -off_t oggz_seek (OGGZ * oggz, off_t offset, int whence); - -#ifdef _UNIMPLEMENTED -long oggz_seek_packets (OGGZ * oggz, long serialno, long packets, int whence); -#endif - -/** \} - */ - -/** - * Request a new serialno, as required for a new stream, ensuring the serialno - * is not yet used for any other streams managed by this OGGZ. - * \param oggz An OGGZ handle - * \returns A new serialno, not already occuring in any logical bitstreams - * in \a oggz. - */ -long oggz_serialno_new (OGGZ * oggz); - -#include - -#endif /* __OGGZ_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_constants.h b/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_constants.h deleted file mode 100644 index 2449b762b4..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_constants.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_CONSTANTS_H__ -#define __OGGZ_CONSTANTS_H__ - -/** \file - * General constants used by liboggz. - */ - -/** - * 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 - */ -enum OggzFlags { - /** Read only */ - OGGZ_READ = 0x00, - - /** Write only */ - OGGZ_WRITE = 0x01, - - /** Disable strict adherence to mapping constraints, eg for - * handling an incomplete stream */ - OGGZ_NONSTRICT = 0x10, - - /** - * Scan for known headers while reading, and automatically set - * metrics appropriately. Opening a file for reading with - * \a flags = OGGZ_READ | OGGZ_AUTO will allow seeking on Speex, - * Vorbis, Theora and all Annodex streams in units of milliseconds, - * once all bos pages have been delivered. */ - OGGZ_AUTO = 0x20 -}; - -enum OggzStatus { - OGGZ_STATUS_INITIALIZED = 0, - OGGZ_STATUS_INTERNAL_ERROR = 1, - - OGGZ_STATUS_READ_ACTIVE = 10, - OGGZ_STATUS_READ_STOP_OK = 11, - OGGZ_STATUS_READ_STOP_ERR = 12, - OGGZ_STATUS_READ_EOF = 13 -}; - -enum OggzStopCtl { - /** Continue calling read callbacks */ - OGGZ_CONTINUE = 0, - - /** Stop calling callbacks, but retain buffered packet data */ - OGGZ_STOP_OK = 1, - - /** Stop calling callbacks, and purge buffered packet data */ - OGGZ_STOP_ERR = -1 -}; - -/** - * Flush options for oggz_write_feed; can be or'ed together - */ -enum OggzFlushOpts { - /** Flush all streams before beginning this packet */ - OGGZ_FLUSH_BEFORE = 0x01, - - /** Flush after this packet */ - OGGZ_FLUSH_AFTER = 0x02 -}; - -/** - * Definitions of error return values - */ -enum OggzError { - /** No error */ - OGGZ_ERR_OK = 0, - - /** generic error */ - OGGZ_ERR_GENERIC = -1, - - /** oggz is not a valid OGGZ */ - OGGZ_ERR_BAD_OGGZ = -2, - - /** The requested operation is not suitable for this OGGZ */ - OGGZ_ERR_INVALID = -3, - - /** oggz contains no logical bitstreams */ - OGGZ_ERR_NO_STREAMS = -4, - - /** Operation is inappropriate for oggz in current bos state */ - OGGZ_ERR_BOS = -5, - - /** Operation is inappropriate for oggz in current eos state */ - OGGZ_ERR_EOS = -6, - - /** Operation requires a valid metric, but none has been set */ - OGGZ_ERR_BAD_METRIC = -7, - - /** System specific error; check errno for details */ - OGGZ_ERR_SYSTEM = -10, - - /** Functionality disabled at build time */ - OGGZ_ERR_DISABLED = -11, - - /** Seeking operation is not possible for this OGGZ */ - OGGZ_ERR_NOSEEK = -13, - - /** The requested serialno does not exist in this OGGZ */ - OGGZ_ERR_BAD_SERIALNO = -20, - - /** Packet disallowed due to invalid byte length */ - OGGZ_ERR_BAD_BYTES = -21, - - /** Packet disallowed due to invalid b_o_s (beginning of stream) flag */ - OGGZ_ERR_BAD_B_O_S = -22, - - /** Packet disallowed due to invalid e_o_s (end of stream) flag */ - OGGZ_ERR_BAD_E_O_S = -23, - - /** Packet disallowed due to invalid granulepos */ - OGGZ_ERR_BAD_GRANULEPOS = -24, - - /** Packet disallowed due to invalid packetno */ - OGGZ_ERR_BAD_PACKETNO = -25, - - /** Guard provided by user has non-zero value */ - OGGZ_ERR_BAD_GUARD = -210, - - /** Attempt to call oggz_write() or oggz_write_output() from within - * a hungry() callback */ - OGGZ_ERR_RECURSIVE_WRITE = -266 -}; - -#endif /* __OGGZ_CONSTANTS_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_io.h b/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_io.h deleted file mode 100644 index 0bc80d3f8c..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_io.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_IO_H__ -#define __OGGZ_IO_H__ - -/** \file - * Overriding the functions used for input and output of raw data. - * - * OggzIO provides a way of overriding the functions Oggz uses to access - * its raw input or output data. This is required in many situations where - * the raw stream cannot be accessed via stdio, but can be accessed by - * other means. This is typically useful within media frameworks, where - * accessing and moving around in the data is possible only using methods - * provided by the framework. - * - * The functions you provide for overriding IO will be used by Oggz - * whenever you call oggz_read() or oggz_write(). They will also be - * used repeatedly by Oggz when you call oggz_seek(). - * - * \note Opening a file with oggz_open() or oggz_open_stdio() is equivalent - * to calling oggz_new() and setting stdio based functions for data IO. - */ - -/** - * This is the signature of a function which you provide for Oggz - * to call when it needs to acquire raw input data. - * - * \param user_handle A generic pointer you have provided earlier - * \param n The length in bytes that Oggz wants to read - * \param buf The buffer that you read data into - * \retval "> 0" The number of bytes successfully read into the buffer - * \retval 0 to indicate that there is no more data to read (End of file) - * \retval "< 0" An error condition - */ -typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n); - -/** - * This is the signature of a function which you provide for Oggz - * to call when it needs to output raw data. - * - * \param user_handle A generic pointer you have provided earlier - * \param n The length in bytes of the data - * \param buf A buffer containing data to write - * \retval ">= 0" The number of bytes successfully written (may be less than - * \a n if a write error has occurred) - * \retval "< 0" An error condition - */ -typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n); - -/** - * This is the signature of a function which you provide for Oggz - * to call when it needs to seek on the raw input or output data. - * - * \param user_handle A generic pointer you have provided earlier - * \param offset The offset in bytes to seek to - * \param whence SEEK_SET, SEEK_CUR or SEEK_END (as for stdio.h) - * \retval ">= 0" The offset seeked to - * \retval "< 0" An error condition - * - * \note If you provide an OggzIOSeek function, you MUST also provide - * an OggzIOTell function, or else all your seeks will fail. - */ -typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence); - -/** - * This is the signature of a function which you provide for Oggz - * to call when it needs to determine the current offset of the raw - * input or output data. - * - * \param user_handle A generic pointer you have provided earlier - * \retval ">= 0" The offset - * \retval "< 0" An error condition - */ -typedef long (*OggzIOTell) (void * user_handle); - -/** - * This is the signature of a function which you provide for Oggz - * to call when it needs to flush the output data. The behaviour - * of this function is similar to that of fflush() in stdio. - * - * \param user_handle A generic pointer you have provided earlier - * \retval 0 Success - * \retval "< 0" An error condition - */ -typedef int (*OggzIOFlush) (void * user_handle); - - -/** - * Set a function for Oggz to call when it needs to read input data. - * - * \param oggz An OGGZ handle - * \param read Your reading function - * \param user_handle Any arbitrary data you wish to pass to the function - * \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; \a oggz not - * open for reading. - */ -int oggz_io_set_read (OGGZ * oggz, OggzIORead read, void * user_handle); - -/** - * Retrieve the user_handle associated with the function you have provided - * for reading input data. - * - * \param oggz An OGGZ handle - * \returns the associated user_handle - */ -void * oggz_io_get_read_user_handle (OGGZ * oggz); - -/** - * Set a function for Oggz to call when it needs to write output data. - * - * \param oggz An OGGZ handle - * \param write Your writing function - * \param user_handle Any arbitrary data you wish to pass to the function - * \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; \a oggz not - * open for writing. - */ -int oggz_io_set_write (OGGZ * oggz, OggzIOWrite write, void * user_handle); - -/** - * Retrieve the user_handle associated with the function you have provided - * for writing output data. - * - * \param oggz An OGGZ handle - * \returns the associated user_handle - */ -void * oggz_io_get_write_user_handle (OGGZ * oggz); - -/** - * Set a function for Oggz to call when it needs to seek on its raw data. - * - * \param oggz An OGGZ handle - * \param seek Your seeking function - * \param user_handle Any arbitrary data you wish to pass to the function - * \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 - * - * \note If you provide an OggzIOSeek function, you MUST also provide - * an OggzIOTell function, or else all your seeks will fail. - */ -int oggz_io_set_seek (OGGZ * oggz, OggzIOSeek seek, void * user_handle); - -/** - * Retrieve the user_handle associated with the function you have provided - * for seeking on input or output data. - * - * \param oggz An OGGZ handle - * \returns the associated user_handle - */ -void * oggz_io_get_seek_user_handle (OGGZ * oggz); - -/** - * Set a function for Oggz to call when it needs to determine the offset - * within its input data (if OGGZ_READ) or output data (if OGGZ_WRITE). - * - * \param oggz An OGGZ handle - * \param tell Your tell function - * \param user_handle Any arbitrary data you wish to pass to the function - * \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 - */ -int oggz_io_set_tell (OGGZ * oggz, OggzIOTell tell, void * user_handle); - -/** - * Retrieve the user_handle associated with the function you have provided - * for determining the current offset in input or output data. - * - * \param oggz An OGGZ handle - * \returns the associated user_handle - */ -void * oggz_io_get_tell_user_handle (OGGZ * oggz); - -/** - * Set a function for Oggz to call when it needs to flush its output. The - * meaning of this is similar to that of fflush() in stdio. - * - * \param oggz An OGGZ handle - * \param flush Your flushing function - * \param user_handle Any arbitrary data you wish to pass to the function - * \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; \a oggz not - * open for writing. - */ -int oggz_io_set_flush (OGGZ * oggz, OggzIOFlush flush, void * user_handle); - -/** - * Retrieve the user_handle associated with the function you have provided - * for flushing output. - * - * \param oggz An OGGZ handle - * \returns the associated user_handle - */ -void * oggz_io_get_flush_user_handle (OGGZ * oggz); - -#endif /* __OGGZ_IO_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_table.h b/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_table.h deleted file mode 100644 index 68901ba5f9..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz/oggz_table.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_TABLE_H__ -#define __OGGZ_TABLE_H__ - -/** \file - * A lookup table. - * - * OggzTable is provided for convenience to allow the storage of - * serialno-specific data. - */ - -/** - * A table of key-value pairs. - */ -typedef void OggzTable; - -/** - * Instantiate a new OggzTable - * \returns A new OggzTable - */ -OggzTable * -oggz_table_new (void); - -/** - * Delete an OggzTable - * \param table An OggzTable - */ -void -oggz_table_delete (OggzTable * table); - -/** - * Insert an element into a table. - * \param table An OggzTable - * \param key Key to access this data element - * \param data The new element to add - * \retval data If the element was successfully added - * \retval NULL If adding the element failed due to a realloc() error - */ -void * -oggz_table_insert (OggzTable * table, long key, void * data); - -/** - * Retrieve the element of an OggzTable indexed by a given key - * \param table An OggzTable - * \param key a key - * \returns The element indexed by \a key - * \retval NULL \a table is undefined, or no element is indexed by \a key - */ -void * -oggz_table_lookup (OggzTable * table, long key); - -/** - * Query the number of elements in an OggzTable - * \param table An OggzTable - * \returns the number of elements in \a table - */ -int -oggz_table_size (OggzTable * table); - -/** - * Retrieve the nth element of an OggzTable - * \param table An OggzTable - * \param n An index into the \a table - * \param key Return value for key corresponding to nth data element - * of \a table - * \returns The nth data element of \a table - * \retval NULL \a table is undefined, or \a n is out of range - */ -void * -oggz_table_nth (OggzTable * table, int n, long * key); - -#endif /* __OGGZ_TABLE_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_auto.c b/src/add-ons/media/plugins/ogg/liboggz/oggz_auto.c deleted file mode 100644 index 74560b0f18..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_auto.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * oggz_auto.c - * - * Conrad Parker - */ - -#include "config.h" - -#if OGGZ_CONFIG_READ -#include -#include - -#include -#include "oggz_auto.h" -#include "oggz_byteorder.h" -#include "oggz_macros.h" - -#define INT32_LE_AT(x) _le_32((*(ogg_int32_t *)(x))) -#define INT32_BE_AT(x) _be_32((*(ogg_int32_t *)(x))) -#define INT64_LE_AT(x) _le_64((*(ogg_int64_t *)(x))) - -/*#define DEBUG*/ - -#define OGGZ_AUTO_MULT 1000 - -static int -auto_speex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) -{ - unsigned char * header = op->packet; - ogg_int64_t granule_rate = 0; - - if (op->bytes < 68) return 0; - - if (strncmp ((char *)header, "Speex ", 8)) return 0; - if (!op->b_o_s) return 0; - - granule_rate = (ogg_int64_t) INT32_LE_AT(&header[36]); -#ifdef DEBUG - printf ("Got speex rate %d\n", (int)granule_rate); -#endif - - oggz_set_metric_linear (oggz, serialno, granule_rate, OGGZ_AUTO_MULT); - - return 1; -} - -static int -auto_vorbis (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) -{ - unsigned char * header = op->packet; - ogg_int64_t granule_rate = 0; - - if (op->bytes < 30) return 0; - - if (header[0] != 0x01) return 0; - if (strncmp ((char *)&header[1], "vorbis", 6)) return 0; - if (!op->b_o_s) return 0; - - granule_rate = (ogg_int64_t) INT32_LE_AT(&header[12]); -#ifdef DEBUG - printf ("Got vorbis rate %d\n", (int)granule_rate); -#endif - - oggz_set_metric_linear (oggz, serialno, granule_rate, OGGZ_AUTO_MULT); - - return 1; -} - -typedef struct { - ogg_int32_t fps_numerator; - ogg_int32_t fps_denominator; - int keyframe_shift; -} oggz_theora_metric_t; - -static int intlog(int num) { - int ret=0; - while(num>0){ - num=num/2; - ret=ret+1; - } - return(ret); -} - -static ogg_int64_t -auto_theora_metric (OGGZ * oggz, long serialno, ogg_int64_t granulepos, - void * user_data) -{ - oggz_theora_metric_t * tdata = (oggz_theora_metric_t *)user_data; - ogg_int64_t iframe, pframe; - ogg_int64_t units; - - iframe = granulepos >> tdata->keyframe_shift; - pframe = granulepos - (iframe << tdata->keyframe_shift); - granulepos = (iframe + pframe); - - units = OGGZ_AUTO_MULT * granulepos * tdata->fps_denominator / - tdata->fps_numerator; - - return units; -} - -static int -auto_theora (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) -{ - unsigned char * header = op->packet; - char keyframe_granule_shift = 0; - oggz_theora_metric_t * tdata; - - if (op->bytes < 41) return 0; - - if (header[0] != 0x80) return 0; - if (strncmp ((char *)&header[1], "theora", 6)) return 0; - if (!op->b_o_s) return 0; - - - tdata = oggz_malloc (sizeof (oggz_theora_metric_t)); - - tdata->fps_numerator = INT32_BE_AT(&header[22]); - tdata->fps_denominator = INT32_BE_AT(&header[26]); - -#if USE_THEORA_PRE_ALPHA_3_FORMAT - /* old header format, used by Theora alpha2 and earlier */ - keyframe_granule_shift = (header[36] & 0xf8) >> 3; -#else - keyframe_granule_shift = (header[40] & 0x03) << 3; - keyframe_granule_shift |= (header[41] & 0xe0) >> 5; -#endif - tdata->keyframe_shift = intlog (keyframe_granule_shift - 1); - -#ifdef DEBUG - printf ("Got theora fps %d/%d, keyframe_granule_shift %d\n", - tdata->fps_numerator, tdata->fps_denominator, - keyframe_granule_shift); -#endif - - /*oggz_set_metric_internal (oggz, serialno, auto_theora_metric, tdata, 1);*/ - oggz_set_metric (oggz, serialno, auto_theora_metric, tdata); - - return 1; -} - -static int -auto_annodex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) -{ - unsigned char * header = op->packet; - - if (op->bytes < 8) return 0; - - if (strncmp ((char *)header, "Annodex", 8)) return 0; - if (!op->b_o_s) return 0; - - /* Yeah ... set it up with a "linear" metric with numerator 0 :) */ - oggz_set_metric_linear (oggz, serialno, 0, 1); - - return 1; -} - -static int -auto_anxdata (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) -{ - unsigned char * header = op->packet; - ogg_int64_t granule_rate_numerator = 0, granule_rate_denominator = 0; - - if (op->bytes < 28) return 0; - - if (strncmp ((char *)header, "AnxData", 8)) return 0; - if (!op->b_o_s) return 0; - - granule_rate_numerator = INT64_LE_AT(&header[8]); - granule_rate_denominator = INT64_LE_AT(&header[16]); -#ifdef DEBUG - printf ("Got AnxData rate %lld/%lld\n", granule_rate_numerator, - granule_rate_denominator); -#endif - - oggz_set_metric_linear (oggz, serialno, - granule_rate_numerator, - OGGZ_AUTO_MULT * granule_rate_denominator); - - return 1; -} - -static OggzReadPacket auto_readers[] = { - auto_speex, - auto_vorbis, - auto_theora, - auto_annodex, - auto_anxdata, - NULL -}; - -int -oggz_auto (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) -{ - OggzReadPacket read_packet; - int i = 0; - - for (read_packet = auto_readers[0]; read_packet; - read_packet = auto_readers[++i]) { - if (read_packet (oggz, op, serialno, user_data)) return 0; - } - - return 0; -} - -#endif /* OGGZ_CONFIG_READ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_auto.h b/src/add-ons/media/plugins/ogg/liboggz/oggz_auto.h deleted file mode 100644 index bb37a75eaa..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_auto.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * oggz_auto.h - * - * Conrad Parker - */ - -#ifndef __OGGZ_AUTO_H__ -#define __OGGZ_AUTO_H__ - -#include - -/** - * Speex - * - * Default field type: LITTLE ENDIAN unsigned integer - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| speex_string: Identifier char[8]: 'Speex ' | 0-3 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 4-7 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| speex_version: char[20] | 8-11 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 12-15 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 16-19 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 20-23 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 24-27 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| speex_version_id | 28-31 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| header_size | 32-35 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| rate | 36-39 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| mode | 40-43 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| mode_bitstream_version | 44-47 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| nb_channels | 48-51 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| bitrate | 52-55 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| frame_size | 56-59 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| vbr | 60-63 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| frames_per_packet | 64-67 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| extra_headers | 68-71 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| reserved1 | 72-75 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| reserved2 | 76-79 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - */ - -/** - * Vorbis - * - * Default field type: LITTLE ENDIAN unsigned integer - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| packtype | Identifier char[6]: 'vorbis' | 0-3 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | version | 4-7 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | channels | 8-11 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| rate | 12-15 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| bitrate_upper | 16-19 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| bitrate_nominal | 20-23 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| bitrate_lower | 24-27 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| l2bs0 | l2bs1 |e| 28-31 -+-+-+-+-+-+-+-+-+-+ - - */ - -/** - * Theora - * - * Default field type: BIG ENDIAN unsigned integer - * - -Field names in full caps refer to fields described in the Theora I -specification. Lowercase refers to theora_info struct members from -libtheora. - -This is the Theora header for theora-alpha3: - -(VMAJ=3, VMIN=2, VREV=0) - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| packtype | Identifier char[6]: 'theora' | 0-3 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | VMAJ | 4-7 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| VMIN | VREV | FMBW: width >> 4 | 8-11 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| FMBH: height >> 4 | PICW: frame_width | 12-15 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | PICH: frame_height | 16-19 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| PICX: offset_x| PICY: offset_y| FRN: fps_numerator | 20-23 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | FRD: fps_denominator | 24-27 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | PARN: aspect_numerator | 28-31 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | PARD: aspect_denominator | 32-35 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| CS: colorspace| NOMBR: target_bitrate | 36-39 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| QUAL | KFGSHIFT| PF| resv| 40-43 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - -This was the Theora header for theora-alpha2: - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| packtype | Identifier char[6]: 'theora' | 0-3 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | Version major | 4-7 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Version minor | Version sub | width >> 4 | 8-11 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| height >> 4 | frame_width | 12-15 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | frame_height | 16-19 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| offset_x | offset_y | fps_numerator | 20-23 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | fps_denominator | 24-27 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | aspect_numerator | 28-31 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | aspect_denominator | 32-35 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| kgshift | colorspace | target_bitrate | 36-39 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | quality | 40-43 -+-+-+-+-+-+-+-+-+-+-+-+ - - */ - -/** - * Annodex - * - * Default field type: LITTLE ENDIAN unsigned integer - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Identifier char[8]: 'Annodex\0' | 0-3 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 4-7 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Version major | Version minor | 8-11 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Timebase numerator | 12-15 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 16-19 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Timebase denominator | 20-23 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 24-27 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| UTC | 28-31 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 32-35 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 36-39 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 40-43 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 44-47 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - */ - -/** - * AnxData - * - * Default field type: LITTLE ENDIAN unsigned integer - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Identifier char[8]: 'AnxData\0' | 0-3 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 4-7 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Granule rate numerator | 8-11 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 12-15 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Granule rate denominator | 16-19 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | 20-23 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Number of secondary header pages | 24-27 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Headers ... | 28- -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - */ - -#endif /* __OGGZ_AUTO_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_byteorder.h b/src/add-ons/media/plugins/ogg/liboggz/oggz_byteorder.h deleted file mode 100644 index c4a7ac5772..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_byteorder.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_BYTEORDER_H__ -#define __OGGZ_BYTEORDER_H__ - -#ifdef _UNUSED_ -static unsigned short -_le_16 (unsigned short s) -{ - unsigned short ret=s; -#ifdef WORDS_BIGENDIAN - ret = (s>>8) & 0x00ffU; - ret += (s<<8) & 0xff00U; -#endif - return ret; -} -#endif - -static ogg_uint32_t -_le_32 (ogg_uint32_t i) -{ - ogg_uint32_t ret=i; -#ifdef WORDS_BIGENDIAN - ret = (i>>24); - ret += (i>>8) & 0x0000ff00; - ret += (i<<8) & 0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -static ogg_uint32_t -_be_32 (ogg_uint32_t i) -{ - ogg_uint32_t ret=i; -#ifndef WORDS_BIGENDIAN - ret = (i>>24); - ret += (i>>8) & 0x0000ff00; - ret += (i<<8) & 0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -static ogg_int64_t -_le_64 (ogg_int64_t l) -{ - ogg_int64_t ret=l; - unsigned char *ucptr = (unsigned char *)&ret; -#ifdef WORDS_BIGENDIAN - unsigned char temp; - - temp = ucptr [0] ; - ucptr [0] = ucptr [7] ; - ucptr [7] = temp ; - - temp = ucptr [1] ; - ucptr [1] = ucptr [6] ; - ucptr [6] = temp ; - - temp = ucptr [2] ; - ucptr [2] = ucptr [5] ; - ucptr [5] = temp ; - - temp = ucptr [3] ; - ucptr [3] = ucptr [4] ; - ucptr [4] = temp ; - -#endif - return (*(ogg_int64_t *)ucptr); -} - -#endif /* __OGGZ_BYTEORDER_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_compat.h b/src/add-ons/media/plugins/ogg/liboggz/oggz_compat.h deleted file mode 100644 index d8671bdcda..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_compat.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "config.h" - -#ifdef HAVE_RANDOM -# define oggz_random random -#else -# define oggz_random rand -#endif - -#ifndef WIN32 -# define oggz_stat_regular(mode) (S_ISREG((mode)) || S_ISLNK((mode))) -#else -# define oggz_stat_regular(mode) ((mode) & S_IFREG) -#endif diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_io.c b/src/add-ons/media/plugins/ogg/liboggz/oggz_io.c deleted file mode 100644 index 6069efc3d8..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_io.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * oggz_io.c - * - * Conrad Parker - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "oggz_compat.h" -#include "oggz_private.h" - -/*#define DEBUG*/ - -size_t -oggz_io_read (OGGZ * oggz, void * buf, size_t n) -{ - OggzIO * io; - size_t bytes; - - if (oggz->file != NULL) { - if ((bytes = fread (buf, 1, n, oggz->file)) == 0) { - if (ferror (oggz->file)) { - return OGGZ_ERR_SYSTEM; - } - } - } - - else if ((io = oggz->io) != NULL) { - if (io->read == NULL) return -1; - bytes = io->read (io->read_user_handle, buf, n); - } - - else return OGGZ_ERR_INVALID; - - return bytes; -} - -size_t -oggz_io_write (OGGZ * oggz, void * buf, size_t n) -{ - OggzIO * io; - size_t bytes; - - if (oggz->file != NULL) { - bytes = fwrite (buf, 1, n, oggz->file); - } - - else if ((io = oggz->io) != NULL) { - if (io->write == NULL) return -1; - bytes = io->write (io->write_user_handle, buf, n); - } - - else return OGGZ_ERR_INVALID; - - return bytes; -} - -int -oggz_io_seek (OGGZ * oggz, long offset, int whence) -{ - OggzIO * io; - - if (oggz->file != NULL) { - if (fseek (oggz->file, offset, whence) == -1) { - if (errno == ESPIPE) { - /*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/ - } else { - /*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/ - } - return OGGZ_ERR_SYSTEM; - } - } - - else if ((io = oggz->io) != NULL) { - if (io->seek == NULL) return -1; - if (io->seek (io->seek_user_handle, offset, whence) == -1) - return -1; - } - - else return OGGZ_ERR_INVALID; - - return 0; -} - -long -oggz_io_tell (OGGZ * oggz) -{ - OggzIO * io; - long offset; - - if (oggz->file != NULL) { - if ((offset = ftell (oggz->file)) == -1) { - if (errno == ESPIPE) { - /*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/ - } else { - /*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/ - } - return -1; - } - } - - else if ((io = oggz->io) != NULL) { - if (io->tell == NULL) return -1; - if ((offset = io->tell (io->tell_user_handle)) == -1) - return -1; - } - - else return OGGZ_ERR_INVALID; - - return offset; -} - -int -oggz_io_flush (OGGZ * oggz) -{ - OggzIO * io; - - if (oggz->file != NULL) { - if (fflush (oggz->file) == EOF) { - /* check errno for write-related errors */ - return OGGZ_ERR_SYSTEM; - } - } - - else if ((io = oggz->io) != NULL) { - if (io->flush == NULL) return OGGZ_ERR_INVALID; - - if (io->flush (io->flush_user_handle) == -1) { - return -1; - } - } - - else return OGGZ_ERR_INVALID; - - return 0; -} - -/* get/set functions */ - -static void -oggz_io_init (OGGZ * oggz) -{ - oggz->io = (OggzIO *) oggz_malloc (sizeof (OggzIO)); - memset (oggz->io, 0, sizeof (OggzIO)); -} - -int -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); - - oggz->io->read = read; - oggz->io->read_user_handle = user_handle; - - return 0; -} - -void * -oggz_io_get_read_user_handle (OGGZ * oggz) -{ - if (oggz == NULL) return NULL; - if (oggz->file != NULL) return NULL; - - if (oggz->io == NULL) return NULL; - - return oggz->io->read_user_handle; -} - -int -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); - - oggz->io->write = write; - oggz->io->write_user_handle = user_handle; - - return 0; -} - -void * -oggz_io_get_write_user_handle (OGGZ * oggz) -{ - if (oggz == NULL) return NULL; - if (oggz->file != NULL) return NULL; - - if (oggz->io == NULL) return NULL; - - return oggz->io->write_user_handle; -} - -int -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); - - oggz->io->seek = seek; - oggz->io->seek_user_handle = user_handle; - - return 0; -} - -void * -oggz_io_get_seek_user_handle (OGGZ * oggz) -{ - if (oggz == NULL) return NULL; - if (oggz->file != NULL) return NULL; - - if (oggz->io == NULL) return NULL; - - return oggz->io->seek_user_handle; -} - -int -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); - - oggz->io->tell = tell; - oggz->io->tell_user_handle = user_handle; - - return 0; -} - -void * -oggz_io_get_tell_user_handle (OGGZ * oggz) -{ - if (oggz == NULL) return NULL; - if (oggz->file != NULL) return NULL; - - if (oggz->io == NULL) return NULL; - - return oggz->io->tell_user_handle; -} - -int -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); - - oggz->io->flush = flush; - oggz->io->flush_user_handle = user_handle; - - return 0; -} - -void * -oggz_io_get_flush_user_handle (OGGZ * oggz) -{ - if (oggz == NULL) return NULL; - if (oggz->file != NULL) return NULL; - - if (oggz->io == NULL) return NULL; - - return oggz->io->flush_user_handle; -} diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_macros.h b/src/add-ons/media/plugins/ogg/liboggz/oggz_macros.h deleted file mode 100644 index edfc2578bc..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_macros.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_MACROS_H__ -#define __OGGZ_MACROS_H__ - -#include - -/* Use the malloc and free used by ogg; defaults are those from stdlib */ -#define oggz_malloc _ogg_malloc -#define oggz_free _ogg_free - -#undef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) - -#undef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) - -#endif /* __OGGZ_MACROS_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_private.h b/src/add-ons/media/plugins/ogg/liboggz/oggz_private.h deleted file mode 100644 index e5416f0095..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_private.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_PRIVATE_H__ -#define __OGGZ_PRIVATE_H__ - -#include -#include - -#include -#include - -#include "oggz_macros.h" -#include "oggz_vector.h" - -typedef struct _OGGZ OGGZ; -typedef struct _OggzIO OggzIO; -typedef struct _OggzReader OggzReader; -typedef struct _OggzWriter OggzWriter; - -typedef int (*OggzReadPacket) (OGGZ * oggz, ogg_packet * op, long serialno, - void * user_data); - -typedef ogg_int64_t (*OggzMetric) (OGGZ * oggz, long serialno, - ogg_int64_t granulepos, - void * user_data); - -typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target, - void * user_data); - -typedef int (*OggzWriteHungry) (OGGZ * oggz, int empty, void * user_data); - -/* oggz_io */ -typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n); -typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n); -typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence); -typedef long (*OggzIOTell) (void * user_handle); -typedef int (*OggzIOFlush) (void * user_handle); - -typedef struct { - ogg_stream_state ogg_stream; - - /* non b_o_s packet has been written (not just queued) */ - int delivered_non_b_o_s; - - int b_o_s; /* beginning of stream */ - int e_o_s; /* end of stream */ - ogg_int64_t granulepos; - ogg_int64_t packetno; - - OggzMetric metric; - void * metric_user_data; - int metric_internal; - - OggzOrder order; - void * order_user_data; - - OggzReadPacket read_packet; - void * read_user_data; -} oggz_stream_t; - -struct _OggzReader { - ogg_sync_state ogg_sync; - - /* XXX: these two can prolly be removed again :) */ - ogg_stream_state ogg_stream; - long current_serialno; - - OggzReadPacket read_packet; - void * read_user_data; - - ogg_int64_t current_unit; - -#if 0 - off_t offset_page_end; /* offset of end of current page */ -#endif -}; - -/** - * Bundle a packet with the stream it is being queued for; used in - * the packet_queue vector - */ -typedef struct { - ogg_packet op; - oggz_stream_t * stream; - int flush; - int * guard; -} oggz_writer_packet_t; - -enum oggz_writer_state { - OGGZ_MAKING_PACKETS = 0, - OGGZ_WRITING_PAGES = 1 -}; - -struct _OggzWriter { - oggz_writer_packet_t * next_zpacket; /* stashed in case of FLUSH_BEFORE */ - OggzVector * packet_queue; - - OggzWriteHungry hungry; - void * hungry_user_data; - int hungry_only_when_empty; - - int writing; /* already mid-write; check for recursive writes */ - int state; /* OGGZ_MAKING_PACKETS or OGGZ_WRITING_PAGES */ - - int flushing; /* whether current packet is being flushed or just paged out */ - - int eog; /* end of page */ -#if 0 - int eop; /* end of packet */ -#endif - int eos; /* end of stream */ - - oggz_writer_packet_t * current_zpacket; - - int packet_offset; /* n bytes already copied out of current packet */ - int page_offset; /* n bytes already copied out of current page */ - - ogg_stream_state * current_stream; -}; - -struct _OggzIO { - OggzIORead read; - void * read_user_handle; - - OggzIOWrite write; - void * write_user_handle; - - OggzIOSeek seek; - void * seek_user_handle; - - OggzIOTell tell; - void * tell_user_handle; - - OggzIOFlush flush; - void * flush_user_handle; -}; - -struct _OGGZ { - int flags; - FILE * file; - OggzIO * io; - - ogg_packet current_packet; - ogg_page current_page; - - off_t offset; /* offset of current page start */ - off_t offset_data_begin; /* offset of unit 0 page start */ - - OggzVector * streams; - int all_at_eos; /* all streams are at eos */ - - OggzMetric metric; - void * metric_user_data; - int metric_internal; - - OggzOrder order; - void * order_user_data; - - union { - OggzReader reader; - OggzWriter writer; - } x; -}; - -OGGZ * oggz_read_init (OGGZ * oggz); -OGGZ * oggz_read_close (OGGZ * oggz); - -OGGZ * oggz_write_init (OGGZ * oggz); -OGGZ * oggz_write_close (OGGZ * oggz); - -oggz_stream_t * oggz_get_stream (OGGZ * oggz, long serialno); -oggz_stream_t * oggz_add_stream (OGGZ * oggz, long serialno); - -int oggz_get_bos (OGGZ * oggz, long serialno); -ogg_int64_t oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos); - -int oggz_set_metric_internal (OGGZ * oggz, long serialno, OggzMetric metric, - void * user_data, int internal); -int oggz_has_metrics (OGGZ * oggz); - -int oggz_purge (OGGZ * oggz); - -int oggz_auto (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data); - -/* oggz_io */ -size_t oggz_io_read (OGGZ * oggz, void * buf, size_t n); -size_t oggz_io_write (OGGZ * oggz, void * buf, size_t n); -int oggz_io_seek (OGGZ * oggz, long offset, int whence); -long oggz_io_tell (OGGZ * oggz); -int oggz_io_flush (OGGZ * oggz); - -#endif /* __OGGZ_PRIVATE_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_read.c b/src/add-ons/media/plugins/ogg/liboggz/oggz_read.c deleted file mode 100644 index 471957a12e..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_read.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * oggz_read.c - * - * Conrad Parker - */ - -#include "config.h" - -#if OGGZ_CONFIG_READ - -#include -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#include -#include - -#include - -#include "oggz_compat.h" -#include "oggz_private.h" - -/*#define DEBUG*/ - -/*#define DEBUG_BY_READING_PAGES*/ - -#define CHUNKSIZE 8500 - -#define oggz_off_t long - -OGGZ * -oggz_read_init (OGGZ * oggz) -{ - OggzReader * reader = &oggz->x.reader; - - ogg_sync_init (&reader->ogg_sync); - ogg_stream_init (&reader->ogg_stream, (int)-1); - reader->current_serialno = -1; - - reader->read_packet = NULL; - reader->read_user_data = NULL; - - reader->current_unit = 0; - - return oggz; -} - -OGGZ * -oggz_read_close (OGGZ * oggz) -{ - OggzReader * reader = &oggz->x.reader; - - ogg_sync_clear (&reader->ogg_sync); - - return oggz; -} - -int -oggz_set_read_callback (OGGZ * oggz, long serialno, - OggzReadPacket read_packet, void * user_data) -{ - OggzReader * reader; - oggz_stream_t * stream; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - reader = &oggz->x.reader; - - if (oggz->flags & OGGZ_WRITE) { - return OGGZ_ERR_INVALID; - } - - if (serialno == -1) { - reader->read_packet = read_packet; - 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 - - stream->read_packet = read_packet; - stream->read_user_data = user_data; - } - - return 0; -} - -/* - * oggz_get_next_page_7 (oggz, og, do_read) - * - * MODIFIED COPY OF CODE FROM BELOW SEEKING STUFF - * - * retrieves the next page. - * returns >= 0 if found; return value is offset of page start - * returns -1 on error - * returns -2 if EOF was encountered - */ -static oggz_off_t -oggz_get_next_page_7 (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; - - do { - more = ogg_sync_pageseek (&reader->ogg_sync, 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 - printf ("get_next_page: skipped %ld bytes\n", -more); -#endif - page_offset -= more; - } else { -#ifdef DEBUG - printf ("get_next_page: page has %ld bytes\n", more); -#endif - found = 1; - } - - } while (!found); - - /* Calculate the byte offset of the page which was found */ - if (bytes > 0) { - oggz->offset = oggz_io_tell (oggz) - bytes + page_offset; - ret = oggz->offset; - } else { - /* didn't need to do any reading -- accumulate the page_offset */ - ret = oggz->offset + page_offset; - oggz->offset += page_offset + more; - } - - return ret; -} - -static int -oggz_read_sync (OGGZ * oggz) -{ - OggzReader * reader = &oggz->x.reader; - - oggz_stream_t * stream; - ogg_stream_state * os; - ogg_packet * op; - long serialno; - - ogg_packet packet; - ogg_page og; - - int cb_ret = 0; - - /*os = &reader->ogg_stream;*/ - op = &packet; - - /* handle one packet. Try to fetch it from current stream state */ - /* extract packets from page */ - while(cb_ret == 0){ - - if (reader->current_serialno != -1) { - /* process a packet if we can. If the machine isn't loaded, - neither is a page */ - while(cb_ret == 0) { - ogg_int64_t granulepos; - int result; - - serialno = reader->current_serialno; - - stream = oggz_get_stream (oggz, serialno); - - if (stream == NULL) { - /* new stream ... check bos etc. */ - if ((stream = oggz_add_stream (oggz, serialno)) == NULL) { - /* error -- could not add stream */ - return -7; - } - } - os = &stream->ogg_stream; - - result = ogg_stream_packetout(os, op); - - if(result == -1) { - /* hole in the data. */ - return -7; - } - - if(result > 0){ - /* got a packet. process it */ - granulepos = op->granulepos; - - if (!stream->metric && (oggz->flags & OGGZ_AUTO)) { - oggz_auto (oggz, op, serialno, NULL); - } - - if ((oggz->metric || stream->metric) && granulepos != -1) { - reader->current_unit = oggz_get_unit (oggz, serialno, granulepos); - } -#ifndef DEBUG_BY_READING_PAGES - if (stream->read_packet) { - cb_ret = - stream->read_packet (oggz, op, serialno, stream->read_user_data); - } else if (reader->read_packet) { - cb_ret = - reader->read_packet (oggz, op, serialno, reader->read_user_data); - } -#endif /* DEBUG_BY_READING_PAGES */ - } - else - break; - } - } - - /* If we've got a stop already, don't read more data in */ - if (cb_ret != 0) return cb_ret; - - if(oggz_get_next_page_7 (oggz, &og) < 0) - return -404; /* eof. leave unitialized */ - - serialno = ogg_page_serialno (&og); - reader->current_serialno = serialno; /* XXX: maybe not necessary */ - - stream = oggz_get_stream (oggz, serialno); - - if (stream == NULL) { - /* new stream ... check bos etc. */ - if ((stream = oggz_add_stream (oggz, serialno)) == NULL) { - /* error -- could not add stream */ - return -7; - } - } - os = &stream->ogg_stream; - -#ifdef DEBUG_BY_READING_PAGES - { - ogg_packet op_debug; - op_debug.packet = og.body; - op_debug.bytes = og.body_len; - op_debug.b_o_s = ogg_page_bos (&og); - op_debug.e_o_s = ogg_page_eos (&og); - op_debug.granulepos = ogg_page_granulepos (&og); - op_debug.packetno = ogg_page_packets (&og); - - if (stream->read_packet) { - cb_ret = stream->read_packet (oggz, &op_debug, serialno, - stream->read_user_data); - } else if (reader->read_packet) { - cb_ret = reader->read_packet (oggz, &op_debug, serialno, - reader->read_user_data); - } - } -#endif - -#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); - } - - return cb_ret; -} - -long -oggz_read (OGGZ * oggz, long n) -{ - OggzReader * reader; - char * buffer; - long bytes, bytes_read = 1, remaining = n, nread = 0; - int cb_ret = 0; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (oggz->flags & OGGZ_WRITE) { - return OGGZ_ERR_INVALID; - } - - reader = &oggz->x.reader; - - cb_ret = oggz_read_sync (oggz); - - /* If there's nothing to read yet, don't flag an error */ - if (reader->current_unit == 0 && cb_ret == -404) cb_ret = 0; - - while (cb_ret != -1 && cb_ret != 1 && bytes_read > 0 && remaining > 0) { - bytes = MIN (remaining, 4096); - buffer = ogg_sync_buffer (&reader->ogg_sync, bytes); - if ((bytes_read = (long) oggz_io_read (oggz, buffer, bytes)) == 0) { - /* schyeah! */ - } - if (bytes_read == OGGZ_ERR_SYSTEM) { - return OGGZ_ERR_SYSTEM; - } - - ogg_sync_wrote (&reader->ogg_sync, bytes_read); - - remaining -= bytes_read; - nread += bytes_read; - - cb_ret = oggz_read_sync (oggz); - } - - if (cb_ret == -1) oggz_purge (oggz); - - return nread; -} - -/* generic */ -long -oggz_read_input (OGGZ * oggz, unsigned char * buf, long n) -{ - OggzReader * reader; - char * buffer; - long bytes, remaining = n, nread = 0; - int cb_ret = 0; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (oggz->flags & OGGZ_WRITE) { - return OGGZ_ERR_INVALID; - } - - reader = &oggz->x.reader; - - cb_ret = oggz_read_sync (oggz); - - /* If there's nothing to read yet, don't flag an error */ - if (reader->current_unit == 0 && cb_ret == -404) cb_ret = 0; - - while (cb_ret != -1 && cb_ret != 1 && /* !oggz->eos && */ remaining > 0) { - bytes = MIN (remaining, 4096); - buffer = ogg_sync_buffer (&reader->ogg_sync, bytes); - memcpy (buffer, buf, bytes); - ogg_sync_wrote (&reader->ogg_sync, bytes); - - buf += bytes; - remaining -= bytes; - nread += bytes; - - cb_ret = oggz_read_sync (oggz); - } - - if (cb_ret == -1) oggz_purge (oggz); - - return nread; -} - -/* oggz_seek() (and oggz_purge()) related functions from here down */ - -/* - * The typical usage is: - * - * oggz_set_data_start (oggz, oggz_tell (oggz)); - */ -int -oggz_set_data_start (OGGZ * oggz, oggz_off_t offset) -{ - if (oggz == NULL) return -1; - - if (offset < 0) return -1; - - oggz->offset_data_begin = offset; - - return 0; -} - -static oggz_off_t -oggz_tell_raw (OGGZ * oggz) -{ - oggz_off_t offset_at; - - offset_at = oggz_io_tell (oggz); - - return offset_at; -} - -/* - * seeks and syncs - */ -static oggz_off_t -oggz_seek_raw (OGGZ * oggz, oggz_off_t offset, int whence) -{ - OggzReader * reader = &oggz->x.reader; - oggz_off_t offset_at; - - if (oggz_io_seek (oggz, offset, whence) == -1) { - return -1; - } - - offset_at = oggz_io_tell (oggz); - - oggz->offset = offset_at; - - ogg_sync_reset (&reader->ogg_sync); - - return offset_at; -} - -static int -oggz_stream_reset (void * data) -{ - oggz_stream_t * stream = (oggz_stream_t *) data; - - if (stream->ogg_stream.serialno != -1) { - ogg_stream_reset (&stream->ogg_stream); - } - - return 0; -} - -static void -oggz_reset_streams (OGGZ * oggz) -{ - oggz_vector_foreach (oggz->streams, oggz_stream_reset); -} - -static long -oggz_reset_seek (OGGZ * oggz, oggz_off_t offset, ogg_int64_t unit, int whence) -{ - OggzReader * reader = &oggz->x.reader; - - oggz_off_t offset_at; - - offset_at = oggz_seek_raw (oggz, offset, whence); - if (offset_at == -1) return -1; - - oggz->offset = offset_at; - -#ifdef DEBUG - printf ("reset to %ld\n", offset_at); -#endif - - if (unit != -1) reader->current_unit = unit; - - return offset_at; -} - -static long -oggz_reset (OGGZ * oggz, oggz_off_t offset, ogg_int64_t unit, int whence) -{ - oggz_reset_streams (oggz); - return oggz_reset_seek (oggz, offset, unit, whence); -} - -int -oggz_purge (OGGZ * oggz) -{ - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (oggz->flags & OGGZ_WRITE) { - return OGGZ_ERR_INVALID; - } - - oggz_reset_streams (oggz); - - if (oggz->file && oggz_reset (oggz, oggz->offset, -1, SEEK_SET) < 0) { - return OGGZ_ERR_SYSTEM; - } - - return 0; -} - -/* - * oggz_get_next_page (oggz, og, do_read) - * - * retrieves the next page. - * returns >= 0 if found; return value is offset of page start - * returns -1 on error - * returns -2 if EOF was encountered - */ -static oggz_off_t -oggz_get_next_page (OGGZ * oggz, ogg_page * og) -{ - OggzReader * reader = &oggz->x.reader; - char * buffer; - long bytes = 0, more; - oggz_off_t page_offset = 0, ret; - int found = 0; - - do { - more = ogg_sync_pageseek (&reader->ogg_sync, og); - - if (more == 0) { - page_offset = 0; - - buffer = ogg_sync_buffer (&reader->ogg_sync, CHUNKSIZE); - if ((bytes = (long) oggz_io_read (oggz, buffer, CHUNKSIZE)) == 0) { - /* schyeah! */ - } - if (bytes == OGGZ_ERR_SYSTEM) { - /*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/ - return -1; - } - - if (bytes == 0) { - return -2; - } else if (oggz->file && feof (oggz->file)) { - clearerr (oggz->file); - return -2; - } - - ogg_sync_wrote(&reader->ogg_sync, bytes); - - } else if (more < 0) { -#ifdef DEBUG - printf ("get_next_page: skipped %ld bytes\n", -more); -#endif - page_offset -= more; - } else { -#ifdef DEBUG - printf ("get_next_page: page has %ld bytes\n", more); -#endif - found = 1; - } - - } while (!found); - - /* Calculate the byte offset of the page which was found */ - if (bytes > 0) { - oggz->offset = oggz_tell_raw (oggz) - bytes + page_offset; - ret = oggz->offset; - } else { - /* didn't need to do any reading -- accumulate the page_offset */ - ret = oggz->offset + page_offset; - oggz->offset += page_offset + more; - } - - return ret; -} - -static oggz_off_t -oggz_get_next_start_page (OGGZ * oggz, ogg_page * og) -{ - oggz_off_t page_offset; - int found = 0; - - while (!found) { - page_offset = oggz_get_next_page (oggz, og); - - /* Return this value if one of the following conditions is met: - * - * page_offset < 0 : error or EOF - * page_offset == 0 : start of stream - * !ogg_page_continued : start of page - */ - if (page_offset <= 0 || !ogg_page_continued (og)) - found = 1; - } - - return page_offset; -} - -static oggz_off_t -oggz_get_prev_start_page (OGGZ * oggz, ogg_page * og, - ogg_int64_t * granule, long * serialno) -{ - oggz_off_t offset_at, offset_start; - oggz_off_t page_offset, prev_offset = 0; - long granule_at = -1; - -#if 0 - offset_at = oggz_tell_raw (oggz); - if (offset_at == -1) return -1; -#else - offset_at = oggz->offset; -#endif - - offset_start = offset_at; - - do { - - offset_start = offset_at - CHUNKSIZE; - if (offset_start < 0) offset_start = 0; - - offset_start = oggz_seek_raw (oggz, offset_start, SEEK_SET); - if (offset_start == -1) return -1; - -#ifdef DEBUG - - printf ("[A] offset_at: @%ld\toffset_start: @%ld\n", - offset_at, offset_start); - - printf ("*** get_prev_start_page: seeked to %ld\n", offset_start); -#endif - - page_offset = 0; - - do { - prev_offset = page_offset; - - page_offset = oggz_get_next_start_page (oggz, og); - if (page_offset == -1) return -1; - if (page_offset == -2) break; - - granule_at = (long)ogg_page_granulepos (og); - -#ifdef DEBUG - printf ("\tGOT page (%ld) @%ld\tat @%ld\n", granule_at, - page_offset, offset_at); -#endif - - /* Need to stash the granule and serialno of this page because og - * will be overwritten by the time we realise this was the desired - * prev page */ - if (page_offset >= 0 && page_offset < offset_at) { - *granule = granule_at; - *serialno = ogg_page_serialno (og); - } - - } while (page_offset >= 0 && page_offset < offset_at); - -#ifdef DEBUG - printf ("[B] offset_at: @%ld\toffset_start: @%ld\n" - "prev_offset: @%ld\tpage_offset: @%ld\n", - offset_at, offset_start, prev_offset, page_offset); -#endif - /* reset the file offset */ - offset_at = offset_start; - - } while (offset_at > 0 && prev_offset == 0); - - if (offset_at > 0) - return prev_offset; - else - return -1; -} - -static oggz_off_t -oggz_scan_for_page (OGGZ * oggz, ogg_page * og, ogg_int64_t unit_target, - oggz_off_t offset_begin, oggz_off_t offset_end) -{ - oggz_off_t offset_at, offset_next; - oggz_off_t offset_prev = -1; - ogg_int64_t granule_at; - ogg_int64_t unit_at; - long serialno; - -#ifdef DEBUG - printf (" SCANNING from %ld...", offset_begin); -#endif - - while (1) { - offset_at = oggz_seek_raw (oggz, offset_begin, SEEK_SET); - if (offset_at == -1) return -1; - -#ifdef DEBUG - printf (" scan @%ld\n", offset_at); -#endif - - offset_next = oggz_get_next_start_page (oggz, og); - - if (offset_next < 0) { - return offset_next; - } - - if (offset_next == 0 && offset_begin != 0) { -#ifdef DEBUG - printf (" ... scanned past EOF\n"); -#endif - return -1; - } - if (offset_next > offset_end) { -#ifdef DEBUG - printf (" ... scanned to page %ld\n", (long)ogg_page_granulepos (og)); -#endif - if (offset_prev != -1) { - offset_at = oggz_seek_raw (oggz, offset_prev, SEEK_SET); - if (offset_at == -1) return -1; - - offset_next = oggz_get_next_start_page (oggz, og); - if (offset_next < 0) return offset_next; - - serialno = ogg_page_serialno (og); - granule_at = ogg_page_granulepos (og); - unit_at = oggz_get_unit (oggz, serialno, granule_at); - - return offset_at; - } else { - return -1; - } - } - - offset_at = offset_next; - - serialno = ogg_page_serialno (og); - granule_at = ogg_page_granulepos (og); - unit_at = oggz_get_unit (oggz, serialno, granule_at); - - if (unit_at < unit_target) { -#ifdef DEBUG - printf (" scan: (%ld) < (%ld)\n", unit_at, unit_target); -#endif - offset_prev = offset_next; - offset_begin = offset_next+1; - } else if (unit_at > unit_target) { -#ifdef DEBUG - printf (" scan: (%ld) > (%ld)\n", unit_at, unit_target); -#endif -#if 0 - /* hole ? */ - offset_at = oggz_seek_raw (oggz, offset_begin, SEEK_SET); - if (offset_at == -1) return -1; - - offset_next = oggz_get_next_start_page (oggz, og); - if (offset_next < 0) return offset_next; - - serialno = ogg_page_serialno (og); - granule_at = ogg_page_granulepos (og); - unit_at = oggz_get_unit (oggz, serialno, granule_at); - - break; -#else - return offset_at; -#endif - } else if (unit_at == unit_target) { -#ifdef DEBUG - printf (" scan: (%ld) == (%ld)\n", unit_at, unit_target); -#endif - break; - } - } - - return offset_at; -} - -static long -oggz_seek_set (OGGZ * oggz, ogg_int64_t unit_target) -{ - OggzReader * reader = &oggz->x.reader; - int fd; - struct stat statbuf; - oggz_off_t offset_orig, offset_at, offset_guess; - oggz_off_t offset_begin, offset_end = -1, offset_next; - ogg_int64_t granule_at; - ogg_int64_t unit_at, unit_begin = 0, unit_end = -1; - long serialno; - double guess_ratio; - ogg_page * og; - - if (oggz == NULL) { - return -1; - } - - if (unit_target > 0 && !oggz_has_metrics (oggz)) { - /* No metric defined */ - return -1; - } - - if (oggz->file != NULL) { - if ((fd = fileno (oggz->file)) == -1) { - /*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/ - return -1; - } - - if (fstat (fd, &statbuf) == -1) { - /*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/ - return -1; - } - - if (oggz_stat_regular (statbuf.st_mode)) { - offset_end = statbuf.st_size; - } else { - /*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/ - - /* XXX: should be able to just carry on and guess, as per io */ - /*return -1;*/ - } - } else { - oggz_off_t offset_save; - - if (oggz->io == NULL || oggz->io->seek == NULL) { - /* No file, and no io seek method */ - return -1; - } - - /* Get the offset of the end by querying the io seek method */ - offset_save = oggz_io_tell (oggz); - if (oggz_io_seek (oggz, 0, SEEK_END) == -1) { - return -1; - } - offset_end = oggz_io_tell (oggz); - if (oggz_io_seek (oggz, offset_save, SEEK_SET) == -1) { - return -1; /* fubar */ - } - } - - if (unit_target == reader->current_unit) { - return (long)reader->current_unit; - } - - if (unit_target == 0) { - offset_at = oggz_reset (oggz, oggz->offset_data_begin, 0, SEEK_SET); - if (offset_at == -1) return -1; - return 0; - } - - offset_at = oggz_tell_raw (oggz); - if (offset_at == -1) return -1; - -#if 0 - offset_orig = offset_at; -#else - offset_orig = oggz->offset; -#endif - - offset_begin = 0; - - unit_at = reader->current_unit; - unit_begin = 0; - unit_end = -1; - - og = &oggz->current_page; - - while (1) { - -#ifdef DEBUG - printf ("oggz_read_seek (%ld): (%ld - %ld) [%ld - %ld]\t", - unit_target, unit_begin, unit_end, offset_begin, offset_end); -#endif - - if (unit_end == -1) { - if (unit_at == unit_begin) { -#ifdef DEBUG - printf ("*G1*"); -#endif - offset_guess = offset_begin + (offset_end - offset_begin)/2; - } else { -#ifdef DEBUG - printf ("*G2*"); -#endif - guess_ratio = - (double)(unit_target - unit_begin) / - (double)(unit_at - unit_begin); - -#ifdef DEBUG - printf ("\nguess_ration %f = (%ld - %ld) / (%ld - %ld)\n", - guess_ratio, unit_target, unit_begin, unit_at, unit_begin); -#endif - - offset_guess = offset_begin + - (oggz_off_t)((offset_at - offset_begin) * guess_ratio); - } - } else if (unit_end <= unit_begin) { -#ifdef DEBUG - printf ("unit_end <= unit_begin\n"); -#endif - break; - } else { -#if 1 - guess_ratio = - (double)(unit_target - unit_begin) / - (double)(unit_end - unit_begin); - - offset_guess = offset_begin + - (oggz_off_t)((offset_end - offset_begin) * guess_ratio); - - /* - if (offset_guess <= offset_begin) { - offset_guess = offset_begin + 1; - } - */ -#else - offset_guess = offset_begin + (offset_end - offset_begin)/2; -#endif - } - -#ifdef DEBUG - printf ("%ld ->", offset_guess); -#endif - - offset_at = oggz_seek_raw (oggz, offset_guess, SEEK_SET); - if (offset_at == -1) { - goto notfound; - } - - offset_next = oggz_get_next_start_page (oggz, og); - -#ifdef DEBUG - printf ("\n"); -#endif - - if (offset_next < 0) { - goto notfound; - } - - if (offset_next > offset_end) { - offset_next = oggz_scan_for_page (oggz, og, unit_target, - offset_begin, offset_end); - - if (offset_next < 0) { - goto notfound; - } - - offset_at = offset_next; - serialno = ogg_page_serialno (og); - granule_at = ogg_page_granulepos (og); - - unit_at = oggz_get_unit (oggz, serialno, granule_at); - - goto found; - } - - offset_at = offset_next; - serialno = ogg_page_serialno (og); - granule_at = ogg_page_granulepos (og); - - unit_at = oggz_get_unit (oggz, serialno, granule_at); - -#ifdef DEBUG - printf ("oggz_read_seek (%ld): got page (%ld) @%ld\n", unit_target, - unit_at, offset_at); -#endif - - if (unit_at < unit_target) { - offset_begin = offset_at; - unit_begin = unit_at; - } else if (unit_at > unit_target) { - offset_end = offset_at-1; - unit_end = unit_at; - } else { - break; - } - } - - found: -#ifdef DEBUG - printf ("FOUND (%ld)\n", unit_at); -#endif - - offset_at = oggz_reset (oggz, offset_at, unit_at, SEEK_SET); - if (offset_at == -1) return -1; - - return (long)reader->current_unit; - - notfound: -#ifdef DEBUG - printf ("NOT FOUND\n"); -#endif - - oggz_reset (oggz, offset_orig, -1, SEEK_SET); - - return -1; -} - -static long -oggz_seek_end (OGGZ * oggz, ogg_int64_t unit_offset) -{ - oggz_off_t offset_orig, offset_at, offset_end; - ogg_int64_t granulepos; - ogg_int64_t unit_end; - long serialno; - ogg_page * og; - - og = &oggz->current_page; - - offset_orig = oggz->offset; - - offset_at = oggz_seek_raw (oggz, 0, SEEK_END); - if (offset_at == -1) return -1; - - offset_end = oggz_get_prev_start_page (oggz, og, &granulepos, &serialno); - - unit_end = oggz_get_unit (oggz, serialno, granulepos); - - if (offset_end < 0) { - oggz_reset (oggz, offset_orig, -1, SEEK_SET); - return -1; - } - -#ifdef DEBUG - printf ("*** oggz_seek_end: found packet (%ld) at @%ld\n", - unit_end, offset_end); -#endif - - return oggz_seek_set (oggz, unit_end + unit_offset); -} - -off_t -oggz_seek (OGGZ * oggz, oggz_off_t offset, int whence) -{ - ogg_int64_t units = -1; - - if (oggz == NULL) return -1; - - if (oggz->flags & OGGZ_WRITE) { - return -1; - } - - if (offset == 0) units = 0; - - return (off_t)oggz_reset (oggz, offset, units, whence); -} - -long -oggz_seek_units (OGGZ * oggz, ogg_int64_t units, int whence) -{ - OggzReader * reader = &oggz->x.reader; - - if (oggz == NULL) return -1; - - if (oggz->flags & OGGZ_WRITE) { - return -1; - } - - if (!oggz_has_metrics (oggz)) { - return -1; - } - - switch (whence) { - case SEEK_SET: - return oggz_seek_set (oggz, units); - break; - case SEEK_CUR: - units += reader->current_unit; - return oggz_seek_set (oggz, units); - break; - case SEEK_END: - return oggz_seek_end (oggz, units); - break; - default: - /*oggz_set_error (oggz, OGGZ_EINVALID);*/ - return -1; - break; - } -} - -long -oggz_seek_byorder (OGGZ * oggz, void * target) -{ - return -1; -} - -long -oggz_seek_packets (OGGZ * oggz, long serialno, long packets, int whence) -{ - return -1; -} - -#else /* OGGZ_CONFIG_READ */ - -#include -#include "oggz_private.h" - -int -oggz_set_read_callback (OGGZ * oggz, long serialno, - OggzReadPacket read_packet, void * user_data) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_read (OGGZ * oggz, long n) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_read_input (OGGZ * oggz, unsigned char * buf, long n) -{ - return OGGZ_ERR_DISABLED; -} - -off_t -oggz_seek (OGGZ * oggz, oggz_off_t offset, int whence) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_seek_units (OGGZ * oggz, ogg_int64_t units, int whence) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_seek_byorder (OGGZ * oggz, void * target) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_seek_packets (OGGZ * oggz, long serialno, long packets, int whence) -{ - return OGGZ_ERR_DISABLED; -} - -#endif diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_table.c b/src/add-ons/media/plugins/ogg/liboggz/oggz_table.c deleted file mode 100644 index 2ea54b3254..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_table.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include "oggz_macros.h" -#include "oggz_vector.h" - -typedef struct _OggzTable OggzTable; - -struct _OggzTable { - OggzVector * keys; - OggzVector * data; -}; - -OggzTable * -oggz_table_new (void) -{ - OggzTable * table; - - table = oggz_malloc (sizeof (OggzTable)); - table->keys = oggz_vector_new (); - table->data = oggz_vector_new (); - - return table; -} - -void -oggz_table_delete (OggzTable * table) -{ - if (table == NULL) return; - - oggz_vector_delete (table->keys); - oggz_vector_delete (table->data); - oggz_free (table); -} - -void * -oggz_table_lookup (OggzTable * table, long key) -{ - int i, size; - - size = oggz_vector_size (table->keys); - for (i = 0; i < size; i++) { - if (oggz_vector_nth_l (table->keys, i) == key) { - return oggz_vector_nth_p (table->data, i); - } - } - - return NULL; -} - -void * -oggz_table_insert (OggzTable * table, long key, void * data) -{ - void * old_data; - - if ((old_data = oggz_table_lookup (table, key)) != NULL) { - if (oggz_vector_remove_l (table->keys, key) == NULL) - return NULL; - - if (oggz_vector_remove_p (table->data, old_data) == NULL) { - /* XXX: This error condition can only happen if the previous - * removal succeeded, and this removal failed, ie. there was - * an error reallocing table->data->data downwards. */ - return NULL; - } - } - - if (oggz_vector_insert_l (table->keys, key) == -1) - return NULL; - - if (oggz_vector_insert_p (table->data, data) == NULL) { - oggz_vector_remove_l (table->keys, key); - return NULL; - } - - return data; -} - -int -oggz_table_size (OggzTable * table) -{ - if (table == NULL) return 0; - return oggz_vector_size (table->data); -} - -void * -oggz_table_nth (OggzTable * table, int n, long * key) -{ - if (table == NULL) return NULL; - if (key) *key = oggz_vector_nth_l (table->keys, n); - return oggz_vector_nth_p (table->data, n); -} diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_vector.c b/src/add-ons/media/plugins/ogg/liboggz/oggz_vector.c deleted file mode 100644 index 6ffc0d4346..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_vector.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include - -#include "oggz_macros.h" - -typedef int (*OggzFunc) (void * data); -typedef int (*OggzFindFunc) (void * data, long serialno); -typedef int (*OggzCmpFunc) (void * a, void * b, void * user_data); - -typedef struct _OggzVector OggzVector; - -typedef union { - void * p; - long l; -} oggz_data_t; - -struct _OggzVector { - int max_elements; - int nr_elements; - oggz_data_t * data; - OggzCmpFunc compare; - void * compare_user_data; -}; - -/* - * A vector of void * or long; iff it's a vector of void * objects, it - * can be optionally sorted. (The sorting is used to implement the - * packet queue; the vector of longs is used to implement OggzTable) - * - * if you set a comparison function (oggz_vector_set_cmp()), the vector - * will be sorted and new elements will be inserted in sorted order. - * - * if you don't set a comparison function, new elements will be appended - * at the tail - * - * to unset the comparison function, call oggz_vector_set_cmp (NULL,NULL) - */ - -OggzVector * -oggz_vector_new (void) -{ - OggzVector * vector; - - vector = oggz_malloc (sizeof (OggzVector)); - - vector->max_elements = 0; - vector->nr_elements = 0; - vector->data = NULL; - vector->compare = NULL; - vector->compare_user_data = NULL; - - return vector; -} - -static void -oggz_vector_clear (OggzVector * vector) -{ - oggz_free (vector->data); - vector->data = NULL; - vector->nr_elements = 0; - vector->max_elements = 0; -} - -void -oggz_vector_delete (OggzVector * vector) -{ - oggz_vector_clear (vector); - oggz_free (vector); -} - -int -oggz_vector_size (OggzVector * vector) -{ - if (vector == NULL) return 0; - - return vector->nr_elements; -} - -void * -oggz_vector_nth_p (OggzVector * vector, int n) -{ - if (vector == NULL) return NULL; - - if (n >= vector->nr_elements) return NULL; - - return vector->data[n].p; -} - -long -oggz_vector_nth_l (OggzVector * vector, int n) -{ - if (vector == NULL) return -1L; - - if (n >= vector->nr_elements) return -1L; - - return vector->data[n].l; -} - -void * -oggz_vector_find (OggzVector * vector, OggzFindFunc func, long serialno) -{ - void * data; - int i; - - for (i = 0; i < vector->nr_elements; i++) { - data = vector->data[i].p; - if (func (data, serialno)) - return data; - } - - return NULL; -} - -int -oggz_vector_foreach (OggzVector * vector, OggzFunc func) -{ - int i; - - for (i = 0; i < vector->nr_elements; i++) { - func (vector->data[i].p); - } - - return 0; -} - -static void -_array_swap (oggz_data_t v[], int i, int j) -{ - void * t; - - t = v[i].p; - v[i].p = v[j].p; - v[j].p = t; -} - -/** - * Helper function for oggz_vector_insert (). Sorts the vector by - * insertion sort, assuming the tail element has just been added and the - * rest of the vector is sorted. - * \param vector An OggzVector - * \pre The vector has just had a new element added to its tail - * \pre All elements other than the tail element are already sorted. - */ -static void -oggz_vector_tail_insertion_sort (OggzVector * vector) -{ - int i; - - if (vector->compare == NULL) return; - - for (i = vector->nr_elements-1; i > 0; i--) { - if (vector->compare (vector->data[i-1].p, vector->data[i].p, - vector->compare_user_data) > 0) { - _array_swap (vector->data, i, i-1); - } else { - break; - } - } - - return; -} - -static OggzVector * -oggz_vector_grow (OggzVector * vector) -{ - void * new_elements; - int new_max_elements; - - vector->nr_elements++; - - if (vector->nr_elements > vector->max_elements) { - if (vector->max_elements == 0) { - new_max_elements = 1; - } else { - new_max_elements = vector->max_elements * 2; - } - - new_elements = - realloc (vector->data, (size_t)new_max_elements * sizeof (oggz_data_t)); - - if (new_elements == NULL) { - vector->nr_elements--; - return NULL; - } - - vector->max_elements = new_max_elements; - vector->data = new_elements; - } - - return vector; -} - -void * -oggz_vector_insert_p (OggzVector * vector, void * data) -{ - if (oggz_vector_grow (vector) == NULL) - return NULL; - - vector->data[vector->nr_elements-1].p = data; - - oggz_vector_tail_insertion_sort (vector); - - return data; - -} - -long -oggz_vector_insert_l (OggzVector * vector, long ldata) -{ - if (oggz_vector_grow (vector) == NULL) - return -1; - - vector->data[vector->nr_elements-1].l = ldata; - - return ldata; -} - -static void -oggz_vector_qsort (OggzVector * vector, int left, int right) -{ - int i, last; - oggz_data_t * v = vector->data; - - if (left >= right) return; - - _array_swap (v, left, (left + right)/2); - last = left; - for (i = left+1; i <= right; i++) { - if (vector->compare (v[i].p, v[left].p, vector->compare_user_data) < 0) - _array_swap (v, ++last, i); - } - _array_swap (v, left, last); - oggz_vector_qsort (vector, left, last-1); - oggz_vector_qsort (vector, last+1, right); -} - -int -oggz_vector_set_cmp (OggzVector * vector, OggzCmpFunc compare, - void * user_data) -{ - vector->compare = compare; - vector->compare_user_data = user_data; - - if (compare) { - oggz_vector_qsort (vector, 0, vector->nr_elements-1); - } - - return 0; -} - - -static void * -oggz_vector_remove_nth (OggzVector * vector, int n) -{ - int i; - oggz_data_t * new_elements; - int new_max_elements; - - vector->nr_elements--; - - if (vector->nr_elements == 0) { - oggz_vector_clear (vector); - } else { - for (i = n; i < vector->nr_elements; i++) { - vector->data[i] = vector->data[i+1]; - } - - if (vector->nr_elements < vector->max_elements/2) { - new_max_elements = vector->max_elements/2; - - new_elements = - realloc (vector->data, - (size_t)new_max_elements * sizeof (oggz_data_t)); - - if (new_elements == NULL) - return NULL; - - vector->max_elements = new_max_elements; - vector->data = new_elements; - } - } - - return vector; -} - -OggzVector * -oggz_vector_remove_p (OggzVector * vector, void * data) -{ - int i; - - for (i = 0; i < vector->nr_elements; i++) { - if (vector->data[i].p == data) { - return oggz_vector_remove_nth (vector, i); - } - } - - return vector; -} - -OggzVector * -oggz_vector_remove_l (OggzVector * vector, long ldata) -{ - int i; - - for (i = 0; i < vector->nr_elements; i++) { - if (vector->data[i].l == ldata) { - return oggz_vector_remove_nth (vector, i); - } - } - - return vector; -} - -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; - - 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 = - 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; - -} diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_vector.h b/src/add-ons/media/plugins/ogg/liboggz/oggz_vector.h deleted file mode 100644 index 4583f4ca1e..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_vector.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __OGGZ_VECTOR_H__ -#define __OGGZ_VECTOR_H__ - -typedef void OggzVector; - -typedef int (*OggzFunc) (void * data); -typedef int (*OggzFindFunc) (void * data, long serialno); -typedef int (*OggzCmpFunc) (void * a, void * b, void * user_data); - -OggzVector * -oggz_vector_new (void); - -void -oggz_vector_delete (OggzVector * vector); - -void * -oggz_vector_find (OggzVector * vector, OggzFindFunc func, long serialno); - -void * -oggz_vector_nth_p (OggzVector * vector, int n); - -long -oggz_vector_nth_l (OggzVector * vector, int n); - -int -oggz_vector_foreach (OggzVector * vector, OggzFunc func); - -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. - * \param vector An OggzVector - * \param data The new element to add - * \retval data If the element was successfully added - * \retval NULL If adding the element failed due to a realloc() error - */ -void * -oggz_vector_insert_p (OggzVector * vector, void * data); - -long -oggz_vector_insert_l (OggzVector * vector, long ldata); - -/** - * Remove a (void *) element of a vector - * \retval \a vector on success - * \retval NULL on failure (realloc error) - */ -OggzVector * -oggz_vector_remove_p (OggzVector * vector, void * data); - -/** - * Remove a (long) element of a vector - * \retval \a vector on success - * \retval NULL on failure (realloc error) - */ -OggzVector * -oggz_vector_remove_l (OggzVector * vector, long ldata); - -int -oggz_vector_set_cmp (OggzVector * vector, OggzCmpFunc compare, - void * user_data); - -void * -oggz_vector_pop (OggzVector * vector); - -#endif /* __OGGZ_VECTOR_H__ */ diff --git a/src/add-ons/media/plugins/ogg/liboggz/oggz_write.c b/src/add-ons/media/plugins/ogg/liboggz/oggz_write.c deleted file mode 100644 index f8e5d7f80d..0000000000 --- a/src/add-ons/media/plugins/ogg/liboggz/oggz_write.c +++ /dev/null @@ -1,749 +0,0 @@ -/* - Copyright (C) 2003 Commonwealth Scientific and Industrial Research - Organisation (CSIRO) Australia - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of CSIRO Australia nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "config.h" - -#if OGGZ_CONFIG_WRITE - -#include -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#include -#include - -#include - -#include "oggz_private.h" -#include "oggz_vector.h" - -/* #define DEBUG */ - -/* #define ALWAYS_FLUSH */ - -/* #define ZPACKET_CMP */ - -#ifdef ZPACKET_CMP -static int -oggz_zpacket_cmp (oggz_writer_packet_t * a, oggz_writer_packet_t * b, - void * user_data) -{ - OGGZ * oggz = (OGGZ *)user_data; - long serialno_a, serialno_b; - ogg_int64_t unit_a, unit_b; - - serialno_a = a->stream->ogg_stream.serialno; - serialno_b = b->stream->ogg_stream.serialno; - - unit_a = oggz_get_unit (oggz, serialno_a, a->op.granulepos); - unit_b = oggz_get_unit (oggz, serialno_b, b->op.granulepos); - - if (unit_a < unit_b) return -1; - else return (unit_a > unit_b); -} -#endif - -OGGZ * -oggz_write_init (OGGZ * oggz) -{ - OggzWriter * writer = &oggz->x.writer; - - writer->next_zpacket = NULL; - - writer->packet_queue = oggz_vector_new (); - -#ifdef ZPACKET_CMP - /* XXX: comparison function should only kick in when a metric is set */ - oggz_vector_set_cmp (writer->packet_queue, - (OggzCmpFunc)oggz_zpacket_cmp, oggz); -#endif - - writer->hungry = NULL; - writer->hungry_user_data = NULL; - writer->hungry_only_when_empty = 0; - - writer->writing = 0; - writer->state = OGGZ_MAKING_PACKETS; - - writer->flushing = 0; -#if 0 - writer->eog = 1; - writer->eop = 1; /* init ready to start next packet */ -#endif - writer->eos = 0; - - writer->current_zpacket = NULL; - - writer->packet_offset = 0; - writer->page_offset = 0; - - return oggz; -} - -static int -oggz_writer_packet_free (oggz_writer_packet_t * zpacket) -{ - if (!zpacket) return 0; - - if (zpacket->guard) { - /* managed by user; flag guard */ - *zpacket->guard = 1; - } else { - /* managed by oggz; free copied data */ - oggz_free (zpacket->op.packet); - } - oggz_free (zpacket); - - return 0; -} - -OGGZ * -oggz_write_close (OGGZ * oggz) -{ - OggzWriter * writer = &oggz->x.writer; - - oggz_vector_foreach (writer->packet_queue, - (OggzFunc)oggz_writer_packet_free); - oggz_vector_delete (writer->packet_queue); - - return oggz; -} - -/******** Packet queueing ********/ - -int -oggz_write_set_hungry_callback (OGGZ * oggz, OggzWriteHungry hungry, - int only_when_empty, void * user_data) -{ - OggzWriter * writer; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (!(oggz->flags & OGGZ_WRITE)) { - return OGGZ_ERR_INVALID; - } - - writer = &oggz->x.writer; - - writer->hungry = hungry; - writer->hungry_user_data = user_data; - writer->hungry_only_when_empty = only_when_empty; - - return 0; -} - -int -oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, - int * guard) -{ - OggzWriter * writer; - oggz_stream_t * stream; - oggz_writer_packet_t * packet; - ogg_packet * new_op; - unsigned char * new_buf; - int b_o_s, e_o_s, bos_auto; - int strict; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (!(oggz->flags & OGGZ_WRITE)) { - return OGGZ_ERR_INVALID; - } - - writer = &oggz->x.writer; - - if (guard && *guard != 0) return OGGZ_ERR_BAD_GUARD; - -#ifdef DEBUG - printf ("oggz_write_feed: (%010ld) FLUSH: %d\n", serialno, flush); -#endif - - /* Cache strict */ - strict = !(oggz->flags & OGGZ_NONSTRICT); - - /* Set bos, eos to canonical values */ - bos_auto = (op->b_o_s == -1) ? 1 : 0; - b_o_s = op->b_o_s ? 1 : 0; - e_o_s = op->e_o_s ? 1 : 0; - - stream = oggz_get_stream (oggz, serialno); - if (stream == NULL) { - if (bos_auto) b_o_s = 1; - - if (strict && b_o_s && !oggz_get_bos (oggz, -1)) { - return OGGZ_ERR_BOS; - } - - if (b_o_s || !strict) { - stream = oggz_add_stream (oggz, serialno); - } else { - return OGGZ_ERR_BAD_SERIALNO; - } - } else { - if (bos_auto) b_o_s = 0; - - if (strict && stream->e_o_s) - return OGGZ_ERR_EOS; - } - - /* Check packet against mapping restrictions */ - if (strict) { - if (op->bytes < 0) return OGGZ_ERR_BAD_BYTES; - if (b_o_s != stream->b_o_s) return OGGZ_ERR_BAD_B_O_S; - - if (op->granulepos != -1 && op->granulepos < stream->granulepos) - return OGGZ_ERR_BAD_GRANULEPOS; - - /* Allow packetno == -1 to indicate oggz should fill it in; otherwise: - * if op is the first packet in the stream, initialize the stream's - * packetno to the given one, otherwise check it for strictness */ - if (op->packetno != -1) { - if (b_o_s) { - stream->packetno = op->packetno; - } else if (op->packetno <= stream->packetno) { - return OGGZ_ERR_BAD_PACKETNO; - } - } - } - - /* OK -- Update stream's memory of packet details */ - - stream->b_o_s = 0; /* The stream is henceforth no longer at bos */ - stream->e_o_s = e_o_s; /* We believe the eos value */ - stream->granulepos = op->granulepos; /* and the granulepos */ - - /* If the user specified a packetno of -1, fill it in automatically; - * otherwise, use the user-specified value */ - stream->packetno = (op->packetno != -1) ? op->packetno : stream->packetno+1; - - /* Now set up the packet and add it to the queue */ - if (guard == NULL) { - new_buf = oggz_malloc ((size_t)op->bytes); - memcpy (new_buf, op->packet, (size_t)op->bytes); - } else { - new_buf = op->packet; - } - - packet = oggz_malloc (sizeof (oggz_writer_packet_t)); - - new_op = &packet->op; - new_op->packet = new_buf; - new_op->bytes = op->bytes; - new_op->b_o_s = op->b_o_s; - new_op->e_o_s = op->e_o_s; - new_op->granulepos = op->granulepos; - new_op->packetno = stream->packetno; - - packet->stream = stream; - packet->flush = flush; - packet->guard = guard; - -#ifdef DEBUG - printf ("oggz_write_feed: made packet bos %ld eos %ld (%ld bytes) FLUSH: %d\n", - new_op->b_o_s, new_op->e_o_s, new_op->bytes, packet->flush); -#endif - - if (oggz_vector_insert_p (writer->packet_queue, packet) == NULL) { - oggz_free (packet); - if (!guard) oggz_free (new_buf); - return -1; - } - - return 0; -} - -/******** Page creation ********/ - -/* - * - - ____ __________________\___ ____ - / \ / Page ready / \ / \ - | \ /=========\ /=========\ / | - Page | || Make || || Write || | Page - !ready V || packet || || page || V ready - | / \=========/ \=========/ \ | - \____/ \___/__________________/ \____/ - \ Page !ready - * - */ - - -/* - * oggz_page_init (oggz) - * - * Initialises the next page of the current packet. - * - * If this returns 0, the page is not ready for writing. - */ -static long -oggz_page_init (OGGZ * oggz) -{ - OggzWriter * writer = &oggz->x.writer; - ogg_stream_state * os; - ogg_page * og; - int ret; - - if (oggz == NULL) return -1; - - os = writer->current_stream; - og = &oggz->current_page; - -#ifdef ALWAYS_FLUSH - ret = ogg_stream_flush (os, og); -#else - if (writer->flushing) { -#ifdef DEBUG - printf ("*** ATTEMPT FLUSH: "); -#endif - ret = ogg_stream_flush (os, og); - } else { -#ifdef DEBUG - printf ("*** ATTEMPT pageout: "); -#endif - ret = ogg_stream_pageout (os, og); - } -#endif - - if (ret) { - writer->page_offset = 0; - } - -#ifdef DEBUG - printf ("%s\n", ret ? "OK" : "NO"); -#endif - - return ret; -} - -/* - * oggz_packet_init (oggz, buf, n) - * - * Initialises the next packet with data from buf, length n - */ -static long -oggz_packet_init (OGGZ * oggz, oggz_writer_packet_t * next_zpacket) -{ - OggzWriter * writer = &oggz->x.writer; - oggz_stream_t * stream; - ogg_stream_state * os; - ogg_packet * op; - - if (oggz == NULL) return -1L; - - writer->current_zpacket = next_zpacket; - op = &next_zpacket->op; - -#ifdef DEBUG - printf ("oggz_packet_init: %ld bytes\n", (long)op->bytes); -#endif - - stream = next_zpacket->stream; - - /* Mark this stream as having delivered a non b_o_s packet if so */ - if (!op->b_o_s) stream->delivered_non_b_o_s = 1; - - os = &stream->ogg_stream; - ogg_stream_packetin (os, op); - - writer->flushing = (next_zpacket->flush & OGGZ_FLUSH_AFTER); -#ifdef DEBUG - printf ("oggz_packet_init: set flush to %d\n", writer->flushing); -#endif - writer->current_stream = os; - writer->packet_offset = 0; - - return 0; -} - -static long -oggz_page_copyout (OGGZ * oggz, unsigned char * buf, long n) -{ - OggzWriter * writer = &oggz->x.writer; - long h, b; - ogg_page * og; - - if (oggz == NULL) return -1L; - - og = &oggz->current_page; - - h = MIN (n, og->header_len - writer->page_offset); - if (h > 0) { - memcpy (buf, og->header + writer->page_offset, h); - writer->page_offset += h; - n -= h; - buf += h; - } else { - h = 0; - } - - b = MIN (n, og->header_len + og->body_len - writer->page_offset); - if (b > 0) { -#ifdef DEBUG - { - unsigned char * c = &og->body[writer->page_offset - og->header_len]; - printf ("oggz_page_copyout [%d] (@%ld): %c%c%c%c ...\n", - ogg_page_serialno (og), (long) ogg_page_granulepos (og), - c[0], c[1], c[2], c[3]); - } -#endif - memcpy (buf, og->body + (writer->page_offset - og->header_len), b); - writer->page_offset += b; - n -= b; - buf += b; - } else { - b = 0; - } - - return h + b; -} - -static long -oggz_page_writeout (OGGZ * oggz, long n) -{ - OggzWriter * writer = &oggz->x.writer; - long h, b, nwritten; - ogg_page * og; - -#ifdef OGGZ_WRITE_DIRECT - int fd; -#endif - - if (oggz == NULL) return -1L; - - og = &oggz->current_page; - -#ifdef OGGZ_WRITE_DIRECT - fd = fileno (oggz->file); -#endif - - h = MIN (n, og->header_len - writer->page_offset); - if (h > 0) { -#ifdef OGGZ_WRITE_DIRECT - nwritten = write (fd, og->header + writer->page_offset, h); -#else - nwritten = (long)oggz_io_write (oggz, og->header + writer->page_offset, h); -#endif - -#ifdef DEBUG - if (nwritten < h) { - printf ("oggz_page_writeout: %ld < %ld\n", nwritten, h); - } -#endif - writer->page_offset += h; - n -= h; - } else { - h = 0; - } - - b = MIN (n, og->header_len + og->body_len - writer->page_offset); - if (b > 0) { -#ifdef OGGZ_WRITE_DIRECT - nwritten = write (fd, - og->body + (writer->page_offset - og->header_len), b); -#else - nwritten = (long)oggz_io_write (oggz, og->body + (writer->page_offset - og->header_len), b); -#endif -#ifdef DEBUG - if (nwritten < b) { - printf ("oggz_page_writeout: %ld < %ld\n", nwritten, b); - } -#endif - writer->page_offset += b; - n -= b; - } else { - b = 0; - } - - return h + b; -} - -static oggz_writer_packet_t * -oggz_dequeue_packet (OGGZ * oggz) -{ - OggzWriter * writer = &oggz->x.writer; - oggz_writer_packet_t * next_zpacket; - - if (writer->next_zpacket != NULL) { - next_zpacket = writer->next_zpacket; - writer->next_zpacket = NULL; - } else { - next_zpacket = oggz_vector_pop (writer->packet_queue); - - if (next_zpacket == NULL) { - if (writer->hungry) { - writer->hungry (oggz, 1, writer->hungry_user_data); - next_zpacket = oggz_vector_pop (writer->packet_queue); - } - } - } - - return next_zpacket; -} - -static long -oggz_writer_make_packet (OGGZ * oggz) -{ - OggzWriter * writer = &oggz->x.writer; - oggz_writer_packet_t * zpacket, * next_zpacket; - int cb_ret = 0, ret = 0; - -#ifdef DEBUG - printf ("make packet ...\n"); -#endif - - /* finished with current packet; unguard */ - zpacket = writer->current_zpacket; - oggz_writer_packet_free (zpacket); - writer->current_zpacket = NULL; - - /* if the user wants the hungry callback after every packet, give - * it to them, marking emptiness appropriately - */ - if (writer->hungry && !writer->hungry_only_when_empty) { - int empty = (oggz_vector_size (writer->packet_queue) == 0); - cb_ret = writer->hungry (oggz, empty, writer->hungry_user_data); - } - - if (cb_ret == 0) { - /* dequeue and init the next packet */ - if ((next_zpacket = oggz_dequeue_packet (oggz)) == NULL) { - /*writer->eos = 1;*/ - ret = 0; - } else { - if ((writer->current_stream != NULL) && - (next_zpacket->flush & OGGZ_FLUSH_BEFORE)) { - writer->flushing = 1; -#ifdef DEBUG - printf ("oggz_writer_make_packet: set flush to %d\n", - writer->flushing); -#endif - next_zpacket->flush &= OGGZ_FLUSH_AFTER; - writer->next_zpacket = next_zpacket; - } else { - oggz_packet_init (oggz, next_zpacket); - } - ret = 1; - } - } else { - ret = 0; - } - - return ret; -} - -long -oggz_write_output (OGGZ * oggz, unsigned char * buf, long n) -{ - OggzWriter * writer = &oggz->x.writer; - long bytes, bytes_written = 1, remaining = n, nwritten = 0; - int active = 1; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (!(oggz->flags & OGGZ_WRITE)) { - return OGGZ_ERR_INVALID; - } - - if (writer->writing) return OGGZ_ERR_RECURSIVE_WRITE; - writer->writing = 1; - - while (active && remaining > 0) { - bytes = MIN (remaining, 1024); - - while (writer->state == OGGZ_MAKING_PACKETS) { - if (!oggz_writer_make_packet (oggz)) { - active = 0; - break; - } - if (oggz_page_init (oggz)) { - writer->state = OGGZ_WRITING_PAGES; - } - } - - if (writer->state == OGGZ_WRITING_PAGES) { - bytes_written = oggz_page_copyout (oggz, buf, bytes); - - if (bytes_written == -1) { - active = 0; - return OGGZ_ERR_SYSTEM; /* XXX: catch next */ - } else if (bytes_written == 0) { - if (!oggz_page_init (oggz)) { - writer->state = OGGZ_MAKING_PACKETS; - } - } - - buf += bytes_written; - - remaining -= bytes_written; - nwritten += bytes_written; - } - } - - writer->writing = 0; - - return nwritten; -} - -long -oggz_write (OGGZ * oggz, long n) -{ - OggzWriter * writer = &oggz->x.writer; - long bytes, bytes_written = 1, remaining = n, nwritten = 0; - int active = 1; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (!(oggz->flags & OGGZ_WRITE)) { - return OGGZ_ERR_INVALID; - } - - if (writer->writing) return OGGZ_ERR_RECURSIVE_WRITE; - writer->writing = 1; - -#ifdef DEBUG - printf ("oggz_write: IN\n"); -#endif - - while (active && remaining > 0) { - bytes = MIN (remaining, 1024); - -#ifdef DEBUG - printf ("oggz_write: write loop (%ld , %ld remain) ...\n", bytes, - remaining); -#endif - - while (writer->state == OGGZ_MAKING_PACKETS) { - if (!oggz_writer_make_packet (oggz)) { - active = 0; -#ifdef DEBUG - printf ("oggz_write: no packets\n"); -#endif - break; - } - if (oggz_page_init (oggz)) { - writer->state = OGGZ_WRITING_PAGES; - } - } - - if (writer->state == OGGZ_WRITING_PAGES) { - bytes_written = oggz_page_writeout (oggz, bytes); - - if (bytes_written == -1) { - active = 0; - return OGGZ_ERR_SYSTEM; /* XXX: catch next */ - } else if (bytes_written == 0) { - if (!oggz_page_init (oggz)) { -#ifdef DEBUG - printf ("oggz_write: bytes_written == 0, DONE\n"); -#endif - writer->state = OGGZ_MAKING_PACKETS; - } - } - - remaining -= bytes_written; - nwritten += bytes_written; - } - } - -#ifdef DEBUG - printf ("oggz_write: OUT %ld\n", nwritten); -#endif - - writer->writing = 0; - - return nwritten; -} - -long -oggz_write_get_next_page_size (OGGZ * oggz) -{ - OggzWriter * writer = &oggz->x.writer; - ogg_page * og; - - if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ; - - if (!(oggz->flags & OGGZ_WRITE)) { - return OGGZ_ERR_INVALID; - } - - og = &oggz->current_page; - - return (og->header_len + og->body_len - (long)writer->page_offset); -} - -#else /* OGGZ_CONFIG_WRITE */ - -#include -#include "oggz_private.h" - -int -oggz_write_set_hungry_callback (OGGZ * oggz, OggzWriteHungry hungry, - int only_when_empty, void * user_data) -{ - return OGGZ_ERR_DISABLED; -} - -int -oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, - int * guard) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_write_output (OGGZ * oggz, unsigned char * buf, long n) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_write (OGGZ * oggz, long n) -{ - return OGGZ_ERR_DISABLED; -} - -long -oggz_write_get_next_page_size (OGGZ * oggz) -{ - return OGGZ_ERR_DISABLED; -} - -#endif diff --git a/src/add-ons/media/plugins/speex/Jamfile b/src/add-ons/media/plugins/speex/Jamfile deleted file mode 100644 index 1e8cbbdebd..0000000000 --- a/src/add-ons/media/plugins/speex/Jamfile +++ /dev/null @@ -1,17 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins speex ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -UsePrivateHeaders media ; - -SubDirHdrs $(SUBDIR) .. ogg ; -SubDirSysHdrs $(SUBDIR) .. ogg libogg ; -SubDirHdrs $(SUBDIR) libspeex ; - -Addon speex : - speexCodecPlugin.cpp - speexCodecDefaults.cpp - : libspeex.a be libmedia.so $(TARGET_LIBSUPC++) -; - -SubInclude HAIKU_TOP src add-ons media plugins speex libspeex ; diff --git a/src/add-ons/media/plugins/speex/libspeex/AUTHORS b/src/add-ons/media/plugins/speex/libspeex/AUTHORS deleted file mode 100644 index b3fd7f53b2..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -Jean-Marc Valin - All the code except the following - -David Rowe via VoiceTronix - lsp.c lsp.h - Also ideas and feedback - -John Francis Edwards: - wave_out.[ch], some #ifdefs for windows port and MSVC project files - -Atsuhiko Yamanaka : - Patch to speexenc.c to add Vorbis comment format - -Radim Kolar : - Patch to speexenc.c for supporting more input formats diff --git a/src/add-ons/media/plugins/speex/libspeex/COPYING b/src/add-ons/media/plugins/speex/libspeex/COPYING deleted file mode 100644 index 37beceff74..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/COPYING +++ /dev/null @@ -1,26 +0,0 @@ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/add-ons/media/plugins/speex/libspeex/ChangeLog b/src/add-ons/media/plugins/speex/libspeex/ChangeLog deleted file mode 100644 index 10db298711..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -2002/03/27 Jean-Marc Valin: -Working encoder and decoder for both narrowband and wideband. - -2002/02/27 Jean-Marc Valin: -Got the basic encoder working as a demo with quantization only on some -parameters. diff --git a/src/add-ons/media/plugins/speex/libspeex/Jamfile b/src/add-ons/media/plugins/speex/libspeex/Jamfile deleted file mode 100644 index 0581fb0dd7..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/Jamfile +++ /dev/null @@ -1,35 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins speex libspeex ; - -SubDirCcFlags -DVERSION=\\\"1.0.3\\\" ; - -StaticLibrary libspeex.a : - nb_celp.c - sb_celp.c - lpc.c - ltp.c - lsp.c - quant_lsp.c - lsp_tables_nb.c - gain_table.c - gain_table_lbr.c - cb_search.c - filters.c - bits.c - modes.c - vq.c - high_lsp_tables.c - vbr.c - hexc_table.c - exc_5_256_table.c - exc_5_64_table.c - exc_8_128_table.c - exc_10_32_table.c - exc_10_16_table.c - exc_20_32_table.c - hexc_10_32_table.c - misc.c - speex_header.c - speex_callbacks.c - math_approx.c - stereo.c -; diff --git a/src/add-ons/media/plugins/speex/libspeex/NEWS b/src/add-ons/media/plugins/speex/libspeex/NEWS deleted file mode 100644 index 9a99529141..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/NEWS +++ /dev/null @@ -1 +0,0 @@ -2002/02/13: Creation of the "Speex" project diff --git a/src/add-ons/media/plugins/speex/libspeex/README b/src/add-ons/media/plugins/speex/libspeex/README deleted file mode 100644 index 84fe74adb4..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/README +++ /dev/null @@ -1,9 +0,0 @@ -See INSTALL file for instruction on how to install Speex. - -The Speex is a patent-free, Open Source/Free Software voice codec. Unlike other codecs like MP3 and Ogg Vorbis, Speex is designed to compress voice at bitrates in the 2-45 kbps range. Possible applications include VoIP, internet audio streaming, archiving of speech data (e.g. voice mail), and audio books. In some sense, it is meant to be complementary to the Ogg Vorbis codec. - -To use the Speex command line tools: - -% speexenc [options] input_file.wav compressed_file.spx - -% speexdec [options] compressed_file.spx output_file.wav diff --git a/src/add-ons/media/plugins/speex/libspeex/TODO b/src/add-ons/media/plugins/speex/libspeex/TODO deleted file mode 100644 index 12a1a535f7..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/TODO +++ /dev/null @@ -1,18 +0,0 @@ -Features --Add maximum/minimum bit-rate control for VBR --Get the encoder to use the rate of packet loss (more conservative pitch gains) - -Long-term quality improvements --Improve perceptual enhancement (including wideband) - -Standards -*Complete Speex RTP profile --MIME type registration --MS ACM wrapper - -*required for 1.0 - -ideas: -Peelable stream (double codebook, higher bands, stereo) -LPC from spectral domain -Better psycho-acoustics? Masking curve from Vorbis diff --git a/src/add-ons/media/plugins/speex/libspeex/bits.c b/src/add-ons/media/plugins/speex/libspeex/bits.c deleted file mode 100644 index e3d4611a0d..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/bits.c +++ /dev/null @@ -1,363 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: speex_bits.c - - Handles bit packing/unpacking - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "speex_bits.h" -#include "misc.h" - -void speex_bits_init(SpeexBits *bits) -{ - int i; - bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME); - bits->buf_size = MAX_BYTES_PER_FRAME; - - for (i=0;ibuf_size;i++) - bits->bytes[i]=0; - bits->nbBits=0; - bits->bytePtr=0; - bits->bitPtr=0; - bits->owner=1; - bits->overflow=0; -} - -void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) -{ - int i; - bits->bytes = (char*)buff; - bits->buf_size = buf_size; - - for (i=0;ibytes[i]=0; - bits->nbBits=0; - bits->bytePtr=0; - bits->bitPtr=0; - bits->owner=0; - bits->overflow=0; -} - -void speex_bits_destroy(SpeexBits *bits) -{ - if (bits->owner) - speex_free(bits->bytes); - /* Will do something once the allocation is dynamic */ -} - -void speex_bits_reset(SpeexBits *bits) -{ - int i; - for (i=0;ibuf_size;i++) - bits->bytes[i]=0; - bits->nbBits=0; - bits->bytePtr=0; - bits->bitPtr=0; - bits->overflow=0; -} - -void speex_bits_rewind(SpeexBits *bits) -{ - bits->bytePtr=0; - bits->bitPtr=0; - bits->overflow=0; -} - -void speex_bits_read_from(SpeexBits *bits, char *bytes, int len) -{ - int i; - if (len > bits->buf_size) - { - speex_warning_int("Packet is larger than allocated buffer: ", len); - if (bits->owner) - { - char *tmp = (char*)speex_realloc(bits->bytes, len); - if (tmp) - { - bits->buf_size=len; - bits->bytes=tmp; - } else { - len=bits->buf_size; - speex_warning("Could not resize input buffer: truncating input"); - } - } else { - speex_warning("Do not own input buffer: truncating input"); - len=bits->buf_size; - } - } - for (i=0;ibytes[i]=bytes[i]; - bits->nbBits=len<<3; - bits->bytePtr=0; - bits->bitPtr=0; - bits->overflow=0; -} - -static void speex_bits_flush(SpeexBits *bits) -{ - int i; - if (bits->bytePtr>0) - { - for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++) - bits->bytes[i-bits->bytePtr]=bits->bytes[i]; - } - bits->nbBits -= bits->bytePtr<<3; - bits->bytePtr=0; -} - -void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len) -{ - int i,pos; - - if ((bits->nbBits>>3)+len+1 > bits->buf_size) - { - speex_warning_int("Packet is larger than allocated buffer: ", len); - if (bits->owner) - { - char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1); - if (tmp) - { - bits->buf_size=(bits->nbBits>>3)+len+1; - bits->bytes=tmp; - } else { - len=bits->buf_size-(bits->nbBits>>3)-1; - speex_warning("Could not resize input buffer: truncating input"); - } - } else { - speex_warning("Do not own input buffer: truncating input"); - len=bits->buf_size; - } - } - - speex_bits_flush(bits); - pos=bits->nbBits>>3; - for (i=0;ibytes[pos+i]=bytes[i]; - bits->nbBits+=len<<3; -} - -int speex_bits_write(SpeexBits *bits, char *bytes, int max_len) -{ - int i; - int bytePtr, bitPtr, nbBits; - - /* Insert terminator, but save the data so we can put it back after */ - bitPtr=bits->bitPtr; - bytePtr=bits->bytePtr; - nbBits=bits->nbBits; - speex_bits_insert_terminator(bits); - bits->bitPtr=bitPtr; - bits->bytePtr=bytePtr; - bits->nbBits=nbBits; - - if (max_len > ((bits->nbBits+7)>>3)) - max_len = ((bits->nbBits+7)>>3); - for (i=0;ibytes[i]; - return max_len; -} - -int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len) -{ - int i; - if (max_len > ((bits->nbBits)>>3)) - max_len = ((bits->nbBits)>>3); - for (i=0;ibytes[i]; - - if (bits->bitPtr>0) - bits->bytes[0]=bits->bytes[max_len]; - else - bits->bytes[0]=0; - for (i=1;i<((bits->nbBits)>>3)+1;i++) - bits->bytes[i]=0; - bits->bytePtr=0; - bits->nbBits &= 7; - return max_len; -} - - -void speex_bits_pack(SpeexBits *bits, int data, int nbBits) -{ - int i; - unsigned int d=data; - - if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size) - { - speex_warning("Buffer too small to pack bits"); - if (bits->owner) - { - char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1); - if (tmp) - { - for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++) - tmp[i]=0; - bits->buf_size=((bits->buf_size+5)*3)>>1; - bits->bytes=tmp; - } else { - speex_warning("Could not resize input buffer: not packing"); - return; - } - } else { - speex_warning("Do not own input buffer: not packing"); - return; - } - } - - while(nbBits) - { - int bit; - bit = (d>>(nbBits-1))&1; - bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr); - bits->bitPtr++; - - if (bits->bitPtr==8) - { - bits->bitPtr=0; - bits->bytePtr++; - } - bits->nbBits++; - nbBits--; - } -} - -int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) -{ - unsigned int d=speex_bits_unpack_unsigned(bits,nbBits); - /* If number is negative */ - if (d>>(nbBits-1)) - { - d |= (-1)<bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return 0; - while(nbBits) - { - d<<=1; - d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1; - bits->bitPtr++; - if (bits->bitPtr==8) - { - bits->bitPtr=0; - bits->bytePtr++; - } - nbBits--; - } - return d; -} - -unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) -{ - unsigned int d=0; - int bitPtr, bytePtr; - char *bytes; - - if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return 0; - - bitPtr=bits->bitPtr; - bytePtr=bits->bytePtr; - bytes = bits->bytes; - while(nbBits) - { - d<<=1; - d |= (bytes[bytePtr]>>(7-bitPtr))&1; - bitPtr++; - if (bitPtr==8) - { - bitPtr=0; - bytePtr++; - } - nbBits--; - } - return d; -} - -int speex_bits_peek(SpeexBits *bits) -{ - if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return 0; - return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1; -} - -void speex_bits_advance(SpeexBits *bits, int n) -{ - int nbytes, nbits; - - if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return; - - nbytes = n >> 3; - nbits = n & 7; - - bits->bytePtr += nbytes; - bits->bitPtr += nbits; - - if (bits->bitPtr>7) - { - bits->bitPtr-=8; - bits->bytePtr++; - } -} - -int speex_bits_remaining(SpeexBits *bits) -{ - if (bits->overflow) - return -1; - else - return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr); -} - -int speex_bits_nbytes(SpeexBits *bits) -{ - return ((bits->nbBits+7)>>3); -} - -void speex_bits_insert_terminator(SpeexBits *bits) -{ - if (bits->bitPtr<7) - speex_bits_pack(bits, 0, 1); - while (bits->bitPtr<7) - speex_bits_pack(bits, 1, 1); -} diff --git a/src/add-ons/media/plugins/speex/libspeex/cb_search.c b/src/add-ons/media/plugins/speex/libspeex/cb_search.c deleted file mode 100644 index 785bb49b3b..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/cb_search.c +++ /dev/null @@ -1,387 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: cb_search.c - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "cb_search.h" -#include "filters.h" -#include "stack_alloc.h" -#include "vq.h" -#include "misc.h" - -void split_cb_search_shape_sign( -float target[], /* target vector */ -float ak[], /* LPCs for this subframe */ -float awk1[], /* Weighted LPCs for this subframe */ -float awk2[], /* Weighted LPCs for this subframe */ -void *par, /* Codebook/search parameters*/ -int p, /* number of LPC coeffs */ -int nsf, /* number of samples in subframe */ -float *exc, -float *r, -SpeexBits *bits, -char *stack, -int complexity -) -{ - int i,j,k,m,n,q; - float *resp; - float *t, *e, *E, *r2; - float *tmp; - float *ndist, *odist; - int *itmp; - float **ot, **nt; - int **nind, **oind; - int *ind; - signed char *shape_cb; - int shape_cb_size, subvect_size, nb_subvect; - split_cb_params *params; - int N=2; - int *best_index; - float *best_dist; - int have_sign; - - N=complexity; - if (N>10) - N=10; - - ot=PUSH(stack, N, float*); - nt=PUSH(stack, N, float*); - oind=PUSH(stack, N, int*); - nind=PUSH(stack, N, int*); - - params = (split_cb_params *) par; - subvect_size = params->subvect_size; - nb_subvect = params->nb_subvect; - shape_cb_size = 1<shape_bits; - shape_cb = params->shape_cb; - have_sign = params->have_sign; - resp = PUSH(stack, shape_cb_size*subvect_size, float); - t = PUSH(stack, nsf, float); - e = PUSH(stack, nsf, float); - r2 = PUSH(stack, nsf, float); - E = PUSH(stack, shape_cb_size, float); - ind = PUSH(stack, nb_subvect, int); - - tmp = PUSH(stack, 2*N*nsf, float); - for (i=0;i=shape_cb_size) - { - sign=-1; - rind-=shape_cb_size; - } - res = resp+rind*subvect_size; - if (sign>0) - for (m=0;m=shape_cb_size) - { - sign=-1; - rind-=shape_cb_size; - } - - g=sign*0.03125*shape_cb[rind*subvect_size+m]; - q=subvect_size-m; - for (n=subvect_size*(i+1);nm;n--) - { - for (q=(i+1)*subvect_size;qshape_bits+have_sign); - } - - /* Put everything back together */ - for (i=0;i=shape_cb_size) - { - sign=-1; - rind-=shape_cb_size; - } - - for (j=0;jsubvect_size; - nb_subvect = params->nb_subvect; - shape_cb_size = 1<shape_bits; - shape_cb = params->shape_cb; - have_sign = params->have_sign; - - ind = PUSH(stack, nb_subvect, int); - signs = PUSH(stack, nb_subvect, int); - - /* Decode codewords and gains */ - for (i=0;ishape_bits); - } - /* Compute decoded excitation */ - for (i=0;i - - -void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order) -{ - int i; - float tmp=1; - for (i=0;i>1; - for (i=0;ilast_pitch=0; - mem->last_pitch_gain[0]=mem->last_pitch_gain[1]=mem->last_pitch_gain[2]=0; - mem->smooth_gain=1; -} - -void comb_filter( -float *exc, /*decoded excitation*/ -float *new_exc, /*enhanced excitation*/ -float *ak, /*LPC filter coefs*/ -int p, /*LPC order*/ -int nsf, /*sub-frame size*/ -int pitch, /*pitch period*/ -float *pitch_gain, /*pitch gain (3-tap)*/ -float comb_gain, /*gain of comb filter*/ -CombFilterMem *mem -) -{ - int i; - float exc_energy=0, new_exc_energy=0; - float gain; - float step; - float fact; - /*Compute excitation energy prior to enhancement*/ - for (i=0;ilast_pitch_gain[0] + mem->last_pitch_gain[1] + mem->last_pitch_gain[2]); - if (g>1.3) - comb_gain*=1.3/g; - if (g<.5) - comb_gain*=2*g; - } - step = 1.0/nsf; - fact=0; - /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/ - for (i=0;ilast_pitch_gain[0]*exc[i-mem->last_pitch+1] + - mem->last_pitch_gain[1]*exc[i-mem->last_pitch] + - mem->last_pitch_gain[2]*exc[i-mem->last_pitch-1] - ); - } - - mem->last_pitch_gain[0] = pitch_gain[0]; - mem->last_pitch_gain[1] = pitch_gain[1]; - mem->last_pitch_gain[2] = pitch_gain[2]; - mem->last_pitch = pitch; - - /*Gain after enhancement*/ - for (i=0;i1) - gain=1; - - for (i=0;ismooth_gain = .96*mem->smooth_gain + .04*gain; - new_exc[i] *= mem->smooth_gain; - } -} diff --git a/src/add-ons/media/plugins/speex/libspeex/filters.h b/src/add-ons/media/plugins/speex/libspeex/filters.h deleted file mode 100644 index ad6dc022d1..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/filters.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: filters.h - Various analysis/synthesis filters - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FILTERS_H -#define FILTERS_H - - -typedef struct CombFilterMem { - int last_pitch; - float last_pitch_gain[3]; - float smooth_gain; -} CombFilterMem; - - -void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack); -void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack); - - -void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem); -void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem); -void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem); - -/* Apply bandwidth expansion on LPC coef */ -void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order); - - - -/* FIR filter */ -void fir_decim_mem(float *x, float *a, float *y, int N, int M, float *mem); - -void syn_percep_zero(float *x, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack); - -void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack); - -void comp_filter_mem_init (CombFilterMem *mem); - -void comb_filter( -float *exc, /*decoded excitation*/ -float *new_exc, /*enhanced excitation*/ -float *ak, /*LPC filter coefs*/ -int p, /*LPC order*/ -int nsf, /*sub-frame size*/ -int pitch, /*pitch period*/ -float *pitch_gain, /*pitch gain (3-tap)*/ -float comb_gain, /*gain of comb filter*/ -CombFilterMem *mem -); - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/filters_sse.h b/src/add-ons/media/plugins/speex/libspeex/filters_sse.h deleted file mode 100644 index 3fba6c8d63..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/filters_sse.h +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: filters.c - Various analysis/synthesis filters - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -void filter_mem2(float *x, float *_num, float *_den, float *y, int N, int ord, float *_mem) -{ - float __num[20], __den[20], __mem[20]; - float *num, *den, *mem; - int i; - - num = (float*)(((int)(__num+4))&0xfffffff0)-1; - den = (float*)(((int)(__den+4))&0xfffffff0)-1; - mem = (float*)(((int)(__mem+4))&0xfffffff0)-1; - for (i=0;i<=10;i++) - num[i]=den[i]=0; - for (i=0;i<10;i++) - mem[i]=0; - - for (i=0;i x(n) * x(n-i) for all n - * `--' - * for lags between 0 and lag-1, and x == 0 outside 0...n-1 - */ -void _spx_autocorr( - const float * x, /* in: [0...n-1] samples x */ - float *ac, /* out: [0...lag-1] ac values */ - int lag, int n) -{ - float d; int i; - while (lag--) { - for (i = lag, d = 0; i < n; i++) d += x[i] * x[i-lag]; - ac[lag] = d; - } -} diff --git a/src/add-ons/media/plugins/speex/libspeex/lpc.h b/src/add-ons/media/plugins/speex/libspeex/lpc.h deleted file mode 100644 index e3f70b5a6d..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/lpc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: lpc.h - Functions for LPC (Linear Prediction Coefficients) analysis - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef LPC_H -#define LPC_H - -void _spx_autocorr( - const float * x, /* in: [0...n-1] samples x */ - float *ac, /* out: [0...lag-1] ac values */ - int lag, int n); - -float /* returns minimum mean square error */ -wld( - float * lpc, /* [0...p-1] LPC coefficients */ - const float * ac, /* in: [0...p] autocorrelation values */ - float * ref, /* out: [0...p-1] reflection coef's */ - int p - ); - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/lsp.c b/src/add-ons/media/plugins/speex/libspeex/lsp.c deleted file mode 100644 index 1af762cdf7..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/lsp.c +++ /dev/null @@ -1,328 +0,0 @@ -/*---------------------------------------------------------------------------*\ -Original copyright - FILE........: AKSLSPD.C - TYPE........: Turbo C - COMPANY.....: Voicetronix - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - -Modified by Jean-Marc Valin - - This file contains functions for converting Linear Prediction - Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the - LSP coefficients are not in radians format but in the x domain of the - unit circle. - - Speex License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include "lsp.h" -#include "stack_alloc.h" - - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#ifndef NULL -#define NULL 0 -#endif - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: cheb_poly_eva() - - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - - This function evaluates a series of Chebyshev polynomials - -\*---------------------------------------------------------------------------*/ - - - -static float cheb_poly_eva(float *coef,float x,int m,char *stack) -/* float coef[] coefficients of the polynomial to be evaluated */ -/* float x the point where polynomial is to be evaluated */ -/* int m order of the polynomial */ -{ - int i; - float *T,sum; - int m2=m>>1; - - /* Allocate memory for Chebyshev series formulation */ - T=PUSH(stack, m2+1, float); - - /* Initialise values */ - T[0]=1; - T[1]=x; - - /* Evaluate Chebyshev series formulation using iterative approach */ - /* Evaluate polynomial and return value also free memory space */ - sum = coef[m2] + coef[m2-1]*x; - x *= 2; - for(i=2;i<=m2;i++) - { - T[i] = x*T[i-1] - T[i-2]; - sum += coef[m2-i] * T[i]; - } - - return sum; -} - - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: lpc_to_lsp() - - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - - This function converts LPC coefficients to LSP - coefficients. - -\*---------------------------------------------------------------------------*/ - - -int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack) -/* float *a lpc coefficients */ -/* int lpcrdr order of LPC coefficients (10) */ -/* float *freq LSP frequencies in the x domain */ -/* int nb number of sub-intervals (4) */ -/* float delta grid spacing interval (0.02) */ - - -{ - - float psuml,psumr,psumm,temp_xr,xl,xr,xm=0; - float temp_psumr/*,temp_qsumr*/; - int i,j,m,flag,k; - float *Q; /* ptrs for memory allocation */ - float *P; - float *px; /* ptrs of respective P'(z) & Q'(z) */ - float *qx; - float *p; - float *q; - float *pt; /* ptr used for cheb_poly_eval() - whether P' or Q' */ - int roots=0; /* DR 8/2/94: number of roots found */ - flag = 1; /* program is searching for a root when, - 1 else has found one */ - m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */ - - - /* Allocate memory space for polynomials */ - Q = PUSH(stack, (m+1), float); - P = PUSH(stack, (m+1), float); - - /* determine P'(z)'s and Q'(z)'s coefficients where - P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ - - px = P; /* initialise ptrs */ - qx = Q; - p = px; - q = qx; - *px++ = 1.0; - *qx++ = 1.0; - for(i=1;i<=m;i++){ - *px++ = a[i]+a[lpcrdr+1-i]-*p++; - *qx++ = a[i]-a[lpcrdr+1-i]+*q++; - } - px = P; - qx = Q; - for(i=0;i= -1.0)){ - float dd; - /* Modified by JMV to provide smaller steps around x=+-1 */ - dd=(delta*(1-.9*xl*xl)); - if (fabs(psuml)<.2) - dd *= .5; - - xr = xl - dd; /* interval spacing */ - psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x) */ - temp_psumr = psumr; - temp_xr = xr; - - /* if no sign change increment xr and re-evaluate poly(xr). Repeat til - sign change. - if a sign change has occurred the interval is bisected and then - checked again for a sign change which determines in which - interval the zero lies in. - If there is no sign change between poly(xm) and poly(xl) set interval - between xm and xr else set interval between xl and xr and repeat till - root is located within the specified limits */ - - if((psumr*psuml)<0.0){ - roots++; - - psumm=psuml; - for(k=0;k<=nb;k++){ - xm = (xl+xr)/2; /* bisect the interval */ - psumm=cheb_poly_eva(pt,xm,lpcrdr,stack); - if(psumm*psuml>0.){ - psuml=psumm; - xl=xm; - } - else{ - psumr=psumm; - xr=xm; - } - } - - /* once zero is found, reset initial interval to xr */ - freq[j] = (xm); - xl = xm; - flag = 0; /* reset flag for next search */ - } - else{ - psuml=temp_psumr; - xl=temp_xr; - } - } - } - return(roots); -} - - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: lsp_to_lpc() - - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - - lsp_to_lpc: This function converts LSP coefficients to LPC - coefficients. - -\*---------------------------------------------------------------------------*/ - - -void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack) -/* float *freq array of LSP frequencies in the x domain */ -/* float *ak array of LPC coefficients */ -/* int lpcrdr order of LPC coefficients */ - - -{ - int i,j; - float xout1,xout2,xin1,xin2; - float *Wp; - float *pw,*n1,*n2,*n3,*n4=NULL; - int m = lpcrdr/2; - - Wp = PUSH(stack, 4*m+2, float); - pw = Wp; - - /* initialise contents of array */ - - for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ - *pw++ = 0.0; - } - - /* Set pointers up */ - - pw = Wp; - xin1 = 1.0; - xin2 = 1.0; - - /* reconstruct P(z) and Q(z) by cascading second order - polynomials in form 1 - 2xz(-1) +z(-2), where x is the - LSP coefficient */ - - for(j=0;j<=lpcrdr;j++){ - int i2=0; - for(i=0;iM_PI-margin) - lsp[len-1]=M_PI-margin; - for (i=1;ilsp[i+1]-margin) - lsp[i]= .5* (lsp[i] + lsp[i+1]-margin); - } -} diff --git a/src/add-ons/media/plugins/speex/libspeex/lsp.h b/src/add-ons/media/plugins/speex/libspeex/lsp.h deleted file mode 100644 index 2540495480..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/lsp.h +++ /dev/null @@ -1,57 +0,0 @@ -/*---------------------------------------------------------------------------*\ -Original Copyright - FILE........: AK2LSPD.H - TYPE........: Turbo C header file - COMPANY.....: Voicetronix - AUTHOR......: James Whitehall - DATE CREATED: 21/11/95 - -Modified by Jean-Marc Valin - - This file contains functions for converting Linear Prediction - Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the - LSP coefficients are not in radians format but in the x domain of the - unit circle. - -\*---------------------------------------------------------------------------*/ -/* Speex License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __AK2LSPD__ -#define __AK2LSPD__ - -int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta, char *stack); -void lsp_to_lpc(float *freq, float *ak, int lpcrdr, char *stack); - -/*Added by JMV*/ -void lsp_enforce_margin(float *lsp, int len, float margin); - - -#endif /* __AK2LSPD__ */ diff --git a/src/add-ons/media/plugins/speex/libspeex/lsp_tables_nb.c b/src/add-ons/media/plugins/speex/libspeex/lsp_tables_nb.c deleted file mode 100644 index a68ce99444..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/lsp_tables_nb.c +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: lsp_tables_nb.c - Codebooks for LSPs in narrowband CELP mode - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -signed char cdbk_nb[640]={ -30,19,38,34,40,32,46,43,58,43, -5,-18,-25,-40,-33,-55,-52,20,34,28, --20,-63,-97,-92,61,53,47,49,53,75, --14,-53,-77,-79,0,-3,-5,19,22,26, --9,-53,-55,66,90,72,85,68,74,52, --4,-41,-58,-31,-18,-31,27,32,30,18, -24,3,8,5,-12,-3,26,28,74,63, --2,-39,-67,-77,-106,-74,59,59,73,65, -44,40,71,72,82,83,98,88,89,60, --6,-31,-47,-48,-13,-39,-9,7,2,79, --1,-39,-60,-17,87,81,65,50,45,19, --21,-67,-91,-87,-41,-50,7,18,39,74, -10,-31,-28,39,24,13,23,5,56,45, -29,10,-5,-13,-11,-35,-18,-8,-10,-8, --25,-71,-77,-21,2,16,50,63,87,87, -5,-32,-40,-51,-68,0,12,6,54,34, -5,-12,32,52,68,64,69,59,65,45, -14,-16,-31,-40,-65,-67,41,49,47,37, --11,-52,-75,-84,-4,57,48,42,42,33, --11,-51,-68,-6,13,0,8,-8,26,32, --23,-53,0,36,56,76,97,105,111,97, --1,-28,-39,-40,-43,-54,-44,-40,-18,35, -16,-20,-19,-28,-42,29,47,38,74,45, -3,-29,-48,-62,-80,-104,-33,56,59,59, -10,17,46,72,84,101,117,123,123,106, --7,-33,-49,-51,-70,-67,-27,-31,70,67, --16,-62,-85,-20,82,71,86,80,85,74, --19,-58,-75,-45,-29,-33,-18,-25,45,57, --12,-42,-5,12,28,36,52,64,81,82, -13,-9,-27,-28,22,3,2,22,26,6, --6,-44,-51,2,15,10,48,43,49,34, --19,-62,-84,-89,-102,-24,8,17,61,68, -39,24,23,19,16,-5,12,15,27,15, --8,-44,-49,-60,-18,-32,-28,52,54,62, --8,-48,-77,-70,66,101,83,63,61,37, --12,-50,-75,-64,33,17,13,25,15,77, -1,-42,-29,72,64,46,49,31,61,44, --8,-47,-54,-46,-30,19,20,-1,-16,0, -16,-12,-18,-9,-26,-27,-10,-22,53,45, --10,-47,-75,-82,-105,-109,8,25,49,77, -50,65,114,117,124,118,115,96,90,61, --9,-45,-63,-60,-75,-57,8,11,20,29, -0,-35,-49,-43,40,47,35,40,55,38, --24,-76,-103,-112,-27,3,23,34,52,75, -8,-29,-43,12,63,38,35,29,24,8, -25,11,1,-15,-18,-43,-7,37,40,21, --20,-56,-19,-19,-4,-2,11,29,51,63, --2,-44,-62,-75,-89,30,57,51,74,51, -50,46,68,64,65,52,63,55,65,43, -18,-9,-26,-35,-55,-69,3,6,8,17, --15,-61,-86,-97,1,86,93,74,78,67, --1,-38,-66,-48,48,39,29,25,17,-1, -13,13,29,39,50,51,69,82,97,98, --2,-36,-46,-27,-16,-30,-13,-4,-7,-4, -25,-5,-11,-6,-25,-21,33,12,31,29, --8,-38,-52,-63,-68,-89,-33,-1,10,74, --2,-15,59,91,105,105,101,87,84,62, --7,-33,-50,-35,-54,-47,25,17,82,81, --13,-56,-83,21,58,31,42,25,72,65, --24,-66,-91,-56,9,-2,21,10,69,75, -2,-24,11,22,25,28,38,34,48,33, -7,-29,-26,17,15,-1,14,0,-2,0, --6,-41,-67,6,-2,-9,19,2,85,74, --22,-67,-84,-71,-50,3,11,-9,2,62}; - -signed char cdbk_nb_low1[320]={ --34,-52,-15,45,2, -23,21,52,24,-33, --9,-1,9,-44,-41, --13,-17,44,22,-17, --6,-4,-1,22,38, -26,16,2,50,27, --35,-34,-9,-41,6, -0,-16,-34,51,8, --14,-31,-49,15,-33, -45,49,33,-11,-37, --62,-54,45,11,-5, --72,11,-1,-12,-11, -24,27,-11,-43,46, -43,33,-12,-9,-1, -1,-4,-23,-57,-71, -11,8,16,17,-8, --20,-31,-41,53,48, --16,3,65,-24,-8, --23,-32,-37,-32,-49, --10,-17,6,38,5, --9,-17,-46,8,52, -3,6,45,40,39, --7,-6,-34,-74,31, -8,1,-16,43,68, --11,-19,-31,4,6, -0,-6,-17,-16,-38, --16,-30,2,9,-39, --16,-1,43,-10,48, -3,3,-16,-31,-3, -62,68,43,13,3, --10,8,20,-56,12, -12,-2,-18,22,-15, --40,-36,1,7,41, -0,1,46,-6,-62, --4,-12,-2,-11,-83, --13,-2,91,33,-10, -0,4,-11,-16,79, -32,37,14,9,51, --21,-28,-56,-34,0, -21,9,-26,11,28, --42,-54,-23,-2,-15, -31,30,8,-39,-66, --39,-36,31,-28,-40, --46,35,40,22,24, -33,48,23,-34,14, -40,32,17,27,-3, -25,26,-13,-61,-17, -11,4,31,60,-6, --26,-41,-64,13,16, --26,54,31,-11,-23, --9,-11,-34,-71,-21, --34,-35,55,50,29, --22,-27,-50,-38,57, -33,42,57,48,26, -11,0,-49,-31,26, --4,-14,5,78,37, -17,0,-49,-12,-23, -26,14,2,2,-43, --17,-12,10,-8,-4, -8,18,12,-6,20, --12,-6,-13,-25,34, -15,40,49,7,8, -13,20,20,-19,-22, --2,-8,2,51,-51}; - -signed char cdbk_nb_low2[320]={ --6,53,-21,-24,4, -26,17,-4,-37,25, -17,-36,-13,31,3, --6,27,15,-10,31, -28,26,-10,-10,-40, -16,-7,15,13,41, --9,0,-4,50,-6, --7,14,38,22,0, --48,2,1,-13,-19, -32,-3,-60,11,-17, --1,-24,-34,-1,35, --5,-27,28,44,13, -25,15,42,-11,15, -51,35,-36,20,8, --4,-12,-29,19,-47, -49,-15,-4,16,-29, --39,14,-30,4,25, --9,-5,-51,-14,-3, --40,-32,38,5,-9, --8,-4,-1,-22,71, --3,14,26,-18,-22, -24,-41,-25,-24,6, -23,19,-10,39,-26, --27,65,45,2,-7, --26,-8,22,-12,16, -15,16,-35,-5,33, --21,-8,0,23,33, -34,6,21,36,6, --7,-22,8,-37,-14, -31,38,11,-4,-3, --39,-32,-8,32,-23, --6,-12,16,20,-28, --4,23,13,-52,-1, -22,6,-33,-40,-6, -4,-62,13,5,-26, -35,39,11,2,57, --11,9,-20,-28,-33, -52,-5,-6,-2,22, --14,-16,-48,35,1, --58,20,13,33,-1, --74,56,-18,-22,-31, -12,6,-14,4,-2, --9,-47,10,-3,29, --17,-5,61,14,47, --12,2,72,-39,-17, -92,64,-53,-51,-15, --30,-38,-41,-29,-28, -27,9,36,9,-35, --42,81,-21,20,25, --16,-5,-17,-35,21, -15,-28,48,2,-2, -9,-19,29,-40,30, --18,-18,18,-16,-57, -15,-20,-12,-15,-37, --15,33,-39,21,-22, --13,35,11,13,-38, --63,29,23,-27,32, -18,3,-26,42,33, --64,-66,-17,16,56, -2,36,3,31,21, --41,-39,8,-57,14, -37,-2,19,-36,-19, --23,-29,-16,1,-3, --8,-10,31,64,-65}; - -signed char cdbk_nb_high1[320]={ --26,-8,29,21,4, -19,-39,33,-7,-36, -56,54,48,40,29, --4,-24,-42,-66,-43, --60,19,-2,37,41, --10,-37,-60,-64,18, --22,77,73,40,25, -4,19,-19,-66,-2, -11,5,21,14,26, --25,-86,-4,18,1, -26,-37,10,37,-1, -24,-12,-59,-11,20, --6,34,-16,-16,42, -19,-28,-51,53,32, -4,10,62,21,-12, --34,27,4,-48,-48, --50,-49,31,-7,-21, --42,-25,-4,-43,-22, -59,2,27,12,-9, --6,-16,-8,-32,-58, --16,-29,-5,41,23, --30,-33,-46,-13,-10, --38,52,52,1,-17, --9,10,26,-25,-6, -33,-20,53,55,25, --32,-5,-42,23,21, -66,5,-28,20,9, -75,29,-7,-42,-39, -15,3,-23,21,6, -11,1,-29,14,63, -10,54,26,-24,-51, --49,7,-23,-51,15, --66,1,60,25,10, -0,-30,-4,-15,17, -19,59,40,4,-5, -33,6,-22,-58,-70, --5,23,-6,60,44, --29,-16,-47,-29,52, --19,50,28,16,35, -31,36,0,-21,6, -21,27,22,42,7, --66,-40,-8,7,19, -46,0,-4,60,36, -45,-7,-29,-6,-32, --39,2,6,-9,33, -20,-51,-34,18,-6, -19,6,11,5,-19, --29,-2,42,-11,-45, --21,-55,57,37,2, --14,-67,-16,-27,-38, -69,48,19,2,-17, -20,-20,-16,-34,-17, --25,-61,10,73,45, -16,-40,-64,-17,-29, --22,56,17,-39,8, --11,8,-25,-18,-13, --19,8,54,57,36, --17,-26,-4,6,-21, -40,42,-4,20,31, -53,10,-34,-53,31, --17,35,0,15,-6, --20,-63,-73,22,25, -29,17,8,-29,-39, --69,18,15,-15,-5}; - -signed char cdbk_nb_high2[320]={ -11,47,16,-9,-46, --32,26,-64,34,-5, -38,-7,47,20,2, --73,-99,-3,-45,20, -70,-52,15,-6,-7, --82,31,21,47,51, -39,-3,9,0,-41, --7,-15,-54,2,0, -27,-31,9,-45,-22, --38,-24,-24,8,-33, -23,5,50,-36,-17, --18,-51,-2,13,19, -43,12,-15,-12,61, -38,38,7,13,0, -6,-1,3,62,9, -27,22,-33,38,-35, --9,30,-43,-9,-32, --1,4,-4,1,-5, --11,-8,38,31,11, --10,-42,-21,-37,1, -43,15,-13,-35,-19, --18,15,23,-26,59, -1,-21,53,8,-41, --50,-14,-28,4,21, -25,-28,-40,5,-40, --41,4,51,-33,-8, --8,1,17,-60,12, -25,-41,17,34,43, -19,45,7,-37,24, --15,56,-2,35,-10, -48,4,-47,-2,5, --5,-54,5,-3,-33, --10,30,-2,-44,-24, --38,9,-9,42,4, -6,-56,44,-16,9, --40,-26,18,-20,10, -28,-41,-21,-4,13, --18,32,-30,-3,37, -15,22,28,50,-40, -3,-29,-64,7,51, --19,-11,17,-27,-40, --64,24,-12,-7,-27, -3,37,48,-1,2, --9,-38,-34,46,1, -27,-6,19,-13,26, -10,34,20,25,40, -50,-6,-7,30,9, --24,0,-23,71,-61, -22,58,-34,-4,2, --49,-33,25,30,-8, --6,-16,77,2,38, --8,-35,-6,-30,56, -78,31,33,-20,13, --39,20,22,4,21, --8,4,-6,10,-83, --41,9,-25,-43,15, --7,-12,-34,-39,-37, --33,19,30,16,-33, -42,-25,25,-68,44, --15,-11,-4,23,50, -14,4,-39,-43,20, --30,60,9,-20,7, -16,19,-33,37,29, -16,-35,7,38,-27}; diff --git a/src/add-ons/media/plugins/speex/libspeex/ltp.c b/src/add-ons/media/plugins/speex/libspeex/ltp.c deleted file mode 100644 index f95d2152ca..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/ltp.c +++ /dev/null @@ -1,548 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: ltp.c - Long-Term Prediction functions - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include "ltp.h" -#include "stack_alloc.h" -#include "filters.h" -#include "speex_bits.h" - -#ifdef _USE_SSE -#include "ltp_sse.h" -#else -static float inner_prod(float *x, float *y, int len) -{ - int i; - float sum1=0,sum2=0,sum3=0,sum4=0; - for (i=0;ibest_score[N-1]) - { - float g1, g; - g1 = corr[i-start]/(energy[i-start]+10); - g = sqrt(g1*corr[i-start]/(e0+10)); - if (g>g1) - g=g1; - if (g<0) - g=0; - for (j=0;j best_score[j]) - { - for (k=N-1;k>j;k--) - { - best_score[k]=best_score[k-1]; - pitch[k]=pitch[k-1]; - gain[k] = gain[k-1]; - } - best_score[j]=score[i-start]; - pitch[j]=i; - gain[j]=g; - break; - } - } - } - } - -} - - - - -/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ -float pitch_gain_search_3tap( -float target[], /* Target vector */ -float ak[], /* LPCs for this subframe */ -float awk1[], /* Weighted LPCs #1 for this subframe */ -float awk2[], /* Weighted LPCs #2 for this subframe */ -float exc[], /* Excitation */ -void *par, -int pitch, /* Pitch value */ -int p, /* Number of LPC coeffs */ -int nsf, /* Number of samples in subframe */ -SpeexBits *bits, -char *stack, -float *exc2, -float *r, -int *cdbk_index -) -{ - int i,j; - float *tmp, *tmp2; - float *x[3]; - float *e[3]; - float corr[3]; - float A[3][3]; - float gain[3]; - int gain_cdbk_size; - signed char *gain_cdbk; - float err1,err2; - - ltp_params *params; - params = (ltp_params*) par; - gain_cdbk=params->gain_cdbk; - gain_cdbk_size=1<gain_bits; - tmp = PUSH(stack, 3*nsf, float); - tmp2 = PUSH(stack, 3*nsf, float); - - x[0]=tmp; - x[1]=tmp+nsf; - x[2]=tmp+2*nsf; - - e[0]=tmp2; - e[1]=tmp2+nsf; - e[2]=tmp2+2*nsf; - - for (i=2;i>=0;i--) - { - int pp=pitch+1-i; - for (j=0;j0) - tot+=ptr[0]; - if (ptr[2]>0) - tot+=ptr[2]; - if (tot>1) - continue; - } - - if (sum>best_sum || i==0) - { - best_sum=sum; - best_cdbk=i; - } - } - gain[0] = 0.015625*gain_cdbk[best_cdbk*3] + .5; - gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5; - gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5; - - *cdbk_index=best_cdbk; - } - - for (i=0;i10) - N=10; - - nbest=PUSH(stack, N, int); - gains = PUSH(stack, N, float); - params = (ltp_params*) par; - - if (N==0 || endpitch_bits); - speex_bits_pack(bits, 0, params->gain_bits); - for (i=0;iend-start+1) - N=end-start+1; - open_loop_nbest_pitch(sw, start, end, nsf, nbest, gains, N, stack); - for (i=0;ipitch_bits); - speex_bits_pack(bits, best_gain_index, params->gain_bits); - /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ - for (i=0;igain_cdbk; - - pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); - pitch += start; - gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); - /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ - gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5; - gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5; - gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5; - - if (count_lost && pitch > subframe_offset) - { - float gain_sum; - - if (1) { - float tmp = count_lost < 4 ? last_pitch_gain : 0.4 * last_pitch_gain; - if (tmp>.95) - tmp=.95; - gain_sum = fabs(gain[1]); - if (gain[0]>0) - gain_sum += gain[0]; - else - gain_sum -= .5*gain[0]; - if (gain[2]>0) - gain_sum += gain[2]; - else - gain_sum -= .5*gain[2]; - if (gain_sum > tmp) { - float fact = tmp/gain_sum; - for (i=0;i<3;i++) - gain[i]*=fact; - - } - - } - - if (0) { - gain_sum = fabs(gain[0])+fabs(gain[1])+fabs(gain[2]); - if (gain_sum>.95) { - float fact = .95/gain_sum; - for (i=0;i<3;i++) - gain[i]*=fact; - } - } - } - - *pitch_val = pitch; - /**gain_val = gain[0]+gain[1]+gain[2];*/ - gain_val[0]=gain[0]; - gain_val[1]=gain[1]; - gain_val[2]=gain[2]; - - { - float *e[3]; - float *tmp2; - tmp2=PUSH(stack, 3*nsf, float); - e[0]=tmp2; - e[1]=tmp2+nsf; - e[2]=tmp2+2*nsf; - - for (i=0;i<3;i++) - { - int j; - int pp=pitch+1-i; -#if 0 - for (j=0;jpp) - tmp1=pp; - for (j=0;jpp+pitch) - tmp3=pp+pitch; - for (j=tmp1;j.99) - pitch_coef=.99; - for (i=0;i.99) - pitch_coef=.99; - for (i=0;i -#include "math_approx.h" - -#ifdef SLOW_TRIG - -float cos_sin[102] = { - 1.00000000, 0.00000000, - 0.99804751, 0.06245932, - 0.99219767, 0.12467473, - 0.98247331, 0.18640330, - 0.96891242, 0.24740396, - 0.95156795, 0.30743851, - 0.93050762, 0.36627253, - 0.90581368, 0.42367626, - 0.87758256, 0.47942554, - 0.84592450, 0.53330267, - 0.81096312, 0.58509727, - 0.77283495, 0.63460708, - 0.73168887, 0.68163876, - 0.68768556, 0.72600866, - 0.64099686, 0.76754350, - 0.59180508, 0.80608111, - 0.54030231, 0.84147098, - 0.48668967, 0.87357494, - 0.43117652, 0.90226759, - 0.37397963, 0.92743692, - 0.31532236, 0.94898462, - 0.25543377, 0.96682656, - 0.19454771, 0.98089306, - 0.13290194, 0.99112919, - 0.07073720, 0.99749499, - 0.00829623, 0.99996559, - -0.05417714, 0.99853134, - -0.11643894, 0.99319785, - -0.17824606, 0.98398595, - -0.23935712, 0.97093160, - -0.29953351, 0.95408578, - -0.35854022, 0.93351428, - -0.41614684, 0.90929743, - -0.47212841, 0.88152979, - -0.52626633, 0.85031979, - -0.57834920, 0.81578931, - -0.62817362, 0.77807320, - -0.67554504, 0.73731872, - -0.72027847, 0.69368503, - -0.76219923, 0.64734252, - -0.80114362, 0.59847214, - -0.83695955, 0.54726475, - -0.86950718, 0.49392030, - -0.89865940, 0.43864710, - -0.92430238, 0.38166099, - -0.94633597, 0.32318451, - -0.96467415, 0.26344599, - -0.97924529, 0.20267873, - -0.98999250, 0.14112001, - -0.99687381, 0.07901022, - -0.99986235, 0.01659189 -}; - -float speex_cos(float x) -{ - int ind; - float delta; - ind = (int)floor(x*16+.5); - delta = x-0.062500*ind; - ind <<= 1; - return cos_sin[ind] - delta*(cos_sin[ind+1] + - .5*delta*(cos_sin[ind] - - .3333333*delta*cos_sin[ind+1])); -} - -#endif - diff --git a/src/add-ons/media/plugins/speex/libspeex/math_approx.h b/src/add-ons/media/plugins/speex/libspeex/math_approx.h deleted file mode 100644 index c917ffd71d..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/math_approx.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: math_approx.c - Various math approximation functions for Speex - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef MATH_APPROX_H -#define MATH_APPROX_H - -float speex_cos(float x); - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/misc.c b/src/add-ons/media/plugins/speex/libspeex/misc.c deleted file mode 100644 index f84e0f6194..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/misc.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: mics.c - Various utility routines for Speex - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "misc.h" -#include -#include -#include - -#ifndef RELEASE -void print_vec(float *vec, int len, char *name) -{ - int i; - printf ("%s ", name); - for (i=0;i>24; - ret += (i>>8)&0x0000ff00; - ret += (i<<8)&0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -unsigned int le_int(unsigned int i) -{ - unsigned int ret=i; -#ifdef WORDS_BIGENDIAN - ret = i>>24; - ret += (i>>8)&0x0000ff00; - ret += (i<<8)&0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -unsigned short be_short(unsigned short s) -{ - unsigned short ret=s; -#ifndef WORDS_BIGENDIAN - ret = s>>8; - ret += s<<8; -#endif - return ret; -} - -unsigned short le_short(unsigned short s) -{ - unsigned short ret=s; -#ifdef WORDS_BIGENDIAN - ret = s>>8; - ret += s<<8; -#endif - return ret; -} - -void *speex_alloc (int size) -{ - return calloc(size,1); -} - -void *speex_realloc (void *ptr, int size) -{ - return realloc(ptr, size); -} - -void speex_free (void *ptr) -{ - free(ptr); -} - -void *speex_move (void *dest, void *src, int n) -{ - return memmove(dest,src,n); -} - -void speex_error(char *str) -{ - fprintf (stderr, "Fatal error: %s\n", str); - exit(1); -} - -void speex_warning(char *str) -{ - fprintf (stderr, "warning: %s\n", str); -} - -void speex_warning_int(char *str, int val) -{ - fprintf (stderr, "warning: %s %d\n", str, val); -} - -void speex_rand_vec(float std, float *data, int len) -{ - int i; - for (i=0;ienc_init(mode); -} - -void *speex_decoder_init(SpeexMode *mode) -{ - return mode->dec_init(mode); -} - -void speex_encoder_destroy(void *state) -{ - (*((SpeexMode**)state))->enc_destroy(state); -} - -int speex_encode(void *state, float *in, SpeexBits *bits) -{ - return (*((SpeexMode**)state))->enc(state, in, bits); -} - -void speex_decoder_destroy(void *state) -{ - (*((SpeexMode**)state))->dec_destroy(state); -} - -int speex_decode(void *state, SpeexBits *bits, float *out) -{ - return (*((SpeexMode**)state))->dec(state, bits, out); -} - - -int speex_encoder_ctl(void *state, int request, void *ptr) -{ - return (*((SpeexMode**)state))->enc_ctl(state, request, ptr); -} - -int speex_decoder_ctl(void *state, int request, void *ptr) -{ - return (*((SpeexMode**)state))->dec_ctl(state, request, ptr); -} - - - -static int nb_mode_query(void *mode, int request, void *ptr) -{ - SpeexNBMode *m = (SpeexNBMode*)mode; - - switch (request) - { - case SPEEX_MODE_FRAME_SIZE: - *((int*)ptr)=m->frameSize; - break; - case SPEEX_SUBMODE_BITS_PER_FRAME: - if (*((int*)ptr)==0) - *((int*)ptr) = NB_SUBMODE_BITS+1; - else if (m->submodes[*((int*)ptr)]==NULL) - *((int*)ptr) = -1; - else - *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; - break; - default: - speex_warning_int("Unknown nb_mode_query request: ", request); - return -1; - } - return 0; -} - -static int wb_mode_query(void *mode, int request, void *ptr) -{ - SpeexSBMode *m = (SpeexSBMode*)mode; - - switch (request) - { - case SPEEX_MODE_FRAME_SIZE: - *((int*)ptr)=2*m->frameSize; - break; - case SPEEX_SUBMODE_BITS_PER_FRAME: - if (*((int*)ptr)==0) - *((int*)ptr) = SB_SUBMODE_BITS+1; - else if (m->submodes[*((int*)ptr)]==NULL) - *((int*)ptr) = -1; - else - *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; - break; - default: - speex_warning_int("Unknown wb_mode_query request: ", request); - return -1; - } - return 0; -} - - -int speex_mode_query(SpeexMode *mode, int request, void *ptr) -{ - return mode->query(mode->mode, request, ptr); -} diff --git a/src/add-ons/media/plugins/speex/libspeex/modes.h b/src/add-ons/media/plugins/speex/libspeex/modes.h deleted file mode 100644 index 0a94357c80..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/modes.h +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file modes.h - @brief Describes the different modes of the codec -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef MODES_H -#define MODES_H - -#include "speex.h" -#include "speex_bits.h" - - -#define NB_SUBMODES 16 -#define NB_SUBMODE_BITS 4 - -#define SB_SUBMODES 8 -#define SB_SUBMODE_BITS 3 - - -/** Quantizes LSPs */ -typedef void (*lsp_quant_func)(float *, float *, int, SpeexBits *); - -/** Decodes quantized LSPs */ -typedef void (*lsp_unquant_func)(float *, int, SpeexBits *); - - -/** Long-term predictor quantization */ -typedef int (*ltp_quant_func)(float *, float *, float *, float *, - float *, float *, void *, int, int, float, - int, int, SpeexBits*, char *, float *, float *, int); - -/** Long-term un-quantize */ -typedef void (*ltp_unquant_func)(float *, int, int, float, void *, int, int *, - float *, SpeexBits*, char*, int, int, float); - - -/** Innovation quantization function */ -typedef void (*innovation_quant_func)(float *, float *, float *, float *, void *, int, int, - float *, float *, SpeexBits *, char *, int); - -/** Innovation unquantization function */ -typedef void (*innovation_unquant_func)(float *, void *, int, SpeexBits*, char *); - -/** Description of a Speex sub-mode (wither narrowband or wideband */ -typedef struct SpeexSubmode { - int lbr_pitch; /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/ - int forced_pitch_gain; /**< Use the same (forced) pitch gain for all sub-frames */ - int have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */ - int double_codebook; /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/ - /*LSP functions*/ - lsp_quant_func lsp_quant; /**< LSP quantization function */ - lsp_unquant_func lsp_unquant; /**< LSP unquantization function */ - - /*Lont-term predictor functions*/ - ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */ - ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */ - void *ltp_params; /**< Pitch parameters (options) */ - - /*Quantization of innovation*/ - innovation_quant_func innovation_quant; /**< Innovation quantization */ - innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */ - void *innovation_params; /**< Innovation quantization parameters*/ - - /*Synthesis filter enhancement*/ - float lpc_enh_k1; /**< Enhancer constant */ - float lpc_enh_k2; /**< Enhancer constant */ - float comb_gain; /**< Gain of enhancer comb filter */ - - int bits_per_frame; /**< Number of bits per frame after encoding*/ -} SpeexSubmode; - -/** Struct defining the encoding/decoding mode*/ -typedef struct SpeexNBMode { - int frameSize; /**< Size of frames used for encoding */ - int subframeSize; /**< Size of sub-frames used for encoding */ - int lpcSize; /**< Order of LPC filter */ - int bufSize; /**< Size of signal buffer to use in encoder */ - int pitchStart; /**< Smallest pitch value allowed */ - int pitchEnd; /**< Largest pitch value allowed */ - - float gamma1; /**< Perceptual filter parameter #1 */ - float gamma2; /**< Perceptual filter parameter #2 */ - float lag_factor; /**< Lag-windowing parameter */ - float lpc_floor; /**< Noise floor for LPC analysis */ - float preemph; /**< Pre-emphasis */ - - SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ - int defaultSubmode; /**< Default sub-mode to use when encoding */ - int quality_map[11]; /**< Mode corresponding to each quality setting */ -} SpeexNBMode; - - -/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */ -typedef struct SpeexSBMode { - SpeexMode *nb_mode; /**< Embedded narrowband mode */ - int frameSize; /**< Size of frames used for encoding */ - int subframeSize; /**< Size of sub-frames used for encoding */ - int lpcSize; /**< Order of LPC filter */ - int bufSize; /**< Signal buffer size in encoder */ - float gamma1; /**< Perceptual filter parameter #1 */ - float gamma2; /**< Perceptual filter parameter #1 */ - float lag_factor; /**< Lag-windowing parameter */ - float lpc_floor; /**< Noise floor for LPC analysis */ - float preemph; /**< Pre-emphasis */ - float folding_gain; - - SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */ - int defaultSubmode; /**< Default sub-mode to use when encoding */ - int low_quality_map[11]; /**< Mode corresponding to each quality setting */ - int quality_map[11]; /**< Mode corresponding to each quality setting */ - float (*vbr_thresh)[11]; - int nb_modes; -} SpeexSBMode; - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/nb_celp.c b/src/add-ons/media/plugins/speex/libspeex/nb_celp.c deleted file mode 100644 index dbef9a9d5f..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/nb_celp.c +++ /dev/null @@ -1,1715 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: nb_celp.c - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include "nb_celp.h" -#include "lpc.h" -#include "lsp.h" -#include "ltp.h" -#include "quant_lsp.h" -#include "cb_search.h" -#include "filters.h" -#include "stack_alloc.h" -#include "vq.h" -#include "speex_bits.h" -#include "vbr.h" -#include "misc.h" -#include "speex_callbacks.h" - -#ifdef SLOW_TRIG -#include "math_approx.h" -#define cos speex_cos -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#define SUBMODE(x) st->submodes[st->submodeID]->x - -float exc_gain_quant_scal3[8]={-2.794750, -1.810660, -1.169850, -0.848119, -0.587190, -0.329818, -0.063266, 0.282826}; - -float exc_gain_quant_scal1[2]={-0.35, 0.05}; - -#define sqr(x) ((x)*(x)) - -void *nb_encoder_init(SpeexMode *m) -{ - EncState *st; - SpeexNBMode *mode; - int i; - - mode=(SpeexNBMode *)m->mode; - st = (EncState*)speex_alloc(sizeof(EncState)+8000*sizeof(float)); - if (!st) - return NULL; - - st->stack = ((char*)st) + sizeof(EncState); - - st->mode=m; - - st->frameSize = mode->frameSize; - st->windowSize = st->frameSize*3/2; - st->nbSubframes=mode->frameSize/mode->subframeSize; - st->subframeSize=mode->subframeSize; - st->lpcSize = mode->lpcSize; - st->bufSize = mode->bufSize; - st->gamma1=mode->gamma1; - st->gamma2=mode->gamma2; - st->min_pitch=mode->pitchStart; - st->max_pitch=mode->pitchEnd; - st->lag_factor=mode->lag_factor; - st->lpc_floor = mode->lpc_floor; - st->preemph = mode->preemph; - - st->submodes=mode->submodes; - st->submodeID=st->submodeSelect=mode->defaultSubmode; - st->pre_mem=0; - st->pre_mem2=0; - st->bounded_pitch = 1; - - /* Allocating input buffer */ - st->inBuf = PUSH(st->stack, st->bufSize, float); - st->frame = st->inBuf + st->bufSize - st->windowSize; - /* Allocating excitation buffer */ - st->excBuf = PUSH(st->stack, st->bufSize, float); - st->exc = st->excBuf + st->bufSize - st->windowSize; - st->swBuf = PUSH(st->stack, st->bufSize, float); - st->sw = st->swBuf + st->bufSize - st->windowSize; - - st->exc2Buf = PUSH(st->stack, st->bufSize, float); - st->exc2 = st->exc2Buf + st->bufSize - st->windowSize; - - st->innov = PUSH(st->stack, st->frameSize, float); - - /* Asymmetric "pseudo-Hamming" window */ - { - int part1, part2; - part1 = st->subframeSize*7/2; - part2 = st->subframeSize*5/2; - st->window = PUSH(st->stack, st->windowSize, float); - for (i=0;iwindow[i]=.54-.46*cos(M_PI*i/part1); - for (i=0;iwindow[part1+i]=.54+.46*cos(M_PI*i/part2); - } - /* Create the window for autocorrelation (lag-windowing) */ - st->lagWindow = PUSH(st->stack, st->lpcSize+1, float); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); - - st->autocorr = PUSH(st->stack, st->lpcSize+1, float); - - st->buf2 = PUSH(st->stack, st->windowSize, float); - - st->lpc = PUSH(st->stack, st->lpcSize+1, float); - st->interp_lpc = PUSH(st->stack, st->lpcSize+1, float); - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc1 = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc2 = PUSH(st->stack, st->lpcSize+1, float); - - st->lsp = PUSH(st->stack, st->lpcSize, float); - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_lsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_lsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->rc = PUSH(st->stack, st->lpcSize, float); - st->first = 1; - for (i=0;ilpcSize;i++) - { - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); - } - - st->mem_sp = PUSH(st->stack, st->lpcSize, float); - st->mem_sw = PUSH(st->stack, st->lpcSize, float); - st->mem_sw_whole = PUSH(st->stack, st->lpcSize, float); - st->mem_exc = PUSH(st->stack, st->lpcSize, float); - - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - - st->pitch = PUSH(st->stack, st->nbSubframes, int); - - st->vbr = PUSHS(st->stack, VBRState); - vbr_init(st->vbr); - st->vbr_quality = 8; - st->vbr_enabled = 0; - st->vad_enabled = 0; - st->dtx_enabled = 0; - st->abr_enabled = 0; - st->abr_drift = 0; - - st->complexity=2; - st->sampling_rate=8000; - st->dtx_count=0; - - return st; -} - -void nb_encoder_destroy(void *state) -{ - EncState *st=(EncState *)state; - /* Free all allocated memory */ - - vbr_destroy(st->vbr); - - /*Free state memory... should be last*/ - speex_free(st); -} - -int nb_encode(void *state, float *in, SpeexBits *bits) -{ - EncState *st; - int i, sub, roots; - int ol_pitch; - float ol_pitch_coef; - float ol_gain; - float *res, *target, *mem; - char *stack; - float *syn_resp; - float lsp_dist=0; - float *orig; - - st=(EncState *)state; - stack=st->stack; - - /* Copy new data in input buffer */ - speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - st->inBuf[st->bufSize-st->frameSize] = in[0] - st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - st->inBuf[st->bufSize-st->frameSize+i] = in[i] - st->preemph*in[i-1]; - st->pre_mem = in[st->frameSize-1]; - - /* Move signals 1 frame towards the past */ - speex_move(st->exc2Buf, st->exc2Buf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->swBuf, st->swBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - - - /* Window for analysis */ - for (i=0;iwindowSize;i++) - st->buf2[i] = st->frame[i] * st->window[i]; - - /* Compute auto-correlation */ - _spx_autocorr(st->buf2, st->autocorr, st->lpcSize+1, st->windowSize); - - st->autocorr[0] += 10; /* prevents NANs */ - st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ - - /* Lag windowing: equivalent to filtering in the power-spectrum domain */ - for (i=0;ilpcSize+1;i++) - st->autocorr[i] *= st->lagWindow[i]; - - /* Levinson-Durbin */ - wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); - st->lpc[0]=1; - - /* LPC to LSPs (x-domain) transform */ - roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack); - /* Check if we found all the roots */ - if (roots==st->lpcSize) - { - /* LSP x-domain to angle domain*/ - for (i=0;ilpcSize;i++) - st->lsp[i] = acos(st->lsp[i]); - } else { - /* Search again if we can afford it */ - if (st->complexity>1) - roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.05, stack); - if (roots==st->lpcSize) - { - /* LSP x-domain to angle domain*/ - for (i=0;ilpcSize;i++) - st->lsp[i] = acos(st->lsp[i]); - } else { - /*If we can't find all LSP's, do some damage control and use previous filter*/ - for (i=0;ilpcSize;i++) - { - st->lsp[i]=st->old_lsp[i]; - } - } - } - - - lsp_dist=0; - for (i=0;ilpcSize;i++) - lsp_dist += (st->old_lsp[i] - st->lsp[i])*(st->old_lsp[i] - st->lsp[i]); - - /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */ - { - if (st->first) - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = st->lsp[i]; - else - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = .375*st->old_lsp[i] + .625*st->lsp[i]; - - lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002); - - /* Compute interpolated LPCs (unquantized) for whole frame*/ - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = cos(st->interp_lsp[i]); - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - - - /*Open-loop pitch*/ - if (!st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) || - SUBMODE(lbr_pitch) != -1) - { - int nol_pitch[6]; - float nol_pitch_coef[6]; - - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); - - filter_mem2(st->frame, st->bw_lpc1, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole); - - open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, - nol_pitch, nol_pitch_coef, 6, stack); - ol_pitch=nol_pitch[0]; - ol_pitch_coef = nol_pitch_coef[0]; - /*Try to remove pitch multiples*/ - for (i=1;i<6;i++) - { - if ((nol_pitch_coef[i]>.85*ol_pitch_coef) && - (fabs(nol_pitch[i]-ol_pitch/2.0)<=1 || fabs(nol_pitch[i]-ol_pitch/3.0)<=1 || - fabs(nol_pitch[i]-ol_pitch/4.0)<=1 || fabs(nol_pitch[i]-ol_pitch/5.0)<=1)) - { - /*ol_pitch_coef=nol_pitch_coef[i];*/ - ol_pitch = nol_pitch[i]; - } - } - /*if (ol_pitch>50) - ol_pitch/=2;*/ - /*ol_pitch_coef = sqrt(ol_pitch_coef);*/ - } else { - ol_pitch=0; - ol_pitch_coef=0; - } - /*Compute "real" excitation*/ - fir_mem2(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc); - - /* Compute open-loop excitation gain */ - ol_gain=0; - for (i=0;iframeSize;i++) - ol_gain += st->exc[i]*st->exc[i]; - - ol_gain=sqrt(1+ol_gain/st->frameSize); - } - - /*VBR stuff*/ - if (st->vbr && (st->vbr_enabled||st->vad_enabled)) - { - - if (st->abr_enabled) - { - float qual_change=0; - if (st->abr_drift2 * st->abr_drift > 0) - { - /* Only adapt if long-term and short-term drift are the same sign */ - qual_change = -.00001*st->abr_drift/(1+st->abr_count); - if (qual_change>.05) - qual_change=.05; - if (qual_change<-.05) - qual_change=-.05; - } - st->vbr_quality += qual_change; - if (st->vbr_quality>10) - st->vbr_quality=10; - if (st->vbr_quality<0) - st->vbr_quality=0; - } - - st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, ol_pitch_coef); - /*if (delta_qual<0)*/ - /* delta_qual*=.1*(3+st->vbr_quality);*/ - if (st->vbr_enabled) - { - int mode; - int choice=0; - float min_diff=100; - mode = 8; - while (mode) - { - int v1; - float thresh; - v1=(int)floor(st->vbr_quality); - if (v1==10) - thresh = vbr_nb_thresh[mode][v1]; - else - thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1]; - if (st->relative_quality > thresh && - st->relative_quality-threshrelative_quality-thresh; - } - mode--; - } - mode=choice; - if (mode==0) - { - if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) - { - mode=1; - st->dtx_count=1; - } else { - mode=0; - st->dtx_count++; - } - } else { - st->dtx_count=0; - } - - speex_encoder_ctl(state, SPEEX_SET_MODE, &mode); - - if (st->abr_enabled) - { - int bitrate; - speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); - st->abr_drift+=(bitrate-st->abr_enabled); - st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); - st->abr_count += 1.0; - } - - } else { - /*VAD only case*/ - int mode; - if (st->relative_quality<2) - { - if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) - { - st->dtx_count=1; - mode=1; - } else { - mode=0; - st->dtx_count++; - } - } else { - st->dtx_count = 0; - mode=st->submodeSelect; - } - /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ - st->submodeID=mode; - } - } else { - st->relative_quality = -1; - } - - /* First, transmit a zero for narrowband */ - speex_bits_pack(bits, 0, 1); - - /* Transmit the sub-mode we use for this frame */ - speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS); - - - /* If null mode (no transmission), just set a couple things to zero*/ - if (st->submodes[st->submodeID] == NULL) - { - for (i=0;iframeSize;i++) - st->exc[i]=st->exc2[i]=st->sw[i]=VERY_SMALL; - - for (i=0;ilpcSize;i++) - st->mem_sw[i]=0; - st->first=1; - st->bounded_pitch = 1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); - - in[0] = st->frame[0] + st->preemph*st->pre_mem2; - for (i=1;iframeSize;i++) - in[i]=st->frame[i] + st->preemph*in[i-1]; - st->pre_mem2=in[st->frameSize-1]; - - return 0; - - } - - /* LSP Quantization */ - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - } - - - /*Quantize LSPs*/ -#if 1 /*0 for unquantized*/ - SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); -#else - for (i=0;ilpcSize;i++) - st->qlsp[i]=st->lsp[i]; -#endif - - /*If we use low bit-rate pitch mode, transmit open-loop pitch*/ - if (SUBMODE(lbr_pitch)!=-1) - { - speex_bits_pack(bits, ol_pitch-st->min_pitch, 7); - } - - if (SUBMODE(forced_pitch_gain)) - { - int quant; - quant = (int)floor(.5+15*ol_pitch_coef); - if (quant>15) - quant=15; - if (quant<0) - quant=0; - speex_bits_pack(bits, quant, 4); - ol_pitch_coef=0.066667*quant; - } - - - /*Quantize and transmit open-loop excitation gain*/ - { - int qe = (int)(floor(.5+3.5*log(ol_gain))); - if (qe<0) - qe=0; - if (qe>31) - qe=31; - ol_gain = exp(qe/3.5); - speex_bits_pack(bits, qe, 5); - } - - /* Special case for first frame */ - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - /* Filter response */ - res = PUSH(stack, st->subframeSize, float); - /* Target signal */ - target = PUSH(stack, st->subframeSize, float); - syn_resp = PUSH(stack, st->subframeSize, float); - mem = PUSH(stack, st->lpcSize, float); - orig = PUSH(stack, st->frameSize, float); - for (i=0;iframeSize;i++) - orig[i]=st->frame[i]; - - /* Loop on sub-frames */ - for (sub=0;subnbSubframes;sub++) - { - float tmp; - int offset; - float *sp, *sw, *exc, *exc2; - int pitch; - - /* Offset relative to start of frame */ - offset = st->subframeSize*sub; - /* Original signal */ - sp=st->frame+offset; - /* Excitation */ - exc=st->exc+offset; - /* Weighted signal */ - sw=st->sw+offset; - - exc2=st->exc2+offset; - - - /* LSP interpolation (quantized and unquantized) */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i]; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - /* Make sure the filters are stable */ - lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002); - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); - - /* Compute interpolated LPCs (quantized and unquantized) */ - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = cos(st->interp_lsp[i]); - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - /* Compute analysis filter gain at w=pi (for use in SB-CELP) */ - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - st->pi_gain[sub] += tmp*st->interp_qlpc[i]; - tmp = -tmp; - } - - /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */ - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - if (st->gamma2>=0) - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); - else - { - st->bw_lpc2[0]=1; - st->bw_lpc2[1]=-st->preemph; - for (i=2;i<=st->lpcSize;i++) - st->bw_lpc2[i]=0; - } - - /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) )*/ - for (i=0;isubframeSize;i++) - exc[i]=0; - exc[0]=1; - syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; - for (i=0;isubframeSize;i++) - exc2[i]=0; - - /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); - - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); - - /* Compute weighted signal */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); - - /* Compute target signal */ - for (i=0;isubframeSize;i++) - target[i]=sw[i]-res[i]; - - for (i=0;isubframeSize;i++) - exc[i]=exc2[i]=0; - - /* If we have a long-term predictor (otherwise, something's wrong) */ - if (SUBMODE(ltp_quant)) - { - int pit_min, pit_max; - /* Long-term prediction */ - if (SUBMODE(lbr_pitch) != -1) - { - /* Low bit-rate pitch handling */ - int margin; - margin = SUBMODE(lbr_pitch); - if (margin) - { - if (ol_pitch < st->min_pitch+margin-1) - ol_pitch=st->min_pitch+margin-1; - if (ol_pitch > st->max_pitch-margin) - ol_pitch=st->max_pitch-margin; - pit_min = ol_pitch-margin+1; - pit_max = ol_pitch+margin; - } else { - pit_min=pit_max=ol_pitch; - } - } else { - pit_min = st->min_pitch; - pit_max = st->max_pitch; - } - - /* Force pitch to use only the current frame if needed */ - if (st->bounded_pitch && pit_max>offset) - pit_max=offset; - - /* Perform pitch search */ - pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, - st->lpcSize, st->subframeSize, bits, stack, - exc2, syn_resp, st->complexity); - - st->pitch[sub]=pitch; - } else { - speex_error ("No pitch prediction, what's wrong"); - } - - /* Update target for adaptive codebook contribution */ - syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, stack); - for (i=0;isubframeSize;i++) - target[i]-=res[i]; - - - /* Quantization of innovation */ - { - float *innov; - float ener=0, ener_1; - - innov = st->innov+sub*st->subframeSize; - for (i=0;isubframeSize;i++) - innov[i]=0; - - residue_percep_zero(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize, stack); - for (i=0;isubframeSize;i++) - ener+=st->buf2[i]*st->buf2[i]; - ener=sqrt(.1+ener/st->subframeSize); - /*for (i=0;isubframeSize;i++) - printf ("%f\n", st->buf2[i]/ener); - */ - - ener /= ol_gain; - - /* Calculate gain correction for the sub-frame (if any) */ - if (SUBMODE(have_subframe_gain)) - { - int qe; - ener=log(ener); - if (SUBMODE(have_subframe_gain)==3) - { - qe = vq_index(&ener, exc_gain_quant_scal3, 1, 8); - speex_bits_pack(bits, qe, 3); - ener=exc_gain_quant_scal3[qe]; - } else { - qe = vq_index(&ener, exc_gain_quant_scal1, 1, 2); - speex_bits_pack(bits, qe, 1); - ener=exc_gain_quant_scal1[qe]; - } - ener=exp(ener); - } else { - ener=1; - } - - ener*=ol_gain; - - /*printf ("%f %f\n", ener, ol_gain);*/ - - ener_1 = 1/ener; - - /* Normalize innovation */ - for (i=0;isubframeSize;i++) - target[i]*=ener_1; - - /* Quantize innovation */ - if (SUBMODE(innovation_quant)) - { - /* Codebook search */ - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov, syn_resp, bits, stack, st->complexity); - - /* De-normalize innovation and update excitation */ - for (i=0;isubframeSize;i++) - innov[i]*=ener; - for (i=0;isubframeSize;i++) - exc[i] += innov[i]; - } else { - speex_error("No fixed codebook"); - } - - /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */ - if (SUBMODE(double_codebook)) { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - for (i=0;isubframeSize;i++) - target[i]*=2.2; - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov2, syn_resp, bits, tmp_stack, st->complexity); - for (i=0;isubframeSize;i++) - innov2[i]*=ener*(1/2.2); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - for (i=0;isubframeSize;i++) - target[i]*=ener; - - } - - /*Keep the previous memory*/ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - /* Final signal synthesis from excitation */ - iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); - - /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); - for (i=0;isubframeSize;i++) - exc2[i]=exc[i]; - } - - /* Store the LSPs for interpolation in the next frame */ - if (st->submodeID>=1) - { - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - if (st->submodeID==1) - { - if (st->dtx_count) - speex_bits_pack(bits, 15, 4); - else - speex_bits_pack(bits, 0, 4); - } - - /* The next frame will not be the first (Duh!) */ - st->first = 0; - - { - float ener=0, err=0; - float snr; - for (i=0;iframeSize;i++) - { - ener+=st->frame[i]*st->frame[i]; - err += (st->frame[i]-orig[i])*(st->frame[i]-orig[i]); - } - snr = 10*log10((ener+1)/(err+1)); - /*printf ("%f %f %f\n", snr, ener, err);*/ - } - - /* Replace input by synthesized speech */ - in[0] = st->frame[0] + st->preemph*st->pre_mem2; - for (i=1;iframeSize;i++) - in[i]=st->frame[i] + st->preemph*in[i-1]; - st->pre_mem2=in[st->frameSize-1]; - - if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0) - st->bounded_pitch = 1; - else - st->bounded_pitch = 0; - - return 1; -} - - -void *nb_decoder_init(SpeexMode *m) -{ - DecState *st; - SpeexNBMode *mode; - int i; - - mode=(SpeexNBMode*)m->mode; - st = (DecState *)speex_alloc(sizeof(DecState)+4000*sizeof(float)); - st->mode=m; - - st->stack = ((char*)st) + sizeof(DecState); - - st->first=1; - /* Codec parameters, should eventually have several "modes"*/ - st->frameSize = mode->frameSize; - st->windowSize = st->frameSize*3/2; - st->nbSubframes=mode->frameSize/mode->subframeSize; - st->subframeSize=mode->subframeSize; - st->lpcSize = mode->lpcSize; - st->bufSize = mode->bufSize; - st->gamma1=mode->gamma1; - st->gamma2=mode->gamma2; - st->min_pitch=mode->pitchStart; - st->max_pitch=mode->pitchEnd; - st->preemph = mode->preemph; - - st->submodes=mode->submodes; - st->submodeID=mode->defaultSubmode; - - st->pre_mem=0; - st->lpc_enh_enabled=0; - - - st->inBuf = PUSH(st->stack, st->bufSize, float); - st->frame = st->inBuf + st->bufSize - st->windowSize; - st->excBuf = PUSH(st->stack, st->bufSize, float); - st->exc = st->excBuf + st->bufSize - st->windowSize; - for (i=0;ibufSize;i++) - st->inBuf[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=0; - st->innov = PUSH(st->stack, st->frameSize, float); - - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->mem_sp = PUSH(st->stack, 5*st->lpcSize, float); - st->comb_mem = PUSHS(st->stack, CombFilterMem); - comp_filter_mem_init (st->comb_mem); - - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - st->last_pitch = 40; - st->count_lost=0; - st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0; - st->pitch_gain_buf_idx = 0; - - st->sampling_rate=8000; - st->last_ol_gain = 0; - - st->user_callback.func = &speex_default_user_handler; - st->user_callback.data = NULL; - for (i=0;i<16;i++) - st->speex_callbacks[i].func = NULL; - - st->voc_m1=st->voc_m2=st->voc_mean=0; - st->voc_offset=0; - st->dtx_enabled=0; - return st; -} - -void nb_decoder_destroy(void *state) -{ - DecState *st; - st=(DecState*)state; - - speex_free(state); -} - -#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a)))) - -static void nb_decode_lost(DecState *st, float *out, char *stack) -{ - int i, sub; - float *awk1, *awk2, *awk3; - float pitch_gain, fact, gain_med; - - fact = exp(-.04*st->count_lost*st->count_lost); - gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]); - if (gain_med < st->last_pitch_gain) - st->last_pitch_gain = gain_med; - - pitch_gain = st->last_pitch_gain; - if (pitch_gain>.95) - pitch_gain=.95; - - pitch_gain *= fact; - - /* Shift all buffers by one frame */ - speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - - awk1=PUSH(stack, (st->lpcSize+1), float); - awk2=PUSH(stack, (st->lpcSize+1), float); - awk3=PUSH(stack, (st->lpcSize+1), float); - - for (sub=0;subnbSubframes;sub++) - { - int offset; - float *sp, *exc; - /* Offset relative to start of frame */ - offset = st->subframeSize*sub; - /* Original signal */ - sp=st->frame+offset; - /* Excitation */ - exc=st->exc+offset; - /* Excitation after post-filter*/ - - /* Calculate perceptually enhanced LPC filter */ - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - if (st->submodes[st->submodeID] != NULL) - { - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - } else { - k1=k2=.7; - } - k3=(1-(1-r*k1)/(1-r*k2))/r; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - } - - /* Make up a plausible excitation */ - /* THIS CAN BE IMPROVED */ - /*if (pitch_gain>.95) - pitch_gain=.95;*/ - { - float innov_gain=0; - for (i=0;iframeSize;i++) - innov_gain += st->innov[i]*st->innov[i]; - innov_gain=sqrt(innov_gain/st->frameSize); - for (i=0;isubframeSize;i++) - { -#if 0 - exc[i] = pitch_gain * exc[i - st->last_pitch] + fact*sqrt(1-pitch_gain)*st->innov[i+offset]; - /*Just so it give the same lost packets as with if 0*/ - /*rand();*/ -#else - /*exc[i]=pitch_gain*exc[i-st->last_pitch] + fact*st->innov[i+offset];*/ - exc[i]=pitch_gain*exc[i-st->last_pitch] + - fact*sqrt(1-pitch_gain)*speex_rand(innov_gain); -#endif - } - } - for (i=0;isubframeSize;i++) - sp[i]=exc[i]; - - /* Signal synthesis */ - if (st->lpc_enh_enabled) - { - filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } else { - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } - } - - out[0] = st->frame[0] + st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - out[i]=st->frame[i] + st->preemph*out[i-1]; - st->pre_mem=out[st->frameSize-1]; - - st->first = 0; - st->count_lost++; - st->pitch_gain_buf[st->pitch_gain_buf_idx++] = pitch_gain; - if (st->pitch_gain_buf_idx > 2) /* rollover */ - st->pitch_gain_buf_idx = 0; -} - -int nb_decode(void *state, SpeexBits *bits, float *out) -{ - DecState *st; - int i, sub; - int pitch; - float pitch_gain[3]; - float ol_gain=0; - int ol_pitch=0; - float ol_pitch_coef=0; - int best_pitch=40; - float best_pitch_gain=0; - int wideband; - int m; - char *stack; - float *awk1, *awk2, *awk3; - float pitch_average=0; - - st=(DecState*)state; - stack=st->stack; - - /* Check if we're in DTX mode*/ - if (!bits && st->dtx_enabled) - { - st->submodeID=0; - } else - { - /* If bits is NULL, consider the packet to be lost (what could we do anyway) */ - if (!bits) - { - nb_decode_lost(st, out, stack); - return 0; - } - - /* Search for next narrowband block (handle requests, skip wideband blocks) */ - do { - wideband = speex_bits_unpack_unsigned(bits, 1); - if (wideband) /* Skip wideband block (for compatibility) */ - { - int submode; - int advance; - advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); - if (advance < 0) - { - speex_warning ("Invalid wideband mode encountered. Corrupted stream?"); - return -2; - } - advance -= (SB_SUBMODE_BITS+1); - speex_bits_advance(bits, advance); - wideband = speex_bits_unpack_unsigned(bits, 1); - if (wideband) - { - advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); - if (advance < 0) - { - speex_warning ("Invalid wideband mode encountered: corrupted stream?"); - return -2; - } - advance -= (SB_SUBMODE_BITS+1); - speex_bits_advance(bits, advance); - wideband = speex_bits_unpack_unsigned(bits, 1); - if (wideband) - { - speex_warning ("More than to wideband layers found: corrupted stream?"); - return -2; - } - - } - } - - /* FIXME: Check for overflow */ - m = speex_bits_unpack_unsigned(bits, 4); - if (m==15) /* We found a terminator */ - { - return -1; - } else if (m==14) /* Speex in-band request */ - { - int ret = speex_inband_handler(bits, st->speex_callbacks, state); - if (ret) - return ret; - } else if (m==13) /* User in-band request */ - { - int ret = st->user_callback.func(bits, state, st->user_callback.data); - if (ret) - return ret; - } else if (m>8) /* Invalid mode */ - { - speex_warning("Invalid mode encountered: corrupted stream?"); - return -2; - } - - } while (m>8); - - /* Get the sub-mode that was used */ - st->submodeID = m; - - } - - /* Shift all buffers by one frame */ - speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - - /* If null mode (no transmission), just set a couple things to zero*/ - if (st->submodes[st->submodeID] == NULL) - { - float *lpc; - lpc = PUSH(stack,11, float); - bw_lpc(.93, st->interp_qlpc, lpc, 10); - /*for (i=0;iframeSize;i++) - st->exc[i]=0;*/ - { - float innov_gain=0; - float pgain=st->last_pitch_gain; - if (pgain>.6) - pgain=.6; - for (i=0;iframeSize;i++) - innov_gain += st->innov[i]*st->innov[i]; - innov_gain=sqrt(innov_gain/st->frameSize); - for (i=0;iframeSize;i++) - st->exc[i]=0; - speex_rand_vec(innov_gain, st->exc, st->frameSize); - } - - - st->first=1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, lpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); - - out[0] = st->frame[0] + st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - out[i]=st->frame[i] + st->preemph*out[i-1]; - st->pre_mem=out[st->frameSize-1]; - st->count_lost=0; - return 0; - } - - /* Unquantize LSPs */ - SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); - - /*Damp memory if a frame was lost and the LSP changed too much*/ - if (st->count_lost) - { - float lsp_dist=0, fact; - for (i=0;ilpcSize;i++) - lsp_dist += fabs(st->old_qlsp[i] - st->qlsp[i]); - fact = .6*exp(-.2*lsp_dist); - for (i=0;i<2*st->lpcSize;i++) - st->mem_sp[i] *= fact; - } - - - /* Handle first frame and lost-packet case */ - if (st->first || st->count_lost) - { - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - /* Get open-loop pitch estimation for low bit-rate pitch coding */ - if (SUBMODE(lbr_pitch)!=-1) - { - ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); - } - - if (SUBMODE(forced_pitch_gain)) - { - int quant; - quant = speex_bits_unpack_unsigned(bits, 4); - ol_pitch_coef=0.066667*quant; - } - - /* Get global excitation gain */ - { - int qe; - qe = speex_bits_unpack_unsigned(bits, 5); - ol_gain = exp(qe/3.5); - } - - awk1=PUSH(stack, st->lpcSize+1, float); - awk2=PUSH(stack, st->lpcSize+1, float); - awk3=PUSH(stack, st->lpcSize+1, float); - - if (st->submodeID==1) - { - int extra; - extra = speex_bits_unpack_unsigned(bits, 4); - - if (extra==15) - st->dtx_enabled=1; - else - st->dtx_enabled=0; - } - if (st->submodeID>1) - st->dtx_enabled=0; - - /*Loop on subframes */ - for (sub=0;subnbSubframes;sub++) - { - int offset; - float *sp, *exc, tmp; - - /* Offset relative to start of frame */ - offset = st->subframeSize*sub; - /* Original signal */ - sp=st->frame+offset; - /* Excitation */ - exc=st->exc+offset; - /* Excitation after post-filter*/ - - /* LSP interpolation (quantized and unquantized) */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - /* Make sure the LSP's are stable */ - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); - - - /* Compute interpolated LPCs (unquantized) */ - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - /* Compute enhanced synthesis filter */ - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - k3=(1-(1-r*k1)/(1-r*k2))/r; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - - } - - /* Compute analysis filter at w=pi */ - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - st->pi_gain[sub] += tmp*st->interp_qlpc[i]; - tmp = -tmp; - } - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; - - /*Adaptive codebook contribution*/ - if (SUBMODE(ltp_unquant)) - { - int pit_min, pit_max; - /* Handle pitch constraints if any */ - if (SUBMODE(lbr_pitch) != -1) - { - int margin; - margin = SUBMODE(lbr_pitch); - if (margin) - { -/* GT - need optimization? - if (ol_pitch < st->min_pitch+margin-1) - ol_pitch=st->min_pitch+margin-1; - if (ol_pitch > st->max_pitch-margin) - ol_pitch=st->max_pitch-margin; - pit_min = ol_pitch-margin+1; - pit_max = ol_pitch+margin; -*/ - pit_min = ol_pitch-margin+1; - if (pit_min < st->min_pitch) - pit_min = st->min_pitch; - pit_max = ol_pitch+margin; - if (pit_max > st->max_pitch) - pit_max = st->max_pitch; - } else { - pit_min = pit_max = ol_pitch; - } - } else { - pit_min = st->min_pitch; - pit_max = st->max_pitch; - } - - /* Pitch synthesis */ - SUBMODE(ltp_unquant)(exc, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), - st->subframeSize, &pitch, &pitch_gain[0], bits, stack, st->count_lost, offset, st->last_pitch_gain); - - /* If we had lost frames, check energy of last received frame */ - if (st->count_lost && ol_gain < st->last_ol_gain) - { - float fact = ol_gain/(st->last_ol_gain+1); - for (i=0;isubframeSize;i++) - exc[i]*=fact; - } - - tmp = fabs(pitch_gain[0]+pitch_gain[1]+pitch_gain[2]); - tmp = fabs(pitch_gain[1]); - if (pitch_gain[0]>0) - tmp += pitch_gain[0]; - else - tmp -= .5*pitch_gain[0]; - if (pitch_gain[2]>0) - tmp += pitch_gain[2]; - else - tmp -= .5*pitch_gain[0]; - - - pitch_average += tmp; - if (tmp>best_pitch_gain) - { - best_pitch = pitch; - best_pitch_gain = tmp; - /* best_pitch_gain = tmp*.9; - if (best_pitch_gain>.85) - best_pitch_gain=.85;*/ - } - } else { - speex_error("No pitch prediction, what's wrong"); - } - - /* Unquantize the innovation */ - { - int q_energy; - float ener; - float *innov; - - innov = st->innov+sub*st->subframeSize; - for (i=0;isubframeSize;i++) - innov[i]=0; - - /* Decode sub-frame gain correction */ - if (SUBMODE(have_subframe_gain)==3) - { - q_energy = speex_bits_unpack_unsigned(bits, 3); - ener = ol_gain*exp(exc_gain_quant_scal3[q_energy]); - } else if (SUBMODE(have_subframe_gain)==1) - { - q_energy = speex_bits_unpack_unsigned(bits, 1); - ener = ol_gain*exp(exc_gain_quant_scal1[q_energy]); - } else { - ener = ol_gain; - } - - if (SUBMODE(innovation_unquant)) - { - /*Fixed codebook contribution*/ - SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack); - } else { - speex_error("No fixed codebook"); - } - - /* De-normalize innovation and update excitation */ - for (i=0;isubframeSize;i++) - innov[i]*=ener; - - /*Vocoder mode*/ - if (st->submodeID==1) - { - float g=ol_pitch_coef; - - - for (i=0;isubframeSize;i++) - exc[i]=0; - while (st->voc_offsetsubframeSize) - { - if (st->voc_offset>=0) - exc[st->voc_offset]=sqrt(1.0*ol_pitch); - st->voc_offset+=ol_pitch; - } - st->voc_offset -= st->subframeSize; - - g=.5+2*(g-.6); - if (g<0) - g=0; - if (g>1) - g=1; - for (i=0;isubframeSize;i++) - { - float exci=exc[i]; - exc[i]=.8*g*exc[i]*ol_gain + .6*g*st->voc_m1*ol_gain + .5*g*innov[i] - .5*g*st->voc_m2 + (1-g)*innov[i]; - st->voc_m1 = exci; - st->voc_m2=innov[i]; - st->voc_mean = .95*st->voc_mean + .05*exc[i]; - exc[i]-=st->voc_mean; - } - } else { - for (i=0;isubframeSize;i++) - exc[i]+=innov[i]; - } - /* Decode second codebook (only for some modes) */ - if (SUBMODE(double_codebook)) - { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, tmp_stack); - for (i=0;isubframeSize;i++) - innov2[i]*=ener*(1/2.2); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - } - - for (i=0;isubframeSize;i++) - sp[i]=exc[i]; - - /* Signal synthesis */ - if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0) - comb_filter(exc, sp, st->interp_qlpc, st->lpcSize, st->subframeSize, - pitch, pitch_gain, SUBMODE(comb_gain), st->comb_mem); - if (st->lpc_enh_enabled) - { - /* Use enhanced LPC filter */ - filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } else { - /* Use regular filter */ - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } - } - - /*Copy output signal*/ - out[0] = st->frame[0] + st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - out[i]=st->frame[i] + st->preemph*out[i-1]; - st->pre_mem=out[st->frameSize-1]; - - - /* Store the LSPs for interpolation in the next frame */ - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - - /* The next frame will not be the first (Duh!) */ - st->first = 0; - st->count_lost=0; - st->last_pitch = best_pitch; - st->last_pitch_gain = .25*pitch_average; - st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain; - if (st->pitch_gain_buf_idx > 2) /* rollover */ - st->pitch_gain_buf_idx = 0; - - st->last_ol_gain = ol_gain; - - return 0; -} - -int nb_encoder_ctl(void *state, int request, void *ptr) -{ - EncState *st; - st=(EncState*)state; - switch(request) - { - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->frameSize; - break; - case SPEEX_SET_LOW_MODE: - case SPEEX_SET_MODE: - st->submodeSelect = st->submodeID = (*(int*)ptr); - break; - case SPEEX_GET_LOW_MODE: - case SPEEX_GET_MODE: - (*(int*)ptr) = st->submodeID; - break; - case SPEEX_SET_VBR: - st->vbr_enabled = (*(int*)ptr); - break; - case SPEEX_GET_VBR: - (*(int*)ptr) = st->vbr_enabled; - break; - case SPEEX_SET_VAD: - st->vad_enabled = (*(int*)ptr); - break; - case SPEEX_GET_VAD: - (*(int*)ptr) = st->vad_enabled; - break; - case SPEEX_SET_DTX: - st->dtx_enabled = (*(int*)ptr); - break; - case SPEEX_GET_DTX: - (*(int*)ptr) = st->dtx_enabled; - break; - case SPEEX_SET_ABR: - st->abr_enabled = (*(int*)ptr); - st->vbr_enabled = 1; - { - int i=10, rate, target; - float vbr_qual; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - vbr_qual=i; - if (vbr_qual<0) - vbr_qual=0; - speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); - st->abr_count=0; - st->abr_drift=0; - st->abr_drift2=0; - } - - break; - case SPEEX_GET_ABR: - (*(int*)ptr) = st->abr_enabled; - break; - case SPEEX_SET_VBR_QUALITY: - st->vbr_quality = (*(float*)ptr); - break; - case SPEEX_GET_VBR_QUALITY: - (*(float*)ptr) = st->vbr_quality; - break; - case SPEEX_SET_QUALITY: - { - int quality = (*(int*)ptr); - if (quality < 0) - quality = 0; - if (quality > 10) - quality = 10; - st->submodeSelect = st->submodeID = ((SpeexNBMode*)(st->mode->mode))->quality_map[quality]; - } - break; - case SPEEX_SET_COMPLEXITY: - st->complexity = (*(int*)ptr); - if (st->complexity<1) - st->complexity=1; - break; - case SPEEX_GET_COMPLEXITY: - (*(int*)ptr) = st->complexity; - break; - case SPEEX_SET_BITRATE: - { - int i=10, rate, target; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - } - break; - case SPEEX_GET_BITRATE: - if (st->submodes[st->submodeID]) - (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; - else - (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; - break; - case SPEEX_SET_SAMPLING_RATE: - st->sampling_rate = (*(int*)ptr); - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_RESET_STATE: - { - int i; - st->bounded_pitch = 1; - st->first = 1; - for (i=0;ilpcSize;i++) - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); - for (i=0;ilpcSize;i++) - st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=st->swBuf[i]=st->inBuf[i]=st->exc2Buf[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->innov[i]; - } - break; - case SPEEX_GET_RELATIVE_QUALITY: - (*(float*)ptr)=st->relative_quality; - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} - -int nb_decoder_ctl(void *state, int request, void *ptr) -{ - DecState *st; - st=(DecState*)state; - switch(request) - { - case SPEEX_GET_LOW_MODE: - case SPEEX_GET_MODE: - (*(int*)ptr) = st->submodeID; - break; - case SPEEX_SET_ENH: - st->lpc_enh_enabled = *((int*)ptr); - break; - case SPEEX_GET_ENH: - *((int*)ptr) = st->lpc_enh_enabled; - break; - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->frameSize; - break; - case SPEEX_GET_BITRATE: - if (st->submodes[st->submodeID]) - (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; - else - (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; - break; - case SPEEX_SET_SAMPLING_RATE: - st->sampling_rate = (*(int*)ptr); - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_SET_HANDLER: - { - SpeexCallback *c = (SpeexCallback*)ptr; - st->speex_callbacks[c->callback_id].func=c->func; - st->speex_callbacks[c->callback_id].data=c->data; - st->speex_callbacks[c->callback_id].callback_id=c->callback_id; - } - break; - case SPEEX_SET_USER_HANDLER: - { - SpeexCallback *c = (SpeexCallback*)ptr; - st->user_callback.func=c->func; - st->user_callback.data=c->data; - st->user_callback.callback_id=c->callback_id; - } - break; - case SPEEX_RESET_STATE: - { - int i; - for (i=0;i<2*st->lpcSize;i++) - st->mem_sp[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=st->inBuf[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->innov[i]; - } - break; - case SPEEX_GET_DTX_STATUS: - *((int*)ptr) = st->dtx_enabled; - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} diff --git a/src/add-ons/media/plugins/speex/libspeex/nb_celp.h b/src/add-ons/media/plugins/speex/libspeex/nb_celp.h deleted file mode 100644 index 7439f1c712..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/nb_celp.h +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file nb_celp.h - @brief Narrowband CELP encoder/decoder -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef NB_CELP_H -#define NB_CELP_H - -#include "modes.h" -#include "speex_bits.h" -#include "speex_callbacks.h" -#include "vbr.h" -#include "filters.h" - -/**Structure representing the full state of the narrowband encoder*/ -typedef struct EncState { - SpeexMode *mode; /**< Mode corresponding to the state */ - int first; /**< Is this the first frame? */ - int frameSize; /**< Size of frames */ - int subframeSize; /**< Size of sub-frames */ - int nbSubframes; /**< Number of sub-frames */ - int windowSize; /**< Analysis (LPC) window length */ - int lpcSize; /**< LPC order */ - int bufSize; /**< Buffer size */ - int min_pitch; /**< Minimum pitch value allowed */ - int max_pitch; /**< Maximum pitch value allowed */ - - int safe_pitch; /**< Don't use too large values for pitch (in case we lose a packet) */ - int bounded_pitch; /**< Next frame should not rely on previous frames for pitch */ - int ol_pitch; /**< Open-loop pitch */ - int ol_voiced; /**< Open-loop voiced/non-voiced decision */ - int *pitch; - float gamma1; /**< Perceptual filter: A(z/gamma1) */ - float gamma2; /**< Perceptual filter: A(z/gamma2) */ - float lag_factor; /**< Lag windowing Gaussian width */ - float lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ - float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/ - float pre_mem; /**< 1-element memory for pre-emphasis */ - float pre_mem2; /**< 1-element memory for pre-emphasis */ - char *stack; /**< Pseudo-stack allocation for temporary memory */ - float *inBuf; /**< Input buffer (original signal) */ - float *frame; /**< Start of original frame */ - float *excBuf; /**< Excitation buffer */ - float *exc; /**< Start of excitation frame */ - float *exc2Buf; /**< "Pitch enhanced" excitation */ - float *exc2; /**< "Pitch enhanced" excitation */ - float *swBuf; /**< Weighted signal buffer */ - float *sw; /**< Start of weighted signal frame */ - float *innov; /**< Innovation for the frame */ - float *window; /**< Temporary (Hanning) window */ - float *buf2; /**< 2nd temporary buffer */ - float *autocorr; /**< auto-correlation */ - float *lagWindow; /**< Window applied to auto-correlation */ - float *lpc; /**< LPCs for current frame */ - float *lsp; /**< LSPs for current frame */ - float *qlsp; /**< Quantized LSPs for current frame */ - float *old_lsp; /**< LSPs for previous frame */ - float *old_qlsp; /**< Quantized LSPs for previous frame */ - float *interp_lsp; /**< Interpolated LSPs */ - float *interp_qlsp; /**< Interpolated quantized LSPs */ - float *interp_lpc; /**< Interpolated LPCs */ - float *interp_qlpc; /**< Interpolated quantized LPCs */ - float *bw_lpc1; /**< LPCs after bandwidth expansion by gamma1 for perceptual weighting*/ - float *bw_lpc2; /**< LPCs after bandwidth expansion by gamma2 for perceptual weighting*/ - float *rc; /**< Reflection coefficients */ - float *mem_sp; /**< Filter memory for signal synthesis */ - float *mem_sw; /**< Filter memory for perceptually-weighted signal */ - float *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/ - float *mem_exc; /**< Filter memory for excitation (whole frame) */ - float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ - - VBRState *vbr; /**< State of the VBR data */ - float vbr_quality; /**< Quality setting for VBR encoding */ - float relative_quality; /**< Relative quality that will be needed by VBR */ - int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ - int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ - int dtx_enabled; /**< 1 for enabling DTX, 0 otherwise */ - int dtx_count; /**< Number of consecutive DTX frames */ - int abr_enabled; /**< ABR setting (in bps), 0 if off */ - float abr_drift; - float abr_drift2; - float abr_count; - int complexity; /**< Complexity setting (0-10 from least complex to most complex) */ - int sampling_rate; - - SpeexSubmode **submodes; /**< Sub-mode data */ - int submodeID; /**< Activated sub-mode */ - int submodeSelect; /**< Mode chosen by the user (may differ from submodeID if VAD is on) */ -} EncState; - -/**Structure representing the full state of the narrowband decoder*/ -typedef struct DecState { - SpeexMode *mode; /**< Mode corresponding to the state */ - int first; /**< Is this the first frame? */ - int count_lost; /**< Was the last frame lost? */ - int frameSize; /**< Size of frames */ - int subframeSize; /**< Size of sub-frames */ - int nbSubframes; /**< Number of sub-frames */ - int windowSize; /**< Analysis (LPC) window length */ - int lpcSize; /**< LPC order */ - int bufSize; /**< Buffer size */ - int min_pitch; /**< Minimum pitch value allowed */ - int max_pitch; /**< Maximum pitch value allowed */ - int sampling_rate; - float last_ol_gain; /**< Open-loop gain for previous frame */ - - - float gamma1; /**< Perceptual filter: A(z/gamma1) */ - float gamma2; /**< Perceptual filter: A(z/gamma2) */ - float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/ - float pre_mem; /**< 1-element memory for pre-emphasis */ - char *stack; /**< Pseudo-stack allocation for temporary memory */ - float *inBuf; /**< Input buffer (original signal) */ - float *frame; /**< Start of original frame */ - float *excBuf; /**< Excitation buffer */ - float *exc; /**< Start of excitation frame */ - float *innov; /**< Innovation for the frame */ - float *qlsp; /**< Quantized LSPs for current frame */ - float *old_qlsp; /**< Quantized LSPs for previous frame */ - float *interp_qlsp; /**< Interpolated quantized LSPs */ - float *interp_qlpc; /**< Interpolated quantized LPCs */ - float *mem_sp; /**< Filter memory for synthesis signal */ - float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ - int last_pitch; /**< Pitch of last correctly decoded frame */ - float last_pitch_gain; /**< Pitch gain of last correctly decoded frame */ - float pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */ - int pitch_gain_buf_idx; /**< Tail of the buffer */ - - SpeexSubmode **submodes; /**< Sub-mode data */ - int submodeID; /**< Activated sub-mode */ - int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */ - CombFilterMem *comb_mem; - SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS]; - - SpeexCallback user_callback; - - /*Vocoder data*/ - float voc_m1; - float voc_m2; - float voc_mean; - int voc_offset; - - int dtx_enabled; -} DecState; - -/** Initializes encoder state*/ -void *nb_encoder_init(SpeexMode *m); - -/** De-allocates encoder state resources*/ -void nb_encoder_destroy(void *state); - -/** Encodes one frame*/ -int nb_encode(void *state, float *in, SpeexBits *bits); - - -/** Initializes decoder state*/ -void *nb_decoder_init(SpeexMode *m); - -/** De-allocates decoder state resources*/ -void nb_decoder_destroy(void *state); - -/** Decodes one frame*/ -int nb_decode(void *state, SpeexBits *bits, float *out); - -/** ioctl-like function for controlling a narrowband encoder */ -int nb_encoder_ctl(void *state, int request, void *ptr); - -/** ioctl-like function for controlling a narrowband decoder */ -int nb_decoder_ctl(void *state, int request, void *ptr); - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/quant_lsp.c b/src/add-ons/media/plugins/speex/libspeex/quant_lsp.c deleted file mode 100644 index fea955d2a0..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/quant_lsp.c +++ /dev/null @@ -1,312 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: quant_lsp.c - LSP vector quantization - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "quant_lsp.h" -#include - -/* Note: x is modified*/ -static int lsp_quant(float *x, signed char *cdbk, int nbVec, int nbDim) -{ - int i,j; - float dist, tmp; - float best_dist=0; - int best_id=0; - signed char *ptr=cdbk; - for (i=0;i tmp2 ? tmp1 : tmp2; - } - for (i=0;i tmp2 ? tmp1 : tmp2; - } - - for (i=0;i tmp2 ? tmp1 : tmp2; - } - - for (i=0;i -#include "sb_celp.h" -#include "stdlib.h" -#include "filters.h" -#include "lpc.h" -#include "lsp.h" -#include "stack_alloc.h" -#include "cb_search.h" -#include "quant_lsp.h" -#include "vq.h" -#include "ltp.h" -#include "misc.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#define sqr(x) ((x)*(x)) - -#define SUBMODE(x) st->submodes[st->submodeID]->x - -#define QMF_ORDER 64 -static float h0[64] = { - 3.596189e-05, -0.0001123515, - -0.0001104587, 0.0002790277, - 0.0002298438, -0.0005953563, - -0.0003823631, 0.00113826, - 0.0005308539, -0.001986177, - -0.0006243724, 0.003235877, - 0.0005743159, -0.004989147, - -0.0002584767, 0.007367171, - -0.0004857935, -0.01050689, - 0.001894714, 0.01459396, - -0.004313674, -0.01994365, - 0.00828756, 0.02716055, - -0.01485397, -0.03764973, - 0.026447, 0.05543245, - -0.05095487, -0.09779096, - 0.1382363, 0.4600981, - 0.4600981, 0.1382363, - -0.09779096, -0.05095487, - 0.05543245, 0.026447, - -0.03764973, -0.01485397, - 0.02716055, 0.00828756, - -0.01994365, -0.004313674, - 0.01459396, 0.001894714, - -0.01050689, -0.0004857935, - 0.007367171, -0.0002584767, - -0.004989147, 0.0005743159, - 0.003235877, -0.0006243724, - -0.001986177, 0.0005308539, - 0.00113826, -0.0003823631, - -0.0005953563, 0.0002298438, - 0.0002790277, -0.0001104587, - -0.0001123515, 3.596189e-05 -}; - -static float h1[64] = { - 3.596189e-05, 0.0001123515, - -0.0001104587, -0.0002790277, - 0.0002298438, 0.0005953563, - -0.0003823631, -0.00113826, - 0.0005308539, 0.001986177, - -0.0006243724, -0.003235877, - 0.0005743159, 0.004989147, - -0.0002584767, -0.007367171, - -0.0004857935, 0.01050689, - 0.001894714, -0.01459396, - -0.004313674, 0.01994365, - 0.00828756, -0.02716055, - -0.01485397, 0.03764973, - 0.026447, -0.05543245, - -0.05095487, 0.09779096, - 0.1382363, -0.4600981, - 0.4600981, -0.1382363, - -0.09779096, 0.05095487, - 0.05543245, -0.026447, - -0.03764973, 0.01485397, - 0.02716055, -0.00828756, - -0.01994365, 0.004313674, - 0.01459396, -0.001894714, - -0.01050689, 0.0004857935, - 0.007367171, 0.0002584767, - -0.004989147, -0.0005743159, - 0.003235877, 0.0006243724, - -0.001986177, -0.0005308539, - 0.00113826, 0.0003823631, - -0.0005953563, -0.0002298438, - 0.0002790277, 0.0001104587, - -0.0001123515, -3.596189e-05 -}; - -void *sb_encoder_init(SpeexMode *m) -{ - int i; - SBEncState *st; - SpeexSBMode *mode; - - st = (SBEncState*)speex_alloc(sizeof(SBEncState)+8000*sizeof(float)); - st->mode = m; - mode = (SpeexSBMode*)m->mode; - - st->stack = ((char*)st) + sizeof(SBEncState); - - st->st_low = speex_encoder_init(mode->nb_mode); - st->full_frame_size = 2*mode->frameSize; - st->frame_size = mode->frameSize; - st->subframeSize = mode->subframeSize; - st->nbSubframes = mode->frameSize/mode->subframeSize; - st->windowSize = st->frame_size*3/2; - st->lpcSize=mode->lpcSize; - st->bufSize=mode->bufSize; - - st->submodes=mode->submodes; - st->submodeSelect = st->submodeID=mode->defaultSubmode; - - i=9; - speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &i); - - st->lag_factor = mode->lag_factor; - st->lpc_floor = mode->lpc_floor; - st->gamma1=mode->gamma1; - st->gamma2=mode->gamma2; - st->first=1; - - st->x0d=PUSH(st->stack, st->frame_size, float); - st->x1d=PUSH(st->stack, st->frame_size, float); - st->high=PUSH(st->stack, st->full_frame_size, float); - st->y0=PUSH(st->stack, st->full_frame_size, float); - st->y1=PUSH(st->stack, st->full_frame_size, float); - - st->h0_mem=PUSH(st->stack, QMF_ORDER, float); - st->h1_mem=PUSH(st->stack, QMF_ORDER, float); - st->g0_mem=PUSH(st->stack, QMF_ORDER, float); - st->g1_mem=PUSH(st->stack, QMF_ORDER, float); - - st->buf=PUSH(st->stack, st->windowSize, float); - st->excBuf=PUSH(st->stack, st->bufSize, float); - st->exc = st->excBuf + st->bufSize - st->windowSize; - - st->res=PUSH(st->stack, st->frame_size, float); - st->sw=PUSH(st->stack, st->frame_size, float); - st->target=PUSH(st->stack, st->frame_size, float); - /*Asymmetric "pseudo-Hamming" window*/ - { - int part1, part2; - part1 = st->subframeSize*7/2; - part2 = st->subframeSize*5/2; - st->window = PUSH(st->stack, st->windowSize, float); - for (i=0;iwindow[i]=.54-.46*cos(M_PI*i/part1); - for (i=0;iwindow[part1+i]=.54+.46*cos(M_PI*i/part2); - } - - st->lagWindow = PUSH(st->stack, st->lpcSize+1, float); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); - - st->rc = PUSH(st->stack, st->lpcSize, float); - st->autocorr = PUSH(st->stack, st->lpcSize+1, float); - st->lpc = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc1 = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc2 = PUSH(st->stack, st->lpcSize+1, float); - st->lsp = PUSH(st->stack, st->lpcSize, float); - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_lsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_lsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_lpc = PUSH(st->stack, st->lpcSize+1, float); - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - - st->mem_sp = PUSH(st->stack, st->lpcSize, float); - st->mem_sp2 = PUSH(st->stack, st->lpcSize, float); - st->mem_sw = PUSH(st->stack, st->lpcSize, float); - - st->vbr_quality = 8; - st->vbr_enabled = 0; - st->vad_enabled = 0; - st->abr_enabled = 0; - st->relative_quality=0; - - st->complexity=2; - speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); - st->sampling_rate*=2; - - return st; -} - -void sb_encoder_destroy(void *state) -{ - SBEncState *st=(SBEncState*)state; - - speex_encoder_destroy(st->st_low); - - speex_free(st); -} - - -int sb_encode(void *state, float *in, SpeexBits *bits) -{ - SBEncState *st; - int i, roots, sub; - char *stack; - float *mem, *innov, *syn_resp; - float *low_pi_gain, *low_exc, *low_innov; - SpeexSBMode *mode; - int dtx; - - st = (SBEncState*)state; - stack=st->stack; - mode = (SpeexSBMode*)(st->mode->mode); - - /* Compute the two sub-bands by filtering with h0 and h1*/ - qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); - - /* Encode the narrowband part*/ - speex_encode(st->st_low, st->x0d, bits); - - /* High-band buffering / sync with low band */ - for (i=0;iwindowSize-st->frame_size;i++) - st->high[i] = st->high[st->frame_size+i]; - for (i=0;iframe_size;i++) - st->high[st->windowSize-st->frame_size+i]=st->x1d[i]; - - speex_move(st->excBuf, st->excBuf+st->frame_size, (st->bufSize-st->frame_size)*sizeof(float)); - - - low_pi_gain = PUSH(stack, st->nbSubframes, float); - low_exc = PUSH(stack, st->frame_size, float); - low_innov = PUSH(stack, st->frame_size, float); - speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); - speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); - speex_encoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); - - speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx); - - if (dtx==0) - dtx=1; - else - dtx=0; - - /* Start encoding the high-band */ - for (i=0;iwindowSize;i++) - st->buf[i] = st->high[i] * st->window[i]; - - /* Compute auto-correlation */ - _spx_autocorr(st->buf, st->autocorr, st->lpcSize+1, st->windowSize); - - st->autocorr[0] += 1; /* prevents NANs */ - st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ - /* Lag windowing: equivalent to filtering in the power-spectrum domain */ - for (i=0;ilpcSize+1;i++) - st->autocorr[i] *= st->lagWindow[i]; - - /* Levinson-Durbin */ - wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); - st->lpc[0]=1; - - /* LPC to LSPs (x-domain) transform */ - roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack); - if (roots!=st->lpcSize) - { - roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.02, stack); - if (roots!=st->lpcSize) { - /*If we can't find all LSP's, do some damage control and use a flat filter*/ - for (i=0;ilpcSize;i++) - { - st->lsp[i]=cos(M_PI*((float)(i+1))/(st->lpcSize+1)); - } - } - } - - /* x-domain to angle domain*/ - for (i=0;ilpcSize;i++) - st->lsp[i] = acos(st->lsp[i]); - - /* VBR code */ - if ((st->vbr_enabled || st->vad_enabled) && !dtx) - { - float e_low=0, e_high=0; - float ratio; - if (st->abr_enabled) - { - float qual_change=0; - if (st->abr_drift2 * st->abr_drift > 0) - { - /* Only adapt if long-term and short-term drift are the same sign */ - qual_change = -.00001*st->abr_drift/(1+st->abr_count); - if (qual_change>.1) - qual_change=.1; - if (qual_change<-.1) - qual_change=-.1; - } - st->vbr_quality += qual_change; - if (st->vbr_quality>10) - st->vbr_quality=10; - if (st->vbr_quality<0) - st->vbr_quality=0; - } - - - for (i=0;iframe_size;i++) - { - e_low += st->x0d[i]* st->x0d[i]; - e_high += st->high[i]* st->high[i]; - } - ratio = log((1+e_high)/(1+e_low)); - speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality); - if (ratio<-4) - ratio=-4; - if (ratio>2) - ratio=2; - /*if (ratio>-2)*/ - if (st->vbr_enabled) - { - int modeid; - modeid = mode->nb_modes-1; - st->relative_quality+=1.0*(ratio+2); - if (st->relative_quality<-1) - st->relative_quality=-1; - while (modeid) - { - int v1; - float thresh; - v1=(int)floor(st->vbr_quality); - if (v1==10) - thresh = mode->vbr_thresh[modeid][v1]; - else - thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] + - (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1]; - if (st->relative_quality >= thresh) - break; - modeid--; - } - speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid); - if (st->abr_enabled) - { - int bitrate; - speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); - st->abr_drift+=(bitrate-st->abr_enabled); - st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); - st->abr_count += 1.0; - } - - } else { - /* VAD only */ - int modeid; - if (st->relative_quality<2.0) - modeid=1; - else - modeid=st->submodeSelect; - /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ - st->submodeID=modeid; - - } - /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/ - } - - speex_bits_pack(bits, 1, 1); - if (dtx) - speex_bits_pack(bits, 0, SB_SUBMODE_BITS); - else - speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS); - - /* If null mode (no transmission), just set a couple things to zero*/ - if (dtx || st->submodes[st->submodeID] == NULL) - { - for (i=0;iframe_size;i++) - st->exc[i]=st->sw[i]=VERY_SMALL; - - for (i=0;ilpcSize;i++) - st->mem_sw[i]=0; - st->first=1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->high, st->subframeSize, st->lpcSize, st->mem_sp); - -#ifndef RELEASE - - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - in[i]=2*(st->y0[i]-st->y1[i]); -#endif - - if (dtx) - return 0; - else - return 1; - } - - - /* LSP quantization */ - SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); - - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - mem=PUSH(stack, st->lpcSize, float); - syn_resp=PUSH(stack, st->subframeSize, float); - innov = PUSH(stack, st->subframeSize, float); - - for (sub=0;subnbSubframes;sub++) - { - float *exc, *sp, *res, *target, *sw, tmp, filter_ratio; - int offset; - float rl, rh, eh=0, el=0; - int fold; - - offset = st->subframeSize*sub; - sp=st->high+offset; - exc=st->exc+offset; - res=st->res+offset; - target=st->target+offset; - sw=st->sw+offset; - - /* LSP interpolation (quantized and unquantized) */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i]; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - lsp_enforce_margin(st->interp_lsp, st->lpcSize, .05); - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .05); - - /* Compute interpolated LPCs (quantized and unquantized) */ - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = cos(st->interp_lsp[i]); - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); - - /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band - filters */ - rl=rh=0; - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - rh += tmp*st->interp_qlpc[i]; - tmp = -tmp; - st->pi_gain[sub]+=st->interp_qlpc[i]; - } - rl = low_pi_gain[sub]; - rl=1/(fabs(rl)+.01); - rh=1/(fabs(rh)+.01); - /* Compute ratio, will help predict the gain */ - filter_ratio=fabs(.01+rh)/(.01+fabs(rl)); - - fold = filter_ratio<5; - /*printf ("filter_ratio %f\n", filter_ratio);*/ - fold=0; - - /* Compute "real excitation" */ - fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); - /* Compute energy of low-band and high-band excitation */ - for (i=0;isubframeSize;i++) - eh+=sqr(exc[i]); - - if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ - float g; - /*speex_bits_pack(bits, 1, 1);*/ - for (i=0;isubframeSize;i++) - el+=sqr(low_innov[offset+i]); - - /* Gain to use if we want to use the low-band excitation for high-band */ - g=eh/(.01+el); - g=sqrt(g); - - g *= filter_ratio; - /*print_vec(&g, 1, "gain factor");*/ - /* Gain quantization */ - { - int quant = (int) floor(.5 + 10 + 8.0 * log((g+.0001))); - /*speex_warning_int("tata", quant);*/ - if (quant<0) - quant=0; - if (quant>31) - quant=31; - speex_bits_pack(bits, quant, 5); - g= .1*exp(quant/9.4); - } - /*printf ("folding gain: %f\n", g);*/ - g /= filter_ratio; - - } else { - float gc, scale, scale_1; - - for (i=0;isubframeSize;i++) - el+=sqr(low_exc[offset+i]); - /*speex_bits_pack(bits, 0, 1);*/ - - gc = sqrt(1+eh)*filter_ratio/sqrt((1+el)*st->subframeSize); - { - int qgc = (int)floor(.5+3.7*(log(gc)+2)); - if (qgc<0) - qgc=0; - if (qgc>15) - qgc=15; - speex_bits_pack(bits, qgc, 4); - gc = exp((1/3.7)*qgc-2); - } - - scale = gc*sqrt(1+el)/filter_ratio; - scale_1 = 1/scale; - - for (i=0;isubframeSize;i++) - exc[i]=0; - exc[0]=1; - syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; - - /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); - - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); - - /* Compute weighted signal */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); - - /* Compute target signal */ - for (i=0;isubframeSize;i++) - target[i]=sw[i]-res[i]; - - for (i=0;isubframeSize;i++) - exc[i]=0; - - - for (i=0;isubframeSize;i++) - target[i]*=scale_1; - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - innov[i]=0; - - /*print_vec(target, st->subframeSize, "\ntarget");*/ - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov, syn_resp, bits, stack, (st->complexity+1)>>1); - /*print_vec(target, st->subframeSize, "after");*/ - - for (i=0;isubframeSize;i++) - exc[i] += innov[i]*scale; - - if (SUBMODE(double_codebook)) { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - for (i=0;isubframeSize;i++) - target[i]*=2.5; - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov2, syn_resp, bits, tmp_stack, (st->complexity+1)>>1); - for (i=0;isubframeSize;i++) - innov2[i]*=scale*(1/2.5); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - } - - /*Keep the previous memory*/ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - /* Final signal synthesis from excitation */ - iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); - - /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); - } - - -#ifndef RELEASE - - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - in[i]=2*(st->y0[i]-st->y1[i]); -#endif - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - - st->first=0; - - return 1; -} - - - - - -void *sb_decoder_init(SpeexMode *m) -{ - SBDecState *st; - SpeexSBMode *mode; - st = (SBDecState*)speex_alloc(sizeof(SBDecState)+6000*sizeof(float)); - st->mode = m; - mode=(SpeexSBMode*)m->mode; - - st->stack = ((char*)st) + sizeof(SBDecState); - - - - st->st_low = speex_decoder_init(mode->nb_mode); - st->full_frame_size = 2*mode->frameSize; - st->frame_size = mode->frameSize; - st->subframeSize = mode->subframeSize; - st->nbSubframes = mode->frameSize/mode->subframeSize; - st->lpcSize=8; - speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); - st->sampling_rate*=2; - - st->submodes=mode->submodes; - st->submodeID=mode->defaultSubmode; - - st->first=1; - - - st->x0d=PUSH(st->stack, st->frame_size, float); - st->x1d=PUSH(st->stack, st->frame_size, float); - st->high=PUSH(st->stack, st->full_frame_size, float); - st->y0=PUSH(st->stack, st->full_frame_size, float); - st->y1=PUSH(st->stack, st->full_frame_size, float); - - st->h0_mem=PUSH(st->stack, QMF_ORDER, float); - st->h1_mem=PUSH(st->stack, QMF_ORDER, float); - st->g0_mem=PUSH(st->stack, QMF_ORDER, float); - st->g1_mem=PUSH(st->stack, QMF_ORDER, float); - - st->exc=PUSH(st->stack, st->frame_size, float); - - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - st->mem_sp = PUSH(st->stack, 2*st->lpcSize, float); - - st->lpc_enh_enabled=0; - - return st; -} - -void sb_decoder_destroy(void *state) -{ - SBDecState *st; - st = (SBDecState*)state; - speex_decoder_destroy(st->st_low); - - speex_free(state); -} - -static void sb_decode_lost(SBDecState *st, float *out, int dtx, char *stack) -{ - int i; - float *awk1, *awk2, *awk3; - int saved_modeid=0; - - if (dtx) - { - saved_modeid=st->submodeID; - st->submodeID=1; - } else { - bw_lpc(0.99, st->interp_qlpc, st->interp_qlpc, st->lpcSize); - } - - st->first=1; - - awk1=PUSH(stack, st->lpcSize+1, float); - awk2=PUSH(stack, st->lpcSize+1, float); - awk3=PUSH(stack, st->lpcSize+1, float); - - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - if (st->submodes[st->submodeID] != NULL) - { - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - } else { - k1=k2=.7; - } - k3=(1-(1-r*k1)/(1-r*k2))/r; - k3=k1-k2; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/ - } - - - /* Final signal synthesis from excitation */ - if (!dtx) - { - for (i=0;iframe_size;i++) - st->exc[i] *= .9; - } - - for (i=0;iframe_size;i++) - st->high[i]=st->exc[i]; - - if (st->lpc_enh_enabled) - { - /* Use enhanced LPC filter */ - filter_mem2(st->high, awk2, awk1, st->high, st->frame_size, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(st->high, awk3, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, - st->mem_sp); - } else { - /* Use regular filter */ - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, - st->mem_sp); - } - - /*iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);*/ - - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - out[i]=2*(st->y0[i]-st->y1[i]); - - if (dtx) - { - st->submodeID=saved_modeid; - } - - return; -} - -int sb_decode(void *state, SpeexBits *bits, float *out) -{ - int i, sub; - SBDecState *st; - int wideband; - int ret; - char *stack; - float *low_pi_gain, *low_exc, *low_innov; - float *awk1, *awk2, *awk3; - int dtx; - SpeexSBMode *mode; - - st = (SBDecState*)state; - stack=st->stack; - mode = (SpeexSBMode*)(st->mode->mode); - - /* Decode the low-band */ - ret = speex_decode(st->st_low, bits, st->x0d); - - speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx); - - /* If error decoding the narrowband part, propagate error */ - if (ret!=0) - { - return ret; - } - - if (!bits) - { - sb_decode_lost(st, out, dtx, stack); - return 0; - } - - /*Check "wideband bit"*/ - if (speex_bits_remaining(bits)>0) - wideband = speex_bits_peek(bits); - else - wideband = 0; - if (wideband) - { - /*Regular wideband frame, read the submode*/ - wideband = speex_bits_unpack_unsigned(bits, 1); - st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - } else - { - /*Was a narrowband frame, set "null submode"*/ - st->submodeID = 0; - } - if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL) - { - speex_warning("Invalid mode encountered: corrupted stream?"); - return -2; - } - - /* If null mode (no transmission), just set a couple things to zero*/ - if (st->submodes[st->submodeID] == NULL) - { - if (dtx) - { - sb_decode_lost(st, out, 1, stack); - return 0; - } - - for (i=0;iframe_size;i++) - st->exc[i]=VERY_SMALL; - - st->first=1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp); - - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - out[i]=2*(st->y0[i]-st->y1[i]); - - return 0; - - } - - for (i=0;iframe_size;i++) - st->exc[i]=0; - - low_pi_gain = PUSH(stack, st->nbSubframes, float); - low_exc = PUSH(stack, st->frame_size, float); - low_innov = PUSH(stack, st->frame_size, float); - speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); - speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); - speex_decoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); - - SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); - - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - awk1=PUSH(stack, st->lpcSize+1, float); - awk2=PUSH(stack, st->lpcSize+1, float); - awk3=PUSH(stack, st->lpcSize+1, float); - - for (sub=0;subnbSubframes;sub++) - { - float *exc, *sp, tmp, filter_ratio, el=0; - int offset; - float rl=0,rh=0; - - offset = st->subframeSize*sub; - sp=st->high+offset; - exc=st->exc+offset; - - /* LSP interpolation */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .05); - - /* LSPs to x-domain */ - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - - /* LSP to LPC */ - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - k3=(1-(1-r*k1)/(1-r*k2))/r; - k3=k1-k2; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/ - } - - - /* Calculate reponse ratio between the low and high filter in the middle - of the band (4000 Hz) */ - - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - rh += tmp*st->interp_qlpc[i]; - tmp = -tmp; - st->pi_gain[sub]+=st->interp_qlpc[i]; - } - rl = low_pi_gain[sub]; - rl=1/(fabs(rl)+.01); - rh=1/(fabs(rh)+.01); - filter_ratio=fabs(.01+rh)/(.01+fabs(rl)); - - - for (i=0;isubframeSize;i++) - exc[i]=0; - if (!SUBMODE(innovation_unquant)) - { - float g; - int quant; - - for (i=0;isubframeSize;i++) - el+=sqr(low_innov[offset+i]); - quant = speex_bits_unpack_unsigned(bits, 5); - g= exp(((float)quant-10)/8.0); - - /*printf ("unquant folding gain: %f\n", g);*/ - g /= filter_ratio; - - /* High-band excitation using the low-band excitation and a gain */ - for (i=0;isubframeSize;i++) - exc[i]=mode->folding_gain*g*low_innov[offset+i]; - /*speex_rand_vec(mode->folding_gain*g*sqrt(el/st->subframeSize), exc, st->subframeSize);*/ - } else { - float gc, scale; - int qgc = speex_bits_unpack_unsigned(bits, 4); - for (i=0;isubframeSize;i++) - el+=sqr(low_exc[offset+i]); - - - gc = exp((1/3.7)*qgc-2); - - scale = gc*sqrt(1+el)/filter_ratio; - - - SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, - bits, stack); - for (i=0;isubframeSize;i++) - exc[i]*=scale; - - if (SUBMODE(double_codebook)) { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, - bits, tmp_stack); - for (i=0;isubframeSize;i++) - innov2[i]*=scale*(1/2.5); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - } - - for (i=0;isubframeSize;i++) - sp[i]=exc[i]; - if (st->lpc_enh_enabled) - { - /* Use enhanced LPC filter */ - filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } else { - /* Use regular filter */ - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } - /*iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);*/ - - } - - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - out[i]=2*(st->y0[i]-st->y1[i]); - - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - - st->first=0; - - return 0; -} - - -int sb_encoder_ctl(void *state, int request, void *ptr) -{ - SBEncState *st; - st=(SBEncState*)state; - switch(request) - { - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->full_frame_size; - break; - case SPEEX_SET_HIGH_MODE: - st->submodeSelect = st->submodeID = (*(int*)ptr); - break; - case SPEEX_SET_LOW_MODE: - speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr); - break; - case SPEEX_SET_DTX: - speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr); - break; - case SPEEX_GET_DTX: - speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr); - break; - case SPEEX_GET_LOW_MODE: - speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); - break; - case SPEEX_SET_MODE: - speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr); - break; - case SPEEX_SET_VBR: - st->vbr_enabled = (*(int*)ptr); - speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr); - break; - case SPEEX_GET_VBR: - (*(int*)ptr) = st->vbr_enabled; - break; - case SPEEX_SET_VAD: - st->vad_enabled = (*(int*)ptr); - speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr); - break; - case SPEEX_GET_VAD: - (*(int*)ptr) = st->vad_enabled; - break; - case SPEEX_SET_VBR_QUALITY: - { - int q; - float qual = (*(float*)ptr)+.6; - st->vbr_quality = (*(float*)ptr); - if (qual>10) - qual=10; - q=(int)floor(.5+*(float*)ptr); - if (q>10) - q=10; - speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual); - speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q); - break; - } - case SPEEX_SET_ABR: - st->abr_enabled = (*(int*)ptr); - st->vbr_enabled = 1; - speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled); - { - int i=10, rate, target; - float vbr_qual; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - vbr_qual=i; - if (vbr_qual<0) - vbr_qual=0; - speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); - st->abr_count=0; - st->abr_drift=0; - st->abr_drift2=0; - } - - break; - case SPEEX_GET_ABR: - (*(int*)ptr) = st->abr_enabled; - break; - case SPEEX_SET_QUALITY: - { - int nb_qual; - int quality = (*(int*)ptr); - if (quality < 0) - quality = 0; - if (quality > 10) - quality = 10; - st->submodeSelect = st->submodeID = ((SpeexSBMode*)(st->mode->mode))->quality_map[quality]; - nb_qual = ((SpeexSBMode*)(st->mode->mode))->low_quality_map[quality]; - speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual); - } - break; - case SPEEX_SET_COMPLEXITY: - speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr); - st->complexity = (*(int*)ptr); - if (st->complexity<1) - st->complexity=1; - break; - case SPEEX_GET_COMPLEXITY: - (*(int*)ptr) = st->complexity; - break; - case SPEEX_SET_BITRATE: - { - int i=10, rate, target; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - } - break; - case SPEEX_GET_BITRATE: - speex_encoder_ctl(st->st_low, request, ptr); - /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/ - if (st->submodes[st->submodeID]) - (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; - else - (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; - /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/ - break; - case SPEEX_SET_SAMPLING_RATE: - { - int tmp=(*(int*)ptr); - st->sampling_rate = tmp; - tmp>>=1; - speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); - } - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_RESET_STATE: - { - int i; - st->first = 1; - for (i=0;ilpcSize;i++) - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); - for (i=0;ilpcSize;i++) - st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=0; - for (i=0;ih0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_RELATIVE_QUALITY: - (*(float*)ptr)=st->relative_quality; - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} - -int sb_decoder_ctl(void *state, int request, void *ptr) -{ - SBDecState *st; - st=(SBDecState*)state; - switch(request) - { - case SPEEX_GET_LOW_MODE: - speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); - break; - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->full_frame_size; - break; - case SPEEX_SET_ENH: - speex_decoder_ctl(st->st_low, request, ptr); - st->lpc_enh_enabled = *((int*)ptr); - break; - case SPEEX_GET_BITRATE: - speex_decoder_ctl(st->st_low, request, ptr); - if (st->submodes[st->submodeID]) - (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; - else - (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; - break; - case SPEEX_SET_SAMPLING_RATE: - { - int tmp=(*(int*)ptr); - st->sampling_rate = tmp; - tmp>>=1; - speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); - } - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_SET_HANDLER: - speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr); - break; - case SPEEX_SET_USER_HANDLER: - speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr); - break; - case SPEEX_RESET_STATE: - { - int i; - for (i=0;i<2*st->lpcSize;i++) - st->mem_sp[i]=0; - for (i=0;ih0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_DTX_STATUS: - speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr); - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} diff --git a/src/add-ons/media/plugins/speex/libspeex/sb_celp.h b/src/add-ons/media/plugins/speex/libspeex/sb_celp.h deleted file mode 100644 index 64b23eea36..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/sb_celp.h +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file sb_celp.h - @brief Sub-band CELP mode used for wideband encoding -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef SB_CELP_H -#define SB_CELP_H - -#include "modes.h" -#include "speex_bits.h" -#include "nb_celp.h" - -/**Structure representing the full state of the sub-band encoder*/ -typedef struct SBEncState { - SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ - void *st_low; /**< State of the low-band (narrowband) encoder */ - int full_frame_size; /**< Length of full-band frames*/ - int frame_size; /**< Length of high-band frames*/ - int subframeSize; /**< Length of high-band sub-frames*/ - int nbSubframes; /**< Number of high-band sub-frames*/ - int windowSize; /**< Length of high-band LPC window*/ - int lpcSize; /**< Order of high-band LPC analysis */ - int bufSize; /**< Buffer size */ - int first; /**< First frame? */ - float lag_factor; /**< Lag-windowing control parameter */ - float lpc_floor; /**< Controls LPC analysis noise floor */ - float gamma1; /**< Perceptual weighting coef 1 */ - float gamma2; /**< Perceptual weighting coef 2 */ - - char *stack; /**< Temporary allocation stack */ - float *x0d, *x1d; /**< QMF filter signals*/ - float *high; /**< High-band signal (buffer) */ - float *y0, *y1; /**< QMF synthesis signals */ - float *h0_mem, *h1_mem, *g0_mem, *g1_mem; /**< QMF memories */ - - float *excBuf; /**< High-band excitation */ - float *exc; /**< High-band excitation (for QMF only)*/ - float *buf; /**< Temporary buffer */ - float *res; /**< Zero-input response (ringing) */ - float *sw; /**< Perceptually weighted signal */ - float *target; /**< Weighted target signal (analysis by synthesis) */ - float *window; /**< LPC analysis window */ - float *lagWindow; /**< Auto-correlation window */ - float *autocorr; /**< Auto-correlation (for LPC analysis) */ - float *rc; /**< Reflection coefficients (unused) */ - float *lpc; /**< LPC coefficients */ - float *lsp; /**< LSP coefficients */ - float *qlsp; /**< Quantized LSPs */ - float *old_lsp; /**< LSPs of previous frame */ - float *old_qlsp; /**< Quantized LSPs of previous frame */ - float *interp_lsp; /**< Interpolated LSPs for current sub-frame */ - float *interp_qlsp; /**< Interpolated quantized LSPs for current sub-frame */ - float *interp_lpc; /**< Interpolated LPCs for current sub-frame */ - float *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ - float *bw_lpc1; /**< Bandwidth-expanded version of LPCs (#1) */ - float *bw_lpc2; /**< Bandwidth-expanded version of LPCs (#2) */ - - float *mem_sp; /**< Synthesis signal memory */ - float *mem_sp2; - float *mem_sw; /**< Perceptual signal memory */ - float *pi_gain; - - float vbr_quality; /**< Quality setting for VBR encoding */ - int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ - int abr_enabled; /**< ABR setting (in bps), 0 if off */ - float abr_drift; - float abr_drift2; - float abr_count; - int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ - float relative_quality; - - SpeexSubmode **submodes; - int submodeID; - int submodeSelect; - int complexity; - int sampling_rate; - -} SBEncState; - - -/**Structure representing the full state of the sub-band decoder*/ -typedef struct SBDecState { - SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ - void *st_low; /**< State of the low-band (narrowband) encoder */ - int full_frame_size; - int frame_size; - int subframeSize; - int nbSubframes; - int lpcSize; - int first; - int sampling_rate; - int lpc_enh_enabled; - - char *stack; - float *x0d, *x1d; - float *high; - float *y0, *y1; - float *h0_mem, *h1_mem, *g0_mem, *g1_mem; - - float *exc; - float *qlsp; - float *old_qlsp; - float *interp_qlsp; - float *interp_qlpc; - - float *mem_sp; - float *pi_gain; - - SpeexSubmode **submodes; - int submodeID; -} SBDecState; - - -/**Initializes encoder state*/ -void *sb_encoder_init(SpeexMode *m); - -/**De-allocates encoder state resources*/ -void sb_encoder_destroy(void *state); - -/**Encodes one frame*/ -int sb_encode(void *state, float *in, SpeexBits *bits); - - -/**Initializes decoder state*/ -void *sb_decoder_init(SpeexMode *m); - -/**De-allocates decoder state resources*/ -void sb_decoder_destroy(void *state); - -/**Decodes one frame*/ -int sb_decode(void *state, SpeexBits *bits, float *out); - -int sb_encoder_ctl(void *state, int request, void *ptr); - -int sb_decoder_ctl(void *state, int request, void *ptr); - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/speex.h b/src/add-ons/media/plugins/speex/libspeex/speex.h deleted file mode 100644 index cafd0cda19..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex.h +++ /dev/null @@ -1,331 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin*/ -/** - @file speex.h - @brief Describes the different modes of the codec -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef SPEEX_H -#define SPEEX_H - -#include "speex_bits.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Values allowed for *ctl() requests */ - -/** Set enhancement on/off (decoder only) */ -#define SPEEX_SET_ENH 0 -/** Get enhancement state (decoder only) */ -#define SPEEX_GET_ENH 1 - -/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/ -/** Obtain frame size used by encoder/decoder */ -#define SPEEX_GET_FRAME_SIZE 3 - -/** Set quality value */ -#define SPEEX_SET_QUALITY 4 -/** Get current quality setting */ -#define SPEEX_GET_QUALITY 5 - -/** Set sub-mode to use */ -#define SPEEX_SET_MODE 6 -/** Get current sub-mode in use */ -#define SPEEX_GET_MODE 7 - -/** Set low-band sub-mode to use (wideband only)*/ -#define SPEEX_SET_LOW_MODE 8 -/** Get current low-band mode in use (wideband only)*/ -#define SPEEX_GET_LOW_MODE 9 - -/** Set high-band sub-mode to use (wideband only)*/ -#define SPEEX_SET_HIGH_MODE 10 -/** Get current high-band mode in use (wideband only)*/ -#define SPEEX_GET_HIGH_MODE 11 - -/** Set VBR on (1) or off (0) */ -#define SPEEX_SET_VBR 12 -/** Get VBR status (1 for on, 0 for off) */ -#define SPEEX_GET_VBR 13 - -/** Set quality value for VBR encoding (0-10) */ -#define SPEEX_SET_VBR_QUALITY 14 -/** Get current quality value for VBR encoding (0-10) */ -#define SPEEX_GET_VBR_QUALITY 15 - -/** Set complexity of the encoder (0-10) */ -#define SPEEX_SET_COMPLEXITY 16 -/** Get current complexity of the encoder (0-10) */ -#define SPEEX_GET_COMPLEXITY 17 - -/** Set bit-rate used by the encoder (or lower) */ -#define SPEEX_SET_BITRATE 18 -/** Get current bit-rate used by the encoder or decoder */ -#define SPEEX_GET_BITRATE 19 - -/**Define a handler function for in-band Speex request*/ -#define SPEEX_SET_HANDLER 20 - -/**Define a handler function for in-band user-defined request*/ -#define SPEEX_SET_USER_HANDLER 22 - -/** Set sampling rate used in bit-rate computation */ -#define SPEEX_SET_SAMPLING_RATE 24 -/** Get sampling rate used in bit-rate computation */ -#define SPEEX_GET_SAMPLING_RATE 25 - -/** Reset the encoder/decoder memories to zero*/ -#define SPEEX_RESET_STATE 26 - -/** Get VBR info (mostly used internally) */ -#define SPEEX_GET_RELATIVE_QUALITY 29 - -/** Set VAD status (1 for on, 0 for off) */ -#define SPEEX_SET_VAD 30 - -/** Get VAD status (1 for on, 0 for off) */ -#define SPEEX_GET_VAD 31 - -/** Set Average Bit-Rate (ABR) to n bits per seconds */ -#define SPEEX_SET_ABR 32 -/** Get Average Bit-Rate (ABR) setting (in bps) */ -#define SPEEX_GET_ABR 33 - -/** Set DTX status (1 for on, 0 for off) */ -#define SPEEX_SET_DTX 34 -/** Get DTX status (1 for on, 0 for off) */ -#define SPEEX_GET_DTX 35 - - -/* Used internally, not to be used in applications */ -/** Used internally*/ -#define SPEEX_GET_PI_GAIN 100 -/** Used internally*/ -#define SPEEX_GET_EXC 101 -/** Used internally*/ -#define SPEEX_GET_INNOV 102 -/** Used internally*/ -#define SPEEX_GET_DTX_STATUS 103 - - -/* Preserving compatibility:*/ -/** Equivalent to SPEEX_SET_ENH */ -#define SPEEX_SET_PF 0 -/** Equivalent to SPEEX_GET_ENH */ -#define SPEEX_GET_PF 1 - - -/* Values allowed for mode queries */ -/** Query the frame size of a mode */ -#define SPEEX_MODE_FRAME_SIZE 0 - -/** Query the size of an encoded frame for a particular sub-mode */ -#define SPEEX_SUBMODE_BITS_PER_FRAME 1 - - -/** Number of defined modes in Speex */ -#define SPEEX_NB_MODES 3 - -struct SpeexMode; - - -/* Prototypes for mode function pointers */ - -/** Encoder state initialization function */ -typedef void *(*encoder_init_func)(struct SpeexMode *mode); - -/** Encoder state destruction function */ -typedef void (*encoder_destroy_func)(void *st); - -/** Main encoding function */ -typedef int (*encode_func)(void *state, float *in, SpeexBits *bits); - -/** Function for controlling the encoder options */ -typedef int (*encoder_ctl_func)(void *state, int request, void *ptr); - -/** Decoder state initialization function */ -typedef void *(*decoder_init_func)(struct SpeexMode *mode); - -/** Decoder state destruction function */ -typedef void (*decoder_destroy_func)(void *st); - -/** Main decoding function */ -typedef int (*decode_func)(void *state, SpeexBits *bits, float *out); - -/** Function for controlling the decoder options */ -typedef int (*decoder_ctl_func)(void *state, int request, void *ptr); - - -/** Query function for a mode */ -typedef int (*mode_query_func)(void *mode, int request, void *ptr); - -/** Struct defining a Speex mode */ -typedef struct SpeexMode { - /** Pointer to the low-level mode data */ - void *mode; - - /** Pointer to the mode query function */ - mode_query_func query; - - /** The name of the mode (you should not rely on this to identify the mode)*/ - char *modeName; - - /**ID of the mode*/ - int modeID; - - /**Version number of the bitstream (incremented every time we break - bitstream compatibility*/ - int bitstream_version; - - /** Pointer to encoder initialization function */ - encoder_init_func enc_init; - - /** Pointer to encoder destruction function */ - encoder_destroy_func enc_destroy; - - /** Pointer to frame encoding function */ - encode_func enc; - - /** Pointer to decoder initialization function */ - decoder_init_func dec_init; - - /** Pointer to decoder destruction function */ - decoder_destroy_func dec_destroy; - - /** Pointer to frame decoding function */ - decode_func dec; - - /** ioctl-like requests for encoder */ - encoder_ctl_func enc_ctl; - - /** ioctl-like requests for decoder */ - decoder_ctl_func dec_ctl; - -} SpeexMode; - -/** - * Returns a handle to a newly created Speex encoder state structure. For now, - * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes - * may be added. Note that for now if you have more than one channels to - * encode, you need one state per channel. - * - * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) - * @return A newly created encoder - */ -void *speex_encoder_init(SpeexMode *mode); - -/** Frees all resources associated to an existing Speex encoder state. - * @param state Encoder state to be destroyed */ -void speex_encoder_destroy(void *state); - -/** Uses an existing encoder state to encode one frame of speech pointed to by - "in". The encoded bit-stream is saved in "bits". - @param state Encoder state - @param in Frame that will be encoded with a +-2^16 range - @param bits Bit-stream where the data will be written - */ -int speex_encode(void *state, float *in, SpeexBits *bits); - -/** Used like the ioctl function to control the encoder parameters - * - * @param state Encoder state - * @param request ioctl-type request (one of the SPEEX_* macros) - * @param ptr Data exchanged to-from function - * @return 0 if frame needs not be transmitted (DTX only), 1 otherwise - */ -int speex_encoder_ctl(void *state, int request, void *ptr); - - -/** Returns a handle to a newly created decoder state structure. For now, - * the mode argument can be &nb_mode or &wb_mode . In the future, more modes - * may be added. Note that for now if you have more than one channels to - * decode, you need one state per channel. - * - * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode) - * @return A newly created decoder state - */ -void *speex_decoder_init(SpeexMode *mode); - -/** Frees all resources associated to an existing decoder state. - * - * @param state State to be destroyed - */ -void speex_decoder_destroy(void *state); - -/** Uses an existing decoder state to decode one frame of speech from - * bit-stream bits. The output speech is saved written to out. - * - * @param state Decoder state - * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost) - * @param out Where to write the decoded frame - * @return return status (0 for no error, -1 for end of stream, -2 other) - */ -int speex_decode(void *state, SpeexBits *bits, float *out); - -/** Used like the ioctl function to control the encoder parameters - * - * @param state Decoder state - * @param request ioctl-type request (one of the SPEEX_* macros) - * @param ptr Data exchanged to-from function - * @return 0 for no error, 1 if a terminator is reached, 2 for another error - */ -int speex_decoder_ctl(void *state, int request, void *ptr); - - -/** Query function for mode information - * - * @param mode Speex mode - * @param request ioctl-type request (one of the SPEEX_* macros) - * @param ptr Data exchanged to-from function - */ -int speex_mode_query(SpeexMode *mode, int request, void *ptr); - - -/** Default narrowband mode */ -extern SpeexMode speex_nb_mode; - -/** Default wideband mode */ -extern SpeexMode speex_wb_mode; - -/** Default "ultra-wideband" mode */ -extern SpeexMode speex_uwb_mode; - -/** List of all modes available */ -extern SpeexMode *speex_mode_list[SPEEX_NB_MODES]; - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/speex_bits.h b/src/add-ons/media/plugins/speex/libspeex/speex_bits.h deleted file mode 100644 index b41fdad7eb..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex_bits.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file speex_bits.h - @brief Handles bit packing/unpacking -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef BITS_H -#define BITS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** Maximum size of the bit-stream (for fixed-size allocation) */ -#define MAX_BYTES_PER_FRAME 2000 - -/** Bit-packing data structure representing (part of) a bit-stream. */ -typedef struct SpeexBits { - char *bytes; /**< "raw" data */ - int nbBits; /**< Total number of bits stored in the stream*/ - int bytePtr; /**< Position of the byte "cursor" */ - int bitPtr; /**< Position of the bit "cursor" within the current byte */ - int owner; /**< Does the struct "own" the "raw" buffer (member "bytes") */ - int overflow;/**< Set to one if we try to read past the valid data */ - int buf_size;/**< Allocated size for buffer */ - int reserved1; /**< Reserved for future use */ - void *reserved2; /**< Reserved for future use */ -} SpeexBits; - -/** Initializes and allocates resources for a SpeexBits struct */ -void speex_bits_init(SpeexBits *bits); - -/** Initializes SpeexBits struct using a pre-allocated buffer*/ -void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size); - -/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/ -void speex_bits_destroy(SpeexBits *bits); - -/** Resets bits to initial value (just after initialization, erasing content)*/ -void speex_bits_reset(SpeexBits *bits); - -/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */ -void speex_bits_rewind(SpeexBits *bits); - -/** Initializes the bit-stream from the data in an area of memory */ -void speex_bits_read_from(SpeexBits *bits, char *bytes, int len); - -/** Append bytes to the bit-stream - * @param bits Bit-stream to operate on - * @param bytes pointer to the bytes what will be appended - * @param len Number of bytes of append - */ -void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len); - -/** Write the content of a bit-stream to an area of memory */ -int speex_bits_write(SpeexBits *bits, char *bytes, int max_len); - -/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */ -int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len); - -/** Append bits to the bit-stream - * @param bits Bit-stream to operate on - * @param data Value to append as integer - * @param nbBits number of bits to consider in "data" - */ -void speex_bits_pack(SpeexBits *bits, int data, int nbBits); - -/** Interpret the next bits in the bit-stream as a signed integer - * - * @param bits Bit-stream to operate on - * @param nbBits Number of bits to interpret - * @return A signed integer represented by the bits read - */ -int speex_bits_unpack_signed(SpeexBits *bits, int nbBits); - -/** Interpret the next bits in the bit-stream as an unsigned integer - * - * @param bits Bit-stream to operate on - * @param nbBits Number of bits to interpret - * @return An unsigned integer represented by the bits read - */ -unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits); - -/** Returns the number of bytes in the bit-stream, including the last one even if it is not "full" - * - * @param bits Bit-stream to operate on - * @return Number of bytes in the stream - */ -int speex_bits_nbytes(SpeexBits *bits); - -/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */ -unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits); - -/** Get the value of the next bit in the stream, without modifying the - * "cursor" position - * - * @param bits Bit-stream to operate on - */ -int speex_bits_peek(SpeexBits *bits); - -/** Advances the position of the "bit cursor" in the stream - * - * @param bits Bit-stream to operate on - * @param n Number of bits to advance - */ -void speex_bits_advance(SpeexBits *bits, int n); - -/** Returns the number of bits remaining to be read in a stream - * - * @param bits Bit-stream to operate on - */ -int speex_bits_remaining(SpeexBits *bits); - -/** Insert a terminator so that the data can be sent as a packet while auto-detecting - * the number of frames in each packet - * - * @param bits Bit-stream to operate on - */ -void speex_bits_insert_terminator(SpeexBits *bits); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/speex_callbacks.c b/src/add-ons/media/plugins/speex/libspeex/speex_callbacks.c deleted file mode 100644 index 3b4869651f..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex_callbacks.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File speex_callbacks.c - Callback handling and in-band signalling - - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "speex_callbacks.h" -#include "misc.h" - -int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) -{ - int id; - SpeexCallback *callback; - /*speex_bits_advance(bits, 5);*/ - id=speex_bits_unpack_unsigned(bits, 4); - callback = callback_list+id; - - if (callback->func) - { - return callback->func(bits, state, callback->data); - } else - /*If callback is not registered, skip the right number of bits*/ - { - int adv; - if (id<2) - adv = 1; - else if (id<8) - adv = 4; - else if (id<10) - adv = 8; - else if (id<12) - adv = 16; - else if (id<14) - adv = 32; - else - adv = 64; - speex_bits_advance(bits, adv); - } - return 0; -} - -int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) -{ - int m; - m = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_MODE, &m); - return 0; -} - -int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) -{ - int m; - m = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m); - return 0; -} - -int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data) -{ - int m; - m = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m); - return 0; -} - -int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) -{ - int vbr; - vbr = speex_bits_unpack_unsigned(bits, 1); - speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr); - return 0; -} - -int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) -{ - int enh; - enh = speex_bits_unpack_unsigned(bits, 1); - speex_decoder_ctl(data, SPEEX_SET_ENH, &enh); - return 0; -} - -int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) -{ - int qual; - qual = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual); - return 0; -} - - -int speex_std_char_handler(SpeexBits *bits, void *state, void *data) -{ - unsigned char ch; - ch = speex_bits_unpack_unsigned(bits, 8); - _speex_putc(ch, data); - return 0; -} - - - -/* Default handler for user callbacks: skip it */ -int speex_default_user_handler(SpeexBits *bits, void *state, void *data) -{ - int req_size = speex_bits_unpack_unsigned(bits, 4); - speex_bits_advance(bits, 5+8*req_size); - return 0; -} diff --git a/src/add-ons/media/plugins/speex/libspeex/speex_callbacks.h b/src/add-ons/media/plugins/speex/libspeex/speex_callbacks.h deleted file mode 100644 index f6334f22a7..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex_callbacks.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin*/ -/** - @file speex_callbacks.h - @brief Describes callback handling and in-band signalling -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef SPEEX_CALLBACKS_H -#define SPEEX_CALLBACKS_H - -#include "speex.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Total number of callbacks */ -#define SPEEX_MAX_CALLBACKS 16 - -/* Describes all the in-band requests */ - -/*These are 1-bit requests*/ -/** Request for perceptual enhancement (1 for on, 0 for off) */ -#define SPEEX_INBAND_ENH_REQUEST 0 -/** Reserved */ -#define SPEEX_INBAND_RESERVED1 1 - -/*These are 4-bit requests*/ -/** Request for a mode change */ -#define SPEEX_INBAND_MODE_REQUEST 2 -/** Request for a low mode change */ -#define SPEEX_INBAND_LOW_MODE_REQUEST 3 -/** Request for a high mode change */ -#define SPEEX_INBAND_HIGH_MODE_REQUEST 4 -/** Request for VBR (1 on, 0 off) */ -#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5 -/** Request to be sent acknowledge */ -#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6 -/** Request for VBR (1 for on, 0 for off) */ -#define SPEEX_INBAND_VBR_REQUEST 7 - -/*These are 8-bit requests*/ -/** Send a character in-band */ -#define SPEEX_INBAND_CHAR 8 -/** Intensity stereo information */ -#define SPEEX_INBAND_STEREO 9 - -/*These are 16-bit requests*/ -/** Transmit max bit-rate allowed */ -#define SPEEX_INBAND_MAX_BITRATE 10 - -/*These are 32-bit requests*/ -/** Acknowledge packet reception */ -#define SPEEX_INBAND_ACKNOWLEDGE 12 - -/** Callback function type */ -typedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data); - -/** Callback information */ -typedef struct SpeexCallback { - int callback_id; /**< ID associated to the callback */ - speex_callback_func func; /**< Callback handler function */ - void *data; /**< Data that will be sent to the handler */ - void *reserved1; /**< Reserved for future use */ - int reserved2; /**< Reserved for future use */ -} SpeexCallback; - -/** Handle in-band request */ -int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state); - -/** Standard handler for mode request (change mode, no questions asked) */ -int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data); - -/** Standard handler for high mode request (change high mode, no questions asked) */ -int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data); - -/** Standard handler for in-band characters (write to stderr) */ -int speex_std_char_handler(SpeexBits *bits, void *state, void *data); - -/** Default handler for user-defined requests: in this case, just ignore */ -int speex_default_user_handler(SpeexBits *bits, void *state, void *data); - - - - -int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data); - -int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); - -int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); - -int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data); - - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/speex_header.c b/src/add-ons/media/plugins/speex/libspeex/speex_header.c deleted file mode 100644 index 7ee1ef343c..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex_header.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: speex_header.c - Describes the Speex header - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "speex_header.h" -#include "misc.h" -#include "speex.h" - -#ifndef NULL -#define NULL 0 -#endif - -#define ENDIAN_SWITCH(x) {x=le_int(x);} - - -/* -typedef struct SpeexHeader { - char speex_string[8]; - char speex_version[SPEEX_HEADER_VERSION_LENGTH]; - int speex_version_id; - int header_size; - int rate; - int mode; - int mode_bitstream_version; - int nb_channels; - int bitrate; - int frame_size; - int vbr; - int frames_per_packet; - int extra_headers; - int reserved1; - int reserved2; -} SpeexHeader; -*/ - -void speex_init_header(SpeexHeader *header, int rate, int nb_channels, SpeexMode *m) -{ - int i; - char *h="Speex "; - /* - strncpy(header->speex_string, "Speex ", 8); - strncpy(header->speex_version, VERSION, SPEEX_HEADER_VERSION_LENGTH-1); - header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0; - */ - for (i=0;i<8;i++) - header->speex_string[i]=h[i]; - for (i=0;ispeex_version[i]=VERSION[i]; - for (;ispeex_version[i]=0; - - header->speex_version_id = 1; - header->header_size = sizeof(SpeexHeader); - - header->rate = rate; - header->mode = m->modeID; - header->mode_bitstream_version = m->bitstream_version; - if (m->modeID<0) - speex_warning("This mode is meant to be used alone"); - header->nb_channels = nb_channels; - header->bitrate = -1; - speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size); - header->vbr = 0; - - header->frames_per_packet = 0; - header->extra_headers = 0; - header->reserved1 = 0; - header->reserved2 = 0; -} - -char *speex_header_to_packet(SpeexHeader *header, int *size) -{ - SpeexHeader *le_header; - le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); - - speex_move(le_header, header, sizeof(SpeexHeader)); - - /*Make sure everything is now little-endian*/ - ENDIAN_SWITCH(le_header->speex_version_id); - ENDIAN_SWITCH(le_header->header_size); - ENDIAN_SWITCH(le_header->rate); - ENDIAN_SWITCH(le_header->mode); - ENDIAN_SWITCH(le_header->mode_bitstream_version); - ENDIAN_SWITCH(le_header->nb_channels); - ENDIAN_SWITCH(le_header->bitrate); - ENDIAN_SWITCH(le_header->frame_size); - ENDIAN_SWITCH(le_header->vbr); - ENDIAN_SWITCH(le_header->frames_per_packet); - ENDIAN_SWITCH(le_header->extra_headers); - - *size = sizeof(SpeexHeader); - return (char *)le_header; -} - -SpeexHeader *speex_packet_to_header(char *packet, int size) -{ - int i; - SpeexHeader *le_header; - char *h = "Speex "; - for (i=0;i<8;i++) - if (packet[i]!=h[i]) - { - speex_warning ("This doesn't look like a Speex file"); - return NULL; - } - - /*FIXME: Do we allow larger headers?*/ - if (size < sizeof(SpeexHeader)) - { - speex_warning("Speex header too small"); - return NULL; - } - - le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); - - speex_move(le_header, packet, sizeof(SpeexHeader)); - - /*Make sure everything is converted correctly from little-endian*/ - ENDIAN_SWITCH(le_header->speex_version_id); - ENDIAN_SWITCH(le_header->header_size); - ENDIAN_SWITCH(le_header->rate); - ENDIAN_SWITCH(le_header->mode); - ENDIAN_SWITCH(le_header->mode_bitstream_version); - ENDIAN_SWITCH(le_header->nb_channels); - ENDIAN_SWITCH(le_header->bitrate); - ENDIAN_SWITCH(le_header->frame_size); - ENDIAN_SWITCH(le_header->vbr); - ENDIAN_SWITCH(le_header->frames_per_packet); - ENDIAN_SWITCH(le_header->extra_headers); - - return le_header; - -} diff --git a/src/add-ons/media/plugins/speex/libspeex/speex_header.h b/src/add-ons/media/plugins/speex/libspeex/speex_header.h deleted file mode 100644 index 8ded911423..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex_header.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file speex_header.h - @brief Describes the Speex header -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - -#ifndef SPEEX_HEADER_H -#define SPEEX_HEADER_H - -#ifdef __cplusplus -extern "C" { -#endif - -struct SpeexMode; - -/** Maximum number of characters for encoding the Speex version number in the header */ -#define SPEEX_HEADER_VERSION_LENGTH 20 - -/** Speex header info for file-based formats */ -typedef struct SpeexHeader { - char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */ - char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */ - int speex_version_id; /**< Version for Speex (for checking compatibility) */ - int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ - int rate; /**< Sampling rate used */ - int mode; /**< Mode used (0 for narrowband, 1 for wideband) */ - int mode_bitstream_version; /**< Version ID of the bit-stream */ - int nb_channels; /**< Number of channels encoded */ - int bitrate; /**< Bit-rate used */ - int frame_size; /**< Size of frames */ - int vbr; /**< 1 for a VBR encoding, 0 otherwise */ - int frames_per_packet; /**< Number of frames stored per Ogg packet */ - int extra_headers; /**< Number of additional headers after the comments */ - int reserved1; /**< Reserved for future use, must be zero */ - int reserved2; /**< Reserved for future use, must be zero */ -} SpeexHeader; - -/** Initializes a SpeexHeader using basic information */ -void speex_init_header(SpeexHeader *header, int rate, int nb_channels, struct SpeexMode *m); - -/** Creates the header packet from the header itself (mostly involves endianness conversion) */ -char *speex_header_to_packet(SpeexHeader *header, int *size); - -/** Creates a SpeexHeader from a packet */ -SpeexHeader *speex_packet_to_header(char *packet, int size); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/speex_stereo.h b/src/add-ons/media/plugins/speex/libspeex/speex_stereo.h deleted file mode 100644 index 505f4bc641..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/speex_stereo.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin*/ -/** - @file speex_stereo.h - @brief Describes the handling for intensity stereo -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef STEREO_H -#define STEREO_H - -#include "speex_bits.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** State used for decoding (intensity) stereo information */ -typedef struct SpeexStereoState { - float balance; /**< Left/right balance info */ - float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ - float smooth_left; /**< Smoothed left channel gain */ - float smooth_right; /**< Smoothed right channel gain */ - float reserved1; /**< Reserved for future use */ - float reserved2; /**< Reserved for future use */ -} SpeexStereoState; - -/** Initialization value for a stereo state */ -#define SPEEX_STEREO_STATE_INIT {1,.5,1,1} - -/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ -void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); - -/** Transforms a mono frame into a stereo frame using intensity stereo info */ -void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo); - -/** Callback handler for intensity stereo info */ -int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/stack_alloc.h b/src/add-ons/media/plugins/speex/libspeex/stack_alloc.h deleted file mode 100644 index 2390b69dc6..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/stack_alloc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: stack_alloc.h - - Temporary memory allocation on stack - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef STACK_ALLOC_H -#define STACK_ALLOC_H - -#if 0 - -/*Aligns the stack to a 'size' boundary */ -#define ALIGN(stack, size) (stack=(void*)((((int)stack)+((size)-1)) & (-(size)))) -/*Aligns the stack to a 'size' boundary minus k */ -#define ALIGN_1(stack, size, k) (stack=(void*)(((((int)stack)+((size)-1+(k))) & (-(size)))-(k))) - -/* Allocates 'size' elements of type 'type' on the stack */ -#define PUSH(stack, size, type) (ALIGN(stack,sizeof(type)),stack=(void*)(((int)stack)+((size)*sizeof(type))),(type*)(((int)stack)-((size)*sizeof(type)))) - - -#else - -/*Aligns the stack to a 'size' boundary */ -#define ALIGN(stack, size) ((stack) += ((size) - (int)(stack)) & ((size) - 1)) - -/* Allocates 'size' elements of type 'type' on the stack */ -#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) - -/* Allocates a struct stack */ -#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type)))) - - -#endif - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/stereo.c b/src/add-ons/media/plugins/speex/libspeex/stereo.c deleted file mode 100644 index e033ce54a4..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/stereo.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: stereo.c - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "speex_stereo.h" -#include "speex_callbacks.h" -#include "vq.h" -#include - -/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ -static float e_ratio_quant[4] = {.25, .315, .397, .5}; - -void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) -{ - int i, tmp; - float e_left=0, e_right=0, e_tot=0; - float balance, e_ratio; - for (i=0;i0) - speex_bits_pack(bits, 0, 1); - else - speex_bits_pack(bits, 1, 1); - balance=floor(.5+fabs(balance)); - if (balance>30) - balance=31; - - speex_bits_pack(bits, (int)balance, 5); - - /*Quantize energy ratio*/ - tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); - speex_bits_pack(bits, tmp, 2); -} - -void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo) -{ - float balance, e_ratio; - int i; - float e_tot=0, e_left, e_right, e_sum; - - balance=stereo->balance; - e_ratio=stereo->e_ratio; - for (i=frame_size-1;i>=0;i--) - { - e_tot += data[i]*data[i]; - } - e_sum=e_tot/e_ratio; - e_left = e_sum*balance / (1+balance); - e_right = e_sum-e_left; - - e_left = sqrt(e_left/(e_tot+.01)); - e_right = sqrt(e_right/(e_tot+.01)); - - for (i=frame_size-1;i>=0;i--) - { - float ftmp=data[i]; - stereo->smooth_left = .98*stereo->smooth_left + .02*e_left; - stereo->smooth_right = .98*stereo->smooth_right + .02*e_right; - data[2*i] = stereo->smooth_left*ftmp; - data[2*i+1] = stereo->smooth_right*ftmp; - } -} - -int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) -{ - SpeexStereoState *stereo; - float sign=1; - int tmp; - - stereo = (SpeexStereoState*)data; - if (speex_bits_unpack_unsigned(bits, 1)) - sign=-1; - tmp = speex_bits_unpack_unsigned(bits, 5); - stereo->balance = exp(sign*.25*tmp); - - tmp = speex_bits_unpack_unsigned(bits, 2); - stereo->e_ratio = e_ratio_quant[tmp]; - - return 0; -} diff --git a/src/add-ons/media/plugins/speex/libspeex/testenc.c b/src/add-ons/media/plugins/speex/libspeex/testenc.c deleted file mode 100644 index 7033ef4a5b..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/testenc.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "speex.h" -#include -#include -#include "speex_callbacks.h" - -#define FRAME_SIZE 160 -#include -int main(int argc, char **argv) -{ - char *inFile, *outFile, *bitsFile; - FILE *fin, *fout, *fbits=NULL; - short in[FRAME_SIZE]; - float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; - char cbits[200]; - int nbBits; - int i; - void *st; - void *dec; - SpeexBits bits; - int tmp; - int bitCount=0; - SpeexCallback callback; - - for (i=0;i32000) - input[i]=32000; - else if (input[i]<-32000) - input[i]=-32000; - } - speex_bits_reset(&bits); - for (i=0;i -#include - -#define FRAME_SIZE 640 -#include -int main(int argc, char **argv) -{ - char *inFile, *outFile, *bitsFile; - FILE *fin, *fout, *fbits=NULL; - short in[FRAME_SIZE]; - float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; - char cbits[200]; - int nbBits; - int i; - void *st; - void *dec; - SpeexBits bits; - int tmp; - int bitCount=0; - - for (i=0;i32000) - input[i]=32000; - else if (input[i]<-32000) - input[i]=-32000; - } - speex_bits_reset(&bits); - for (i=0;i -#include - -#define FRAME_SIZE 320 -#include -int main(int argc, char **argv) -{ - char *inFile, *outFile, *bitsFile; - FILE *fin, *fout, *fbits=NULL; - short in[FRAME_SIZE]; - float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; - char cbits[200]; - int nbBits; - int i; - void *st; - void *dec; - SpeexBits bits; - int tmp; - int bitCount=0; - - for (i=0;i32000) - input[i]=32000; - else if (input[i]<-32000) - input[i]=-32000; - } - speex_bits_reset(&bits); - for (i=0;i - - -#define sqr(x) ((x)*(x)) - -#define MIN_ENERGY 6000 -#define NOISE_POW .3 - - -float vbr_nb_thresh[9][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* CNG */ - { 3.5, 2.5, 2.0, 1.2, 0.5, 0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /* 2 kbps */ - {10.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 kbps */ - {11.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 kbps */ - {11.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 kbps */ - {11.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 kbps */ - { 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 kbps */ -}; - - -float vbr_hb_thresh[5][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* 2 kbps */ - {11.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 kbps */ -}; - -float vbr_uhb_thresh[2][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ - { 3.9, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0} /* 2 kbps */ -}; - -void vbr_init(VBRState *vbr) -{ - int i; - - vbr->average_energy=0; - vbr->last_energy=1; - vbr->accum_sum=0; - vbr->energy_alpha=.1; - vbr->soft_pitch=0; - vbr->last_pitch_coef=0; - vbr->last_quality=0; - - vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW); - vbr->noise_accum_count=.05; - vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; - vbr->consec_noise=0; - - - for (i=0;ilast_log_energy[i] = log(MIN_ENERGY); -} - - -/* - This function should analyse the signal and decide how critical the - coding error will be perceptually. The following factors should be - taken into account: - - -Attacks (positive energy derivative) should be coded with more bits - - -Stationary voiced segments should receive more bits - - -Segments with (very) low absolute energy should receive less bits (maybe - only shaped noise?) - - -DTX for near-zero energy? - - -Stationary fricative segments should have less bits - - -Temporal masking: when energy slope is decreasing, decrease the bit-rate - - -Decrease bit-rate for males (low pitch)? - - -(wideband only) less bits in the high-band when signal is very - non-stationary (harder to notice high-frequency noise)??? - -*/ - -float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef) -{ - int i; - float ener=0, ener1=0, ener2=0; - float qual=7; - int va; - float log_energy; - float non_st=0; - float voicing; - float pow_ener; - - for (i=0;i>1;i++) - ener1 += sig[i]*sig[i]; - - for (i=len>>1;ilast_log_energy[i]); - non_st = non_st/(30*VBR_MEMORY_SIZE); - if (non_st>1) - non_st=1; - - voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4); - vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener; - vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; - pow_ener = pow(ener,NOISE_POW); - if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY) - vbr->noise_accum = .05*pow_ener; - - if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level) - || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level) - || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level) - || (voicing<0 && non_st < .05)) - { - float tmp; - va = 0; - vbr->consec_noise++; - if (pow_ener > 3*vbr->noise_level) - tmp = 3*vbr->noise_level; - else - tmp = pow_ener; - if (vbr->consec_noise>=4) - { - vbr->noise_accum = .95*vbr->noise_accum + .05*tmp; - vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; - } - } else { - va = 1; - vbr->consec_noise=0; - } - - if (pow_ener < vbr->noise_level && ener>MIN_ENERGY) - { - vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener; - vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; - } - - /* Checking for very low absolute energy */ - if (ener < 30000) - { - qual -= .7; - if (ener < 10000) - qual-=.7; - if (ener < 3000) - qual-=.7; - } else { - float short_diff, long_diff; - short_diff = log((ener+1)/(1+vbr->last_energy)); - long_diff = log((ener+1)/(1+vbr->average_energy)); - /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/ - - if (long_diff<-5) - long_diff=-5; - if (long_diff>2) - long_diff=2; - - if (long_diff>0) - qual += .6*long_diff; - if (long_diff<0) - qual += .5*long_diff; - if (short_diff>0) - { - if (short_diff>5) - short_diff=5; - qual += .5*short_diff; - } - /* Checking for energy increases */ - if (ener2 > 1.6*ener1) - qual += .5; - } - vbr->last_energy = ener; - vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef; - qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4)); - - if (qual < vbr->last_quality) - qual = .5*qual + .5*vbr->last_quality; - if (qual<4) - qual=4; - if (qual>10) - qual=10; - - /* - if (vbr->consec_noise>=2) - qual-=1.3; - if (vbr->consec_noise>=5) - qual-=1.3; - if (vbr->consec_noise>=12) - qual-=1.3; - */ - if (vbr->consec_noise>=3) - qual=4; - - if (vbr->consec_noise) - qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3)); - if (qual<0) - qual=0; - - if (ener<60000) - { - if (vbr->consec_noise>2) - qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); - if (ener<10000&&vbr->consec_noise>2) - qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); - if (qual<0) - qual=0; - qual += .3*log(ener/60000.0); - } - if (qual<-1) - qual=-1; - - /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/ - - vbr->last_pitch_coef = pitch_coef; - vbr->last_quality = qual; - - for (i=VBR_MEMORY_SIZE-1;i>0;i--) - vbr->last_log_energy[i] = vbr->last_log_energy[i-1]; - vbr->last_log_energy[0] = log_energy; - - /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/ - - return qual; -} - -void vbr_destroy(VBRState *vbr) -{ -} diff --git a/src/add-ons/media/plugins/speex/libspeex/vbr.h b/src/add-ons/media/plugins/speex/libspeex/vbr.h deleted file mode 100644 index 405b47f64c..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/vbr.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: vbr.h - - VBR-related routines - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - -#ifndef VBR_H -#define VBR_H - -#define VBR_MEMORY_SIZE 5 - -extern float vbr_nb_thresh[9][11]; -extern float vbr_hb_thresh[5][11]; -extern float vbr_uhb_thresh[2][11]; - -typedef struct VBRState { - float energy_alpha; - float average_energy; - float last_energy; - float last_log_energy[VBR_MEMORY_SIZE]; - float accum_sum; - float last_pitch_coef; - float soft_pitch; - float last_quality; - float noise_level; - float noise_accum; - float noise_accum_count; - int consec_noise; -} VBRState; - -void vbr_init(VBRState *vbr); - -float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef); - -void vbr_destroy(VBRState *vbr); - -#endif diff --git a/src/add-ons/media/plugins/speex/libspeex/vq.c b/src/add-ons/media/plugins/speex/libspeex/vq.c deleted file mode 100644 index ed36f7d27f..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/vq.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: vq.c - Vector quantization - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "vq.h" - -/*Finds the index of the entry in a codebook that best matches the input*/ -int vq_index(float *in, float *codebook, int len, int entries) -{ - int i,j; - float min_dist=0; - int best_index=0; - for (i=0;i= 1) && (k > used || dist < best_dist[k-1]); k--) - { - best_dist[k]=best_dist[k-1]; - nbest[k] = nbest[k-1]; - } - best_dist[k]=dist; - nbest[k]=i; - used++; - } - } -} - -/*Finds the indices of the n-best entries in a codebook with sign*/ -void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist) -{ - int i,j,k, sign, used; - used=0; - for (i=0;i0) - { - sign=1; - dist=-dist; - } else - { - sign=0; - } - dist += .5*E[i]; - if (i= 1) && (k > used || dist < best_dist[k-1]); k--) - { - best_dist[k]=best_dist[k-1]; - nbest[k] = nbest[k-1]; - } - best_dist[k]=dist; - nbest[k]=i; - used++; - if (sign) - nbest[k]+=entries; - } - } -} diff --git a/src/add-ons/media/plugins/speex/libspeex/vq.h b/src/add-ons/media/plugins/speex/libspeex/vq.h deleted file mode 100644 index e82ba6c0ab..0000000000 --- a/src/add-ons/media/plugins/speex/libspeex/vq.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: vq.h - Vector quantization - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef VQ_H -#define VQ_H - -int vq_index(float *in, float *codebook, int len, int entries); - -void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist); - -void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist); - -#endif diff --git a/src/add-ons/media/plugins/speex/speexCodecDefaults.cpp b/src/add-ons/media/plugins/speex/speexCodecDefaults.cpp deleted file mode 100644 index 5897a43625..0000000000 --- a/src/add-ons/media/plugins/speex/speexCodecDefaults.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "speexCodecDefaults.h" - -bool SpeexSettings::perceptual_post_filter = true; -speex_mode SpeexSettings::preferred_band = automatic_band; -speex_channels SpeexSettings::preferred_channels = automatic_channels; -int SpeexSettings::sampling_rate = 0; - -SpeexSettings::SpeexSettings() -{ -} - -/* static */ bool -SpeexSettings::PerceptualPostFilter(void) -{ - return perceptual_post_filter; -} - -/* static */ speex_mode -SpeexSettings::PreferredBand(void) -{ - return preferred_band; -} - -/* static */ speex_channels -SpeexSettings::PreferredChannels(void) -{ - return preferred_channels; -} - -// if non-zero, specifies a sampling rate in Hertz -/* static */ int -SpeexSettings::SamplingRate(void) -{ - return sampling_rate; -} diff --git a/src/add-ons/media/plugins/speex/speexCodecDefaults.h b/src/add-ons/media/plugins/speex/speexCodecDefaults.h deleted file mode 100644 index d714b7bf96..0000000000 --- a/src/add-ons/media/plugins/speex/speexCodecDefaults.h +++ /dev/null @@ -1,30 +0,0 @@ - -enum speex_mode { - automatic_band = -1, - narrow_band, - wide_band, - ultra_wide_band, -}; - -enum speex_channels { - automatic_channels = -1, - mono_channels, - stereo_channels, -}; - -class SpeexSettings { -private: - SpeexSettings(); -public: - static bool PerceptualPostFilter(void); - static speex_mode PreferredBand(void); - static speex_channels PreferredChannels(void); - // if non-zero, specifies a sampling rate in Hertz - static int SamplingRate(void); - -private: - static bool perceptual_post_filter; - static speex_mode preferred_band; - static speex_channels preferred_channels; - static int sampling_rate; -}; diff --git a/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp b/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp deleted file mode 100644 index 9083771829..0000000000 --- a/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "ogg/ogg.h" -#include "speexCodecPlugin.h" -#include "speexCodecDefaults.h" -#include "OggSpeexFormats.h" - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) -#endif - -#define DECODE_BUFFER_SIZE (32 * 1024) - - -inline void -AdjustBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - size_t frame_size = (raf->format & 0xf) * raf->channel_count; - if (raf->buffer_size <= frame_size) { - raf->buffer_size = frame_size * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); - } else { - raf->buffer_size = (raf->buffer_size / frame_size) * frame_size; - } -} - - -static media_format -speex_decoded_media_format() -{ - media_format format; - format.type = B_MEDIA_RAW_AUDIO; - init_speex_media_raw_audio_format(&format.u.raw_audio); - return format; -} - - -/* - * SpeexDecoder - */ - - -SpeexDecoder::SpeexDecoder() -{ - TRACE("SpeexDecoder::SpeexDecoder\n"); - speex_bits_init(&fBits); - fDecoderState = 0; - fHeader = 0; - fStereoState = 0; - fSpeexOutputLength = 0; - fStartTime = 0; - fFrameSize = 0; - fOutputBufferSize = 0; -} - - -SpeexDecoder::~SpeexDecoder() -{ - TRACE("SpeexDecoder::~SpeexDecoder\n"); - // the fStereoState is destroyed by fDecoderState -// delete fStereoState; - speex_bits_destroy(&fBits); - speex_decoder_destroy(fDecoderState); -} - - -void -SpeexDecoder::GetCodecInfo(media_codec_info *info) -{ - strncpy(info->short_name, "speex-libspeex", sizeof(info->short_name)); - strncpy(info->pretty_name, "speex decoder [libspeex], by Andrew Bachmann", sizeof(info->pretty_name)); -} - - -status_t -SpeexDecoder::Setup(media_format *inputFormat, - const void *infoBuffer, size_t infoSize) -{ - TRACE("SpeexDecoder::Setup\n"); - if (!format_is_compatible(speex_encoded_media_format(),*inputFormat)) { - return B_MEDIA_BAD_FORMAT; - } - // grab header packets from meta data - if (inputFormat->MetaDataSize() != sizeof(std::vector)) { - TRACE("SpeexDecoder::Setup not called with ogg_packet meta data: not speex\n"); - return B_ERROR; - } - std::vector * packets = (std::vector *)inputFormat->MetaData(); - if (packets->size() < 2) { - TRACE("SpeexDecoder::Setup not called with at least two ogg_packets: not speex\n"); - return B_ERROR; - } - // parse header packet - ogg_packet * packet = &(*packets)[0]; - fHeader = speex_packet_to_header((char*)packet->packet, packet->bytes); - if (fHeader == NULL) { - TRACE("SpeexDecoder::Setup failed in ogg_packet to speex_header conversion\n"); - return B_ERROR; - } - if (packets->size() != 2 + (unsigned)fHeader->extra_headers) { - TRACE("SpeexDecoder::Setup not called with all the extra headers\n"); - delete fHeader; - fHeader = 0; - return B_ERROR; - } - // modify header to reflect settings - switch (SpeexSettings::PreferredBand()) { - case narrow_band: - fHeader->mode = 0; - break; - case wide_band: - fHeader->mode = 1; - break; - case ultra_wide_band: - fHeader->mode = 2; - break; - case automatic_band: - default: - break; - } - switch (SpeexSettings::PreferredChannels()) { - case mono_channels: - fHeader->nb_channels = 1; - break; - case stereo_channels: - fHeader->nb_channels = 2; - break; - case automatic_channels: - default: - break; - } - if (fHeader->nb_channels == 0) { - fHeader->nb_channels = 1; - } - if (fHeader->frames_per_packet == 0) { - fHeader->frames_per_packet = 1; - } - if (SpeexSettings::SamplingRate() != 0) { - fHeader->rate = SpeexSettings::SamplingRate(); - } - // sanity checks -#ifdef STRICT_SPEEX - if (header->speex_version_id > 1) { - TRACE("SpeexDecoder::Setup failed: version id too new"); - return B_ERROR; - } -#endif - if (fHeader->mode >= SPEEX_NB_MODES) { - TRACE("SpeexDecoder::Setup failed: unknown speex mode\n"); - return B_ERROR; - } - // setup from header - SpeexMode * mode = speex_mode_list[fHeader->mode]; -#ifdef STRICT_SPEEX - if (mode->bitstream_version != fHeader->mode_bitstream_version) { - TRACE("SpeexDecoder::Setup failed: bitstream version mismatch"); - return B_ERROR; - } -#endif - // initialize decoder - fDecoderState = speex_decoder_init(mode); - if (fDecoderState == NULL) { - TRACE("SpeexDecoder::Setup failed to initialize the decoder state"); - return B_ERROR; - } - if (SpeexSettings::PerceptualPostFilter()) { - int enabled = 1; - speex_decoder_ctl(fDecoderState, SPEEX_SET_ENH, &enabled); - } - speex_decoder_ctl(fDecoderState, SPEEX_GET_FRAME_SIZE, &fHeader->frame_size); - if (fHeader->nb_channels == 2) { - SpeexCallback callback; - SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; - callback.callback_id = SPEEX_INBAND_STEREO; - callback.func = speex_std_stereo_request_handler; - fStereoState = new SpeexStereoState(stereo); - callback.data = fStereoState; - speex_decoder_ctl(fDecoderState, SPEEX_SET_HANDLER, &callback); - } - speex_decoder_ctl(fDecoderState, SPEEX_SET_SAMPLING_RATE, &fHeader->rate); - // fill out the encoding format - media_format requested_format = speex_decoded_media_format(); - ((media_raw_audio_format)requested_format.u.raw_audio) = inputFormat->u.encoded_audio.output; - return NegotiateOutputFormat(&requested_format); -} - - -status_t -SpeexDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat) -{ - TRACE("SpeexDecoder::NegotiateOutputFormat\n"); - // BMediaTrack::DecodedFormat - // Pass in ioFormat the format that you want (with wildcards - // as applicable). The codec will find and return in ioFormat - // its best matching format. - // - // BMediaDecoder::SetOutputFormat - // sets the format the decoder should output. On return, - // the outputFormat is changed to match the actual format - // that will be output; this can be different if you - // specified any wildcards. - // - // Be R5 behavior seems to be that we can never fail. If we - // don't support the requested format, just return one we do. - media_format format = speex_decoded_media_format(); - format.u.raw_audio.frame_rate = (float)fHeader->rate; - format.u.raw_audio.channel_count = fHeader->nb_channels; - format.u.raw_audio.channel_mask = B_CHANNEL_LEFT | (fHeader->nb_channels != 1 ? B_CHANNEL_RIGHT : 0); - if (!format_is_compatible(format,*ioDecodedFormat)) { - *ioDecodedFormat = format; - } - ioDecodedFormat->SpecializeTo(&format); - AdjustBufferSize(&ioDecodedFormat->u.raw_audio); - int output_length = fHeader->frame_size * format.AudioFrameSize(); - ioDecodedFormat->u.raw_audio.buffer_size - = ((ioDecodedFormat->u.raw_audio.buffer_size - 1) / output_length + 1) * output_length; - // setup output variables - fFrameSize = ioDecodedFormat->AudioFrameSize(); - fOutputBufferSize = ioDecodedFormat->u.raw_audio.buffer_size; - fSpeexOutputLength = output_length; - return B_OK; -} - - -status_t -SpeexDecoder::Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time) -{ - TRACE("SpeexDecoder::Seek\n"); - int ignore = 0; - speex_decoder_ctl(fDecoderState, SPEEX_RESET_STATE, &ignore); - return B_OK; -} - - -status_t -SpeexDecoder::Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info /* = 0 */) -{ -// TRACE("SpeexDecoder::Decode\n"); - float * out_buffer = static_cast(buffer); - int32 out_bytes_needed = fOutputBufferSize; - - bool synced = false; - - int total_samples = 0; - while (out_bytes_needed >= fSpeexOutputLength) { - // get a new packet - const void *chunkBuffer; - size_t chunkSize; - media_header mh; - status_t status = GetNextChunk(&chunkBuffer, &chunkSize, &mh); - if (status == B_LAST_BUFFER_ERROR) { - goto done; - } - if (status != B_OK) { - TRACE("SpeexDecoder::Decode: GetNextChunk failed\n"); - return status; - } - if (!synced) { - if (mh.start_time > 0) { - mediaHeader->start_time = mh.start_time - (1000000LL * total_samples) / fHeader->rate; - synced = true; - } - } - speex_bits_read_from(&fBits, (char*)chunkBuffer, chunkSize); - for (int frame = 0 ; frame < fHeader->frames_per_packet ; frame++) { - int ret = speex_decode(fDecoderState, &fBits, out_buffer); - if (ret == -1) { - break; - } - if (ret == -2) { - TRACE("SpeexDecoder::Decode: corrupted stream?\n"); - break; - } - if (speex_bits_remaining(&fBits) < 0) { - TRACE("SpeexDecoder::Decode: decoding overflow: corrupted stream?\n"); - break; - } - if (fHeader->nb_channels == 2) { - speex_decode_stereo(out_buffer, fHeader->frame_size, fStereoState); - } - for (int i = 0 ; i < fHeader->frame_size * fHeader->nb_channels ; i++) { - out_buffer[i] /= 32000.0; - } - out_buffer += fHeader->frame_size * fHeader->nb_channels; - out_bytes_needed -= fSpeexOutputLength; - total_samples += fHeader->frame_size; - } - } - -done: - if (!synced) { - mediaHeader->start_time = fStartTime; - } - fStartTime = mediaHeader->start_time + (1000000LL * total_samples) / fHeader->rate; - - *frameCount = (fOutputBufferSize - out_bytes_needed) / fFrameSize; - - if (out_buffer != buffer) { - return B_OK; - } - return B_LAST_BUFFER_ERROR; -} - - -/* - * SpeexDecoderPlugin - */ - - -Decoder * -SpeexDecoderPlugin::NewDecoder(uint index) -{ - return new SpeexDecoder; -} - - -static media_format speex_formats[1]; - -status_t -SpeexDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count) -{ - media_format_description description = speex_description(); - media_format format = speex_encoded_media_format(); - - BMediaFormats mediaFormats; - status_t result = mediaFormats.InitCheck(); - if (result != B_OK) { - return result; - } - result = mediaFormats.MakeFormatFor(&description, 1, &format); - if (result != B_OK) { - return result; - } - speex_formats[0] = format; - - *formats = speex_formats; - *count = 1; - - return result; -} - - -/* - * instantiate_plugin - */ - - -MediaPlugin *instantiate_plugin() -{ - return new SpeexDecoderPlugin; -} diff --git a/src/add-ons/media/plugins/speex/speexCodecPlugin.h b/src/add-ons/media/plugins/speex/speexCodecPlugin.h deleted file mode 100644 index 289babb5c5..0000000000 --- a/src/add-ons/media/plugins/speex/speexCodecPlugin.h +++ /dev/null @@ -1,46 +0,0 @@ -#include "DecoderPlugin.h" -#include "speex.h" -#include "speex_header.h" -#include "speex_stereo.h" -#include "speex_callbacks.h" - -class SpeexDecoder : public Decoder -{ -public: - SpeexDecoder(); - ~SpeexDecoder(); - - void GetCodecInfo(media_codec_info *info); - status_t Setup(media_format *inputFormat, - const void *infoBuffer, size_t infoSize); - - status_t NegotiateOutputFormat(media_format *ioDecodedFormat); - - status_t Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time); - - - status_t Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info); - -private: - SpeexBits fBits; - void * fDecoderState; - SpeexHeader * fHeader; - SpeexStereoState * fStereoState; - - int fSpeexOutputLength; - - bigtime_t fStartTime; - int fFrameSize; - int fOutputBufferSize; -}; - - -class SpeexDecoderPlugin : public DecoderPlugin -{ -public: - Decoder * NewDecoder(uint index); - status_t GetSupportedFormats(media_format ** formats, size_t * count); -}; diff --git a/src/add-ons/media/plugins/theora/Jamfile b/src/add-ons/media/plugins/theora/Jamfile deleted file mode 100644 index 8029b95ca2..0000000000 --- a/src/add-ons/media/plugins/theora/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins theora ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -UsePrivateHeaders media shared ; - -SubDirSysHdrs $(SUBDIR) libtheora ; -SubDirHdrs $(SUBDIR) .. ogg ; -SubDirSysHdrs $(SUBDIR) .. ogg libogg ; - -Addon theora : - theoraCodecPlugin.cpp - : libtheora.a libogg.a be libmedia.so $(TARGET_LIBSUPC++) -; - -SubInclude HAIKU_TOP src add-ons media plugins theora libtheora ; diff --git a/src/add-ons/media/plugins/theora/libtheora/Jamfile b/src/add-ons/media/plugins/theora/libtheora/Jamfile deleted file mode 100644 index 96378a8b7c..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/Jamfile +++ /dev/null @@ -1,38 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins theora libtheora ; - -SubDirSysHdrs $(SUBDIR) ; -SubDirHdrs $(SUBDIR) .. .. ogg ; -SubDirSysHdrs $(SUBDIR) .. .. ogg libogg ; - -SubDirCcFlags -DPACKAGE=\\\"libtheora\\\" -DVERSION=\\\"1.1.0\\\" ; -SubDirCcFlags -D_REENTRANT -DPIC -DTRUE=true ; - -local arch_sources ; -if $(TARGET_ARCH) = x86 { - arch_sources = - mmxidct.c - mmxfrag.c - mmxstate.c - x86state.c - ; - - SEARCH_SOURCE += [ FDirName $(SUBDIR) x86 ] ; -} - -StaticLibrary libtheora.a : - apiwrapper.c - bitpack.c - decapiwrapper.c - decinfo.c - decode.c - dequant.c - fragment.c - huffdec.c - idct.c - info.c - internal.c - quant.c - state.c - - $(arch_sources) -; diff --git a/src/add-ons/media/plugins/theora/libtheora/analyze.c b/src/add-ons/media/plugins/theora/libtheora/analyze.c deleted file mode 100644 index af01b60dff..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/analyze.c +++ /dev/null @@ -1,2709 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: mode selection code - last mod: $Id$ - - ********************************************************************/ -#include -#include -#include "encint.h" -#include "modedec.h" - - - -typedef struct oc_fr_state oc_fr_state; -typedef struct oc_qii_state oc_qii_state; -typedef struct oc_enc_pipeline_state oc_enc_pipeline_state; -typedef struct oc_rd_metric oc_rd_metric; -typedef struct oc_mode_choice oc_mode_choice; - - - -/*There are 8 possible schemes used to encode macro block modes. - Schemes 0-6 use a maximally-skewed Huffman code to code each of the modes. - The same set of Huffman codes is used for each of these 7 schemes, but the - mode assigned to each codeword varies. - Scheme 0 writes a custom mapping from codeword to MB mode to the bitstream, - while schemes 1-6 have a fixed mapping. - Scheme 7 just encodes each mode directly in 3 bits.*/ - -/*The mode orderings for the various mode coding schemes. - Scheme 0 uses a custom alphabet, which is not stored in this table. - This is the inverse of the equivalent table OC_MODE_ALPHABETS in the - decoder.*/ -static const unsigned char OC_MODE_RANKS[7][OC_NMODES]={ - /*Last MV dominates.*/ - /*L P M N I G GM 4*/ - {3,4,2,0,1,5,6,7}, - /*L P N M I G GM 4*/ - {2,4,3,0,1,5,6,7}, - /*L M P N I G GM 4*/ - {3,4,1,0,2,5,6,7}, - /*L M N P I G GM 4*/ - {2,4,1,0,3,5,6,7}, - /*No MV dominates.*/ - /*N L P M I G GM 4*/ - {0,4,3,1,2,5,6,7}, - /*N G L P M I GM 4*/ - {0,5,4,2,3,1,6,7}, - /*Default ordering.*/ - /*N I M L P G GM 4*/ - {0,1,2,3,4,5,6,7} -}; - - - -/*Initialize the mode scheme chooser. - This need only be called once per encoder.*/ -void oc_mode_scheme_chooser_init(oc_mode_scheme_chooser *_chooser){ - int si; - _chooser->mode_ranks[0]=_chooser->scheme0_ranks; - for(si=1;si<8;si++)_chooser->mode_ranks[si]=OC_MODE_RANKS[si-1]; -} - -/*Reset the mode scheme chooser. - This needs to be called once for each frame, including the first.*/ -static void oc_mode_scheme_chooser_reset(oc_mode_scheme_chooser *_chooser){ - int si; - memset(_chooser->mode_counts,0,OC_NMODES*sizeof(*_chooser->mode_counts)); - /*Scheme 0 starts with 24 bits to store the mode list in.*/ - _chooser->scheme_bits[0]=24; - memset(_chooser->scheme_bits+1,0,7*sizeof(*_chooser->scheme_bits)); - for(si=0;si<8;si++){ - /*Scheme 7 should always start first, and scheme 0 should always start - last.*/ - _chooser->scheme_list[si]=7-si; - _chooser->scheme0_list[si]=_chooser->scheme0_ranks[si]=si; - } -} - - -/*This is the real purpose of this data structure: not actually selecting a - mode scheme, but estimating the cost of coding a given mode given all the - modes selected so far. - This is done via opportunity cost: the cost is defined as the number of bits - required to encode all the modes selected so far including the current one - using the best possible scheme, minus the number of bits required to encode - all the modes selected so far not including the current one using the best - possible scheme. - The computational expense of doing this probably makes it overkill. - Just be happy we take a greedy approach instead of trying to solve the - global mode-selection problem (which is NP-hard). - _mb_mode: The mode to determine the cost of. - Return: The number of bits required to code this mode.*/ -static int oc_mode_scheme_chooser_cost(oc_mode_scheme_chooser *_chooser, - int _mb_mode){ - int scheme0; - int scheme1; - int best_bits; - int mode_bits; - int si; - int scheme_bits; - scheme0=_chooser->scheme_list[0]; - scheme1=_chooser->scheme_list[1]; - best_bits=_chooser->scheme_bits[scheme0]; - mode_bits=OC_MODE_BITS[scheme0+1>>3][_chooser->mode_ranks[scheme0][_mb_mode]]; - /*Typical case: If the difference between the best scheme and the next best - is greater than 6 bits, then adding just one mode cannot change which - scheme we use.*/ - if(_chooser->scheme_bits[scheme1]-best_bits>6)return mode_bits; - /*Otherwise, check to see if adding this mode selects a different scheme as - the best.*/ - si=1; - best_bits+=mode_bits; - do{ - /*For any scheme except 0, we can just use the bit cost of the mode's rank - in that scheme.*/ - if(scheme1!=0){ - scheme_bits=_chooser->scheme_bits[scheme1]+ - OC_MODE_BITS[scheme1+1>>3][_chooser->mode_ranks[scheme1][_mb_mode]]; - } - else{ - int ri; - /*For scheme 0, incrementing the mode count could potentially change the - mode's rank. - Find the index where the mode would be moved to in the optimal list, - and use its bit cost instead of the one for the mode's current - position in the list.*/ - /*We don't recompute scheme bits; this is computing opportunity cost, not - an update.*/ - for(ri=_chooser->scheme0_ranks[_mb_mode];ri>0&& - _chooser->mode_counts[_mb_mode]>= - _chooser->mode_counts[_chooser->scheme0_list[ri-1]];ri--); - scheme_bits=_chooser->scheme_bits[0]+OC_MODE_BITS[0][ri]; - } - if(scheme_bits=8)break; - scheme1=_chooser->scheme_list[si]; - } - while(_chooser->scheme_bits[scheme1]-_chooser->scheme_bits[scheme0]<=6); - return best_bits-_chooser->scheme_bits[scheme0]; -} - -/*Incrementally update the mode counts and per-scheme bit counts and re-order - the scheme lists once a mode has been selected. - _mb_mode: The mode that was chosen.*/ -static void oc_mode_scheme_chooser_update(oc_mode_scheme_chooser *_chooser, - int _mb_mode){ - int ri; - int si; - _chooser->mode_counts[_mb_mode]++; - /*Re-order the scheme0 mode list if necessary.*/ - for(ri=_chooser->scheme0_ranks[_mb_mode];ri>0;ri--){ - int pmode; - pmode=_chooser->scheme0_list[ri-1]; - if(_chooser->mode_counts[pmode]>=_chooser->mode_counts[_mb_mode])break; - /*Reorder the mode ranking.*/ - _chooser->scheme0_ranks[pmode]++; - _chooser->scheme0_list[ri]=pmode; - } - _chooser->scheme0_ranks[_mb_mode]=ri; - _chooser->scheme0_list[ri]=_mb_mode; - /*Now add the bit cost for the mode to each scheme.*/ - for(si=0;si<8;si++){ - _chooser->scheme_bits[si]+= - OC_MODE_BITS[si+1>>3][_chooser->mode_ranks[si][_mb_mode]]; - } - /*Finally, re-order the list of schemes.*/ - for(si=1;si<8;si++){ - int sj; - int scheme0; - int bits0; - sj=si; - scheme0=_chooser->scheme_list[si]; - bits0=_chooser->scheme_bits[scheme0]; - do{ - int scheme1; - scheme1=_chooser->scheme_list[sj-1]; - if(bits0>=_chooser->scheme_bits[scheme1])break; - _chooser->scheme_list[sj]=scheme1; - } - while(--sj>0); - _chooser->scheme_list[sj]=scheme0; - } -} - - - -/*The number of bits required to encode a super block run. - _run_count: The desired run count; must be positive and less than 4130.*/ -static int oc_sb_run_bits(int _run_count){ - int i; - for(i=0;_run_count>=OC_SB_RUN_VAL_MIN[i+1];i++); - return OC_SB_RUN_CODE_NBITS[i]; -} - -/*The number of bits required to encode a block run. - _run_count: The desired run count; must be positive and less than 30.*/ -static int oc_block_run_bits(int _run_count){ - return OC_BLOCK_RUN_CODE_NBITS[_run_count-1]; -} - - - -/*State to track coded block flags and their bit cost.*/ -struct oc_fr_state{ - ptrdiff_t bits; - unsigned sb_partial_count:16; - unsigned sb_full_count:16; - unsigned b_coded_count_prev:8; - unsigned b_coded_count:8; - unsigned b_count:8; - signed int sb_partial:2; - signed int sb_full:2; - signed int b_coded_prev:2; - signed int b_coded:2; -}; - - - -static void oc_fr_state_init(oc_fr_state *_fr){ - _fr->bits=0; - _fr->sb_partial_count=0; - _fr->sb_full_count=0; - _fr->b_coded_count_prev=0; - _fr->b_coded_count=0; - _fr->b_count=0; - _fr->sb_partial=-1; - _fr->sb_full=-1; - _fr->b_coded_prev=-1; - _fr->b_coded=-1; -} - - -static void oc_fr_state_advance_sb(oc_fr_state *_fr, - int _sb_partial,int _sb_full){ - ptrdiff_t bits; - int sb_partial_count; - int sb_full_count; - bits=_fr->bits; - /*Extend the sb_partial run, or start a new one.*/ - sb_partial_count=_fr->sb_partial; - if(_fr->sb_partial==_sb_partial){ - if(sb_partial_count>=4129){ - bits++; - sb_partial_count=0; - } - else bits-=oc_sb_run_bits(sb_partial_count); - } - else sb_partial_count=0; - sb_partial_count++; - bits+=oc_sb_run_bits(sb_partial_count); - if(!_sb_partial){ - /*Extend the sb_full run, or start a new one.*/ - sb_full_count=_fr->sb_full_count; - if(_fr->sb_full==_sb_full){ - if(sb_full_count>=4129){ - bits++; - sb_full_count=0; - } - else bits-=oc_sb_run_bits(sb_full_count); - } - else sb_full_count=0; - sb_full_count++; - bits+=oc_sb_run_bits(sb_full_count); - _fr->sb_full=_sb_full; - _fr->sb_full_count=sb_full_count; - } - _fr->bits=bits; - _fr->sb_partial=_sb_partial; - _fr->sb_partial_count=sb_partial_count; -} - -/*Flush any outstanding block flags for a SB (e.g., one with fewer than 16 - blocks).*/ -static void oc_fr_state_flush_sb(oc_fr_state *_fr){ - ptrdiff_t bits; - int sb_partial; - int sb_full=sb_full; - int b_coded_count; - int b_coded; - int b_count; - b_count=_fr->b_count; - if(b_count>0){ - bits=_fr->bits; - b_coded=_fr->b_coded; - b_coded_count=_fr->b_coded_count; - if(b_coded_count>=b_count){ - /*This SB was fully coded/uncoded; roll back the partial block flags.*/ - bits-=oc_block_run_bits(b_coded_count); - if(b_coded_count>b_count)bits+=oc_block_run_bits(b_coded_count-b_count); - sb_partial=0; - sb_full=b_coded; - b_coded=_fr->b_coded_prev; - b_coded_count=_fr->b_coded_count_prev; - } - else{ - /*It was partially coded.*/ - sb_partial=1; - /*sb_full is unused.*/ - } - _fr->bits=bits; - _fr->b_coded_count=b_coded_count; - _fr->b_coded_count_prev=b_coded_count; - _fr->b_count=0; - _fr->b_coded=b_coded; - _fr->b_coded_prev=b_coded; - oc_fr_state_advance_sb(_fr,sb_partial,sb_full); - } -} - -static void oc_fr_state_advance_block(oc_fr_state *_fr,int _b_coded){ - ptrdiff_t bits; - int b_coded_count; - int b_count; - int sb_partial; - int sb_full=sb_full; - bits=_fr->bits; - /*Extend the b_coded run, or start a new one.*/ - b_coded_count=_fr->b_coded_count; - if(_fr->b_coded==_b_coded)bits-=oc_block_run_bits(b_coded_count); - else b_coded_count=0; - b_coded_count++; - b_count=_fr->b_count+1; - if(b_count>=16){ - /*We finished a superblock.*/ - if(b_coded_count>=16){ - /*It was fully coded/uncoded; roll back the partial block flags.*/ - if(b_coded_count>16)bits+=oc_block_run_bits(b_coded_count-16); - sb_partial=0; - sb_full=_b_coded; - _b_coded=_fr->b_coded_prev; - b_coded_count=_fr->b_coded_count_prev; - } - else{ - bits+=oc_block_run_bits(b_coded_count); - /*It was partially coded.*/ - sb_partial=1; - /*sb_full is unused.*/ - } - _fr->bits=bits; - _fr->b_coded_count=b_coded_count; - _fr->b_coded_count_prev=b_coded_count; - _fr->b_count=0; - _fr->b_coded=_b_coded; - _fr->b_coded_prev=_b_coded; - oc_fr_state_advance_sb(_fr,sb_partial,sb_full); - } - else{ - bits+=oc_block_run_bits(b_coded_count); - _fr->bits=bits; - _fr->b_coded_count=b_coded_count; - _fr->b_count=b_count; - _fr->b_coded=_b_coded; - } -} - -static void oc_fr_skip_block(oc_fr_state *_fr){ - oc_fr_state_advance_block(_fr,0); -} - -static void oc_fr_code_block(oc_fr_state *_fr){ - oc_fr_state_advance_block(_fr,1); -} - -static int oc_fr_cost1(const oc_fr_state *_fr){ - oc_fr_state tmp; - ptrdiff_t bits; - *&tmp=*_fr; - oc_fr_skip_block(&tmp); - bits=tmp.bits; - *&tmp=*_fr; - oc_fr_code_block(&tmp); - return (int)(tmp.bits-bits); -} - -static int oc_fr_cost4(const oc_fr_state *_pre,const oc_fr_state *_post){ - oc_fr_state tmp; - *&tmp=*_pre; - oc_fr_skip_block(&tmp); - oc_fr_skip_block(&tmp); - oc_fr_skip_block(&tmp); - oc_fr_skip_block(&tmp); - return (int)(_post->bits-tmp.bits); -} - - - -struct oc_qii_state{ - ptrdiff_t bits; - unsigned qi01_count:14; - signed int qi01:2; - unsigned qi12_count:14; - signed int qi12:2; -}; - - - -static void oc_qii_state_init(oc_qii_state *_qs){ - _qs->bits=0; - _qs->qi01_count=0; - _qs->qi01=-1; - _qs->qi12_count=0; - _qs->qi12=-1; -} - - -static void oc_qii_state_advance(oc_qii_state *_qd, - const oc_qii_state *_qs,int _qii){ - ptrdiff_t bits; - int qi01; - int qi01_count; - int qi12; - int qi12_count; - bits=_qs->bits; - qi01=_qii+1>>1; - qi01_count=_qs->qi01_count; - if(qi01==_qs->qi01){ - if(qi01_count>=4129){ - bits++; - qi01_count=0; - } - else bits-=oc_sb_run_bits(qi01_count); - } - else qi01_count=0; - qi01_count++; - bits+=oc_sb_run_bits(qi01_count); - qi12_count=_qs->qi12_count; - if(_qii){ - qi12=_qii>>1; - if(qi12==_qs->qi12){ - if(qi12_count>=4129){ - bits++; - qi12_count=0; - } - else bits-=oc_sb_run_bits(qi12_count); - } - else qi12_count=0; - qi12_count++; - bits+=oc_sb_run_bits(qi12_count); - } - else qi12=_qs->qi12; - _qd->bits=bits; - _qd->qi01=qi01; - _qd->qi01_count=qi01_count; - _qd->qi12=qi12; - _qd->qi12_count=qi12_count; -} - - - -/*Temporary encoder state for the analysis pipeline.*/ -struct oc_enc_pipeline_state{ - int bounding_values[256]; - oc_fr_state fr[3]; - oc_qii_state qs[3]; - /*Condensed dequantization tables.*/ - const ogg_uint16_t *dequant[3][3][2]; - /*Condensed quantization tables.*/ - const oc_iquant *enquant[3][3][2]; - /*Skip SSD storage for the current MCU in each plane.*/ - unsigned *skip_ssd[3]; - /*Coded/uncoded fragment lists for each plane for the current MCU.*/ - ptrdiff_t *coded_fragis[3]; - ptrdiff_t *uncoded_fragis[3]; - ptrdiff_t ncoded_fragis[3]; - ptrdiff_t nuncoded_fragis[3]; - /*The starting fragment for the current MCU in each plane.*/ - ptrdiff_t froffset[3]; - /*The starting row for the current MCU in each plane.*/ - int fragy0[3]; - /*The ending row for the current MCU in each plane.*/ - int fragy_end[3]; - /*The starting superblock for the current MCU in each plane.*/ - unsigned sbi0[3]; - /*The ending superblock for the current MCU in each plane.*/ - unsigned sbi_end[3]; - /*The number of tokens for zzi=1 for each color plane.*/ - int ndct_tokens1[3]; - /*The outstanding eob_run count for zzi=1 for each color plane.*/ - int eob_run1[3]; - /*Whether or not the loop filter is enabled.*/ - int loop_filter; -}; - - -static void oc_enc_pipeline_init(oc_enc_ctx *_enc,oc_enc_pipeline_state *_pipe){ - ptrdiff_t *coded_fragis; - unsigned mcu_nvsbs; - ptrdiff_t mcu_nfrags; - int hdec; - int vdec; - int pli; - int qii; - int qti; - /*Initialize the per-plane coded block flag trackers. - These are used for bit-estimation purposes only; the real flag bits span - all three planes, so we can't compute them in parallel.*/ - for(pli=0;pli<3;pli++)oc_fr_state_init(_pipe->fr+pli); - for(pli=0;pli<3;pli++)oc_qii_state_init(_pipe->qs+pli); - /*Set up the per-plane skip SSD storage pointers.*/ - mcu_nvsbs=_enc->mcu_nvsbs; - mcu_nfrags=mcu_nvsbs*_enc->state.fplanes[0].nhsbs*16; - hdec=!(_enc->state.info.pixel_fmt&1); - vdec=!(_enc->state.info.pixel_fmt&2); - _pipe->skip_ssd[0]=_enc->mcu_skip_ssd; - _pipe->skip_ssd[1]=_pipe->skip_ssd[0]+mcu_nfrags; - _pipe->skip_ssd[2]=_pipe->skip_ssd[1]+(mcu_nfrags>>hdec+vdec); - /*Set up per-plane pointers to the coded and uncoded fragments lists. - Unlike the decoder, each planes' coded and uncoded fragment list is kept - separate during the analysis stage; we only make the coded list for all - three planes contiguous right before the final packet is output - (destroying the uncoded lists, which are no longer needed).*/ - coded_fragis=_enc->state.coded_fragis; - for(pli=0;pli<3;pli++){ - _pipe->coded_fragis[pli]=coded_fragis; - coded_fragis+=_enc->state.fplanes[pli].nfrags; - _pipe->uncoded_fragis[pli]=coded_fragis; - } - memset(_pipe->ncoded_fragis,0,sizeof(_pipe->ncoded_fragis)); - memset(_pipe->nuncoded_fragis,0,sizeof(_pipe->nuncoded_fragis)); - /*Set up condensed quantizer tables.*/ - for(pli=0;pli<3;pli++){ - for(qii=0;qii<_enc->state.nqis;qii++){ - int qi; - qi=_enc->state.qis[qii]; - for(qti=0;qti<2;qti++){ - _pipe->dequant[pli][qii][qti]=_enc->state.dequant_tables[qi][pli][qti]; - _pipe->enquant[pli][qii][qti]=_enc->enquant_tables[qi][pli][qti]; - } - } - } - /*Initialize the tokenization state.*/ - for(pli=0;pli<3;pli++){ - _pipe->ndct_tokens1[pli]=0; - _pipe->eob_run1[pli]=0; - } - /*Initialize the bounding value array for the loop filter.*/ - _pipe->loop_filter=!oc_state_loop_filter_init(&_enc->state, - _pipe->bounding_values); -} - -/*Sets the current MCU stripe to super block row _sby. - Return: A non-zero value if this was the last MCU.*/ -static int oc_enc_pipeline_set_stripe(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,int _sby){ - const oc_fragment_plane *fplane; - unsigned mcu_nvsbs; - int sby_end; - int notdone; - int vdec; - int pli; - mcu_nvsbs=_enc->mcu_nvsbs; - sby_end=_enc->state.fplanes[0].nvsbs; - notdone=_sby+mcu_nvsbsstate.fplanes+pli; - _pipe->sbi0[pli]=fplane->sboffset+(_sby>>vdec)*fplane->nhsbs; - _pipe->fragy0[pli]=_sby<<2-vdec; - _pipe->froffset[pli]=fplane->froffset - +_pipe->fragy0[pli]*(ptrdiff_t)fplane->nhfrags; - if(notdone){ - _pipe->sbi_end[pli]=fplane->sboffset+(sby_end>>vdec)*fplane->nhsbs; - _pipe->fragy_end[pli]=sby_end<<2-vdec; - } - else{ - _pipe->sbi_end[pli]=fplane->sboffset+fplane->nsbs; - _pipe->fragy_end[pli]=fplane->nvfrags; - } - vdec=!(_enc->state.info.pixel_fmt&2); - } - return notdone; -} - -static void oc_enc_pipeline_finish_mcu_plane(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,int _pli,int _sdelay,int _edelay){ - int refi; - /*Copy over all the uncoded fragments from this plane and advance the uncoded - fragment list.*/ - _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli]; - oc_state_frag_copy_list(&_enc->state,_pipe->uncoded_fragis[_pli], - _pipe->nuncoded_fragis[_pli],OC_FRAME_SELF,OC_FRAME_PREV,_pli); - _pipe->nuncoded_fragis[_pli]=0; - /*Perform DC prediction.*/ - oc_enc_pred_dc_frag_rows(_enc,_pli, - _pipe->fragy0[_pli],_pipe->fragy_end[_pli]); - /*Finish DC tokenization.*/ - oc_enc_tokenize_dc_frag_list(_enc,_pli, - _pipe->coded_fragis[_pli],_pipe->ncoded_fragis[_pli], - _pipe->ndct_tokens1[_pli],_pipe->eob_run1[_pli]); - _pipe->ndct_tokens1[_pli]=_enc->ndct_tokens[_pli][1]; - _pipe->eob_run1[_pli]=_enc->eob_run[_pli][1]; - /*And advance the coded fragment list.*/ - _enc->state.ncoded_fragis[_pli]+=_pipe->ncoded_fragis[_pli]; - _pipe->coded_fragis[_pli]+=_pipe->ncoded_fragis[_pli]; - _pipe->ncoded_fragis[_pli]=0; - /*Apply the loop filter if necessary.*/ - refi=_enc->state.ref_frame_idx[OC_FRAME_SELF]; - if(_pipe->loop_filter){ - oc_state_loop_filter_frag_rows(&_enc->state,_pipe->bounding_values, - refi,_pli,_pipe->fragy0[_pli]-_sdelay,_pipe->fragy_end[_pli]-_edelay); - } - else _sdelay=_edelay=0; - /*To fill borders, we have an additional two pixel delay, since a fragment - in the next row could filter its top edge, using two pixels from a - fragment in this row. - But there's no reason to delay a full fragment between the two.*/ - oc_state_borders_fill_rows(&_enc->state,refi,_pli, - (_pipe->fragy0[_pli]-_sdelay<<3)-(_sdelay<<1), - (_pipe->fragy_end[_pli]-_edelay<<3)-(_edelay<<1)); -} - - - -/*Cost information about the coded blocks in a MB.*/ -struct oc_rd_metric{ - int uncoded_ac_ssd; - int coded_ac_ssd; - int ac_bits; - int dc_flag; -}; - - - -static int oc_enc_block_transform_quantize(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,int _pli,ptrdiff_t _fragi,int _overhead_bits, - oc_rd_metric *_mo,oc_token_checkpoint **_stack){ - OC_ALIGN16(ogg_int16_t dct[64]); - OC_ALIGN16(ogg_int16_t data[64]); - ogg_uint16_t dc_dequant; - const ogg_uint16_t *dequant; - const oc_iquant *enquant; - ptrdiff_t frag_offs; - int ystride; - const unsigned char *src; - const unsigned char *ref; - unsigned char *dst; - int frame_type; - int nonzero; - unsigned uncoded_ssd; - unsigned coded_ssd; - int coded_dc; - oc_token_checkpoint *checkpoint; - oc_fragment *frags; - int mb_mode; - int mv_offs[2]; - int nmv_offs; - int ac_bits; - int borderi; - int qti; - int qii; - int pi; - int zzi; - int v; - int val; - int d; - int s; - int dc; - frags=_enc->state.frags; - frag_offs=_enc->state.frag_buf_offs[_fragi]; - ystride=_enc->state.ref_ystride[_pli]; - src=_enc->state.ref_frame_data[OC_FRAME_IO]+frag_offs; - borderi=frags[_fragi].borderi; - qii=frags[_fragi].qii; - if(qii&~3){ -#if !defined(OC_COLLECT_METRICS) - if(_enc->sp_level>=OC_SP_LEVEL_EARLY_SKIP){ - /*Enable early skip detection.*/ - frags[_fragi].coded=0; - return 0; - } -#endif - /*Try and code this block anyway.*/ - qii&=3; - frags[_fragi].qii=qii; - } - mb_mode=frags[_fragi].mb_mode; - ref=_enc->state.ref_frame_data[ - _enc->state.ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]]+frag_offs; - dst=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_SELF]] - +frag_offs; - /*Motion compensation:*/ - switch(mb_mode){ - case OC_MODE_INTRA:{ - nmv_offs=0; - oc_enc_frag_sub_128(_enc,data,src,ystride); - }break; - case OC_MODE_GOLDEN_NOMV: - case OC_MODE_INTER_NOMV:{ - nmv_offs=1; - mv_offs[0]=0; - oc_enc_frag_sub(_enc,data,src,ref,ystride); - }break; - default:{ - const oc_mv *frag_mvs; - frag_mvs=(const oc_mv *)_enc->state.frag_mvs; - nmv_offs=oc_state_get_mv_offsets(&_enc->state,mv_offs,_pli, - frag_mvs[_fragi][0],frag_mvs[_fragi][1]); - if(nmv_offs>1){ - oc_enc_frag_copy2(_enc,dst, - ref+mv_offs[0],ref+mv_offs[1],ystride); - oc_enc_frag_sub(_enc,data,src,dst,ystride); - } - else oc_enc_frag_sub(_enc,data,src,ref+mv_offs[0],ystride); - }break; - } -#if defined(OC_COLLECT_METRICS) - { - unsigned satd; - switch(nmv_offs){ - case 0:satd=oc_enc_frag_intra_satd(_enc,src,ystride);break; - case 1:{ - satd=oc_enc_frag_satd_thresh(_enc,src,ref+mv_offs[0],ystride,UINT_MAX); - }break; - default:{ - satd=oc_enc_frag_satd_thresh(_enc,src,dst,ystride,UINT_MAX); - } - } - _enc->frag_satd[_fragi]=satd; - } -#endif - /*Transform:*/ - oc_enc_fdct8x8(_enc,dct,data); - /*Quantize the DC coefficient:*/ - qti=mb_mode!=OC_MODE_INTRA; - enquant=_pipe->enquant[_pli][0][qti]; - dc_dequant=_pipe->dequant[_pli][0][qti][0]; - v=dct[0]; - val=v<<1; - s=OC_SIGNMASK(val); - val+=dc_dequant+s^s; - val=((enquant[0].m*(ogg_int32_t)val>>16)+val>>enquant[0].l)-s; - dc=OC_CLAMPI(-580,val,580); - nonzero=0; - /*Quantize the AC coefficients:*/ - dequant=_pipe->dequant[_pli][qii][qti]; - enquant=_pipe->enquant[_pli][qii][qti]; - for(zzi=1;zzi<64;zzi++){ - v=dct[OC_FZIG_ZAG[zzi]]; - d=dequant[zzi]; - val=v<<1; - v=abs(val); - if(v>=d){ - s=OC_SIGNMASK(val); - /*The bias added here rounds ties away from zero, since token - optimization can only decrease the magnitude of the quantized - value.*/ - val+=d+s^s; - /*Note the arithmetic right shift is not guaranteed by ANSI C. - Hopefully no one still uses ones-complement architectures.*/ - val=((enquant[zzi].m*(ogg_int32_t)val>>16)+val>>enquant[zzi].l)-s; - data[zzi]=OC_CLAMPI(-580,val,580); - nonzero=zzi; - } - else data[zzi]=0; - } - /*Tokenize.*/ - checkpoint=*_stack; - ac_bits=oc_enc_tokenize_ac(_enc,_pli,_fragi,data,dequant,dct,nonzero+1, - _stack,qti?0:3); - /*Reconstruct. - TODO: nonzero may need to be adjusted after tokenization.*/ - if(nonzero==0){ - ogg_int16_t p; - int ci; - /*We round this dequant product (and not any of the others) because there's - no iDCT rounding.*/ - p=(ogg_int16_t)(dc*(ogg_int32_t)dc_dequant+15>>5); - /*LOOP VECTORIZES.*/ - for(ci=0;ci<64;ci++)data[ci]=p; - } - else{ - data[0]=dc*dc_dequant; - oc_idct8x8(&_enc->state,data,nonzero+1); - } - if(!qti)oc_enc_frag_recon_intra(_enc,dst,ystride,data); - else{ - oc_enc_frag_recon_inter(_enc,dst, - nmv_offs==1?ref+mv_offs[0]:dst,ystride,data); - } - frame_type=_enc->state.frame_type; -#if !defined(OC_COLLECT_METRICS) - if(frame_type!=OC_INTRA_FRAME) -#endif - { - /*In retrospect, should we have skipped this block?*/ - oc_enc_frag_sub(_enc,data,src,dst,ystride); - coded_ssd=coded_dc=0; - if(borderi<0){ - for(pi=0;pi<64;pi++){ - coded_ssd+=data[pi]*data[pi]; - coded_dc+=data[pi]; - } - } - else{ - ogg_int64_t mask; - mask=_enc->state.borders[borderi].mask; - for(pi=0;pi<64;pi++,mask>>=1)if(mask&1){ - coded_ssd+=data[pi]*data[pi]; - coded_dc+=data[pi]; - } - } - /*Scale to match DCT domain.*/ - coded_ssd<<=4; - /*We actually only want the AC contribution to the SSD.*/ - coded_ssd-=coded_dc*coded_dc>>2; -#if defined(OC_COLLECT_METRICS) - _enc->frag_ssd[_fragi]=coded_ssd; - } - if(frame_type!=OC_INTRA_FRAME){ -#endif - uncoded_ssd=_pipe->skip_ssd[_pli][_fragi-_pipe->froffset[_pli]]; - if(uncoded_ssdlambda&& - /*Don't allow luma blocks to be skipped in 4MV mode when VP3 - compatibility is enabled.*/ - (!_enc->vp3_compatible||mb_mode!=OC_MODE_INTER_MV_FOUR||_pli)){ - /*Hm, not worth it; roll back.*/ - oc_enc_tokenlog_rollback(_enc,checkpoint,(*_stack)-checkpoint); - *_stack=checkpoint; - frags[_fragi].coded=0; - return 0; - } - } - else _mo->dc_flag=1; - _mo->uncoded_ac_ssd+=uncoded_ssd; - _mo->coded_ac_ssd+=coded_ssd; - _mo->ac_bits+=ac_bits; - } - oc_qii_state_advance(_pipe->qs+_pli,_pipe->qs+_pli,qii); - frags[_fragi].dc=dc; - frags[_fragi].coded=1; - return 1; -} - -static int oc_enc_mb_transform_quantize_luma(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,unsigned _mbi,int _mode_overhead){ - /*Worst case token stack usage for 4 fragments.*/ - oc_token_checkpoint stack[64*4]; - oc_token_checkpoint *stackptr; - const oc_sb_map *sb_maps; - signed char *mb_modes; - oc_fragment *frags; - ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t *uncoded_fragis; - ptrdiff_t nuncoded_fragis; - oc_rd_metric mo; - oc_fr_state fr_checkpoint; - oc_qii_state qs_checkpoint; - int mb_mode; - int ncoded; - ptrdiff_t fragi; - int bi; - *&fr_checkpoint=*(_pipe->fr+0); - *&qs_checkpoint=*(_pipe->qs+0); - sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - mb_modes=_enc->state.mb_modes; - frags=_enc->state.frags; - coded_fragis=_pipe->coded_fragis[0]; - ncoded_fragis=_pipe->ncoded_fragis[0]; - uncoded_fragis=_pipe->uncoded_fragis[0]; - nuncoded_fragis=_pipe->nuncoded_fragis[0]; - mb_mode=mb_modes[_mbi]; - ncoded=0; - stackptr=stack; - memset(&mo,0,sizeof(mo)); - for(bi=0;bi<4;bi++){ - fragi=sb_maps[_mbi>>2][_mbi&3][bi]; - frags[fragi].mb_mode=mb_mode; - if(oc_enc_block_transform_quantize(_enc, - _pipe,0,fragi,oc_fr_cost1(_pipe->fr+0),&mo,&stackptr)){ - oc_fr_code_block(_pipe->fr+0); - coded_fragis[ncoded_fragis++]=fragi; - ncoded++; - } - else{ - *(uncoded_fragis-++nuncoded_fragis)=fragi; - oc_fr_skip_block(_pipe->fr+0); - } - } - if(_enc->state.frame_type!=OC_INTRA_FRAME){ - if(ncoded>0&&!mo.dc_flag){ - int cost; - /*Some individual blocks were worth coding. - See if that's still true when accounting for mode and MV overhead.*/ - cost=mo.coded_ac_ssd+_enc->lambda*(mo.ac_bits - +oc_fr_cost4(&fr_checkpoint,_pipe->fr+0)+_mode_overhead); - if(mo.uncoded_ac_ssd<=cost){ - /*Taking macroblock overhead into account, it is not worth coding this - MB.*/ - oc_enc_tokenlog_rollback(_enc,stack,stackptr-stack); - *(_pipe->fr+0)=*&fr_checkpoint; - *(_pipe->qs+0)=*&qs_checkpoint; - for(bi=0;bi<4;bi++){ - fragi=sb_maps[_mbi>>2][_mbi&3][bi]; - if(frags[fragi].coded){ - *(uncoded_fragis-++nuncoded_fragis)=fragi; - frags[fragi].coded=0; - } - oc_fr_skip_block(_pipe->fr+0); - } - ncoded_fragis-=ncoded; - ncoded=0; - } - } - /*If no luma blocks coded, the mode is forced.*/ - if(ncoded==0)mb_modes[_mbi]=OC_MODE_INTER_NOMV; - /*Assume that a 1MV with a single coded block is always cheaper than a 4MV - with a single coded block. - This may not be strictly true: a 4MV computes chroma MVs using (0,0) for - skipped blocks, while a 1MV does not.*/ - else if(ncoded==1&&mb_mode==OC_MODE_INTER_MV_FOUR){ - mb_modes[_mbi]=OC_MODE_INTER_MV; - } - } - _pipe->ncoded_fragis[0]=ncoded_fragis; - _pipe->nuncoded_fragis[0]=nuncoded_fragis; - return ncoded; -} - -static void oc_enc_sb_transform_quantize_chroma(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,int _pli,int _sbi_start,int _sbi_end){ - const oc_sb_map *sb_maps; - oc_sb_flags *sb_flags; - ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t *uncoded_fragis; - ptrdiff_t nuncoded_fragis; - int sbi; - sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - sb_flags=_enc->state.sb_flags; - coded_fragis=_pipe->coded_fragis[_pli]; - ncoded_fragis=_pipe->ncoded_fragis[_pli]; - uncoded_fragis=_pipe->uncoded_fragis[_pli]; - nuncoded_fragis=_pipe->nuncoded_fragis[_pli]; - for(sbi=_sbi_start;sbi<_sbi_end;sbi++){ - /*Worst case token stack usage for 1 fragment.*/ - oc_token_checkpoint stack[64]; - oc_rd_metric mo; - int quadi; - int bi; - memset(&mo,0,sizeof(mo)); - for(quadi=0;quadi<4;quadi++)for(bi=0;bi<4;bi++){ - ptrdiff_t fragi; - fragi=sb_maps[sbi][quadi][bi]; - if(fragi>=0){ - oc_token_checkpoint *stackptr; - stackptr=stack; - if(oc_enc_block_transform_quantize(_enc, - _pipe,_pli,fragi,oc_fr_cost1(_pipe->fr+_pli),&mo,&stackptr)){ - coded_fragis[ncoded_fragis++]=fragi; - oc_fr_code_block(_pipe->fr+_pli); - } - else{ - *(uncoded_fragis-++nuncoded_fragis)=fragi; - oc_fr_skip_block(_pipe->fr+_pli); - } - } - } - oc_fr_state_flush_sb(_pipe->fr+_pli); - sb_flags[sbi].coded_fully=_pipe->fr[_pli].sb_full; - sb_flags[sbi].coded_partially=_pipe->fr[_pli].sb_partial; - } - _pipe->ncoded_fragis[_pli]=ncoded_fragis; - _pipe->nuncoded_fragis[_pli]=nuncoded_fragis; -} - -/*Mode decision is done by exhaustively examining all potential choices. - Obviously, doing the motion compensation, fDCT, tokenization, and then - counting the bits each token uses is computationally expensive. - Theora's EOB runs can also split the cost of these tokens across multiple - fragments, and naturally we don't know what the optimal choice of Huffman - codes will be until we know all the tokens we're going to encode in all the - fragments. - So we use a simple approach to estimating the bit cost and distortion of each - mode based upon the SATD value of the residual before coding. - The mathematics behind the technique are outlined by Kim \cite{Kim03}, but - the process (modified somewhat from that of the paper) is very simple. - We build a non-linear regression of the mappings from - (pre-transform+quantization) SATD to (post-transform+quantization) bits and - SSD for each qi. - A separate set of mappings is kept for each quantization type and color - plane. - The mappings are constructed by partitioning the SATD values into a small - number of bins (currently 24) and using a linear regression in each bin - (as opposed to the 0th-order regression used by Kim). - The bit counts and SSD measurements are obtained by examining actual encoded - frames, with appropriate lambda values and optimal Huffman codes selected. - EOB bits are assigned to the fragment that started the EOB run (as opposed to - dividing them among all the blocks in the run; though the latter approach - seems more theoretically correct, Monty's testing showed a small improvement - with the former, though that may have been merely statistical noise). - - @ARTICLE{Kim03, - author="Hyun Mun Kim", - title="Adaptive Rate Control Using Nonlinear Regression", - journal="IEEE Transactions on Circuits and Systems for Video Technology", - volume=13, - number=5, - pages="432--439", - month=May, - year=2003 - }*/ - -/*Computes (_ssd+_lambda*_rate)/(1<>OC_BIT_SCALE)+((_rate)>>OC_BIT_SCALE)*(_lambda) \ - +(((_ssd)&(1<>1)>>OC_BIT_SCALE) - -/*Estimate the R-D cost of the DCT coefficients given the SATD of a block after - prediction.*/ -static unsigned oc_dct_cost2(unsigned *_ssd, - int _qi,int _pli,int _qti,int _satd){ - unsigned rmse; - int bin; - int dx; - int y0; - int z0; - int dy; - int dz; - /*SATD metrics for chroma planes vary much less than luma, so we scale them - by 4 to distribute them into the mode decision bins more evenly.*/ - _satd<<=_pli+1&2; - bin=OC_MINI(_satd>>OC_SAD_SHIFT,OC_SAD_BINS-2); - dx=_satd-(bin<>OC_SAD_SHIFT),0); - *_ssd=rmse*rmse>>2*OC_RMSE_SCALE-OC_BIT_SCALE; - return OC_MAXI(y0+(dy*dx>>OC_SAD_SHIFT),0); -} - -/*Select luma block-level quantizers for a MB in an INTRA frame.*/ -static unsigned oc_analyze_intra_mb_luma(oc_enc_ctx *_enc, - const oc_qii_state *_qs,unsigned _mbi){ - const unsigned char *src; - const ptrdiff_t *frag_buf_offs; - const oc_sb_map *sb_maps; - oc_fragment *frags; - ptrdiff_t frag_offs; - ptrdiff_t fragi; - oc_qii_state qs[4][3]; - unsigned cost[4][3]; - unsigned ssd[4][3]; - unsigned rate[4][3]; - int prev[3][3]; - unsigned satd; - unsigned best_cost; - unsigned best_ssd; - unsigned best_rate; - int best_qii; - int qii; - int lambda; - int ystride; - int nqis; - int bi; - frag_buf_offs=_enc->state.frag_buf_offs; - sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ystride=_enc->state.ref_ystride[0]; - fragi=sb_maps[_mbi>>2][_mbi&3][0]; - frag_offs=frag_buf_offs[fragi]; - satd=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - nqis=_enc->state.nqis; - lambda=_enc->lambda; - for(qii=0;qiistate.qis[qii],0,0,satd) - +(qs[0][qii].bits-_qs->bits<>2][_mbi&3][bi]; - frag_offs=frag_buf_offs[fragi]; - satd=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - for(qii=0;qiistate.qis[qii],0,0,satd); - best_ssd=ssd[bi-1][0]+cur_ssd; - best_rate=rate[bi-1][0]+cur_rate - +(qt[0].bits-qs[bi-1][0].bits<state.frags; - for(bi=3;;){ - fragi=sb_maps[_mbi>>2][_mbi&3][bi]; - frags[fragi].qii=best_qii; - if(bi--<=0)break; - best_qii=prev[bi][best_qii]; - } - return best_cost; -} - -/*Select a block-level quantizer for a single chroma block in an INTRA frame.*/ -static unsigned oc_analyze_intra_chroma_block(oc_enc_ctx *_enc, - const oc_qii_state *_qs,int _pli,ptrdiff_t _fragi){ - const unsigned char *src; - oc_fragment *frags; - ptrdiff_t frag_offs; - oc_qii_state qt[3]; - unsigned cost[3]; - unsigned satd; - unsigned best_cost; - int best_qii; - int qii; - int lambda; - int ystride; - int nqis; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ystride=_enc->state.ref_ystride[_pli]; - frag_offs=_enc->state.frag_buf_offs[_fragi]; - satd=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - nqis=_enc->state.nqis; - lambda=_enc->lambda; - best_qii=0; - for(qii=0;qiistate.qis[qii],_pli,0,satd) - +(qt[qii].bits-_qs->bits<state.frags; - frags[_fragi].qii=best_qii; - return best_cost; -} - -static void oc_enc_sb_transform_quantize_intra_chroma(oc_enc_ctx *_enc, - oc_enc_pipeline_state *_pipe,int _pli,int _sbi_start,int _sbi_end){ - const oc_sb_map *sb_maps; - oc_sb_flags *sb_flags; - ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - int sbi; - sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - sb_flags=_enc->state.sb_flags; - coded_fragis=_pipe->coded_fragis[_pli]; - ncoded_fragis=_pipe->ncoded_fragis[_pli]; - for(sbi=_sbi_start;sbi<_sbi_end;sbi++){ - /*Worst case token stack usage for 1 fragment.*/ - oc_token_checkpoint stack[64]; - int quadi; - int bi; - for(quadi=0;quadi<4;quadi++)for(bi=0;bi<4;bi++){ - ptrdiff_t fragi; - fragi=sb_maps[sbi][quadi][bi]; - if(fragi>=0){ - oc_token_checkpoint *stackptr; - oc_analyze_intra_chroma_block(_enc,_pipe->qs+_pli,_pli,fragi); - stackptr=stack; - oc_enc_block_transform_quantize(_enc, - _pipe,_pli,fragi,0,NULL,&stackptr); - coded_fragis[ncoded_fragis++]=fragi; - } - } - } - _pipe->ncoded_fragis[_pli]=ncoded_fragis; -} - -/*Analysis stage for an INTRA frame.*/ -void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode){ - oc_enc_pipeline_state pipe; - const unsigned char *map_idxs; - int nmap_idxs; - oc_sb_flags *sb_flags; - signed char *mb_modes; - const oc_mb_map *mb_maps; - oc_mb_enc_info *embs; - oc_fragment *frags; - unsigned stripe_sby; - unsigned mcu_nvsbs; - int notstart; - int notdone; - int refi; - int pli; - _enc->state.frame_type=OC_INTRA_FRAME; - oc_enc_tokenize_start(_enc); - oc_enc_pipeline_init(_enc,&pipe); - /*Choose MVs and MB modes and quantize and code luma. - Must be done in Hilbert order.*/ - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - nmap_idxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - _enc->state.ncoded_fragis[0]=0; - _enc->state.ncoded_fragis[1]=0; - _enc->state.ncoded_fragis[2]=0; - sb_flags=_enc->state.sb_flags; - mb_modes=_enc->state.mb_modes; - mb_maps=(const oc_mb_map *)_enc->state.mb_maps; - embs=_enc->mb_info; - frags=_enc->state.frags; - notstart=0; - notdone=1; - mcu_nvsbs=_enc->mcu_nvsbs; - for(stripe_sby=0;notdone;stripe_sby+=mcu_nvsbs){ - unsigned sbi; - unsigned sbi_end; - notdone=oc_enc_pipeline_set_stripe(_enc,&pipe,stripe_sby); - sbi_end=pipe.sbi_end[0]; - for(sbi=pipe.sbi0[0];sbistate.curframe_num>0)oc_mcenc_search(_enc,mbi); - oc_analyze_intra_mb_luma(_enc,pipe.qs+0,mbi); - mb_modes[mbi]=OC_MODE_INTRA; - oc_enc_mb_transform_quantize_luma(_enc,&pipe,mbi,0); - /*Propagate final MB mode and MVs to the chroma blocks.*/ - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_maps[mbi][pli][bi]; - frags[fragi].mb_mode=OC_MODE_INTRA; - } - } - } - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,0,notstart,notdone); - /*Code chroma planes.*/ - for(pli=1;pli<3;pli++){ - oc_enc_sb_transform_quantize_intra_chroma(_enc,&pipe, - pli,pipe.sbi0[pli],pipe.sbi_end[pli]); - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,pli,notstart,notdone); - } - notstart=1; - } - /*Finish filling in the reference frame borders.*/ - refi=_enc->state.ref_frame_idx[OC_FRAME_SELF]; - for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_enc->state,refi,pli); - _enc->state.ntotal_coded_fragis=_enc->state.nfrags; -} - - - -/*Cost information about a MB mode.*/ -struct oc_mode_choice{ - unsigned cost; - unsigned ssd; - unsigned rate; - unsigned overhead; - unsigned char qii[12]; -}; - - - -static void oc_mode_set_cost(oc_mode_choice *_modec,int _lambda){ - _modec->cost=OC_MODE_RD_COST(_modec->ssd, - _modec->rate+_modec->overhead,_lambda); -} - -/*A set of skip SSD's to use to disable early skipping.*/ -static const unsigned OC_NOSKIP[12]={ - UINT_MAX,UINT_MAX,UINT_MAX,UINT_MAX, - UINT_MAX,UINT_MAX,UINT_MAX,UINT_MAX, - UINT_MAX,UINT_MAX,UINT_MAX,UINT_MAX -}; - -/*The estimated number of bits used by a coded chroma block to specify the AC - quantizer. - TODO: Currently this is just 0.5*log2(3) (estimating about 50% compression); - measurements suggest this is in the right ballpark, but it varies somewhat - with lambda.*/ -#define OC_CHROMA_QII_RATE ((0xCAE00D1DU>>31-OC_BIT_SCALE)+1>>1) - -static void oc_analyze_mb_mode_luma(oc_enc_ctx *_enc, - oc_mode_choice *_modec,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _frag_satd[12],const unsigned _skip_ssd[12],int _qti){ - oc_fr_state fr; - oc_qii_state qs; - unsigned ssd; - unsigned rate; - int overhead; - unsigned satd; - unsigned best_ssd; - unsigned best_rate; - int best_overhead; - int best_fri; - int best_qii; - unsigned cur_cost; - unsigned cur_ssd; - unsigned cur_rate; - int cur_overhead; - int lambda; - int nqis; - int nskipped; - int bi; - int qii; - lambda=_enc->lambda; - nqis=_enc->state.nqis; - /*We could do a trellis optimization here, but we don't make final skip - decisions until after transform+quantization, so the result wouldn't be - optimal anyway. - Instead we just use a greedy approach; for most SATD values, the - differences between the qiis are large enough to drown out the cost to - code the flags, anyway.*/ - *&fr=*_fr; - *&qs=*_qs; - ssd=rate=overhead=nskipped=0; - for(bi=0;bi<4;bi++){ - oc_fr_state ft[2]; - oc_qii_state qt[3]; - unsigned best_cost; - satd=_frag_satd[bi]; - *(ft+0)=*&fr; - oc_fr_code_block(ft+0); - oc_qii_state_advance(qt+0,&qs,0); - best_overhead=(ft[0].bits-fr.bits<state.qis[0],0,_qti,satd) - +(qt[0].bits-qs.bits<state.qis[qii],0,_qti,satd) - +(qt[qii].bits-qs.bits<qii[bi]=best_qii; - } - _modec->ssd=ssd; - _modec->rate=rate; - _modec->overhead=OC_MAXI(overhead,0); -} - -static void oc_analyze_mb_mode_chroma(oc_enc_ctx *_enc, - oc_mode_choice *_modec,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _frag_satd[12],const unsigned _skip_ssd[12],int _qti){ - unsigned ssd; - unsigned rate; - unsigned satd; - unsigned best_ssd; - unsigned best_rate; - int best_qii; - unsigned cur_cost; - unsigned cur_ssd; - unsigned cur_rate; - int lambda; - int nblocks; - int nqis; - int pli; - int bi; - int qii; - lambda=_enc->lambda; - nqis=_enc->state.nqis; - ssd=_modec->ssd; - rate=_modec->rate; - /*Because (except in 4:4:4 mode) we aren't considering chroma blocks in coded - order, we assume a constant overhead for coded block and qii flags.*/ - nblocks=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - nblocks=(nblocks-4>>1)+4; - bi=4; - for(pli=1;pli<3;pli++){ - for(;bistate.qis[0],pli,_qti,satd) - +OC_CHROMA_QII_RATE; - best_cost=OC_MODE_RD_COST(ssd+best_ssd,rate+best_rate,lambda); - best_qii=0; - for(qii=1;qiistate.qis[qii],0,_qti,satd) - +OC_CHROMA_QII_RATE; - cur_cost=OC_MODE_RD_COST(ssd+cur_ssd,rate+cur_rate,lambda); - if(cur_costqii[bi]=best_qii; - } - nblocks=(nblocks-4<<1)+4; - } - _modec->ssd=ssd; - _modec->rate=rate; -} - -static void oc_skip_cost(oc_enc_ctx *_enc,oc_enc_pipeline_state *_pipe, - unsigned _mbi,unsigned _ssd[12]){ - OC_ALIGN16(ogg_int16_t buffer[64]); - const unsigned char *src; - const unsigned char *ref; - int ystride; - const oc_fragment *frags; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *sb_map; - const oc_mb_map_plane *mb_map; - const unsigned char *map_idxs; - int map_nidxs; - ogg_int64_t mask; - unsigned uncoded_ssd; - int uncoded_dc; - unsigned dc_dequant; - int dc_flag; - int mapii; - int mapi; - int pli; - int bi; - ptrdiff_t fragi; - ptrdiff_t frag_offs; - int borderi; - int pi; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_PREV]]; - ystride=_enc->state.ref_ystride[0]; - frags=_enc->state.frags; - frag_buf_offs=_enc->state.frag_buf_offs; - sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; - dc_dequant=_enc->state.dequant_tables[_enc->state.qis[0]][0][1][0]; - for(bi=0;bi<4;bi++){ - fragi=sb_map[bi]; - frag_offs=frag_buf_offs[fragi]; - oc_enc_frag_sub(_enc,buffer,src+frag_offs,ref+frag_offs,ystride); - borderi=frags[fragi].borderi; - uncoded_ssd=uncoded_dc=0; - if(borderi<0){ - for(pi=0;pi<64;pi++){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } - } - else{ - ogg_int64_t mask; - mask=_enc->state.borders[borderi].mask; - for(pi=0;pi<64;pi++,mask>>=1)if(mask&1){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } - } - /*Scale to match DCT domain.*/ - uncoded_ssd<<=4; - /*We actually only want the AC contribution to the SSD.*/ - uncoded_ssd-=uncoded_dc*uncoded_dc>>2; - /*DC is a special case; if there's more than a full-quantizer improvement - in the effective DC component, always force-code the block.*/ - dc_flag=abs(uncoded_dc)>dc_dequant<<1; - uncoded_ssd|=-dc_flag; - _pipe->skip_ssd[0][fragi-_pipe->froffset[0]]=_ssd[bi]=uncoded_ssd; - } - mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; - map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - map_nidxs=(map_nidxs-4>>1)+4; - mapii=4; - for(pli=1;pli<3;pli++){ - ystride=_enc->state.ref_ystride[pli]; - dc_dequant=_enc->state.dequant_tables[_enc->state.qis[0]][pli][1][0]; - for(;mapiistate.borders[borderi].mask; - for(pi=0;pi<64;pi++,mask>>=1)if(mask&1){ - uncoded_ssd+=buffer[pi]*buffer[pi]; - uncoded_dc+=buffer[pi]; - } - } - /*Scale to match DCT domain.*/ - uncoded_ssd<<=4; - /*We actually only want the AC contribution to the SSD.*/ - uncoded_ssd-=uncoded_dc*uncoded_dc>>2; - /*DC is a special case; if there's more than a full-quantizer improvement - in the effective DC component, always force-code the block.*/ - dc_flag=abs(uncoded_dc)>dc_dequant<<1; - uncoded_ssd|=-dc_flag; - _pipe->skip_ssd[pli][fragi-_pipe->froffset[pli]]=_ssd[mapii]=uncoded_ssd; - } - map_nidxs=(map_nidxs-4<<1)+4; - } -} - -static void oc_mb_intra_satd(oc_enc_ctx *_enc,unsigned _mbi, - unsigned _frag_satd[12]){ - const unsigned char *src; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *sb_map; - const oc_mb_map_plane *mb_map; - const unsigned char *map_idxs; - int map_nidxs; - int mapii; - int mapi; - int ystride; - int pli; - int bi; - ptrdiff_t fragi; - ptrdiff_t frag_offs; - frag_buf_offs=_enc->state.frag_buf_offs; - sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ystride=_enc->state.ref_ystride[0]; - for(bi=0;bi<4;bi++){ - fragi=sb_map[bi]; - frag_offs=frag_buf_offs[fragi]; - _frag_satd[bi]=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - } - mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ - ystride=_enc->state.ref_ystride[1]; - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_map[pli][bi]; - frag_offs=frag_buf_offs[fragi]; - _frag_satd[mapii]=oc_enc_frag_intra_satd(_enc,src+frag_offs,ystride); - } -} - -static void oc_cost_intra(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _frag_satd[12],const unsigned _skip_ssd[12]){ - oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,_frag_satd,_skip_ssd,0); - oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs,_frag_satd,_skip_ssd,0); - _modec->overhead+= - oc_mode_scheme_chooser_cost(&_enc->chooser,OC_MODE_INTRA)<lambda); -} - -static void oc_cost_inter(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,int _mb_mode,const signed char *_mv, - const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12]){ - unsigned frag_satd[12]; - const unsigned char *src; - const unsigned char *ref; - int ystride; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *sb_map; - const oc_mb_map_plane *mb_map; - const unsigned char *map_idxs; - int map_nidxs; - int mapii; - int mapi; - int mv_offs[2]; - int dx; - int dy; - int pli; - int bi; - ptrdiff_t fragi; - ptrdiff_t frag_offs; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[ - _enc->state.ref_frame_idx[OC_FRAME_FOR_MODE(_mb_mode)]]; - ystride=_enc->state.ref_ystride[0]; - frag_buf_offs=_enc->state.frag_buf_offs; - sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3]; - dx=_mv[0]; - dy=_mv[1]; - _modec->rate=_modec->ssd=0; - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,dx,dy)>1){ - for(bi=0;bi<4;bi++){ - fragi=sb_map[bi]; - frag_offs=frag_buf_offs[fragi]; - frag_satd[bi]=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); - } - } - else{ - for(bi=0;bi<4;bi++){ - fragi=sb_map[bi]; - frag_offs=frag_buf_offs[fragi]; - frag_satd[bi]=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); - } - } - mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ - ystride=_enc->state.ref_ystride[1]; - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,1,dx,dy)>1){ - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_map[pli][bi]; - frag_offs=frag_buf_offs[fragi]; - frag_satd[mapii]=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); - } - } - else{ - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_map[pli][bi]; - frag_offs=frag_buf_offs[fragi]; - frag_satd[mapii]=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); - } - } - oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,1); - oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,1); - _modec->overhead+= - oc_mode_scheme_chooser_cost(&_enc->chooser,_mb_mode)<lambda); -} - -static void oc_cost_inter_nomv(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,int _mb_mode,const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _skip_ssd[12]){ - static const oc_mv OC_MV_ZERO; - oc_cost_inter(_enc,_modec,_mbi,_mb_mode,OC_MV_ZERO,_fr,_qs,_skip_ssd); -} - -static int oc_cost_inter1mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,int _mb_mode,const signed char *_mv, - const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12]){ - int bits0; - oc_cost_inter(_enc,_modec,_mbi,_mb_mode,_mv,_fr,_qs,_skip_ssd); - bits0=OC_MV_BITS[0][_mv[0]+31]+OC_MV_BITS[0][_mv[1]+31]; - _modec->overhead+=OC_MINI(_enc->mv_bits[0]+bits0,_enc->mv_bits[1]+12) - -OC_MINI(_enc->mv_bits[0],_enc->mv_bits[1])<lambda); - return bits0; -} - -/*A mapping from oc_mb_map (raster) ordering to oc_sb_map (Hilbert) ordering.*/ -static const unsigned char OC_MB_PHASE[4][4]={ - {0,1,3,2},{0,3,1,2},{0,3,1,2},{2,3,1,0} -}; - -static void oc_cost_inter4mv(oc_enc_ctx *_enc,oc_mode_choice *_modec, - unsigned _mbi,oc_mv _mv[4],const oc_fr_state *_fr,const oc_qii_state *_qs, - const unsigned _skip_ssd[12]){ - unsigned frag_satd[12]; - oc_mv lbmvs[4]; - oc_mv cbmvs[4]; - const unsigned char *src; - const unsigned char *ref; - int ystride; - const ptrdiff_t *frag_buf_offs; - oc_mv *frag_mvs; - const oc_mb_map_plane *mb_map; - const unsigned char *map_idxs; - int map_nidxs; - int nqis; - int mapii; - int mapi; - int mv_offs[2]; - int dx; - int dy; - int pli; - int bi; - ptrdiff_t fragi; - ptrdiff_t frag_offs; - int bits0; - int bits1; - unsigned satd; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_PREV]]; - ystride=_enc->state.ref_ystride[0]; - frag_buf_offs=_enc->state.frag_buf_offs; - frag_mvs=_enc->state.frag_mvs; - mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi]; - _modec->rate=_modec->ssd=0; - for(bi=0;bi<4;bi++){ - fragi=mb_map[0][bi]; - dx=_mv[bi][0]; - dy=_mv[bi][1]; - /*Save the block MVs as the current ones while we're here; we'll replace - them if we don't ultimately choose 4MV mode.*/ - frag_mvs[fragi][0]=(signed char)dx; - frag_mvs[fragi][1]=(signed char)dy; - frag_offs=frag_buf_offs[fragi]; - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,dx,dy)>1){ - satd=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); - } - else{ - satd=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); - } - frag_satd[OC_MB_PHASE[_mbi&3][bi]]=satd; - } - oc_analyze_mb_mode_luma(_enc,_modec,_fr,_qs,frag_satd, - _enc->vp3_compatible?OC_NOSKIP:_skip_ssd,1); - /*Figure out which blocks are being skipped and give them (0,0) MVs.*/ - bits0=0; - bits1=0; - nqis=_enc->state.nqis; - for(bi=0;bi<4;bi++){ - if(_modec->qii[OC_MB_PHASE[_mbi&3][bi]]>=nqis){ - memset(lbmvs+bi,0,sizeof(*lbmvs)); - } - else{ - memcpy(lbmvs+bi,_mv+bi,sizeof(*lbmvs)); - bits0+=OC_MV_BITS[0][_mv[bi][0]+31]+OC_MV_BITS[0][_mv[bi][1]+31]; - bits1+=12; - } - } - (*OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt])(cbmvs, - (const oc_mv *)lbmvs); - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/ - ystride=_enc->state.ref_ystride[1]; - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_map[pli][bi]; - dx=cbmvs[bi][0]; - dy=cbmvs[bi][1]; - frag_offs=frag_buf_offs[fragi]; - /*TODO: We could save half these calls by re-using the results for the Cb - and Cr planes; is it worth it?*/ - if(oc_state_get_mv_offsets(&_enc->state,mv_offs,pli,dx,dy)>1){ - satd=oc_enc_frag_satd2_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride,UINT_MAX); - } - else{ - satd=oc_enc_frag_satd_thresh(_enc,src+frag_offs, - ref+frag_offs+mv_offs[0],ystride,UINT_MAX); - } - frag_satd[mapii]=satd; - } - oc_analyze_mb_mode_chroma(_enc,_modec,_fr,_qs,frag_satd,_skip_ssd,1); - _modec->overhead+= - oc_mode_scheme_chooser_cost(&_enc->chooser,OC_MODE_INTER_MV_FOUR) - +OC_MINI(_enc->mv_bits[0]+bits0,_enc->mv_bits[1]+bits1) - -OC_MINI(_enc->mv_bits[0],_enc->mv_bits[1])<lambda); -} - -int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode){ - oc_set_chroma_mvs_func set_chroma_mvs; - oc_enc_pipeline_state pipe; - oc_qii_state intra_luma_qs; - oc_mv last_mv; - oc_mv prior_mv; - ogg_int64_t interbits; - ogg_int64_t intrabits; - const unsigned char *map_idxs; - int nmap_idxs; - unsigned *coded_mbis; - unsigned *uncoded_mbis; - size_t ncoded_mbis; - size_t nuncoded_mbis; - oc_sb_flags *sb_flags; - signed char *mb_modes; - const oc_sb_map *sb_maps; - const oc_mb_map *mb_maps; - oc_mb_enc_info *embs; - oc_fragment *frags; - oc_mv *frag_mvs; - int qi; - unsigned stripe_sby; - unsigned mcu_nvsbs; - int notstart; - int notdone; - int vdec; - unsigned sbi; - unsigned sbi_end; - int refi; - int pli; - set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt]; - _enc->state.frame_type=OC_INTER_FRAME; - oc_mode_scheme_chooser_reset(&_enc->chooser); - oc_enc_tokenize_start(_enc); - oc_enc_pipeline_init(_enc,&pipe); - if(_allow_keyframe)oc_qii_state_init(&intra_luma_qs); - _enc->mv_bits[0]=_enc->mv_bits[1]=0; - interbits=intrabits=0; - last_mv[0]=last_mv[1]=prior_mv[0]=prior_mv[1]=0; - /*Choose MVs and MB modes and quantize and code luma. - Must be done in Hilbert order.*/ - map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt]; - nmap_idxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt]; - qi=_enc->state.qis[0]; - coded_mbis=_enc->coded_mbis; - uncoded_mbis=coded_mbis+_enc->state.nmbs; - ncoded_mbis=0; - nuncoded_mbis=0; - _enc->state.ncoded_fragis[0]=0; - _enc->state.ncoded_fragis[1]=0; - _enc->state.ncoded_fragis[2]=0; - sb_flags=_enc->state.sb_flags; - mb_modes=_enc->state.mb_modes; - sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - mb_maps=(const oc_mb_map *)_enc->state.mb_maps; - embs=_enc->mb_info; - frags=_enc->state.frags; - frag_mvs=_enc->state.frag_mvs; - vdec=!(_enc->state.info.pixel_fmt&2); - notstart=0; - notdone=1; - mcu_nvsbs=_enc->mcu_nvsbs; - for(stripe_sby=0;notdone;stripe_sby+=mcu_nvsbs){ - notdone=oc_enc_pipeline_set_stripe(_enc,&pipe,stripe_sby); - sbi_end=pipe.sbi_end[0]; - for(sbi=pipe.sbi0[0];sbisp_levelsp_levellambda*3; - if(modes[OC_MODE_INTER_MV_FOUR].cost>2][mbi&3][bi]; - frags[fragi].qii=modes[mb_mode].qii[bi]; - } - if(oc_enc_mb_transform_quantize_luma(_enc,&pipe,mbi, - modes[mb_mode].overhead>>OC_BIT_SCALE)>0){ - int orig_mb_mode; - orig_mb_mode=mb_mode; - mb_mode=mb_modes[mbi]; - switch(mb_mode){ - case OC_MODE_INTER_MV:{ - memcpy(prior_mv,last_mv,sizeof(prior_mv)); - /*If we're backing out from 4MV, find the MV we're actually - using.*/ - if(orig_mb_mode==OC_MODE_INTER_MV_FOUR){ - for(bi=0;;bi++){ - fragi=mb_maps[mbi][0][bi]; - if(frags[fragi].coded){ - memcpy(last_mv,frag_mvs[fragi],sizeof(last_mv)); - dx=frag_mvs[fragi][0]; - dy=frag_mvs[fragi][1]; - break; - } - } - mb_mv_bits_0=OC_MV_BITS[0][dx+31]+OC_MV_BITS[0][dy+31]; - } - /*Otherwise we used the original analysis MV.*/ - else{ - memcpy(last_mv, - embs[mbi].analysis_mv[0][OC_FRAME_PREV],sizeof(last_mv)); - } - _enc->mv_bits[0]+=mb_mv_bits_0; - _enc->mv_bits[1]+=12; - }break; - case OC_MODE_INTER_MV_LAST2:{ - oc_mv tmp_mv; - memcpy(tmp_mv,prior_mv,sizeof(tmp_mv)); - memcpy(prior_mv,last_mv,sizeof(prior_mv)); - memcpy(last_mv,tmp_mv,sizeof(last_mv)); - }break; - case OC_MODE_GOLDEN_MV:{ - _enc->mv_bits[0]+=mb_gmv_bits_0; - _enc->mv_bits[1]+=12; - }break; - case OC_MODE_INTER_MV_FOUR:{ - oc_mv lbmvs[4]; - oc_mv cbmvs[4]; - memcpy(prior_mv,last_mv,sizeof(prior_mv)); - for(bi=0;bi<4;bi++){ - fragi=mb_maps[mbi][0][bi]; - if(frags[fragi].coded){ - memcpy(last_mv,frag_mvs[fragi],sizeof(last_mv)); - memcpy(lbmvs[bi],frag_mvs[fragi],sizeof(lbmvs[bi])); - _enc->mv_bits[0]+=OC_MV_BITS[0][frag_mvs[fragi][0]+31] - +OC_MV_BITS[0][frag_mvs[fragi][1]+31]; - _enc->mv_bits[1]+=12; - } - /*Replace the block MVs for not-coded blocks with (0,0).*/ - else memset(lbmvs[bi],0,sizeof(lbmvs[bi])); - } - (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs); - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_maps[mbi][pli][bi]; - frags[fragi].mb_mode=mb_mode; - frags[fragi].qii=modes[OC_MODE_INTER_MV_FOUR].qii[mapii]; - memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(frag_mvs[fragi])); - } - }break; - } - coded_mbis[ncoded_mbis++]=mbi; - oc_mode_scheme_chooser_update(&_enc->chooser,mb_mode); - interbits+=modes[mb_mode].rate+modes[mb_mode].overhead; - } - else{ - *(uncoded_mbis-++nuncoded_mbis)=mbi; - mb_mode=OC_MODE_INTER_NOMV; - dx=dy=0; - } - /*Propagate final MB mode and MVs to the chroma blocks. - This has already been done for 4MV mode, since it requires individual - block motion vectors.*/ - if(mb_mode!=OC_MODE_INTER_MV_FOUR){ - for(mapii=4;mapii>2; - bi=mapi&3; - fragi=mb_maps[mbi][pli][bi]; - frags[fragi].mb_mode=mb_mode; - /*If we switched from 4MV mode to INTER_MV mode, then the qii - values won't have been chosen with the right MV, but it's - probaby not worth re-estimating them.*/ - frags[fragi].qii=modes[mb_mode].qii[mapii]; - frag_mvs[fragi][0]=(signed char)dx; - frag_mvs[fragi][1]=(signed char)dy; - } - } - } - oc_fr_state_flush_sb(pipe.fr+0); - sb_flags[sbi].coded_fully=pipe.fr[0].sb_full; - sb_flags[sbi].coded_partially=pipe.fr[0].sb_partial; - } - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,0,notstart,notdone); - /*Code chroma planes.*/ - for(pli=1;pli<3;pli++){ - oc_enc_sb_transform_quantize_chroma(_enc,&pipe, - pli,pipe.sbi0[pli],pipe.sbi_end[pli]); - oc_enc_pipeline_finish_mcu_plane(_enc,&pipe,pli,notstart,notdone); - } - notstart=1; - } - /*Finish filling in the reference frame borders.*/ - refi=_enc->state.ref_frame_idx[OC_FRAME_SELF]; - for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_enc->state,refi,pli); - /*Finish adding flagging overhead costs to inter bit counts to determine if - we should have coded a key frame instead.*/ - if(_allow_keyframe){ - if(interbits>intrabits)return 1; - /*Technically the chroma plane counts are over-estimations, because they - don't account for continuing runs from the luma planes, but the - inaccuracy is small.*/ - for(pli=0;pli<3;pli++)interbits+=pipe.fr[pli].bits<mv_bits[0],_enc->mv_bits[1])<chooser.scheme_bits[_enc->chooser.scheme_list[0]]<intrabits)return 1; - } - _enc->ncoded_mbis=ncoded_mbis; - /*Compact the coded fragment list.*/ - { - ptrdiff_t ncoded_fragis; - ncoded_fragis=_enc->state.ncoded_fragis[0]; - for(pli=1;pli<3;pli++){ - memmove(_enc->state.coded_fragis+ncoded_fragis, - _enc->state.coded_fragis+_enc->state.fplanes[pli].froffset, - _enc->state.ncoded_fragis[pli]*sizeof(*_enc->state.coded_fragis)); - ncoded_fragis+=_enc->state.ncoded_fragis[pli]; - } - _enc->state.ntotal_coded_fragis=ncoded_fragis; - } - return 0; -} - -#if defined(OC_COLLECT_METRICS) -# include -# include - -/*TODO: It may be helpful (for block-level quantizers especially) to separate - out the contributions from AC and DC into separate tables.*/ - -# define OC_ZWEIGHT (0.25) - -static void oc_mode_metrics_add(oc_mode_metrics *_metrics, - double _w,int _satd,int _rate,double _rmse){ - double rate; - /*Accumulate statistics without the scaling; this lets us change the scale - factor yet still use old data.*/ - rate=ldexp(_rate,-OC_BIT_SCALE); - if(_metrics->fragw>0){ - double dsatd; - double drate; - double drmse; - double w; - dsatd=_satd-_metrics->satd/_metrics->fragw; - drate=rate-_metrics->rate/_metrics->fragw; - drmse=_rmse-_metrics->rmse/_metrics->fragw; - w=_metrics->fragw*_w/(_metrics->fragw+_w); - _metrics->satd2+=dsatd*dsatd*w; - _metrics->satdrate+=dsatd*drate*w; - _metrics->rate2+=drate*drate*w; - _metrics->satdrmse+=dsatd*drmse*w; - _metrics->rmse2+=drmse*drmse*w; - } - _metrics->fragw+=_w; - _metrics->satd+=_satd*_w; - _metrics->rate+=rate*_w; - _metrics->rmse+=_rmse*_w; -} - -static void oc_mode_metrics_merge(oc_mode_metrics *_dst, - const oc_mode_metrics *_src,int _n){ - int i; - /*Find a non-empty set of metrics.*/ - for(i=0;i<_n&&_src[i].fragw<=0;i++); - if(i>=_n){ - memset(_dst,0,sizeof(*_dst)); - return; - } - memcpy(_dst,_src+i,sizeof(*_dst)); - /*And iterate over the remaining non-empty sets of metrics.*/ - for(i++;i<_n;i++)if(_src[i].fragw>0){ - double wa; - double wb; - double dsatd; - double drate; - double drmse; - double w; - wa=_dst->fragw; - wb=_src[i].fragw; - dsatd=_src[i].satd/wb-_dst->satd/wa; - drate=_src[i].rate/wb-_dst->rate/wa; - drmse=_src[i].rmse/wb-_dst->rmse/wa; - w=wa*wb/(wa+wb); - _dst->fragw+=_src[i].fragw; - _dst->satd+=_src[i].satd; - _dst->rate+=_src[i].rate; - _dst->rmse+=_src[i].rmse; - _dst->satd2+=_src[i].satd2+dsatd*dsatd*w; - _dst->satdrate+=_src[i].satdrate+dsatd*drate*w; - _dst->rate2+=_src[i].rate2+drate*drate*w; - _dst->satdrmse+=_src[i].satdrmse+dsatd*drmse*w; - _dst->rmse2+=_src[i].rmse2+drmse*drmse*w; - } -} - -/*Compile collected SATD/rate/RMSE metrics into a form that's immediately - useful for mode decision.*/ -static void oc_enc_mode_metrics_update(oc_enc_ctx *_enc,int _qi){ - int pli; - int qti; - oc_restore_fpu(&_enc->state); - /*Convert raw collected data into cleaned up sample points.*/ - for(pli=0;pli<3;pli++){ - for(qti=0;qti<2;qti++){ - double fragw; - int bin0; - int bin1; - int bin; - fragw=0; - bin0=bin1=0; - for(bin=0;bin=OC_ZWEIGHT){ - fragw-=OC_MODE_METRICS[_qi][pli][qti][bin0++].fragw; - } - /*Merge statistics and fit lines.*/ - oc_mode_metrics_merge(&metrics, - OC_MODE_METRICS[_qi][pli][qti]+bin0,bin1-bin0); - if(metrics.fragw>0&&metrics.satd2>0){ - double a; - double b; - double msatd; - double mrate; - double mrmse; - double rate; - double rmse; - msatd=metrics.satd/metrics.fragw; - mrate=metrics.rate/metrics.fragw; - mrmse=metrics.rmse/metrics.fragw; - /*Compute the points on these lines corresponding to the actual bin - value.*/ - b=metrics.satdrate/metrics.satd2; - a=mrate-b*msatd; - rate=ldexp(a+b*(bin<>1); - return -_extra_bits; -} - -/*Handles the pure zero run tokens.*/ -static ptrdiff_t oc_token_skip_zrl(int _token,int _extra_bits){ - return _extra_bits+1; -} - -/*Handles a normal coefficient value token.*/ -static ptrdiff_t oc_token_skip_val(void){ - return 1; -} - -/*Handles a category 1A zero run/coefficient value combo token.*/ -static ptrdiff_t oc_token_skip_run_cat1a(int _token){ - return _token-OC_DCT_RUN_CAT1A+2; -} - -/*Handles category 1b, 1c, 2a, and 2b zero run/coefficient value combo tokens.*/ -static ptrdiff_t oc_token_skip_run(int _token,int _extra_bits){ - int run_cati; - int ncoeffs_mask; - int ncoeffs_adjust; - run_cati=_token-OC_DCT_RUN_CAT1B; - ncoeffs_mask=OC_BYTE_TABLE32(3,7,0,1,run_cati); - ncoeffs_adjust=OC_BYTE_TABLE32(7,11,2,3,run_cati); - return (_extra_bits&ncoeffs_mask)+ncoeffs_adjust; -} - -/*A jump table for computing the number of coefficients or blocks to skip for - a given token value. - This reduces all the conditional branches, etc., needed to parse these token - values down to one indirect jump.*/ -static const oc_token_skip_func OC_TOKEN_SKIP_TABLE[TH_NDCT_TOKENS]={ - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob, - oc_token_skip_eob6, - oc_token_skip_zrl, - oc_token_skip_zrl, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_val, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - (oc_token_skip_func)oc_token_skip_run_cat1a, - oc_token_skip_run, - oc_token_skip_run, - oc_token_skip_run, - oc_token_skip_run -}; - -/*Determines the number of blocks or coefficients to be skipped for a given - token value. - _token: The token value to skip. - _extra_bits: The extra bits attached to this token. - Return: A positive value indicates that number of coefficients are to be - skipped in the current block. - Otherwise, the negative of the return value indicates that number of - blocks are to be ended. - 0 will never be returned, so that at least one coefficient in one - block will always be decoded for every token.*/ -static ptrdiff_t oc_dct_token_skip(int _token,int _extra_bits){ - return (*OC_TOKEN_SKIP_TABLE[_token])(_token,_extra_bits); -} - - - -void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc){ - static const unsigned char OC_ZZI_HUFF_OFFSET[64]={ - 0,16,16,16,16,16,32,32, - 32,32,32,32,32,32,32,48, - 48,48,48,48,48,48,48,48, - 48,48,48,48,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64 - }; - const oc_fragment *frags; - const unsigned *frag_satd; - const unsigned *frag_ssd; - const ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t fragii; - double fragw; - int qti; - int qii; - int qi; - int pli; - int zzi; - int token; - int eb; - oc_restore_fpu(&_enc->state); - /*Load any existing mode metrics if we haven't already.*/ - if(!oc_has_mode_metrics){ - FILE *fmetrics; - memset(OC_MODE_METRICS,0,sizeof(OC_MODE_METRICS)); - fmetrics=fopen("modedec.stats","rb"); - if(fmetrics!=NULL){ - fread(OC_MODE_METRICS,sizeof(OC_MODE_METRICS),1,fmetrics); - fclose(fmetrics); - } - for(qi=0;qi<64;qi++)oc_enc_mode_metrics_update(_enc,qi); - oc_has_mode_metrics=1; - } - qti=_enc->state.frame_type; - frags=_enc->state.frags; - frag_satd=_enc->frag_satd; - frag_ssd=_enc->frag_ssd; - coded_fragis=_enc->state.coded_fragis; - ncoded_fragis=fragii=0; - /*Weight the fragments by the inverse frame size; this prevents HD content - from dominating the statistics.*/ - fragw=1.0/_enc->state.nfrags; - for(pli=0;pli<3;pli++){ - ptrdiff_t ti[64]; - int eob_token[64]; - int eob_run[64]; - /*Set up token indices and eob run counts. - We don't bother trying to figure out the real cost of the runs that span - coefficients; instead we use the costs that were available when R-D - token optimization was done.*/ - for(zzi=0;zzi<64;zzi++){ - ti[zzi]=_enc->dct_token_offs[pli][zzi]; - if(ti[zzi]>0){ - token=_enc->dct_tokens[pli][zzi][0]; - eb=_enc->extra_bits[pli][zzi][0]; - eob_token[zzi]=token; - eob_run[zzi]=-oc_dct_token_skip(token,eb); - } - else{ - eob_token[zzi]=OC_NDCT_EOB_TOKEN_MAX; - eob_run[zzi]=0; - } - } - /*Scan the list of coded fragments for this plane.*/ - ncoded_fragis+=_enc->state.ncoded_fragis[pli]; - for(;fragii0){ - /*We've reached the end of the block.*/ - eob_run[zzi]--; - break; - } - huffi=_enc->huff_idxs[qti][zzi>0][pli+1>>1] - +OC_ZZI_HUFF_OFFSET[zzi]; - if(eob_token[zzi]huff_codes[huffi][eob_token[zzi]].nbits - +OC_DCT_TOKEN_EXTRA_BITS[eob_token[zzi]]; - eob_token[zzi]=OC_NDCT_EOB_TOKEN_MAX; - } - token=_enc->dct_tokens[pli][zzi][ti[zzi]]; - eb=_enc->extra_bits[pli][zzi][ti[zzi]]; - ti[zzi]++; - skip=oc_dct_token_skip(token,eb); - if(skip<0){ - eob_token[zzi]=token; - eob_run[zzi]=-skip; - } - else{ - /*A regular DCT value token; accumulate the bits for it.*/ - frag_bits+=_enc->huff_codes[huffi][token].nbits - +OC_DCT_TOKEN_EXTRA_BITS[token]; - zzi+=skip; - } - } - mb_mode=frags[fragi].mb_mode; - qi=_enc->state.qis[frags[fragi].qii]; - satd=frag_satd[fragi]<<(pli+1&2); - bin=OC_MINI(satd>>OC_SAD_SHIFT,OC_SAD_BINS-1); - oc_mode_metrics_add(OC_MODE_METRICS[qi][pli][mb_mode!=OC_MODE_INTRA]+bin, - fragw,satd,frag_bits<state.nqis;qii++){ - oc_enc_mode_metrics_update(_enc,_enc->state.qis[qii]); - } -} - -void oc_enc_mode_metrics_dump(oc_enc_ctx *_enc){ - FILE *fmetrics; - int qi; - /*Generate sample points for complete list of QI values.*/ - for(qi=0;qi<64;qi++)oc_enc_mode_metrics_update(_enc,qi); - fmetrics=fopen("modedec.stats","wb"); - if(fmetrics!=NULL){ - fwrite(OC_MODE_METRICS,sizeof(OC_MODE_METRICS),1,fmetrics); - fclose(fmetrics); - } - fprintf(stdout, - "/*File generated by libtheora with OC_COLLECT_METRICS" - " defined at compile time.*/\n" - "#if !defined(_modedec_H)\n" - "# define _modedec_H (1)\n" - "\n" - "\n" - "\n" - "# if defined(OC_COLLECT_METRICS)\n" - "typedef struct oc_mode_metrics oc_mode_metrics;\n" - "# endif\n" - "typedef struct oc_mode_rd oc_mode_rd;\n" - "\n" - "\n" - "\n" - "/*The number of extra bits of precision at which to store rate" - " metrics.*/\n" - "# define OC_BIT_SCALE (%i)\n" - "/*The number of extra bits of precision at which to store RMSE metrics.\n" - " This must be at least half OC_BIT_SCALE (rounded up).*/\n" - "# define OC_RMSE_SCALE (%i)\n" - "/*The number of bins to partition statistics into.*/\n" - "# define OC_SAD_BINS (%i)\n" - "/*The number of bits of precision to drop" - " from SAD scores to assign them to a\n" - " bin.*/\n" - "# define OC_SAD_SHIFT (%i)\n" - "\n" - "\n" - "\n" - "# if defined(OC_COLLECT_METRICS)\n" - "struct oc_mode_metrics{\n" - " double fragw;\n" - " double satd;\n" - " double rate;\n" - " double rmse;\n" - " double satd2;\n" - " double satdrate;\n" - " double rate2;\n" - " double satdrmse;\n" - " double rmse2;\n" - "};\n" - "\n" - "\n" - "int oc_has_mode_metrics;\n" - "oc_mode_metrics OC_MODE_METRICS[64][3][2][OC_SAD_BINS];\n" - "# endif\n" - "\n" - "\n" - "\n" - "struct oc_mode_rd{\n" - " ogg_int16_t rate;\n" - " ogg_int16_t rmse;\n" - "};\n" - "\n" - "\n" - "# if !defined(OC_COLLECT_METRICS)\n" - "static const\n" - "# endif\n" - "oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={\n", - OC_BIT_SCALE,OC_RMSE_SCALE,OC_SAD_BINS,OC_SAD_SHIFT); - for(qi=0;qi<64;qi++){ - int pli; - fprintf(stdout," {\n"); - for(pli=0;pli<3;pli++){ - int qti; - fprintf(stdout," {\n"); - for(qti=0;qti<2;qti++){ - int bin; - static const char *pl_names[3]={"Y'","Cb","Cr"}; - static const char *qti_names[2]={"INTRA","INTER"}; - fprintf(stdout," /*%s qi=%i %s*/\n", - pl_names[pli],qi,qti_names[qti]); - fprintf(stdout," {\n"); - fprintf(stdout," "); - for(bin=0;bin -#include -#include -#include "apiwrapper.h" - - - -const char *theora_version_string(void){ - return th_version_string(); -} - -ogg_uint32_t theora_version_number(void){ - return th_version_number(); -} - -void theora_info_init(theora_info *_ci){ - memset(_ci,0,sizeof(*_ci)); -} - -void theora_info_clear(theora_info *_ci){ - th_api_wrapper *api; - api=(th_api_wrapper *)_ci->codec_setup; - memset(_ci,0,sizeof(*_ci)); - if(api!=NULL){ - if(api->clear!=NULL)(*api->clear)(api); - _ogg_free(api); - } -} - -void theora_clear(theora_state *_th){ - /*Provide compatibility with mixed encoder and decoder shared lib versions.*/ - if(_th->internal_decode!=NULL){ - (*((oc_state_dispatch_vtable *)_th->internal_decode)->clear)(_th); - } - if(_th->internal_encode!=NULL){ - (*((oc_state_dispatch_vtable *)_th->internal_encode)->clear)(_th); - } - if(_th->i!=NULL)theora_info_clear(_th->i); - memset(_th,0,sizeof(*_th)); -} - -int theora_control(theora_state *_th,int _req,void *_buf,size_t _buf_sz){ - /*Provide compatibility with mixed encoder and decoder shared lib versions.*/ - if(_th->internal_decode!=NULL){ - return (*((oc_state_dispatch_vtable *)_th->internal_decode)->control)(_th, - _req,_buf,_buf_sz); - } - else if(_th->internal_encode!=NULL){ - return (*((oc_state_dispatch_vtable *)_th->internal_encode)->control)(_th, - _req,_buf,_buf_sz); - } - else return TH_EINVAL; -} - -ogg_int64_t theora_granule_frame(theora_state *_th,ogg_int64_t _gp){ - /*Provide compatibility with mixed encoder and decoder shared lib versions.*/ - if(_th->internal_decode!=NULL){ - return (*((oc_state_dispatch_vtable *)_th->internal_decode)->granule_frame)( - _th,_gp); - } - else if(_th->internal_encode!=NULL){ - return (*((oc_state_dispatch_vtable *)_th->internal_encode)->granule_frame)( - _th,_gp); - } - else return -1; -} - -double theora_granule_time(theora_state *_th, ogg_int64_t _gp){ - /*Provide compatibility with mixed encoder and decoder shared lib versions.*/ - if(_th->internal_decode!=NULL){ - return (*((oc_state_dispatch_vtable *)_th->internal_decode)->granule_time)( - _th,_gp); - } - else if(_th->internal_encode!=NULL){ - return (*((oc_state_dispatch_vtable *)_th->internal_encode)->granule_time)( - _th,_gp); - } - else return -1; -} - -void oc_theora_info2th_info(th_info *_info,const theora_info *_ci){ - _info->version_major=_ci->version_major; - _info->version_minor=_ci->version_minor; - _info->version_subminor=_ci->version_subminor; - _info->frame_width=_ci->width; - _info->frame_height=_ci->height; - _info->pic_width=_ci->frame_width; - _info->pic_height=_ci->frame_height; - _info->pic_x=_ci->offset_x; - _info->pic_y=_ci->offset_y; - _info->fps_numerator=_ci->fps_numerator; - _info->fps_denominator=_ci->fps_denominator; - _info->aspect_numerator=_ci->aspect_numerator; - _info->aspect_denominator=_ci->aspect_denominator; - switch(_ci->colorspace){ - case OC_CS_ITU_REC_470M:_info->colorspace=TH_CS_ITU_REC_470M;break; - case OC_CS_ITU_REC_470BG:_info->colorspace=TH_CS_ITU_REC_470BG;break; - default:_info->colorspace=TH_CS_UNSPECIFIED;break; - } - switch(_ci->pixelformat){ - case OC_PF_420:_info->pixel_fmt=TH_PF_420;break; - case OC_PF_422:_info->pixel_fmt=TH_PF_422;break; - case OC_PF_444:_info->pixel_fmt=TH_PF_444;break; - default:_info->pixel_fmt=TH_PF_RSVD; - } - _info->target_bitrate=_ci->target_bitrate; - _info->quality=_ci->quality; - _info->keyframe_granule_shift=_ci->keyframe_frequency_force>0? - OC_MINI(31,oc_ilog(_ci->keyframe_frequency_force-1)):0; -} - -int theora_packet_isheader(ogg_packet *_op){ - return th_packet_isheader(_op); -} - -int theora_packet_iskeyframe(ogg_packet *_op){ - return th_packet_iskeyframe(_op); -} - -int theora_granule_shift(theora_info *_ci){ - /*This breaks when keyframe_frequency_force is not positive or is larger than - 2**31 (if your int is more than 32 bits), but that's what the original - function does.*/ - return oc_ilog(_ci->keyframe_frequency_force-1); -} - -void theora_comment_init(theora_comment *_tc){ - th_comment_init((th_comment *)_tc); -} - -char *theora_comment_query(theora_comment *_tc,char *_tag,int _count){ - return th_comment_query((th_comment *)_tc,_tag,_count); -} - -int theora_comment_query_count(theora_comment *_tc,char *_tag){ - return th_comment_query_count((th_comment *)_tc,_tag); -} - -void theora_comment_clear(theora_comment *_tc){ - th_comment_clear((th_comment *)_tc); -} - -void theora_comment_add(theora_comment *_tc,char *_comment){ - th_comment_add((th_comment *)_tc,_comment); -} - -void theora_comment_add_tag(theora_comment *_tc, char *_tag, char *_value){ - th_comment_add_tag((th_comment *)_tc,_tag,_value); -} diff --git a/src/add-ons/media/plugins/theora/libtheora/apiwrapper.h b/src/add-ons/media/plugins/theora/libtheora/apiwrapper.h deleted file mode 100644 index 93454d7bda..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/apiwrapper.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: apiwrapper.h 13596 2007-08-23 20:05:38Z tterribe $ - - ********************************************************************/ - -#if !defined(_apiwrapper_H) -# define _apiwrapper_H (1) -# include -# include -# include "theora/theoradec.h" -# include "theora/theoraenc.h" -# include "internal.h" - -typedef struct th_api_wrapper th_api_wrapper; -typedef struct th_api_info th_api_info; - -/*Provide an entry point for the codec setup to clear itself in case we ever - want to break pieces off into a common base library shared by encoder and - decoder. - In addition, this makes several other pieces of the API wrapper cleaner.*/ -typedef void (*oc_setup_clear_func)(void *_ts); - -/*Generally only one of these pointers will be non-NULL in any given instance. - Technically we do not even really need this struct, since we should be able - to figure out which one from "context", but doing it this way makes sure we - don't flub it up.*/ -struct th_api_wrapper{ - oc_setup_clear_func clear; - th_setup_info *setup; - th_dec_ctx *decode; - th_enc_ctx *encode; -}; - -struct th_api_info{ - th_api_wrapper api; - theora_info info; -}; - - -void oc_theora_info2th_info(th_info *_info,const theora_info *_ci); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/bitpack.c b/src/add-ons/media/plugins/theora/libtheora/bitpack.c deleted file mode 100644 index 8195003bad..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/bitpack.c +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: packing variable sized words into an octet stream - last mod: $Id: bitpack.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include -#include -#include "bitpack.h" - -/*We're 'MSb' endian; if we write a word but read individual bits, - then we'll read the MSb first.*/ - -void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){ - memset(_b,0,sizeof(*_b)); - _b->ptr=_buf; - _b->stop=_buf+_bytes; -} - -static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){ - const unsigned char *ptr; - const unsigned char *stop; - oc_pb_window window; - int available; - window=_b->window; - available=_b->bits; - ptr=_b->ptr; - stop=_b->stop; - while(available<=OC_PB_WINDOW_SIZE-8&&ptrptr=ptr; - if(_bits>available){ - if(ptr>=stop){ - _b->eof=1; - available=OC_LOTS_OF_BITS; - } - else window|=*ptr>>(available&7); - } - _b->bits=available; - return window; -} - -int oc_pack_look1(oc_pack_buf *_b){ - oc_pb_window window; - int available; - window=_b->window; - available=_b->bits; - if(available<1)_b->window=window=oc_pack_refill(_b,1); - return window>>OC_PB_WINDOW_SIZE-1; -} - -void oc_pack_adv1(oc_pack_buf *_b){ - _b->window<<=1; - _b->bits--; -} - -/*Here we assume that 0<=_bits&&_bits<=32.*/ -long oc_pack_read(oc_pack_buf *_b,int _bits){ - oc_pb_window window; - int available; - long result; - window=_b->window; - available=_b->bits; - if(_bits==0)return 0; - if(available<_bits){ - window=oc_pack_refill(_b,_bits); - available=_b->bits; - } - result=window>>OC_PB_WINDOW_SIZE-_bits; - available-=_bits; - window<<=1; - window<<=_bits-1; - _b->bits=available; - _b->window=window; - return result; -} - -int oc_pack_read1(oc_pack_buf *_b){ - oc_pb_window window; - int available; - int result; - window=_b->window; - available=_b->bits; - if(available<1){ - window=oc_pack_refill(_b,1); - available=_b->bits; - } - result=window>>OC_PB_WINDOW_SIZE-1; - available--; - window<<=1; - _b->bits=available; - _b->window=window; - return result; -} - -long oc_pack_bytes_left(oc_pack_buf *_b){ - if(_b->eof)return -1; - return _b->stop-_b->ptr+(_b->bits>>3); -} diff --git a/src/add-ons/media/plugins/theora/libtheora/bitpack.h b/src/add-ons/media/plugins/theora/libtheora/bitpack.h deleted file mode 100644 index a020a292f5..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/bitpack.h +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: packing variable sized words into an octet stream - last mod: $Id: bitwise.c 7675 2004-09-01 00:34:39Z xiphmont $ - - ********************************************************************/ -#if !defined(_bitpack_H) -# define _bitpack_H (1) -# include - - - -typedef unsigned long oc_pb_window; -typedef struct oc_pack_buf oc_pack_buf; - - - -# define OC_PB_WINDOW_SIZE ((int)sizeof(oc_pb_window)*CHAR_BIT) -/*This is meant to be a large, positive constant that can still be efficiently - loaded as an immediate (on platforms like ARM, for example). - Even relatively modest values like 100 would work fine.*/ -# define OC_LOTS_OF_BITS (0x40000000) - - - -struct oc_pack_buf{ - oc_pb_window window; - const unsigned char *ptr; - const unsigned char *stop; - int bits; - int eof; -}; - -void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes); -int oc_pack_look1(oc_pack_buf *_b); -void oc_pack_adv1(oc_pack_buf *_b); -/*Here we assume 0<=_bits&&_bits<=32.*/ -long oc_pack_read(oc_pack_buf *_b,int _bits); -int oc_pack_read1(oc_pack_buf *_b); -/* returns -1 for read beyond EOF, or the number of whole bytes available */ -long oc_pack_bytes_left(oc_pack_buf *_b); - -/*These two functions are implemented locally in huffdec.c*/ -/*Read in bits without advancing the bitptr. - Here we assume 0<=_bits&&_bits<=32.*/ -/*static int oc_pack_look(oc_pack_buf *_b,int _bits);*/ -/*static void oc_pack_adv(oc_pack_buf *_b,int _bits);*/ - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/cpu.c b/src/add-ons/media/plugins/theora/libtheora/cpu.c deleted file mode 100644 index a863aad7f3..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/cpu.c +++ /dev/null @@ -1,226 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - CPU capability detection for x86 processors. - Originally written by Rudolf Marek. - - function: - last mod: $Id: cpu.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include "cpu.h" - -#if !defined(OC_X86_ASM) -static ogg_uint32_t oc_cpu_flags_get(void){ - return 0; -} -#else -# if !defined(_MSC_VER) -# if defined(__amd64__)||defined(__x86_64__) -/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when - compiling with -fPIC.*/ -# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ - __asm__ __volatile__( \ - "cpuid\n\t" \ - :[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \ - :"a"(_op) \ - :"cc" \ - ) -# else -/*On x86-32, not so much.*/ -# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ - __asm__ __volatile__( \ - "xchgl %%ebx,%[ebx]\n\t" \ - "cpuid\n\t" \ - "xchgl %%ebx,%[ebx]\n\t" \ - :[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \ - :"a"(_op) \ - :"cc" \ - ) -# endif -# else -/*Why does MSVC need this complicated rigamarole? - At this point I honestly do not care.*/ - -/*Visual C cpuid helper function. - For VS2005 we could as well use the _cpuid builtin, but that wouldn't work - for VS2003 users, so we do it in inline assembler.*/ -static void oc_cpuid_helper(ogg_uint32_t _cpu_info[4],ogg_uint32_t _op){ - _asm{ - mov eax,[_op] - mov esi,_cpu_info - cpuid - mov [esi+0],eax - mov [esi+4],ebx - mov [esi+8],ecx - mov [esi+12],edx - } -} - -# define cpuid(_op,_eax,_ebx,_ecx,_edx) \ - do{ \ - ogg_uint32_t cpu_info[4]; \ - oc_cpuid_helper(cpu_info,_op); \ - (_eax)=cpu_info[0]; \ - (_ebx)=cpu_info[1]; \ - (_ecx)=cpu_info[2]; \ - (_edx)=cpu_info[3]; \ - }while(0) - -static void oc_detect_cpuid_helper(ogg_uint32_t *_eax,ogg_uint32_t *_ebx){ - _asm{ - pushfd - pushfd - pop eax - mov ebx,eax - xor eax,200000h - push eax - popfd - pushfd - pop eax - popfd - mov ecx,_eax - mov [ecx],eax - mov ecx,_ebx - mov [ecx],ebx - } -} -# endif - -static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){ - ogg_uint32_t flags; - /*If there isn't even MMX, give up.*/ - if(!(_edx&0x00800000))return 0; - flags=OC_CPU_X86_MMX; - if(_edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE; - if(_edx&0x04000000)flags|=OC_CPU_X86_SSE2; - if(_ecx&0x00000001)flags|=OC_CPU_X86_PNI; - if(_ecx&0x00000100)flags|=OC_CPU_X86_SSSE3; - if(_ecx&0x00080000)flags|=OC_CPU_X86_SSE4_1; - if(_ecx&0x00100000)flags|=OC_CPU_X86_SSE4_2; - return flags; -} - -static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){ - ogg_uint32_t flags; - /*If there isn't even MMX, give up.*/ - if(!(_edx&0x00800000))return 0; - flags=OC_CPU_X86_MMX; - if(_edx&0x00400000)flags|=OC_CPU_X86_MMXEXT; - if(_edx&0x80000000)flags|=OC_CPU_X86_3DNOW; - if(_edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT; - if(_ecx&0x00000040)flags|=OC_CPU_X86_SSE4A; - if(_ecx&0x00000800)flags|=OC_CPU_X86_SSE5; - return flags; -} - -static ogg_uint32_t oc_cpu_flags_get(void){ - ogg_uint32_t flags; - ogg_uint32_t eax; - ogg_uint32_t ebx; - ogg_uint32_t ecx; - ogg_uint32_t edx; -# if !defined(__amd64__)&&!defined(__x86_64__) - /*Not all x86-32 chips support cpuid, so we have to check.*/ -# if !defined(_MSC_VER) - __asm__ __volatile__( - "pushfl\n\t" - "pushfl\n\t" - "popl %[a]\n\t" - "movl %[a],%[b]\n\t" - "xorl $0x200000,%[a]\n\t" - "pushl %[a]\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %[a]\n\t" - "popfl\n\t" - :[a]"=r"(eax),[b]"=r"(ebx) - : - :"cc" - ); -# else - oc_detect_cpuid_helper(&eax,&ebx); -# endif - /*No cpuid.*/ - if(eax==ebx)return 0; -# endif - cpuid(0,eax,ebx,ecx,edx); - /* l e t n I e n i u n e G*/ - if(ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547|| - /* 6 8 x M T e n i u n e G*/ - ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547){ - /*Intel, Transmeta (tested with Crusoe TM5800):*/ - cpuid(1,eax,ebx,ecx,edx); - flags=oc_parse_intel_flags(edx,ecx); - } - /* D M A c i t n e h t u A*/ - else if(ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541|| - /* C S N y b e d o e G*/ - ecx==0x43534e20&&edx==0x79622065&&ebx==0x646f6547){ - /*AMD, Geode:*/ - cpuid(0x80000000,eax,ebx,ecx,edx); - if(eax<0x80000001)flags=0; - else{ - cpuid(0x80000001,eax,ebx,ecx,edx); - flags=oc_parse_amd_flags(edx,ecx); - } - /*Also check for SSE.*/ - cpuid(1,eax,ebx,ecx,edx); - flags|=oc_parse_intel_flags(edx,ecx); - } - /*Technically some VIA chips can be configured in the BIOS to return any - string here the user wants. - There is a special detection method that can be used to identify such - processors, but in my opinion, if the user really wants to change it, they - deserve what they get.*/ - /* s l u a H r u a t n e C*/ - else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){ - /*VIA:*/ - /*I only have documentation for the C7 (Esther) and Isaiah (forthcoming) - chips (thanks to the engineers from Centaur Technology who provided it). - These chips support Intel-like cpuid info. - The C3-2 (Nehemiah) cores appear to, as well.*/ - cpuid(1,eax,ebx,ecx,edx); - flags=oc_parse_intel_flags(edx,ecx); - if(eax>=0x80000001){ - /*The (non-Nehemiah) C3 processors support AMD-like cpuid info. - We need to check this even if the Intel test succeeds to pick up 3DNow! - support on these processors. - Unlike actual AMD processors, we cannot _rely_ on this info, since - some cores (e.g., the 693 stepping of the Nehemiah) claim to support - this function, yet return edx=0, despite the Intel test indicating - MMX support. - Therefore the features detected here are strictly added to those - detected by the Intel test.*/ - /*TODO: How about earlier chips?*/ - cpuid(0x80000001,eax,ebx,ecx,edx); - /*Note: As of the C7, this function returns Intel-style extended feature - flags, not AMD-style. - Currently, this only defines bits 11, 20, and 29 (0x20100800), which - do not conflict with any of the AMD flags we inspect. - For the remaining bits, Intel tells us, "Do not count on their value", - but VIA assures us that they will all be zero (at least on the C7 and - Isaiah chips). - In the (unlikely) event a future processor uses bits 18, 19, 30, or 31 - (0xC0C00000) for something else, we will have to add code to detect - the model to decide when it is appropriate to inspect them.*/ - flags|=oc_parse_amd_flags(edx,ecx); - } - } - else{ - /*Implement me.*/ - flags=0; - } - return flags; -} -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/cpu.h b/src/add-ons/media/plugins/theora/libtheora/cpu.h deleted file mode 100644 index a43c957a39..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/cpu.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - function: - last mod: $Id: cpu.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#if !defined(_x86_cpu_H) -# define _x86_cpu_H (1) -#include "internal.h" - -#define OC_CPU_X86_MMX (1<<0) -#define OC_CPU_X86_3DNOW (1<<1) -#define OC_CPU_X86_3DNOWEXT (1<<2) -#define OC_CPU_X86_MMXEXT (1<<3) -#define OC_CPU_X86_SSE (1<<4) -#define OC_CPU_X86_SSE2 (1<<5) -#define OC_CPU_X86_PNI (1<<6) -#define OC_CPU_X86_SSSE3 (1<<7) -#define OC_CPU_X86_SSE4_1 (1<<8) -#define OC_CPU_X86_SSE4_2 (1<<9) -#define OC_CPU_X86_SSE4A (1<<10) -#define OC_CPU_X86_SSE5 (1<<11) - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/dct.h b/src/add-ons/media/plugins/theora/libtheora/dct.h deleted file mode 100644 index 24ba6f111a..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/dct.h +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: dct.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -/*Definitions shared by the forward and inverse DCT transforms.*/ -#if !defined(_dct_H) -# define _dct_H (1) - -/*cos(n*pi/16) (resp. sin(m*pi/16)) scaled by 65536.*/ -#define OC_C1S7 ((ogg_int32_t)64277) -#define OC_C2S6 ((ogg_int32_t)60547) -#define OC_C3S5 ((ogg_int32_t)54491) -#define OC_C4S4 ((ogg_int32_t)46341) -#define OC_C5S3 ((ogg_int32_t)36410) -#define OC_C6S2 ((ogg_int32_t)25080) -#define OC_C7S1 ((ogg_int32_t)12785) - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/decapiwrapper.c b/src/add-ons/media/plugins/theora/libtheora/decapiwrapper.c deleted file mode 100644 index 12ea475d17..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/decapiwrapper.c +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: decapiwrapper.c 13596 2007-08-23 20:05:38Z tterribe $ - - ********************************************************************/ - -#include -#include -#include -#include "apiwrapper.h" -#include "decint.h" -#include "theora/theoradec.h" - -static void th_dec_api_clear(th_api_wrapper *_api){ - if(_api->setup)th_setup_free(_api->setup); - if(_api->decode)th_decode_free(_api->decode); - memset(_api,0,sizeof(*_api)); -} - -static void theora_decode_clear(theora_state *_td){ - if(_td->i!=NULL)theora_info_clear(_td->i); - memset(_td,0,sizeof(*_td)); -} - -static int theora_decode_control(theora_state *_td,int _req, - void *_buf,size_t _buf_sz){ - return th_decode_ctl(((th_api_wrapper *)_td->i->codec_setup)->decode, - _req,_buf,_buf_sz); -} - -static ogg_int64_t theora_decode_granule_frame(theora_state *_td, - ogg_int64_t _gp){ - return th_granule_frame(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp); -} - -static double theora_decode_granule_time(theora_state *_td,ogg_int64_t _gp){ - return th_granule_time(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp); -} - -static const oc_state_dispatch_vtable OC_DEC_DISPATCH_VTBL={ - (oc_state_clear_func)theora_decode_clear, - (oc_state_control_func)theora_decode_control, - (oc_state_granule_frame_func)theora_decode_granule_frame, - (oc_state_granule_time_func)theora_decode_granule_time, -}; - -static void th_info2theora_info(theora_info *_ci,const th_info *_info){ - _ci->version_major=_info->version_major; - _ci->version_minor=_info->version_minor; - _ci->version_subminor=_info->version_subminor; - _ci->width=_info->frame_width; - _ci->height=_info->frame_height; - _ci->frame_width=_info->pic_width; - _ci->frame_height=_info->pic_height; - _ci->offset_x=_info->pic_x; - _ci->offset_y=_info->pic_y; - _ci->fps_numerator=_info->fps_numerator; - _ci->fps_denominator=_info->fps_denominator; - _ci->aspect_numerator=_info->aspect_numerator; - _ci->aspect_denominator=_info->aspect_denominator; - switch(_info->colorspace){ - case TH_CS_ITU_REC_470M:_ci->colorspace=OC_CS_ITU_REC_470M;break; - case TH_CS_ITU_REC_470BG:_ci->colorspace=OC_CS_ITU_REC_470BG;break; - default:_ci->colorspace=OC_CS_UNSPECIFIED;break; - } - switch(_info->pixel_fmt){ - case TH_PF_420:_ci->pixelformat=OC_PF_420;break; - case TH_PF_422:_ci->pixelformat=OC_PF_422;break; - case TH_PF_444:_ci->pixelformat=OC_PF_444;break; - default:_ci->pixelformat=OC_PF_RSVD; - } - _ci->target_bitrate=_info->target_bitrate; - _ci->quality=_info->quality; - _ci->keyframe_frequency_force=1<<_info->keyframe_granule_shift; -} - -int theora_decode_init(theora_state *_td,theora_info *_ci){ - th_api_info *apiinfo; - th_api_wrapper *api; - th_info info; - api=(th_api_wrapper *)_ci->codec_setup; - /*Allocate our own combined API wrapper/theora_info struct. - We put them both in one malloc'd block so that when the API wrapper is - freed, the info struct goes with it. - This avoids having to figure out whether or not we need to free the info - struct in either theora_info_clear() or theora_clear().*/ - apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo)); - if(apiinfo==NULL)return OC_FAULT; - /*Make our own copy of the info struct, since its lifetime should be - independent of the one we were passed in.*/ - *&apiinfo->info=*_ci; - /*Convert the info struct now instead of saving the the one we decoded with - theora_decode_header(), since the user might have modified values (i.e., - color space, aspect ratio, etc. can be specified from a higher level). - The user also might be doing something "clever" with the header packets if - they are not using an Ogg encapsulation.*/ - oc_theora_info2th_info(&info,_ci); - /*Don't bother to copy the setup info; th_decode_alloc() makes its own copy - of the stuff it needs.*/ - apiinfo->api.decode=th_decode_alloc(&info,api->setup); - if(apiinfo->api.decode==NULL){ - _ogg_free(apiinfo); - return OC_EINVAL; - } - apiinfo->api.clear=(oc_setup_clear_func)th_dec_api_clear; - _td->internal_encode=NULL; - /*Provide entry points for ABI compatibility with old decoder shared libs.*/ - _td->internal_decode=(void *)&OC_DEC_DISPATCH_VTBL; - _td->granulepos=0; - _td->i=&apiinfo->info; - _td->i->codec_setup=&apiinfo->api; - return 0; -} - -int theora_decode_header(theora_info *_ci,theora_comment *_cc,ogg_packet *_op){ - th_api_wrapper *api; - th_info info; - int ret; - api=(th_api_wrapper *)_ci->codec_setup; - /*Allocate an API wrapper struct on demand, since it will not also include a - theora_info struct like the ones that are used in a theora_state struct.*/ - if(api==NULL){ - _ci->codec_setup=_ogg_calloc(1,sizeof(*api)); - if(_ci->codec_setup==NULL)return OC_FAULT; - api=(th_api_wrapper *)_ci->codec_setup; - api->clear=(oc_setup_clear_func)th_dec_api_clear; - } - /*Convert from the theora_info struct instead of saving our own th_info - struct between calls. - The user might be doing something "clever" with the header packets if they - are not using an Ogg encapsulation, and we don't want to break this.*/ - oc_theora_info2th_info(&info,_ci); - /*We rely on the fact that theora_comment and th_comment structures are - actually identical. - Take care not to change this fact unless you change the code here as - well!*/ - ret=th_decode_headerin(&info,(th_comment *)_cc,&api->setup,_op); - /*We also rely on the fact that the error return code values are the same, - and that the implementations of these two functions return the same set of - them. - Note that theora_decode_header() really can return OC_NOTFORMAT, even - though it is not currently documented to do so.*/ - if(ret<0)return ret; - th_info2theora_info(_ci,&info); - return 0; -} - -int theora_decode_packetin(theora_state *_td,ogg_packet *_op){ - th_api_wrapper *api; - ogg_int64_t gp; - int ret; - if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT; - api=(th_api_wrapper *)_td->i->codec_setup; - ret=th_decode_packetin(api->decode,_op,&gp); - if(ret<0)return OC_BADPACKET; - _td->granulepos=gp; - return 0; -} - -int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){ - th_api_wrapper *api; - th_dec_ctx *decode; - th_ycbcr_buffer buf; - int ret; - if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT; - api=(th_api_wrapper *)_td->i->codec_setup; - decode=(th_dec_ctx *)api->decode; - if(!decode)return OC_FAULT; - ret=th_decode_ycbcr_out(decode,buf); - if(ret>=0){ - _yuv->y_width=buf[0].width; - _yuv->y_height=buf[0].height; - _yuv->y_stride=buf[0].stride; - _yuv->uv_width=buf[1].width; - _yuv->uv_height=buf[1].height; - _yuv->uv_stride=buf[1].stride; - _yuv->y=buf[0].data; - _yuv->u=buf[1].data; - _yuv->v=buf[2].data; - } - return ret; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/decinfo.c b/src/add-ons/media/plugins/theora/libtheora/decinfo.c deleted file mode 100644 index 845eb1361c..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/decinfo.c +++ /dev/null @@ -1,246 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: decinfo.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include -#include -#include -#include "decint.h" - - - -/*Unpacks a series of octets from a given byte array into the pack buffer. - No checking is done to ensure the buffer contains enough data. - _opb: The pack buffer to read the octets from. - _buf: The byte array to store the unpacked bytes in. - _len: The number of octets to unpack.*/ -static void oc_unpack_octets(oc_pack_buf *_opb,char *_buf,size_t _len){ - while(_len-->0){ - long val; - val=oc_pack_read(_opb,8); - *_buf++=(char)val; - } -} - -/*Unpacks a 32-bit integer encoded by octets in little-endian form.*/ -static long oc_unpack_length(oc_pack_buf *_opb){ - long ret[4]; - int i; - for(i=0;i<4;i++)ret[i]=oc_pack_read(_opb,8); - return ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24; -} - -static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){ - long val; - /*Check the codec bitstream version.*/ - val=oc_pack_read(_opb,8); - _info->version_major=(unsigned char)val; - val=oc_pack_read(_opb,8); - _info->version_minor=(unsigned char)val; - val=oc_pack_read(_opb,8); - _info->version_subminor=(unsigned char)val; - /*verify we can parse this bitstream version. - We accept earlier minors and all subminors, by spec*/ - if(_info->version_major>TH_VERSION_MAJOR|| - _info->version_major==TH_VERSION_MAJOR&& - _info->version_minor>TH_VERSION_MINOR){ - return TH_EVERSION; - } - /*Read the encoded frame description.*/ - val=oc_pack_read(_opb,16); - _info->frame_width=(ogg_uint32_t)val<<4; - val=oc_pack_read(_opb,16); - _info->frame_height=(ogg_uint32_t)val<<4; - val=oc_pack_read(_opb,24); - _info->pic_width=(ogg_uint32_t)val; - val=oc_pack_read(_opb,24); - _info->pic_height=(ogg_uint32_t)val; - val=oc_pack_read(_opb,8); - _info->pic_x=(ogg_uint32_t)val; - val=oc_pack_read(_opb,8); - _info->pic_y=(ogg_uint32_t)val; - val=oc_pack_read(_opb,32); - _info->fps_numerator=(ogg_uint32_t)val; - val=oc_pack_read(_opb,32); - _info->fps_denominator=(ogg_uint32_t)val; - if(_info->frame_width==0||_info->frame_height==0|| - _info->pic_width+_info->pic_x>_info->frame_width|| - _info->pic_height+_info->pic_y>_info->frame_height|| - _info->fps_numerator==0||_info->fps_denominator==0){ - return TH_EBADHEADER; - } - /*Note: The sense of pic_y is inverted in what we pass back to the - application compared to how it is stored in the bitstream. - This is because the bitstream uses a right-handed coordinate system, while - applications expect a left-handed one.*/ - _info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y; - val=oc_pack_read(_opb,24); - _info->aspect_numerator=(ogg_uint32_t)val; - val=oc_pack_read(_opb,24); - _info->aspect_denominator=(ogg_uint32_t)val; - val=oc_pack_read(_opb,8); - _info->colorspace=(th_colorspace)val; - val=oc_pack_read(_opb,24); - _info->target_bitrate=(int)val; - val=oc_pack_read(_opb,6); - _info->quality=(int)val; - val=oc_pack_read(_opb,5); - _info->keyframe_granule_shift=(int)val; - val=oc_pack_read(_opb,2); - _info->pixel_fmt=(th_pixel_fmt)val; - if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER; - val=oc_pack_read(_opb,3); - if(val!=0||oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER; - return 0; -} - -static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){ - long len; - int i; - /*Read the vendor string.*/ - len=oc_unpack_length(_opb); - if(len<0||len>oc_pack_bytes_left(_opb))return TH_EBADHEADER; - _tc->vendor=_ogg_malloc((size_t)len+1); - if(_tc->vendor==NULL)return TH_EFAULT; - oc_unpack_octets(_opb,_tc->vendor,len); - _tc->vendor[len]='\0'; - /*Read the user comments.*/ - _tc->comments=(int)oc_unpack_length(_opb); - len=_tc->comments; - if(len<0||len>(LONG_MAX>>2)||len<<2>oc_pack_bytes_left(_opb)){ - _tc->comments=0; - return TH_EBADHEADER; - } - _tc->comment_lengths=(int *)_ogg_malloc( - _tc->comments*sizeof(_tc->comment_lengths[0])); - _tc->user_comments=(char **)_ogg_malloc( - _tc->comments*sizeof(_tc->user_comments[0])); - for(i=0;i<_tc->comments;i++){ - len=oc_unpack_length(_opb); - if(len<0||len>oc_pack_bytes_left(_opb)){ - _tc->comments=i; - return TH_EBADHEADER; - } - _tc->comment_lengths[i]=len; - _tc->user_comments[i]=_ogg_malloc((size_t)len+1); - if(_tc->user_comments[i]==NULL){ - _tc->comments=i; - return TH_EFAULT; - } - oc_unpack_octets(_opb,_tc->user_comments[i],len); - _tc->user_comments[i][len]='\0'; - } - return oc_pack_bytes_left(_opb)<0?TH_EBADHEADER:0; -} - -static int oc_setup_unpack(oc_pack_buf *_opb,th_setup_info *_setup){ - int ret; - /*Read the quantizer tables.*/ - ret=oc_quant_params_unpack(_opb,&_setup->qinfo); - if(ret<0)return ret; - /*Read the Huffman trees.*/ - return oc_huff_trees_unpack(_opb,_setup->huff_tables); -} - -static void oc_setup_clear(th_setup_info *_setup){ - oc_quant_params_clear(&_setup->qinfo); - oc_huff_trees_clear(_setup->huff_tables); -} - -static int oc_dec_headerin(oc_pack_buf *_opb,th_info *_info, - th_comment *_tc,th_setup_info **_setup,ogg_packet *_op){ - char buffer[6]; - long val; - int packtype; - int ret; - val=oc_pack_read(_opb,8); - packtype=(int)val; - /*If we're at a data packet and we have received all three headers, we're - done.*/ - if(!(packtype&0x80)&&_info->frame_width>0&&_tc->vendor!=NULL&&*_setup!=NULL){ - return 0; - } - /*Check the codec string.*/ - oc_unpack_octets(_opb,buffer,6); - if(memcmp(buffer,"theora",6)!=0)return TH_ENOTFORMAT; - switch(packtype){ - /*Codec info header.*/ - case 0x80:{ - /*This should be the first packet, and we should not already be - initialized.*/ - if(!_op->b_o_s||_info->frame_width>0)return TH_EBADHEADER; - ret=oc_info_unpack(_opb,_info); - if(ret<0)th_info_clear(_info); - else ret=3; - }break; - /*Comment header.*/ - case 0x81:{ - if(_tc==NULL)return TH_EFAULT; - /*We shoud have already decoded the info header, and should not yet have - decoded the comment header.*/ - if(_info->frame_width==0||_tc->vendor!=NULL)return TH_EBADHEADER; - ret=oc_comment_unpack(_opb,_tc); - if(ret<0)th_comment_clear(_tc); - else ret=2; - }break; - /*Codec setup header.*/ - case 0x82:{ - oc_setup_info *setup; - if(_tc==NULL||_setup==NULL)return TH_EFAULT; - /*We should have already decoded the info header and the comment header, - and should not yet have decoded the setup header.*/ - if(_info->frame_width==0||_tc->vendor==NULL||*_setup!=NULL){ - return TH_EBADHEADER; - } - setup=(oc_setup_info *)_ogg_calloc(1,sizeof(*setup)); - if(setup==NULL)return TH_EFAULT; - ret=oc_setup_unpack(_opb,setup); - if(ret<0){ - oc_setup_clear(setup); - _ogg_free(setup); - } - else{ - *_setup=setup; - ret=1; - } - }break; - default:{ - /*We don't know what this header is.*/ - return TH_EBADHEADER; - }break; - } - return ret; -} - - -/*Decodes one header packet. - This should be called repeatedly with the packets at the beginning of the - stream until it returns 0.*/ -int th_decode_headerin(th_info *_info,th_comment *_tc, - th_setup_info **_setup,ogg_packet *_op){ - oc_pack_buf opb; - if(_op==NULL)return TH_EBADHEADER; - if(_info==NULL)return TH_EFAULT; - oc_pack_readinit(&opb,_op->packet,_op->bytes); - return oc_dec_headerin(&opb,_info,_tc,_setup,_op); -} - -void th_setup_free(th_setup_info *_setup){ - if(_setup!=NULL){ - oc_setup_clear(_setup); - _ogg_free(_setup); - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/decint.h b/src/add-ons/media/plugins/theora/libtheora/decint.h deleted file mode 100644 index 261b67631a..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/decint.h +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: decint.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include -#if !defined(_decint_H) -# define _decint_H (1) -# include "theora/theoradec.h" -# include "internal.h" -# include "bitpack.h" - -typedef struct th_setup_info oc_setup_info; -typedef struct th_dec_ctx oc_dec_ctx; - -# include "huffdec.h" -# include "dequant.h" - -/*Constants for the packet-in state machine specific to the decoder.*/ - -/*Next packet to read: Data packet.*/ -#define OC_PACKET_DATA (0) - - - -struct th_setup_info{ - /*The Huffman codes.*/ - oc_huff_node *huff_tables[TH_NHUFFMAN_TABLES]; - /*The quantization parameters.*/ - th_quant_info qinfo; -}; - - - -struct th_dec_ctx{ - /*Shared encoder/decoder state.*/ - oc_theora_state state; - /*Whether or not packets are ready to be emitted. - This takes on negative values while there are remaining header packets to - be emitted, reaches 0 when the codec is ready for input, and goes to 1 - when a frame has been processed and a data packet is ready.*/ - int packet_state; - /*Buffer in which to assemble packets.*/ - oc_pack_buf opb; - /*Huffman decode trees.*/ - oc_huff_node *huff_tables[TH_NHUFFMAN_TABLES]; - /*The index of the first token in each plane for each coefficient.*/ - ptrdiff_t ti0[3][64]; - /*The number of outstanding EOB runs at the start of each coefficient in each - plane.*/ - ptrdiff_t eob_runs[3][64]; - /*The DCT token lists.*/ - unsigned char *dct_tokens; - /*The extra bits associated with DCT tokens.*/ - unsigned char *extra_bits; - /*The number of dct tokens unpacked so far.*/ - int dct_tokens_count; - /*The out-of-loop post-processing level.*/ - int pp_level; - /*The DC scale used for out-of-loop deblocking.*/ - int pp_dc_scale[64]; - /*The sharpen modifier used for out-of-loop deringing.*/ - int pp_sharp_mod[64]; - /*The DC quantization index of each block.*/ - unsigned char *dc_qis; - /*The variance of each block.*/ - int *variances; - /*The storage for the post-processed frame buffer.*/ - unsigned char *pp_frame_data; - /*Whether or not the post-processsed frame buffer has space for chroma.*/ - int pp_frame_state; - /*The buffer used for the post-processed frame. - Note that this is _not_ guaranteed to have the same strides and offsets as - the reference frame buffers.*/ - th_ycbcr_buffer pp_frame_buf; - /*The striped decode callback function.*/ - th_stripe_callback stripe_cb; -# if defined(HAVE_CAIRO) - /*Output metrics for debugging.*/ - int telemetry; - int telemetry_mbmode; - int telemetry_mv; - int telemetry_qi; - int telemetry_bits; - int telemetry_frame_bytes; - int telemetry_coding_bytes; - int telemetry_mode_bytes; - int telemetry_mv_bytes; - int telemetry_qi_bytes; - int telemetry_dc_bytes; - unsigned char *telemetry_frame_data; -# endif -}; - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/decode.c b/src/add-ons/media/plugins/theora/libtheora/decode.c deleted file mode 100644 index 66e64295a3..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/decode.c +++ /dev/null @@ -1,2943 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: decode.c 33343 2009-09-29 00:37:35Z phoudoin $ - - ********************************************************************/ - -#include -#include -#include -#include "decint.h" -#if defined(OC_DUMP_IMAGES) -# include -# include "png.h" -#endif -#if defined(HAVE_CAIRO) -# include -#endif - - -/*No post-processing.*/ -#define OC_PP_LEVEL_DISABLED (0) -/*Keep track of DC qi for each block only.*/ -#define OC_PP_LEVEL_TRACKDCQI (1) -/*Deblock the luma plane.*/ -#define OC_PP_LEVEL_DEBLOCKY (2) -/*Dering the luma plane.*/ -#define OC_PP_LEVEL_DERINGY (3) -/*Stronger luma plane deringing.*/ -#define OC_PP_LEVEL_SDERINGY (4) -/*Deblock the chroma planes.*/ -#define OC_PP_LEVEL_DEBLOCKC (5) -/*Dering the chroma planes.*/ -#define OC_PP_LEVEL_DERINGC (6) -/*Stronger chroma plane deringing.*/ -#define OC_PP_LEVEL_SDERINGC (7) -/*Maximum valid post-processing level.*/ -#define OC_PP_LEVEL_MAX (7) - - - -/*The mode alphabets for the various mode coding schemes. - Scheme 0 uses a custom alphabet, which is not stored in this table.*/ -static const unsigned char OC_MODE_ALPHABETS[7][OC_NMODES]={ - /*Last MV dominates */ - { - OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_MV, - OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV, - OC_MODE_INTER_MV_FOUR - }, - { - OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_NOMV, - OC_MODE_INTER_MV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV, - OC_MODE_INTER_MV_FOUR - }, - { - OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV,OC_MODE_INTER_MV_LAST2, - OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV, - OC_MODE_INTER_MV_FOUR - }, - { - OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV,OC_MODE_INTER_NOMV, - OC_MODE_INTER_MV_LAST2,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV, - OC_MODE_GOLDEN_MV,OC_MODE_INTER_MV_FOUR - }, - /*No MV dominates.*/ - { - OC_MODE_INTER_NOMV,OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2, - OC_MODE_INTER_MV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV, - OC_MODE_INTER_MV_FOUR - }, - { - OC_MODE_INTER_NOMV,OC_MODE_GOLDEN_NOMV,OC_MODE_INTER_MV_LAST, - OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_MV,OC_MODE_INTRA,OC_MODE_GOLDEN_MV, - OC_MODE_INTER_MV_FOUR - }, - /*Default ordering.*/ - { - OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_INTER_MV,OC_MODE_INTER_MV_LAST, - OC_MODE_INTER_MV_LAST2,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV, - OC_MODE_INTER_MV_FOUR - } -}; - - -/*The original DCT tokens are extended and reordered during the construction of - the Huffman tables. - The extension means more bits can be read with fewer calls to the bitpacker - during the Huffman decoding process (at the cost of larger Huffman tables), - and fewer tokens require additional extra bits (reducing the average storage - per decoded token). - The revised ordering reveals essential information in the token value - itself; specifically, whether or not there are additional extra bits to read - and the parameter to which those extra bits are applied. - The token is used to fetch a code word from the OC_DCT_CODE_WORD table below. - The extra bits are added into code word at the bit position inferred from the - token value, giving the final code word from which all required parameters - are derived. - The number of EOBs and the leading zero run length can be extracted directly. - The coefficient magnitude is optionally negated before extraction, according - to a 'flip' bit.*/ - -/*The number of additional extra bits that are decoded with each of the - internal DCT tokens.*/ -static const unsigned char OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[15]={ - 12,4,3,3,4,4,5,5,8,8,8,8,3,3,6 -}; - -/*Whether or not an internal token needs any additional extra bits.*/ -#define OC_DCT_TOKEN_NEEDS_MORE(token) \ - (token<(sizeof(OC_INTERNAL_DCT_TOKEN_EXTRA_BITS)/ \ - sizeof(*OC_INTERNAL_DCT_TOKEN_EXTRA_BITS))) - -/*This token (OC_DCT_REPEAT_RUN3_TOKEN) requires more than 8 extra bits.*/ -#define OC_DCT_TOKEN_FAT_EOB (0) - -/*The number of EOBs to use for an end-of-frame token. - Note: We want to set eobs to PTRDIFF_MAX here, but that requires C99, which - is not yet available everywhere; this should be equivalent.*/ -#define OC_DCT_EOB_FINISH (~(size_t)0>>1) - -/*The location of the (6) run legth bits in the code word. - These are placed at index 0 and given 8 bits (even though 6 would suffice) - because it may be faster to extract the lower byte on some platforms.*/ -#define OC_DCT_CW_RLEN_SHIFT (0) -/*The location of the (12) EOB bits in the code word.*/ -#define OC_DCT_CW_EOB_SHIFT (8) -/*The location of the (1) flip bit in the code word. - This must be right under the magnitude bits.*/ -#define OC_DCT_CW_FLIP_BIT (20) -/*The location of the (11) token magnitude bits in the code word. - These must be last, and rely on a sign-extending right shift.*/ -#define OC_DCT_CW_MAG_SHIFT (21) - -/*Pack the given fields into a code word.*/ -#define OC_DCT_CW_PACK(_eobs,_rlen,_mag,_flip) \ - ((_eobs)<state,_info,3); - if(ret<0)return ret; - ret=oc_huff_trees_copy(_dec->huff_tables, - (const oc_huff_node *const *)_setup->huff_tables); - if(ret<0){ - oc_state_clear(&_dec->state); - return ret; - } - /*For each fragment, allocate one byte for every DCT coefficient token, plus - one byte for extra-bits for each token, plus one more byte for the long - EOB run, just in case it's the very last token and has a run length of - one.*/ - _dec->dct_tokens=(unsigned char *)_ogg_malloc((64+64+1)* - _dec->state.nfrags*sizeof(_dec->dct_tokens[0])); - if(_dec->dct_tokens==NULL){ - oc_huff_trees_clear(_dec->huff_tables); - oc_state_clear(&_dec->state); - return TH_EFAULT; - } - for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ - _dec->state.dequant_tables[qi][pli][qti]= - _dec->state.dequant_table_data[qi][pli][qti]; - } - oc_dequant_tables_init(_dec->state.dequant_tables,_dec->pp_dc_scale, - &_setup->qinfo); - for(qi=0;qi<64;qi++){ - int qsum; - qsum=0; - for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){ - qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+ - _dec->state.dequant_tables[qti][pli][qi][17]+ - _dec->state.dequant_tables[qti][pli][qi][18]+ - _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0); - } - _dec->pp_sharp_mod[qi]=-(qsum>>11); - } - memcpy(_dec->state.loop_filter_limits,_setup->qinfo.loop_filter_limits, - sizeof(_dec->state.loop_filter_limits)); - _dec->pp_level=OC_PP_LEVEL_DISABLED; - _dec->dc_qis=NULL; - _dec->variances=NULL; - _dec->pp_frame_data=NULL; - _dec->stripe_cb.ctx=NULL; - _dec->stripe_cb.stripe_decoded=NULL; -#if defined(HAVE_CAIRO) - _dec->telemetry=0; - _dec->telemetry_bits=0; - _dec->telemetry_qi=0; - _dec->telemetry_mbmode=0; - _dec->telemetry_mv=0; - _dec->telemetry_frame_data=NULL; -#endif - return 0; -} - -static void oc_dec_clear(oc_dec_ctx *_dec){ -#if defined(HAVE_CAIRO) - _ogg_free(_dec->telemetry_frame_data); -#endif - _ogg_free(_dec->pp_frame_data); - _ogg_free(_dec->variances); - _ogg_free(_dec->dc_qis); - _ogg_free(_dec->dct_tokens); - oc_huff_trees_clear(_dec->huff_tables); - oc_state_clear(&_dec->state); -} - - -static int oc_dec_frame_header_unpack(oc_dec_ctx *_dec){ - long val; - /*Check to make sure this is a data packet.*/ - val=oc_pack_read1(&_dec->opb); - if(val!=0)return TH_EBADPACKET; - /*Read in the frame type (I or P).*/ - val=oc_pack_read1(&_dec->opb); - _dec->state.frame_type=(int)val; - /*Read in the qi list.*/ - val=oc_pack_read(&_dec->opb,6); - _dec->state.qis[0]=(unsigned char)val; - val=oc_pack_read1(&_dec->opb); - if(!val)_dec->state.nqis=1; - else{ - val=oc_pack_read(&_dec->opb,6); - _dec->state.qis[1]=(unsigned char)val; - val=oc_pack_read1(&_dec->opb); - if(!val)_dec->state.nqis=2; - else{ - val=oc_pack_read(&_dec->opb,6); - _dec->state.qis[2]=(unsigned char)val; - _dec->state.nqis=3; - } - } - if(_dec->state.frame_type==OC_INTRA_FRAME){ - /*Keyframes have 3 unused configuration bits, holdovers from VP3 days. - Most of the other unused bits in the VP3 headers were eliminated. - I don't know why these remain.*/ - /*I wanted to eliminate wasted bits, but not all config wiggle room - --Monty.*/ - val=oc_pack_read(&_dec->opb,3); - if(val!=0)return TH_EIMPL; - } - return 0; -} - -/*Mark all fragments as coded and in OC_MODE_INTRA. - This also builds up the coded fragment list (in coded order), and clears the - uncoded fragment list. - It does not update the coded macro block list nor the super block flags, as - those are not used when decoding INTRA frames.*/ -static void oc_dec_mark_all_intra(oc_dec_ctx *_dec){ - const oc_sb_map *sb_maps; - const oc_sb_flags *sb_flags; - oc_fragment *frags; - ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t prev_ncoded_fragis; - unsigned nsbs; - unsigned sbi; - int pli; - coded_fragis=_dec->state.coded_fragis; - prev_ncoded_fragis=ncoded_fragis=0; - sb_maps=(const oc_sb_map *)_dec->state.sb_maps; - sb_flags=_dec->state.sb_flags; - frags=_dec->state.frags; - sbi=nsbs=0; - for(pli=0;pli<3;pli++){ - nsbs+=_dec->state.fplanes[pli].nsbs; - for(;sbi=0){ - frags[fragi].coded=1; - frags[fragi].mb_mode=OC_MODE_INTRA; - coded_fragis[ncoded_fragis++]=fragi; - } - } - } - } - _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis; - prev_ncoded_fragis=ncoded_fragis; - } - _dec->state.ntotal_coded_fragis=ncoded_fragis; -} - -/*Decodes the bit flags indicating whether each super block is partially coded - or not. - Return: The number of partially coded super blocks.*/ -static unsigned oc_dec_partial_sb_flags_unpack(oc_dec_ctx *_dec){ - oc_sb_flags *sb_flags; - unsigned nsbs; - unsigned sbi; - unsigned npartial; - unsigned run_count; - long val; - int flag; - val=oc_pack_read1(&_dec->opb); - flag=(int)val; - sb_flags=_dec->state.sb_flags; - nsbs=_dec->state.nsbs; - sbi=npartial=0; - while(sbiopb); - full_run=run_count>=4129; - do{ - sb_flags[sbi].coded_partially=flag; - sb_flags[sbi].coded_fully=0; - npartial+=flag; - sbi++; - } - while(--run_count>0&&sbiopb); - flag=(int)val; - } - else flag=!flag; - } - /*TODO: run_count should be 0 here. - If it's not, we should issue a warning of some kind.*/ - return npartial; -} - -/*Decodes the bit flags for whether or not each non-partially-coded super - block is fully coded or not. - This function should only be called if there is at least one - non-partially-coded super block. - Return: The number of partially coded super blocks.*/ -static void oc_dec_coded_sb_flags_unpack(oc_dec_ctx *_dec){ - oc_sb_flags *sb_flags; - unsigned nsbs; - unsigned sbi; - unsigned run_count; - long val; - int flag; - sb_flags=_dec->state.sb_flags; - nsbs=_dec->state.nsbs; - /*Skip partially coded super blocks.*/ - for(sbi=0;sb_flags[sbi].coded_partially;sbi++); - val=oc_pack_read1(&_dec->opb); - flag=(int)val; - do{ - int full_run; - run_count=oc_sb_run_unpack(&_dec->opb); - full_run=run_count>=4129; - for(;sbiopb); - flag=(int)val; - } - else flag=!flag; - } - while(sbistate.nsbs)oc_dec_coded_sb_flags_unpack(_dec); - if(npartial>0){ - val=oc_pack_read1(&_dec->opb); - flag=!(int)val; - } - else flag=0; - sb_maps=(const oc_sb_map *)_dec->state.sb_maps; - sb_flags=_dec->state.sb_flags; - frags=_dec->state.frags; - sbi=nsbs=run_count=0; - coded_fragis=_dec->state.coded_fragis; - uncoded_fragis=coded_fragis+_dec->state.nfrags; - prev_ncoded_fragis=ncoded_fragis=nuncoded_fragis=0; - for(pli=0;pli<3;pli++){ - nsbs+=_dec->state.fplanes[pli].nsbs; - for(;sbi=0){ - int coded; - if(sb_flags[sbi].coded_fully)coded=1; - else if(!sb_flags[sbi].coded_partially)coded=0; - else{ - if(run_count<=0){ - run_count=oc_block_run_unpack(&_dec->opb); - flag=!flag; - } - run_count--; - coded=flag; - } - if(coded)coded_fragis[ncoded_fragis++]=fragi; - else *(uncoded_fragis-++nuncoded_fragis)=fragi; - frags[fragi].coded=coded; - } - } - } - } - _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis; - prev_ncoded_fragis=ncoded_fragis; - } - _dec->state.ntotal_coded_fragis=ncoded_fragis; - /*TODO: run_count should be 0 here. - If it's not, we should issue a warning of some kind.*/ -} - - - -typedef int (*oc_mode_unpack_func)(oc_pack_buf *_opb); - -static int oc_vlc_mode_unpack(oc_pack_buf *_opb){ - long val; - int i; - for(i=0;i<7;i++){ - val=oc_pack_read1(_opb); - if(!val)break; - } - return i; -} - -static int oc_clc_mode_unpack(oc_pack_buf *_opb){ - long val; - val=oc_pack_read(_opb,3); - return (int)val; -} - -/*Unpacks the list of macro block modes for INTER frames.*/ -static void oc_dec_mb_modes_unpack(oc_dec_ctx *_dec){ - const oc_mb_map *mb_maps; - signed char *mb_modes; - const oc_fragment *frags; - const unsigned char *alphabet; - unsigned char scheme0_alphabet[8]; - oc_mode_unpack_func mode_unpack; - size_t nmbs; - size_t mbi; - long val; - int mode_scheme; - val=oc_pack_read(&_dec->opb,3); - mode_scheme=(int)val; - if(mode_scheme==0){ - int mi; - /*Just in case, initialize the modes to something. - If the bitstream doesn't contain each index exactly once, it's likely - corrupt and the rest of the packet is garbage anyway, but this way we - won't crash, and we'll decode SOMETHING.*/ - /*LOOP VECTORIZES*/ - for(mi=0;miopb,3); - scheme0_alphabet[val]=OC_MODE_ALPHABETS[6][mi]; - } - alphabet=scheme0_alphabet; - } - else alphabet=OC_MODE_ALPHABETS[mode_scheme-1]; - if(mode_scheme==7)mode_unpack=oc_clc_mode_unpack; - else mode_unpack=oc_vlc_mode_unpack; - mb_modes=_dec->state.mb_modes; - mb_maps=(const oc_mb_map *)_dec->state.mb_maps; - nmbs=_dec->state.nmbs; - frags=_dec->state.frags; - for(mbi=0;mbiopb)]; - /*There were none: INTER_NOMV is forced.*/ - else mb_modes[mbi]=OC_MODE_INTER_NOMV; - } - } -} - - - -typedef int (*oc_mv_comp_unpack_func)(oc_pack_buf *_opb); - -static int oc_vlc_mv_comp_unpack(oc_pack_buf *_opb){ - long bits; - int mask; - int mv; - bits=oc_pack_read(_opb,3); - switch(bits){ - case 0:return 0; - case 1:return 1; - case 2:return -1; - case 3: - case 4:{ - mv=(int)(bits-1); - bits=oc_pack_read1(_opb); - }break; - /*case 5: - case 6: - case 7:*/ - default:{ - mv=1<>1); - bits&=1; - }break; - } - mask=-(int)bits; - return mv+mask^mask; -} - -static int oc_clc_mv_comp_unpack(oc_pack_buf *_opb){ - long bits; - int mask; - int mv; - bits=oc_pack_read(_opb,6); - mv=(int)bits>>1; - mask=-((int)bits&1); - return mv+mask^mask; -} - -/*Unpacks the list of motion vectors for INTER frames, and propagtes the macro - block modes and motion vectors to the individual fragments.*/ -static void oc_dec_mv_unpack_and_frag_modes_fill(oc_dec_ctx *_dec){ - const oc_mb_map *mb_maps; - const signed char *mb_modes; - oc_set_chroma_mvs_func set_chroma_mvs; - oc_mv_comp_unpack_func mv_comp_unpack; - oc_fragment *frags; - oc_mv *frag_mvs; - const unsigned char *map_idxs; - int map_nidxs; - oc_mv last_mv[2]; - oc_mv cbmvs[4]; - size_t nmbs; - size_t mbi; - long val; - set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt]; - val=oc_pack_read1(&_dec->opb); - mv_comp_unpack=val?oc_clc_mv_comp_unpack:oc_vlc_mv_comp_unpack; - map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt]; - map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt]; - memset(last_mv,0,sizeof(last_mv)); - frags=_dec->state.frags; - frag_mvs=_dec->state.frag_mvs; - mb_maps=(const oc_mb_map *)_dec->state.mb_maps; - mb_modes=_dec->state.mb_modes; - nmbs=_dec->state.nmbs; - for(mbi=0;mbi>2][mapi&3]; - if(frags[fragi].coded)coded[ncoded++]=mapi; - } - while(++mapiiopb); - lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb); - memcpy(frag_mvs[fragi],lbmvs[bi],sizeof(lbmvs[bi])); - } - else lbmvs[bi][0]=lbmvs[bi][1]=0; - } - if(codedi>0){ - memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1])); - memcpy(last_mv[0],lbmvs[coded[codedi-1]],sizeof(last_mv[0])); - } - if(codedi>2][bi]; - frags[fragi].mb_mode=mb_mode; - memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(cbmvs[bi])); - } - } - }break; - case OC_MODE_INTER_MV:{ - memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1])); - mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb); - mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb); - }break; - case OC_MODE_INTER_MV_LAST:memcpy(mbmv,last_mv[0],sizeof(mbmv));break; - case OC_MODE_INTER_MV_LAST2:{ - memcpy(mbmv,last_mv[1],sizeof(mbmv)); - memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1])); - memcpy(last_mv[0],mbmv,sizeof(last_mv[0])); - }break; - case OC_MODE_GOLDEN_MV:{ - mbmv[0]=(signed char)(*mv_comp_unpack)(&_dec->opb); - mbmv[1]=(signed char)(*mv_comp_unpack)(&_dec->opb); - }break; - default:memset(mbmv,0,sizeof(mbmv));break; - } - /*4MV mode fills in the fragments itself. - For all other modes we can use this common code.*/ - if(mb_mode!=OC_MODE_INTER_MV_FOUR){ - for(codedi=0;codedi>2][mapi&3]; - frags[fragi].mb_mode=mb_mode; - memcpy(frag_mvs[fragi],mbmv,sizeof(mbmv)); - } - } - } - } -} - -static void oc_dec_block_qis_unpack(oc_dec_ctx *_dec){ - oc_fragment *frags; - const ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t fragii; - ptrdiff_t fragi; - ncoded_fragis=_dec->state.ntotal_coded_fragis; - if(ncoded_fragis<=0)return; - frags=_dec->state.frags; - coded_fragis=_dec->state.coded_fragis; - if(_dec->state.nqis==1){ - /*If this frame has only a single qi value, then just use it for all coded - fragments.*/ - for(fragii=0;fragiiopb); - flag=(int)val; - nqi1=0; - fragii=0; - while(fragiiopb); - full_run=run_count>=4129; - do{ - frags[coded_fragis[fragii++]].qii=flag; - nqi1+=flag; - } - while(--run_count>0&&fragiiopb); - flag=(int)val; - } - else flag=!flag; - } - /*TODO: run_count should be 0 here. - If it's not, we should issue a warning of some kind.*/ - /*If we have 3 different qi's for this frame, and there was at least one - fragment with a non-zero qi, make the second pass.*/ - if(_dec->state.nqis==3&&nqi1>0){ - /*Skip qii==0 fragments.*/ - for(fragii=0;frags[coded_fragis[fragii]].qii==0;fragii++); - val=oc_pack_read1(&_dec->opb); - flag=(int)val; - do{ - int full_run; - run_count=oc_sb_run_unpack(&_dec->opb); - full_run=run_count>=4129; - for(;fragiiopb); - flag=(int)val; - } - else flag=!flag; - } - while(fragiidct_tokens; - frags=_dec->state.frags; - coded_fragis=_dec->state.coded_fragis; - ncoded_fragis=fragii=eobs=ti=0; - for(pli=0;pli<3;pli++){ - ptrdiff_t run_counts[64]; - ptrdiff_t eob_count; - ptrdiff_t eobi; - int rli; - ncoded_fragis+=_dec->state.ncoded_fragis[pli]; - memset(run_counts,0,sizeof(run_counts)); - _dec->eob_runs[pli][0]=eobs; - _dec->ti0[pli][0]=ti; - /*Continue any previous EOB run, if there was one.*/ - eobi=eobs; - if(ncoded_fragis-fragii0)frags[coded_fragis[fragii++]].dc=0; - while(fragiiopb, - _dec->huff_tables[_huff_idxs[pli+1>>1]]); - dct_tokens[ti++]=(unsigned char)token; - if(OC_DCT_TOKEN_NEEDS_MORE(token)){ - eb=(int)oc_pack_read(&_dec->opb, - OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[token]); - dct_tokens[ti++]=(unsigned char)eb; - if(token==OC_DCT_TOKEN_FAT_EOB)dct_tokens[ti++]=(unsigned char)(eb>>8); - eb<<=OC_DCT_TOKEN_EB_POS(token); - } - else eb=0; - cw=OC_DCT_CODE_WORD[token]+eb; - eobs=cw>>OC_DCT_CW_EOB_SHIFT&0xFFF; - if(cw==OC_DCT_CW_FINISH)eobs=OC_DCT_EOB_FINISH; - if(eobs){ - eobi=OC_MINI(eobs,ncoded_fragis-fragii); - eob_count+=eobi; - eobs-=eobi; - while(eobi-->0)frags[coded_fragis[fragii++]].dc=0; - } - else{ - int coeff; - skip=(unsigned char)(cw>>OC_DCT_CW_RLEN_SHIFT); - cw^=-(cw&1<>OC_DCT_CW_MAG_SHIFT; - if(skip)coeff=0; - run_counts[skip]++; - frags[coded_fragis[fragii++]].dc=coeff; - } - } - /*Add the total EOB count to the longest run length.*/ - run_counts[63]+=eob_count; - /*And convert the run_counts array to a moment table.*/ - for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1]; - /*Finally, subtract off the number of coefficients that have been - accounted for by runs started in this coefficient.*/ - for(rli=64;rli-->0;)_ntoks_left[pli][rli]-=run_counts[rli]; - } - _dec->dct_tokens_count=ti; - return eobs; -} - -/*Unpacks the AC coefficient tokens. - This can completely discard coefficient values while unpacking, and so is - somewhat simpler than unpacking the DC coefficient tokens. - _huff_idx: The index of the Huffman table to use for each color plane. - _ntoks_left: The number of tokens left to be decoded in each color plane for - each coefficient. - This is updated as EOB tokens and zero run tokens are decoded. - _eobs: The length of any outstanding EOB run from previous - coefficients. - Return: The length of any outstanding EOB run.*/ -static int oc_dec_ac_coeff_unpack(oc_dec_ctx *_dec,int _zzi,int _huff_idxs[2], - ptrdiff_t _ntoks_left[3][64],ptrdiff_t _eobs){ - unsigned char *dct_tokens; - ptrdiff_t ti; - int pli; - dct_tokens=_dec->dct_tokens; - ti=_dec->dct_tokens_count; - for(pli=0;pli<3;pli++){ - ptrdiff_t run_counts[64]; - ptrdiff_t eob_count; - size_t ntoks_left; - size_t ntoks; - int rli; - _dec->eob_runs[pli][_zzi]=_eobs; - _dec->ti0[pli][_zzi]=ti; - ntoks_left=_ntoks_left[pli][_zzi]; - memset(run_counts,0,sizeof(run_counts)); - eob_count=0; - ntoks=0; - while(ntoks+_eobsopb, - _dec->huff_tables[_huff_idxs[pli+1>>1]]); - dct_tokens[ti++]=(unsigned char)token; - if(OC_DCT_TOKEN_NEEDS_MORE(token)){ - eb=(int)oc_pack_read(&_dec->opb, - OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[token]); - dct_tokens[ti++]=(unsigned char)eb; - if(token==OC_DCT_TOKEN_FAT_EOB)dct_tokens[ti++]=(unsigned char)(eb>>8); - eb<<=OC_DCT_TOKEN_EB_POS(token); - } - else eb=0; - cw=OC_DCT_CODE_WORD[token]+eb; - skip=(unsigned char)(cw>>OC_DCT_CW_RLEN_SHIFT); - _eobs=cw>>OC_DCT_CW_EOB_SHIFT&0xFFF; - if(cw==OC_DCT_CW_FINISH)_eobs=OC_DCT_EOB_FINISH; - if(_eobs==0){ - run_counts[skip]++; - ntoks++; - } - } - /*Add the portion of the last EOB run actually used by this coefficient.*/ - eob_count+=ntoks_left-ntoks; - /*And remove it from the remaining EOB count.*/ - _eobs-=ntoks_left-ntoks; - /*Add the total EOB count to the longest run length.*/ - run_counts[63]+=eob_count; - /*And convert the run_counts array to a moment table.*/ - for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1]; - /*Finally, subtract off the number of coefficients that have been - accounted for by runs started in this coefficient.*/ - for(rli=64-_zzi;rli-->0;)_ntoks_left[pli][_zzi+rli]-=run_counts[rli]; - } - _dec->dct_tokens_count=ti; - return _eobs; -} - -/*Tokens describing the DCT coefficients that belong to each fragment are - stored in the bitstream grouped by coefficient, not by fragment. - - This means that we either decode all the tokens in order, building up a - separate coefficient list for each fragment as we go, and then go back and - do the iDCT on each fragment, or we have to create separate lists of tokens - for each coefficient, so that we can pull the next token required off the - head of the appropriate list when decoding a specific fragment. - - The former was VP3's choice, and it meant 2*w*h extra storage for all the - decoded coefficient values. - - We take the second option, which lets us store just one to three bytes per - token (generally far fewer than the number of coefficients, due to EOB - tokens and zero runs), and which requires us to only maintain a counter for - each of the 64 coefficients, instead of a counter for every fragment to - determine where the next token goes. - - We actually use 3 counters per coefficient, one for each color plane, so we - can decode all color planes simultaneously. - This lets color conversion, etc., be done as soon as a full MCU (one or - two super block rows) is decoded, while the image data is still in cache.*/ - -static void oc_dec_residual_tokens_unpack(oc_dec_ctx *_dec){ - static const unsigned char OC_HUFF_LIST_MAX[5]={1,6,15,28,64}; - ptrdiff_t ntoks_left[3][64]; - int huff_idxs[2]; - ptrdiff_t eobs; - long val; - int pli; - int zzi; - int hgi; - for(pli=0;pli<3;pli++)for(zzi=0;zzi<64;zzi++){ - ntoks_left[pli][zzi]=_dec->state.ncoded_fragis[pli]; - } - val=oc_pack_read(&_dec->opb,4); - huff_idxs[0]=(int)val; - val=oc_pack_read(&_dec->opb,4); - huff_idxs[1]=(int)val; - _dec->eob_runs[0][0]=0; - eobs=oc_dec_dc_coeff_unpack(_dec,huff_idxs,ntoks_left); -#if defined(HAVE_CAIRO) - _dec->telemetry_dc_bytes=oc_pack_bytes_left(&_dec->opb); -#endif - val=oc_pack_read(&_dec->opb,4); - huff_idxs[0]=(int)val; - val=oc_pack_read(&_dec->opb,4); - huff_idxs[1]=(int)val; - zzi=1; - for(hgi=1;hgi<5;hgi++){ - huff_idxs[0]+=16; - huff_idxs[1]+=16; - for(;zzipp_level<=OC_PP_LEVEL_DISABLED){ - if(_dec->dc_qis!=NULL){ - _ogg_free(_dec->dc_qis); - _dec->dc_qis=NULL; - _ogg_free(_dec->variances); - _dec->variances=NULL; - _ogg_free(_dec->pp_frame_data); - _dec->pp_frame_data=NULL; - } - return 1; - } - if(_dec->dc_qis==NULL){ - /*If we haven't been tracking DC quantization indices, there's no point in - starting now.*/ - if(_dec->state.frame_type!=OC_INTRA_FRAME)return 1; - _dec->dc_qis=(unsigned char *)_ogg_malloc( - _dec->state.nfrags*sizeof(_dec->dc_qis[0])); - if(_dec->dc_qis==NULL)return 1; - memset(_dec->dc_qis,_dec->state.qis[0],_dec->state.nfrags); - } - else{ - unsigned char *dc_qis; - const ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t fragii; - unsigned char qi0; - /*Update the DC quantization index of each coded block.*/ - dc_qis=_dec->dc_qis; - coded_fragis=_dec->state.coded_fragis; - ncoded_fragis=_dec->state.ncoded_fragis[0]+ - _dec->state.ncoded_fragis[1]+_dec->state.ncoded_fragis[2]; - qi0=(unsigned char)_dec->state.qis[0]; - for(fragii=0;fragiipp_level<=OC_PP_LEVEL_TRACKDCQI){ - if(_dec->variances!=NULL){ - _ogg_free(_dec->variances); - _dec->variances=NULL; - _ogg_free(_dec->pp_frame_data); - _dec->pp_frame_data=NULL; - } - return 1; - } - if(_dec->variances==NULL){ - size_t frame_sz; - size_t c_sz; - int c_w; - int c_h; - frame_sz=_dec->state.info.frame_width*(size_t)_dec->state.info.frame_height; - c_w=_dec->state.info.frame_width>>!(_dec->state.info.pixel_fmt&1); - c_h=_dec->state.info.frame_height>>!(_dec->state.info.pixel_fmt&2); - c_sz=c_w*(size_t)c_h; - /*Allocate space for the chroma planes, even if we're not going to use - them; this simplifies allocation state management, though it may waste - memory on the few systems that don't overcommit pages.*/ - frame_sz+=c_sz<<1; - _dec->pp_frame_data=(unsigned char *)_ogg_malloc( - frame_sz*sizeof(_dec->pp_frame_data[0])); - _dec->variances=(int *)_ogg_malloc( - _dec->state.nfrags*sizeof(_dec->variances[0])); - if(_dec->variances==NULL||_dec->pp_frame_data==NULL){ - _ogg_free(_dec->pp_frame_data); - _dec->pp_frame_data=NULL; - _ogg_free(_dec->variances); - _dec->variances=NULL; - return 1; - } - /*Force an update of the PP buffer pointers.*/ - _dec->pp_frame_state=0; - } - /*Update the PP buffer pointers if necessary.*/ - if(_dec->pp_frame_state!=1+(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC)){ - if(_dec->pp_levelpp_frame_buf[0].width=_dec->state.info.frame_width; - _dec->pp_frame_buf[0].height=_dec->state.info.frame_height; - _dec->pp_frame_buf[0].stride=-_dec->pp_frame_buf[0].width; - _dec->pp_frame_buf[0].data=_dec->pp_frame_data+ - (1-_dec->pp_frame_buf[0].height)*(ptrdiff_t)_dec->pp_frame_buf[0].stride; - } - else{ - size_t y_sz; - size_t c_sz; - int c_w; - int c_h; - /*Otherwise, set up pointers to all three PP planes.*/ - y_sz=_dec->state.info.frame_width*(size_t)_dec->state.info.frame_height; - c_w=_dec->state.info.frame_width>>!(_dec->state.info.pixel_fmt&1); - c_h=_dec->state.info.frame_height>>!(_dec->state.info.pixel_fmt&2); - c_sz=c_w*(size_t)c_h; - _dec->pp_frame_buf[0].width=_dec->state.info.frame_width; - _dec->pp_frame_buf[0].height=_dec->state.info.frame_height; - _dec->pp_frame_buf[0].stride=_dec->pp_frame_buf[0].width; - _dec->pp_frame_buf[0].data=_dec->pp_frame_data; - _dec->pp_frame_buf[1].width=c_w; - _dec->pp_frame_buf[1].height=c_h; - _dec->pp_frame_buf[1].stride=_dec->pp_frame_buf[1].width; - _dec->pp_frame_buf[1].data=_dec->pp_frame_buf[0].data+y_sz; - _dec->pp_frame_buf[2].width=c_w; - _dec->pp_frame_buf[2].height=c_h; - _dec->pp_frame_buf[2].stride=_dec->pp_frame_buf[2].width; - _dec->pp_frame_buf[2].data=_dec->pp_frame_buf[1].data+c_sz; - oc_ycbcr_buffer_flip(_dec->pp_frame_buf,_dec->pp_frame_buf); - } - _dec->pp_frame_state=1+(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC); - } - /*If we're not processing chroma, copy the reference frame's chroma planes.*/ - if(_dec->pp_levelpp_frame_buf+1, - _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]]+1, - sizeof(_dec->pp_frame_buf[1])*2); - } - return 0; -} - - - -typedef struct{ - int bounding_values[256]; - ptrdiff_t ti[3][64]; - ptrdiff_t eob_runs[3][64]; - const ptrdiff_t *coded_fragis[3]; - const ptrdiff_t *uncoded_fragis[3]; - ptrdiff_t ncoded_fragis[3]; - ptrdiff_t nuncoded_fragis[3]; - const ogg_uint16_t *dequant[3][3][2]; - int fragy0[3]; - int fragy_end[3]; - int pred_last[3][3]; - int mcu_nvfrags; - int loop_filter; - int pp_level; -}oc_dec_pipeline_state; - - - -/*Initialize the main decoding pipeline.*/ -static void oc_dec_pipeline_init(oc_dec_ctx *_dec, - oc_dec_pipeline_state *_pipe){ - const ptrdiff_t *coded_fragis; - const ptrdiff_t *uncoded_fragis; - int pli; - int qii; - int qti; - /*If chroma is sub-sampled in the vertical direction, we have to decode two - super block rows of Y' for each super block row of Cb and Cr.*/ - _pipe->mcu_nvfrags=4<state.info.pixel_fmt&2); - /*Initialize the token and extra bits indices for each plane and - coefficient.*/ - memcpy(_pipe->ti,_dec->ti0,sizeof(_pipe->ti)); - /*Also copy over the initial the EOB run counts.*/ - memcpy(_pipe->eob_runs,_dec->eob_runs,sizeof(_pipe->eob_runs)); - /*Set up per-plane pointers to the coded and uncoded fragments lists.*/ - coded_fragis=_dec->state.coded_fragis; - uncoded_fragis=coded_fragis+_dec->state.nfrags; - for(pli=0;pli<3;pli++){ - ptrdiff_t ncoded_fragis; - _pipe->coded_fragis[pli]=coded_fragis; - _pipe->uncoded_fragis[pli]=uncoded_fragis; - ncoded_fragis=_dec->state.ncoded_fragis[pli]; - coded_fragis+=ncoded_fragis; - uncoded_fragis+=ncoded_fragis-_dec->state.fplanes[pli].nfrags; - } - /*Set up condensed quantizer tables.*/ - for(pli=0;pli<3;pli++){ - for(qii=0;qii<_dec->state.nqis;qii++){ - for(qti=0;qti<2;qti++){ - _pipe->dequant[pli][qii][qti]= - _dec->state.dequant_tables[_dec->state.qis[qii]][pli][qti]; - } - } - } - /*Set the previous DC predictor to 0 for all color planes and frame types.*/ - memset(_pipe->pred_last,0,sizeof(_pipe->pred_last)); - /*Initialize the bounding value array for the loop filter.*/ - _pipe->loop_filter=!oc_state_loop_filter_init(&_dec->state, - _pipe->bounding_values); - /*Initialize any buffers needed for post-processing. - We also save the current post-processing level, to guard against the user - changing it from a callback.*/ - if(!oc_dec_postprocess_init(_dec))_pipe->pp_level=_dec->pp_level; - /*If we don't have enough information to post-process, disable it, regardless - of the user-requested level.*/ - else{ - _pipe->pp_level=OC_PP_LEVEL_DISABLED; - memcpy(_dec->pp_frame_buf, - _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]], - sizeof(_dec->pp_frame_buf[0])*3); - } -} - -/*Undo the DC prediction in a single plane of an MCU (one or two super block - rows). - As a side effect, the number of coded and uncoded fragments in this plane of - the MCU is also computed.*/ -static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec, - oc_dec_pipeline_state *_pipe,int _pli){ - const oc_fragment_plane *fplane; - oc_fragment *frags; - int *pred_last; - ptrdiff_t ncoded_fragis; - ptrdiff_t fragi; - int fragx; - int fragy; - int fragy0; - int fragy_end; - int nhfrags; - /*Compute the first and last fragment row of the current MCU for this - plane.*/ - fplane=_dec->state.fplanes+_pli; - fragy0=_pipe->fragy0[_pli]; - fragy_end=_pipe->fragy_end[_pli]; - nhfrags=fplane->nhfrags; - pred_last=_pipe->pred_last[_pli]; - frags=_dec->state.frags; - ncoded_fragis=0; - fragi=fplane->froffset+fragy0*(ptrdiff_t)nhfrags; - for(fragy=fragy0;fragy=nhfrags)ur_ref=-1; - else{ - ur_ref=u_frags[fragi+1].coded? - OC_FRAME_FOR_MODE(u_frags[fragi+1].mb_mode):-1; - } - if(frags[fragi].coded){ - int pred; - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); - /*We break out a separate case based on which of our neighbors use - the same reference frames. - This is somewhat faster than trying to make a generic case which - handles all of them, since it reduces lots of poorly predicted - jumps to one switch statement, and also lets a number of the - multiplications be optimized out by strength reduction.*/ - switch((l_ref==ref)|(ul_ref==ref)<<1| - (u_ref==ref)<<2|(ur_ref==ref)<<3){ - default:pred=pred_last[ref];break; - case 1: - case 3:pred=frags[fragi-1].dc;break; - case 2:pred=u_frags[fragi-1].dc;break; - case 4: - case 6: - case 12:pred=u_frags[fragi].dc;break; - case 5:pred=(frags[fragi-1].dc+u_frags[fragi].dc)/2;break; - case 8:pred=u_frags[fragi+1].dc;break; - case 9: - case 11: - case 13:{ - pred=(75*frags[fragi-1].dc+53*u_frags[fragi+1].dc)/128; - }break; - case 10:pred=(u_frags[fragi-1].dc+u_frags[fragi+1].dc)/2;break; - case 14:{ - pred=(3*(u_frags[fragi-1].dc+u_frags[fragi+1].dc) - +10*u_frags[fragi].dc)/16; - }break; - case 7: - case 15:{ - int p0; - int p1; - int p2; - p0=frags[fragi-1].dc; - p1=u_frags[fragi-1].dc; - p2=u_frags[fragi].dc; - pred=(29*(p0+p2)-26*p1)/32; - if(abs(pred-p2)>128)pred=p2; - else if(abs(pred-p0)>128)pred=p0; - else if(abs(pred-p1)>128)pred=p1; - }break; - } - pred_last[ref]=frags[fragi].dc+=pred; - ncoded_fragis++; - l_ref=ref; - } - else l_ref=-1; - ul_ref=u_ref; - u_ref=ur_ref; - } - } - } - _pipe->ncoded_fragis[_pli]=ncoded_fragis; - /*Also save the number of uncoded fragments so we know how many to copy.*/ - _pipe->nuncoded_fragis[_pli]= - (fragy_end-fragy0)*(ptrdiff_t)nhfrags-ncoded_fragis; -} - -/*Reconstructs all coded fragments in a single MCU (one or two super block - rows). - This requires that each coded fragment have a proper macro block mode and - motion vector (if not in INTRA mode), and have it's DC value decoded, with - the DC prediction process reversed, and the number of coded and uncoded - fragments in this plane of the MCU be counted. - The token lists for each color plane and coefficient should also be filled - in, along with initial token offsets, extra bits offsets, and EOB run - counts.*/ -static void oc_dec_frags_recon_mcu_plane(oc_dec_ctx *_dec, - oc_dec_pipeline_state *_pipe,int _pli){ - unsigned char *dct_tokens; - const unsigned char *dct_fzig_zag; - ogg_uint16_t dc_quant[2]; - const oc_fragment *frags; - const ptrdiff_t *coded_fragis; - ptrdiff_t ncoded_fragis; - ptrdiff_t fragii; - ptrdiff_t *ti; - ptrdiff_t *eob_runs; - int qti; - dct_tokens=_dec->dct_tokens; - dct_fzig_zag=_dec->state.opt_data.dct_fzig_zag; - frags=_dec->state.frags; - coded_fragis=_pipe->coded_fragis[_pli]; - ncoded_fragis=_pipe->ncoded_fragis[_pli]; - ti=_pipe->ti[_pli]; - eob_runs=_pipe->eob_runs[_pli]; - for(qti=0;qti<2;qti++)dc_quant[qti]=_pipe->dequant[_pli][0][qti][0]; - for(fragii=0;fragiidequant[_pli][frags[fragi].qii][qti]; - /*Decode the AC coefficients.*/ - for(zzi=0;zzi<64;){ - int token; - last_zzi=zzi; - if(eob_runs[zzi]){ - eob_runs[zzi]--; - break; - } - else{ - ptrdiff_t eob; - int cw; - int rlen; - int coeff; - int lti; - lti=ti[zzi]; - token=dct_tokens[lti++]; - cw=OC_DCT_CODE_WORD[token]; - /*These parts could be done branchless, but the branches are fairly - predictable and the C code translates into more than a few - instructions, so it's worth it to avoid them.*/ - if(OC_DCT_TOKEN_NEEDS_MORE(token)){ - cw+=dct_tokens[lti++]<>OC_DCT_CW_EOB_SHIFT&0xFFF; - if(token==OC_DCT_TOKEN_FAT_EOB){ - eob+=dct_tokens[lti++]<<8; - if(eob==0)eob=OC_DCT_EOB_FINISH; - } - rlen=(unsigned char)(cw>>OC_DCT_CW_RLEN_SHIFT); - cw^=-(cw&1<>OC_DCT_CW_MAG_SHIFT; - eob_runs[zzi]=eob; - ti[zzi]=lti; - zzi+=rlen; - dct_coeffs[dct_fzig_zag[zzi]]=(ogg_int16_t)(coeff*(int)ac_quant[zzi]); - zzi+=!eob; - } - } - /*TODO: zzi should be exactly 64 here. - If it's not, we should report some kind of warning.*/ - zzi=OC_MINI(zzi,64); - dct_coeffs[0]=(ogg_int16_t)frags[fragi].dc; - /*last_zzi is always initialized. - If your compiler thinks otherwise, it is dumb.*/ - oc_state_frag_recon(&_dec->state,fragi,_pli, - dct_coeffs,last_zzi,dc_quant[qti]); - } - _pipe->coded_fragis[_pli]+=ncoded_fragis; - /*Right now the reconstructed MCU has only the coded blocks in it.*/ - /*TODO: We make the decision here to always copy the uncoded blocks into it - from the reference frame. - We could also copy the coded blocks back over the reference frame, if we - wait for an additional MCU to be decoded, which might be faster if only a - small number of blocks are coded. - However, this introduces more latency, creating a larger cache footprint. - It's unknown which decision is better, but this one results in simpler - code, and the hard case (high bitrate, high resolution) is handled - correctly.*/ - /*Copy the uncoded blocks from the previous reference frame.*/ - _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli]; - oc_state_frag_copy_list(&_dec->state,_pipe->uncoded_fragis[_pli], - _pipe->nuncoded_fragis[_pli],OC_FRAME_SELF,OC_FRAME_PREV,_pli); -} - -/*Filter a horizontal block edge.*/ -static void oc_filter_hedge(unsigned char *_dst,int _dst_ystride, - const unsigned char *_src,int _src_ystride,int _qstep,int _flimit, - int *_variance0,int *_variance1){ - unsigned char *rdst; - const unsigned char *rsrc; - unsigned char *cdst; - const unsigned char *csrc; - int r[10]; - int sum0; - int sum1; - int bx; - int by; - rdst=_dst; - rsrc=_src; - for(bx=0;bx<8;bx++){ - cdst=rdst; - csrc=rsrc; - for(by=0;by<10;by++){ - r[by]=*csrc; - csrc+=_src_ystride; - } - sum0=sum1=0; - for(by=0;by<4;by++){ - sum0+=abs(r[by+1]-r[by]); - sum1+=abs(r[by+5]-r[by+6]); - } - *_variance0+=OC_MINI(255,sum0); - *_variance1+=OC_MINI(255,sum1); - if(sum0<_flimit&&sum1<_flimit&&r[5]-r[4]<_qstep&&r[4]-r[5]<_qstep){ - *cdst=(unsigned char)(r[0]*3+r[1]*2+r[2]+r[3]+r[4]+4>>3); - cdst+=_dst_ystride; - *cdst=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3); - cdst+=_dst_ystride; - for(by=0;by<4;by++){ - *cdst=(unsigned char)(r[by]+r[by+1]+r[by+2]+r[by+3]*2+ - r[by+4]+r[by+5]+r[by+6]+4>>3); - cdst+=_dst_ystride; - } - *cdst=(unsigned char)(r[4]+r[5]+r[6]+r[7]*2+r[8]+r[9]*2+4>>3); - cdst+=_dst_ystride; - *cdst=(unsigned char)(r[5]+r[6]+r[7]+r[8]*2+r[9]*3+4>>3); - } - else{ - for(by=1;by<=8;by++){ - *cdst=(unsigned char)r[by]; - cdst+=_dst_ystride; - } - } - rdst++; - rsrc++; - } -} - -/*Filter a vertical block edge.*/ -static void oc_filter_vedge(unsigned char *_dst,int _dst_ystride, - int _qstep,int _flimit,int *_variances){ - unsigned char *rdst; - const unsigned char *rsrc; - unsigned char *cdst; - int r[10]; - int sum0; - int sum1; - int bx; - int by; - cdst=_dst; - for(by=0;by<8;by++){ - rsrc=cdst-1; - rdst=cdst; - for(bx=0;bx<10;bx++)r[bx]=*rsrc++; - sum0=sum1=0; - for(bx=0;bx<4;bx++){ - sum0+=abs(r[bx+1]-r[bx]); - sum1+=abs(r[bx+5]-r[bx+6]); - } - _variances[0]+=OC_MINI(255,sum0); - _variances[1]+=OC_MINI(255,sum1); - if(sum0<_flimit&&sum1<_flimit&&r[5]-r[4]<_qstep&&r[4]-r[5]<_qstep){ - *rdst++=(unsigned char)(r[0]*3+r[1]*2+r[2]+r[3]+r[4]+4>>3); - *rdst++=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3); - for(bx=0;bx<4;bx++){ - *rdst++=(unsigned char)(r[bx]+r[bx+1]+r[bx+2]+r[bx+3]*2+ - r[bx+4]+r[bx+5]+r[bx+6]+4>>3); - } - *rdst++=(unsigned char)(r[4]+r[5]+r[6]+r[7]*2+r[8]+r[9]*2+4>>3); - *rdst=(unsigned char)(r[5]+r[6]+r[7]+r[8]*2+r[9]*3+4>>3); - } - cdst+=_dst_ystride; - } -} - -static void oc_dec_deblock_frag_rows(oc_dec_ctx *_dec, - th_img_plane *_dst,th_img_plane *_src,int _pli,int _fragy0, - int _fragy_end){ - oc_fragment_plane *fplane; - int *variance; - unsigned char *dc_qi; - unsigned char *dst; - const unsigned char *src; - ptrdiff_t froffset; - int dst_ystride; - int src_ystride; - int nhfrags; - int width; - int notstart; - int notdone; - int flimit; - int qstep; - int y_end; - int y; - int x; - _dst+=_pli; - _src+=_pli; - fplane=_dec->state.fplanes+_pli; - nhfrags=fplane->nhfrags; - froffset=fplane->froffset+_fragy0*(ptrdiff_t)nhfrags; - variance=_dec->variances+froffset; - dc_qi=_dec->dc_qis+froffset; - notstart=_fragy0>0; - notdone=_fragy_endnvfrags; - /*We want to clear an extra row of variances, except at the end.*/ - memset(variance+(nhfrags&-notstart),0, - (_fragy_end+notdone-_fragy0-notstart)*(nhfrags*sizeof(variance[0]))); - /*Except for the first time, we want to point to the middle of the row.*/ - y=(_fragy0<<3)+(notstart<<2); - dst_ystride=_dst->stride; - src_ystride=_src->stride; - dst=_dst->data+y*(ptrdiff_t)dst_ystride; - src=_src->data+y*(ptrdiff_t)src_ystride; - width=_dst->width; - for(;y<4;y++){ - memcpy(dst,src,width*sizeof(dst[0])); - dst+=dst_ystride; - src+=src_ystride; - } - /*We also want to skip the last row in the frame for this loop.*/ - y_end=_fragy_end-!notdone<<3; - for(;ypp_dc_scale[*dc_qi]; - flimit=(qstep*3)>>2; - oc_filter_hedge(dst,dst_ystride,src-src_ystride,src_ystride, - qstep,flimit,variance,variance+nhfrags); - variance++; - dc_qi++; - for(x=8;xpp_dc_scale[*dc_qi]; - flimit=(qstep*3)>>2; - oc_filter_hedge(dst+x,dst_ystride,src+x-src_ystride,src_ystride, - qstep,flimit,variance,variance+nhfrags); - oc_filter_vedge(dst+x-(dst_ystride<<2)-4,dst_ystride, - qstep,flimit,variance-1); - variance++; - dc_qi++; - } - dst+=dst_ystride<<3; - src+=src_ystride<<3; - } - /*And finally, handle the last row in the frame, if it's in the range.*/ - if(!notdone){ - int height; - height=_dst->height; - for(;ypp_dc_scale[*dc_qi++]; - flimit=(qstep*3)>>2; - oc_filter_vedge(dst+x-(dst_ystride<<3)-4,dst_ystride, - qstep,flimit,variance++); - } - } -} - -static void oc_dering_block(unsigned char *_idata,int _ystride,int _b, - int _dc_scale,int _sharp_mod,int _strong){ - static const unsigned char MOD_MAX[2]={24,32}; - static const unsigned char MOD_SHIFT[2]={1,0}; - const unsigned char *psrc; - const unsigned char *src; - const unsigned char *nsrc; - unsigned char *dst; - int vmod[72]; - int hmod[72]; - int mod_hi; - int by; - int bx; - mod_hi=OC_MINI(3*_dc_scale,MOD_MAX[_strong]); - dst=_idata; - src=dst; - psrc=src-(_ystride&-!(_b&4)); - for(by=0;by<9;by++){ - for(bx=0;bx<8;bx++){ - int mod; - mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<>7); - for(bx=1;bx<7;bx++){ - a=128; - b=64; - w=hmod[(bx<<3)+by]; - a-=w; - b+=w*src[bx-1]; - w=vmod[(by<<3)+bx]; - a-=w; - b+=w*psrc[bx]; - w=vmod[(by+1<<3)+bx]; - a-=w; - b+=w*nsrc[bx]; - w=hmod[(bx+1<<3)+by]; - a-=w; - b+=w*src[bx+1]; - dst[bx]=OC_CLAMP255(a*src[bx]+b>>7); - } - a=128; - b=64; - w=hmod[(7<<3)+by]; - a-=w; - b+=w*src[6]; - w=vmod[(by<<3)+7]; - a-=w; - b+=w*psrc[7]; - w=vmod[(by+1<<3)+7]; - a-=w; - b+=w*nsrc[7]; - w=hmod[(8<<3)+by]; - a-=w; - b+=w*src[7+!(_b&2)]; - dst[7]=OC_CLAMP255(a*src[7]+b>>7); - dst+=_ystride; - psrc=src; - src=nsrc; - nsrc+=_ystride&-(!(_b&8)|by<6); - } -} - -#define OC_DERING_THRESH1 (384) -#define OC_DERING_THRESH2 (4*OC_DERING_THRESH1) -#define OC_DERING_THRESH3 (5*OC_DERING_THRESH1) -#define OC_DERING_THRESH4 (10*OC_DERING_THRESH1) - -static void oc_dec_dering_frag_rows(oc_dec_ctx *_dec,th_img_plane *_img, - int _pli,int _fragy0,int _fragy_end){ - th_img_plane *iplane; - oc_fragment_plane *fplane; - oc_fragment *frag; - int *variance; - unsigned char *idata; - ptrdiff_t froffset; - int ystride; - int nhfrags; - int sthresh; - int strong; - int y_end; - int width; - int height; - int y; - int x; - iplane=_img+_pli; - fplane=_dec->state.fplanes+_pli; - nhfrags=fplane->nhfrags; - froffset=fplane->froffset+_fragy0*(ptrdiff_t)nhfrags; - variance=_dec->variances+froffset; - frag=_dec->state.frags+froffset; - strong=_dec->pp_level>=(_pli?OC_PP_LEVEL_SDERINGC:OC_PP_LEVEL_SDERINGY); - sthresh=_pli?OC_DERING_THRESH4:OC_DERING_THRESH3; - y=_fragy0<<3; - ystride=iplane->stride; - idata=iplane->data+y*(ptrdiff_t)ystride; - y_end=_fragy_end<<3; - width=iplane->width; - height=iplane->height; - for(;ystate.qis[frag->qii]; - var=*variance; - b=(x<=0)|(x+8>=width)<<1|(y<=0)<<2|(y+8>=height)<<3; - if(strong&&var>sthresh){ - oc_dering_block(idata+x,ystride,b, - _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1); - if(_pli||!(b&1)&&*(variance-1)>OC_DERING_THRESH4|| - !(b&2)&&variance[1]>OC_DERING_THRESH4|| - !(b&4)&&*(variance-nhfrags)>OC_DERING_THRESH4|| - !(b&8)&&variance[nhfrags]>OC_DERING_THRESH4){ - oc_dering_block(idata+x,ystride,b, - _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1); - oc_dering_block(idata+x,ystride,b, - _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1); - } - } - else if(var>OC_DERING_THRESH2){ - oc_dering_block(idata+x,ystride,b, - _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1); - } - else if(var>OC_DERING_THRESH1){ - oc_dering_block(idata+x,ystride,b, - _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],0); - } - frag++; - variance++; - } - idata+=ystride<<3; - } -} - - - -th_dec_ctx *th_decode_alloc(const th_info *_info,const th_setup_info *_setup){ - oc_dec_ctx *dec; - if(_info==NULL||_setup==NULL)return NULL; - dec=_ogg_malloc(sizeof(*dec)); - if(dec==NULL||oc_dec_init(dec,_info,_setup)<0){ - _ogg_free(dec); - return NULL; - } - dec->state.curframe_num=0; - return dec; -} - -void th_decode_free(th_dec_ctx *_dec){ - if(_dec!=NULL){ - oc_dec_clear(_dec); - _ogg_free(_dec); - } -} - -int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, - size_t _buf_sz){ - switch(_req){ - case TH_DECCTL_GET_PPLEVEL_MAX:{ - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - (*(int *)_buf)=OC_PP_LEVEL_MAX; - return 0; - }break; - case TH_DECCTL_SET_PPLEVEL:{ - int pp_level; - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - pp_level=*(int *)_buf; - if(pp_level<0||pp_level>OC_PP_LEVEL_MAX)return TH_EINVAL; - _dec->pp_level=pp_level; - return 0; - }break; - case TH_DECCTL_SET_GRANPOS:{ - ogg_int64_t granpos; - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(ogg_int64_t))return TH_EINVAL; - granpos=*(ogg_int64_t *)_buf; - if(granpos<0)return TH_EINVAL; - _dec->state.granpos=granpos; - _dec->state.keyframe_num=(granpos>>_dec->state.info.keyframe_granule_shift) - -_dec->state.granpos_bias; - _dec->state.curframe_num=_dec->state.keyframe_num - +(granpos&(1<<_dec->state.info.keyframe_granule_shift)-1); - return 0; - }break; - case TH_DECCTL_SET_STRIPE_CB:{ - th_stripe_callback *cb; - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(th_stripe_callback))return TH_EINVAL; - cb=(th_stripe_callback *)_buf; - _dec->stripe_cb.ctx=cb->ctx; - _dec->stripe_cb.stripe_decoded=cb->stripe_decoded; - return 0; - }break; -#ifdef HAVE_CAIRO - case TH_DECCTL_SET_TELEMETRY_MBMODE:{ - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; - _dec->telemetry_mbmode=*(int *)_buf; - return 0; - }break; - case TH_DECCTL_SET_TELEMETRY_MV:{ - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; - _dec->telemetry_mv=*(int *)_buf; - return 0; - }break; - case TH_DECCTL_SET_TELEMETRY_QI:{ - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; - _dec->telemetry_qi=*(int *)_buf; - return 0; - }break; - case TH_DECCTL_SET_TELEMETRY_BITS:{ - if(_dec==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - _dec->telemetry=1; - _dec->telemetry_bits=*(int *)_buf; - return 0; - }break; -#endif - default:return TH_EIMPL; - } -} - -/*We're decoding an INTER frame, but have no initialized reference - buffers (i.e., decoding did not start on a key frame). - We initialize them to a solid gray here.*/ -static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){ - th_info *info; - size_t yplane_sz; - size_t cplane_sz; - int yhstride; - int yheight; - int chstride; - int cheight; - _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0; - _dec->state.ref_frame_idx[OC_FRAME_PREV]=0; - _dec->state.ref_frame_idx[OC_FRAME_SELF]=1; - info=&_dec->state.info; - yhstride=info->frame_width+2*OC_UMV_PADDING; - yheight=info->frame_height+2*OC_UMV_PADDING; - chstride=yhstride>>!(info->pixel_fmt&1); - cheight=yheight>>!(info->pixel_fmt&2); - yplane_sz=yhstride*(size_t)yheight; - cplane_sz=chstride*(size_t)cheight; - memset(_dec->state.ref_frame_data[0],0x80,yplane_sz+2*cplane_sz); -} - -int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, - ogg_int64_t *_granpos){ - int ret; - if(_dec==NULL||_op==NULL)return TH_EFAULT; - /*A completely empty packet indicates a dropped frame and is treated exactly - like an inter frame with no coded blocks. - Only proceed if we have a non-empty packet.*/ - if(_op->bytes!=0){ - oc_dec_pipeline_state pipe; - th_ycbcr_buffer stripe_buf; - int stripe_fragy; - int refi; - int pli; - int notstart; - int notdone; - oc_pack_readinit(&_dec->opb,_op->packet,_op->bytes); -#if defined(HAVE_CAIRO) - _dec->telemetry_frame_bytes=_op->bytes; -#endif - ret=oc_dec_frame_header_unpack(_dec); - if(ret<0)return ret; - /*Select a free buffer to use for the reconstructed version of this - frame.*/ - if(_dec->state.frame_type!=OC_INTRA_FRAME&& - (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| - _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){ - /*No reference frames yet!*/ - oc_dec_init_dummy_frame(_dec); - refi=_dec->state.ref_frame_idx[OC_FRAME_SELF]; - } - else{ - for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]|| - refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++); - _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; - } - if(_dec->state.frame_type==OC_INTRA_FRAME){ - oc_dec_mark_all_intra(_dec); - _dec->state.keyframe_num=_dec->state.curframe_num; -#if defined(HAVE_CAIRO) - _dec->telemetry_coding_bytes= - _dec->telemetry_mode_bytes= - _dec->telemetry_mv_bytes=oc_pack_bytes_left(&_dec->opb); -#endif - } - else{ - oc_dec_coded_flags_unpack(_dec); -#if defined(HAVE_CAIRO) - _dec->telemetry_coding_bytes=oc_pack_bytes_left(&_dec->opb); -#endif - oc_dec_mb_modes_unpack(_dec); -#if defined(HAVE_CAIRO) - _dec->telemetry_mode_bytes=oc_pack_bytes_left(&_dec->opb); -#endif - oc_dec_mv_unpack_and_frag_modes_fill(_dec); -#if defined(HAVE_CAIRO) - _dec->telemetry_mv_bytes=oc_pack_bytes_left(&_dec->opb); -#endif - } - oc_dec_block_qis_unpack(_dec); -#if defined(HAVE_CAIRO) - _dec->telemetry_qi_bytes=oc_pack_bytes_left(&_dec->opb); -#endif - oc_dec_residual_tokens_unpack(_dec); - /*Update granule position. - This must be done before the striped decode callbacks so that the - application knows what to do with the frame data.*/ - _dec->state.granpos=(_dec->state.keyframe_num+_dec->state.granpos_bias<< - _dec->state.info.keyframe_granule_shift) - +(_dec->state.curframe_num-_dec->state.keyframe_num); - _dec->state.curframe_num++; - if(_granpos!=NULL)*_granpos=_dec->state.granpos; - /*All of the rest of the operations -- DC prediction reversal, - reconstructing coded fragments, copying uncoded fragments, loop - filtering, extending borders, and out-of-loop post-processing -- should - be pipelined. - I.e., DC prediction reversal, reconstruction, and uncoded fragment - copying are done for one or two super block rows, then loop filtering is - run as far as it can, then bordering copying, then post-processing. - For 4:2:0 video a Minimum Codable Unit or MCU contains two luma super - block rows, and one chroma. - Otherwise, an MCU consists of one super block row from each plane. - Inside each MCU, we perform all of the steps on one color plane before - moving on to the next. - After reconstruction, the additional filtering stages introduce a delay - since they need some pixels from the next fragment row. - Thus the actual number of decoded rows available is slightly smaller for - the first MCU, and slightly larger for the last. - - This entire process allows us to operate on the data while it is still in - cache, resulting in big performance improvements. - An application callback allows further application processing (blitting - to video memory, color conversion, etc.) to also use the data while it's - in cache.*/ - oc_dec_pipeline_init(_dec,&pipe); - oc_ycbcr_buffer_flip(stripe_buf,_dec->pp_frame_buf); - notstart=0; - notdone=1; - for(stripe_fragy=0;notdone;stripe_fragy+=pipe.mcu_nvfrags){ - int avail_fragy0; - int avail_fragy_end; - avail_fragy0=avail_fragy_end=_dec->state.fplanes[0].nvfrags; - notdone=stripe_fragy+pipe.mcu_nvfragsstate.fplanes+pli; - /*Compute the first and last fragment row of the current MCU for this - plane.*/ - frag_shift=pli!=0&&!(_dec->state.info.pixel_fmt&2); - pipe.fragy0[pli]=stripe_fragy>>frag_shift; - pipe.fragy_end[pli]=OC_MINI(fplane->nvfrags, - pipe.fragy0[pli]+(pipe.mcu_nvfrags>>frag_shift)); - oc_dec_dc_unpredict_mcu_plane(_dec,&pipe,pli); - oc_dec_frags_recon_mcu_plane(_dec,&pipe,pli); - sdelay=edelay=0; - if(pipe.loop_filter){ - sdelay+=notstart; - edelay+=notdone; - oc_state_loop_filter_frag_rows(&_dec->state,pipe.bounding_values, - refi,pli,pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay); - } - /*To fill the borders, we have an additional two pixel delay, since a - fragment in the next row could filter its top edge, using two pixels - from a fragment in this row. - But there's no reason to delay a full fragment between the two.*/ - oc_state_borders_fill_rows(&_dec->state,refi,pli, - (pipe.fragy0[pli]-sdelay<<3)-(sdelay<<1), - (pipe.fragy_end[pli]-edelay<<3)-(edelay<<1)); - /*Out-of-loop post-processing.*/ - pp_offset=3*(pli!=0); - if(pipe.pp_level>=OC_PP_LEVEL_DEBLOCKY+pp_offset){ - /*Perform de-blocking in one plane.*/ - sdelay+=notstart; - edelay+=notdone; - oc_dec_deblock_frag_rows(_dec,_dec->pp_frame_buf, - _dec->state.ref_frame_bufs[refi],pli, - pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay); - if(pipe.pp_level>=OC_PP_LEVEL_DERINGY+pp_offset){ - /*Perform de-ringing in one plane.*/ - sdelay+=notstart; - edelay+=notdone; - oc_dec_dering_frag_rows(_dec,_dec->pp_frame_buf,pli, - pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay); - } - } - /*If no post-processing is done, we still need to delay a row for the - loop filter, thanks to the strange filtering order VP3 chose.*/ - else if(pipe.loop_filter){ - sdelay+=notstart; - edelay+=notdone; - } - /*Compute the intersection of the available rows in all planes. - If chroma is sub-sampled, the effect of each of its delays is - doubled, but luma might have more post-processing filters enabled - than chroma, so we don't know up front which one is the limiting - factor.*/ - avail_fragy0=OC_MINI(avail_fragy0,pipe.fragy0[pli]-sdelay<stripe_cb.stripe_decoded!=NULL){ - /*The callback might want to use the FPU, so let's make sure they can. - We violate all kinds of ABI restrictions by not doing this until - now, but none of them actually matter since we don't use floating - point ourselves.*/ - oc_restore_fpu(&_dec->state); - /*Make the callback, ensuring we flip the sense of the "start" and - "end" of the available region upside down.*/ - (*_dec->stripe_cb.stripe_decoded)(_dec->stripe_cb.ctx,stripe_buf, - _dec->state.fplanes[0].nvfrags-avail_fragy_end, - _dec->state.fplanes[0].nvfrags-avail_fragy0); - } - notstart=1; - } - /*Finish filling in the reference frame borders.*/ - for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_dec->state,refi,pli); - /*Update the reference frame indices.*/ - if(_dec->state.frame_type==OC_INTRA_FRAME){ - /*The new frame becomes both the previous and gold reference frames.*/ - _dec->state.ref_frame_idx[OC_FRAME_GOLD]= - _dec->state.ref_frame_idx[OC_FRAME_PREV]= - _dec->state.ref_frame_idx[OC_FRAME_SELF]; - } - else{ - /*Otherwise, just replace the previous reference frame.*/ - _dec->state.ref_frame_idx[OC_FRAME_PREV]= - _dec->state.ref_frame_idx[OC_FRAME_SELF]; - } - /*Restore the FPU before dump_frame, since that _does_ use the FPU (for PNG - gamma values, if nothing else).*/ - oc_restore_fpu(&_dec->state); -#if defined(OC_DUMP_IMAGES) - /*Don't dump images for dropped frames.*/ - oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec"); -#endif - return 0; - } - else{ - if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0|| - _dec->state.ref_frame_idx[OC_FRAME_PREV]<0){ - int refi; - /*No reference frames yet!*/ - oc_dec_init_dummy_frame(_dec); - refi=_dec->state.ref_frame_idx[OC_FRAME_PREV]; - _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi; - memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi], - sizeof(_dec->pp_frame_buf[0])*3); - } - /*Just update the granule position and return.*/ - _dec->state.granpos=(_dec->state.keyframe_num+_dec->state.granpos_bias<< - _dec->state.info.keyframe_granule_shift) - +(_dec->state.curframe_num-_dec->state.keyframe_num); - _dec->state.curframe_num++; - if(_granpos!=NULL)*_granpos=_dec->state.granpos; - return TH_DUPFRAME; - } -} - -int th_decode_ycbcr_out(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr){ - if(_dec==NULL||_ycbcr==NULL)return TH_EFAULT; - oc_ycbcr_buffer_flip(_ycbcr,_dec->pp_frame_buf); -#if defined(HAVE_CAIRO) - /*If telemetry ioctls are active, we need to draw to the output buffer. - Stuff the plane into cairo.*/ - if(_dec->telemetry){ - cairo_surface_t *cs; - unsigned char *data; - unsigned char *y_row; - unsigned char *u_row; - unsigned char *v_row; - unsigned char *rgb_row; - int cstride; - int w; - int h; - int x; - int y; - int hdec; - int vdec; - w=_ycbcr[0].width; - h=_ycbcr[0].height; - hdec=!(_dec->state.info.pixel_fmt&1); - vdec=!(_dec->state.info.pixel_fmt&2); - /*Lazy data buffer init. - We could try to re-use the post-processing buffer, which would save - memory, but complicate the allocation logic there. - I don't think anyone cares about memory usage when using telemetry; it is - not meant for embedded devices.*/ - if(_dec->telemetry_frame_data==NULL){ - _dec->telemetry_frame_data=_ogg_malloc( - (w*h+2*(w>>hdec)*(h>>vdec))*sizeof(*_dec->telemetry_frame_data)); - if(_dec->telemetry_frame_data==NULL)return 0; - } - cs=cairo_image_surface_create(CAIRO_FORMAT_RGB24,w,h); - /*Sadly, no YUV support in Cairo (yet); convert into the RGB buffer.*/ - data=cairo_image_surface_get_data(cs); - if(data==NULL){ - cairo_surface_destroy(cs); - return 0; - } - cstride=cairo_image_surface_get_stride(cs); - y_row=_ycbcr[0].data; - u_row=_ycbcr[1].data; - v_row=_ycbcr[2].data; - rgb_row=data; - for(y=0;y>hdec]-363703744)/1635200; - g=(3827562*y_row[x]-1287801*u_row[x>>hdec] - -2672387*v_row[x>>hdec]+447306710)/3287200; - b=(952000*y_row[x]+1649289*u_row[x>>hdec]-225932192)/817600; - rgb_row[4*x+0]=OC_CLAMP255(b); - rgb_row[4*x+1]=OC_CLAMP255(g); - rgb_row[4*x+2]=OC_CLAMP255(r); - } - y_row+=_ycbcr[0].stride; - u_row+=_ycbcr[1].stride&-((y&1)|!vdec); - v_row+=_ycbcr[2].stride&-((y&1)|!vdec); - rgb_row+=cstride; - } - /*Draw coded identifier for each macroblock (stored in Hilbert order).*/ - { - cairo_t *c; - const oc_fragment *frags; - oc_mv *frag_mvs; - const signed char *mb_modes; - oc_mb_map *mb_maps; - size_t nmbs; - size_t mbi; - int row2; - int col2; - int qim[3]={0,0,0}; - if(_dec->state.nqis==2){ - int bqi; - bqi=_dec->state.qis[0]; - if(_dec->state.qis[1]>bqi)qim[1]=1; - if(_dec->state.qis[1]state.nqis==3){ - int bqi; - int cqi; - int dqi; - bqi=_dec->state.qis[0]; - cqi=_dec->state.qis[1]; - dqi=_dec->state.qis[2]; - if(cqi>bqi&&dqi>bqi){ - if(dqi>cqi){ - qim[1]=1; - qim[2]=2; - } - else{ - qim[1]=2; - qim[2]=1; - } - } - else if(cqistate.frags; - frag_mvs=_dec->state.frag_mvs; - mb_modes=_dec->state.mb_modes; - mb_maps=_dec->state.mb_maps; - nmbs=_dec->state.nmbs; - row2=0; - col2=0; - for(mbi=0;mbi>1)&1))*16-16; - x=(col2>>1)*16; - cairo_set_line_width(c,1.); - /*Keyframe (all intra) red box.*/ - if(_dec->state.frame_type==OC_INTRA_FRAME){ - if(_dec->telemetry_mbmode&0x02){ - cairo_set_source_rgba(c,1.,0,0,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,0,0,.25); - cairo_fill(c); - } - } - else{ - const signed char *frag_mv; - ptrdiff_t fragi; - for(bi=0;bi<4;bi++){ - fragi=mb_maps[mbi][0][bi]; - if(fragi>=0&&frags[fragi].coded){ - frag_mv=frag_mvs[fragi]; - break; - } - } - if(bi<4){ - switch(mb_modes[mbi]){ - case OC_MODE_INTRA:{ - if(_dec->telemetry_mbmode&0x02){ - cairo_set_source_rgba(c,1.,0,0,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,0,0,.25); - cairo_fill(c); - } - }break; - case OC_MODE_INTER_NOMV:{ - if(_dec->telemetry_mbmode&0x01){ - cairo_set_source_rgba(c,0,0,1.,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,0,0,1.,.25); - cairo_fill(c); - } - }break; - case OC_MODE_INTER_MV:{ - if(_dec->telemetry_mbmode&0x04){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x04){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_INTER_MV_LAST:{ - if(_dec->telemetry_mbmode&0x08){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_move_to(c,x+13.5,y+2.5); - cairo_line_to(c,x+2.5,y+8); - cairo_line_to(c,x+13.5,y+13.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x08){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_INTER_MV_LAST2:{ - if(_dec->telemetry_mbmode&0x10){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_move_to(c,x+8,y+2.5); - cairo_line_to(c,x+2.5,y+8); - cairo_line_to(c,x+8,y+13.5); - cairo_move_to(c,x+13.5,y+2.5); - cairo_line_to(c,x+8,y+8); - cairo_line_to(c,x+13.5,y+13.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x10){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_GOLDEN_NOMV:{ - if(_dec->telemetry_mbmode&0x20){ - cairo_set_source_rgba(c,1.,1.,0,.5); - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,1.,0,.25); - cairo_fill(c); - } - }break; - case OC_MODE_GOLDEN_MV:{ - if(_dec->telemetry_mbmode&0x40){ - cairo_rectangle(c,x+2.5,y+2.5,11,11); - cairo_set_source_rgba(c,1.,1.,0,.5); - cairo_stroke(c); - } - if(_dec->telemetry_mv&0x40){ - cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+8,y+8); - cairo_stroke(c); - } - }break; - case OC_MODE_INTER_MV_FOUR:{ - if(_dec->telemetry_mbmode&0x80){ - cairo_rectangle(c,x+2.5,y+2.5,4,4); - cairo_rectangle(c,x+9.5,y+2.5,4,4); - cairo_rectangle(c,x+2.5,y+9.5,4,4); - cairo_rectangle(c,x+9.5,y+9.5,4,4); - cairo_set_source_rgba(c,0,1.,0,.5); - cairo_stroke(c); - } - /*4mv is odd, coded in raster order.*/ - fragi=mb_maps[mbi][0][0]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+4+frag_mv[0],y+12-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+4+frag_mv[0]*.66,y+12-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+4+frag_mv[0]*.33,y+12-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+4,y+12); - cairo_stroke(c); - } - fragi=mb_maps[mbi][0][1]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+12+frag_mv[0],y+12-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+12+frag_mv[0]*.66,y+12-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+12+frag_mv[0]*.33,y+12-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+12,y+12); - cairo_stroke(c); - } - fragi=mb_maps[mbi][0][2]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+4+frag_mv[0],y+4-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+4+frag_mv[0]*.66,y+4-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+4+frag_mv[0]*.33,y+4-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+4,y+4); - cairo_stroke(c); - } - fragi=mb_maps[mbi][0][3]; - if(frags[fragi].coded&&_dec->telemetry_mv&0x80){ - frag_mv=frag_mvs[fragi]; - cairo_move_to(c,x+12+frag_mv[0],y+4-frag_mv[1]); - cairo_set_source_rgba(c,1.,1.,1.,.9); - cairo_set_line_width(c,3.); - cairo_line_to(c,x+12+frag_mv[0]*.66,y+4-frag_mv[1]*.66); - cairo_stroke_preserve(c); - cairo_set_line_width(c,2.); - cairo_line_to(c,x+12+frag_mv[0]*.33,y+4-frag_mv[1]*.33); - cairo_stroke_preserve(c); - cairo_set_line_width(c,1.); - cairo_line_to(c,x+12,y+4); - cairo_stroke(c); - } - }break; - } - } - } - /*qii illustration.*/ - if(_dec->telemetry_qi&0x2){ - cairo_set_line_cap(c,CAIRO_LINE_CAP_SQUARE); - for(bi=0;bi<4;bi++){ - ptrdiff_t fragi; - int qiv; - int xp; - int yp; - xp=x+(bi&1)*8; - yp=y+8-(bi&2)*4; - fragi=mb_maps[mbi][0][bi]; - if(fragi>=0&&frags[fragi].coded){ - qiv=qim[frags[fragi].qii]; - cairo_set_line_width(c,3.); - cairo_set_source_rgba(c,0.,0.,0.,.5); - switch(qiv){ - /*Double plus:*/ - case 2:{ - if((bi&1)^((bi&2)>>1)){ - cairo_move_to(c,xp+2.5,yp+1.5); - cairo_line_to(c,xp+2.5,yp+3.5); - cairo_move_to(c,xp+1.5,yp+2.5); - cairo_line_to(c,xp+3.5,yp+2.5); - cairo_move_to(c,xp+5.5,yp+4.5); - cairo_line_to(c,xp+5.5,yp+6.5); - cairo_move_to(c,xp+4.5,yp+5.5); - cairo_line_to(c,xp+6.5,yp+5.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,0.,1.,1.,1.); - } - else{ - cairo_move_to(c,xp+5.5,yp+1.5); - cairo_line_to(c,xp+5.5,yp+3.5); - cairo_move_to(c,xp+4.5,yp+2.5); - cairo_line_to(c,xp+6.5,yp+2.5); - cairo_move_to(c,xp+2.5,yp+4.5); - cairo_line_to(c,xp+2.5,yp+6.5); - cairo_move_to(c,xp+1.5,yp+5.5); - cairo_line_to(c,xp+3.5,yp+5.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,0.,1.,1.,1.); - } - }break; - /*Double minus:*/ - case -2:{ - cairo_move_to(c,xp+2.5,yp+2.5); - cairo_line_to(c,xp+5.5,yp+2.5); - cairo_move_to(c,xp+2.5,yp+5.5); - cairo_line_to(c,xp+5.5,yp+5.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,1.,1.,1.); - }break; - /*Plus:*/ - case 1:{ - if(bi&2==0)yp-=2; - if(bi&1==0)xp-=2; - cairo_move_to(c,xp+4.5,yp+2.5); - cairo_line_to(c,xp+4.5,yp+6.5); - cairo_move_to(c,xp+2.5,yp+4.5); - cairo_line_to(c,xp+6.5,yp+4.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,.1,1.,.3,1.); - break; - } - /*Fall through.*/ - /*Minus:*/ - case -1:{ - cairo_move_to(c,xp+2.5,yp+4.5); - cairo_line_to(c,xp+6.5,yp+4.5); - cairo_stroke_preserve(c); - cairo_set_source_rgba(c,1.,.3,.1,1.); - }break; - default:continue; - } - cairo_set_line_width(c,1.); - cairo_stroke(c); - } - } - } - col2++; - if((col2>>1)>=_dec->state.nhmbs){ - col2=0; - row2+=2; - } - } - /*Bit usage indicator[s]:*/ - if(_dec->telemetry_bits){ - int widths[6]; - int fpsn; - int fpsd; - int mult; - int fullw; - int padw; - int i; - fpsn=_dec->state.info.fps_numerator; - fpsd=_dec->state.info.fps_denominator; - mult=(_dec->telemetry_bits>=0xFF?1:_dec->telemetry_bits); - fullw=250.f*h*fpsd*mult/fpsn; - padw=w-24; - /*Header and coded block bits.*/ - if(_dec->telemetry_frame_bytes<0|| - _dec->telemetry_frame_bytes==OC_LOTS_OF_BITS){ - _dec->telemetry_frame_bytes=0; - } - if(_dec->telemetry_coding_bytes<0|| - _dec->telemetry_coding_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_coding_bytes=0; - } - if(_dec->telemetry_mode_bytes<0|| - _dec->telemetry_mode_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_mode_bytes=0; - } - if(_dec->telemetry_mv_bytes<0|| - _dec->telemetry_mv_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_mv_bytes=0; - } - if(_dec->telemetry_qi_bytes<0|| - _dec->telemetry_qi_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_qi_bytes=0; - } - if(_dec->telemetry_dc_bytes<0|| - _dec->telemetry_dc_bytes>_dec->telemetry_frame_bytes){ - _dec->telemetry_dc_bytes=0; - } - widths[0]=padw*(_dec->telemetry_frame_bytes-_dec->telemetry_coding_bytes)/fullw; - widths[1]=padw*(_dec->telemetry_coding_bytes-_dec->telemetry_mode_bytes)/fullw; - widths[2]=padw*(_dec->telemetry_mode_bytes-_dec->telemetry_mv_bytes)/fullw; - widths[3]=padw*(_dec->telemetry_mv_bytes-_dec->telemetry_qi_bytes)/fullw; - widths[4]=padw*(_dec->telemetry_qi_bytes-_dec->telemetry_dc_bytes)/fullw; - widths[5]=padw*(_dec->telemetry_dc_bytes)/fullw; - for(i=0;i<6;i++)if(widths[i]>w)widths[i]=w; - cairo_set_source_rgba(c,.0,.0,.0,.6); - cairo_rectangle(c,10,h-33,widths[0]+1,5); - cairo_rectangle(c,10,h-29,widths[1]+1,5); - cairo_rectangle(c,10,h-25,widths[2]+1,5); - cairo_rectangle(c,10,h-21,widths[3]+1,5); - cairo_rectangle(c,10,h-17,widths[4]+1,5); - cairo_rectangle(c,10,h-13,widths[5]+1,5); - cairo_fill(c); - cairo_set_source_rgb(c,1,0,0); - cairo_rectangle(c,10.5,h-32.5,widths[0],4); - cairo_fill(c); - cairo_set_source_rgb(c,0,1,0); - cairo_rectangle(c,10.5,h-28.5,widths[1],4); - cairo_fill(c); - cairo_set_source_rgb(c,0,0,1); - cairo_rectangle(c,10.5,h-24.5,widths[2],4); - cairo_fill(c); - cairo_set_source_rgb(c,.6,.4,.0); - cairo_rectangle(c,10.5,h-20.5,widths[3],4); - cairo_fill(c); - cairo_set_source_rgb(c,.3,.3,.3); - cairo_rectangle(c,10.5,h-16.5,widths[4],4); - cairo_fill(c); - cairo_set_source_rgb(c,.5,.5,.8); - cairo_rectangle(c,10.5,h-12.5,widths[5],4); - cairo_fill(c); - } - /*Master qi indicator[s]:*/ - if(_dec->telemetry_qi&0x1){ - cairo_text_extents_t extents; - char buffer[10]; - int p; - int y; - p=0; - y=h-7.5; - if(_dec->state.qis[0]>=10)buffer[p++]=48+_dec->state.qis[0]/10; - buffer[p++]=48+_dec->state.qis[0]%10; - if(_dec->state.nqis>=2){ - buffer[p++]=' '; - if(_dec->state.qis[1]>=10)buffer[p++]=48+_dec->state.qis[1]/10; - buffer[p++]=48+_dec->state.qis[1]%10; - } - if(_dec->state.nqis==3){ - buffer[p++]=' '; - if(_dec->state.qis[2]>=10)buffer[p++]=48+_dec->state.qis[2]/10; - buffer[p++]=48+_dec->state.qis[2]%10; - } - buffer[p++]='\0'; - cairo_select_font_face(c,"sans", - CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(c,18); - cairo_text_extents(c,buffer,&extents); - cairo_set_source_rgb(c,1,1,1); - cairo_move_to(c,w-extents.x_advance-10,y); - cairo_show_text(c,buffer); - cairo_set_source_rgb(c,0,0,0); - cairo_move_to(c,w-extents.x_advance-10,y); - cairo_text_path(c,buffer); - cairo_set_line_width(c,.8); - cairo_set_line_join(c,CAIRO_LINE_JOIN_ROUND); - cairo_stroke(c); - } - cairo_destroy(c); - } - /*Out of the Cairo plane into the telemetry YUV buffer.*/ - _ycbcr[0].data=_dec->telemetry_frame_data; - _ycbcr[0].stride=_ycbcr[0].width; - _ycbcr[1].data=_ycbcr[0].data+h*_ycbcr[0].stride; - _ycbcr[1].stride=_ycbcr[1].width; - _ycbcr[2].data=_ycbcr[1].data+(h>>vdec)*_ycbcr[1].stride; - _ycbcr[2].stride=_ycbcr[2].width; - y_row=_ycbcr[0].data; - u_row=_ycbcr[1].data; - v_row=_ycbcr[2].data; - rgb_row=data; - /*This is one of the few places it's worth handling chroma on a - case-by-case basis.*/ - switch(_dec->state.info.pixel_fmt){ - case TH_PF_420:{ - for(y=0;y>1]=OC_CLAMP255(u); - v_row[x>>1]=OC_CLAMP255(v); - } - y_row+=_ycbcr[0].stride<<1; - u_row+=_ycbcr[1].stride; - v_row+=_ycbcr[2].stride; - rgb_row+=cstride<<1; - } - }break; - case TH_PF_422:{ - for(y=0;y>1]=OC_CLAMP255(u); - v_row[x>>1]=OC_CLAMP255(v); - } - y_row+=_ycbcr[0].stride; - u_row+=_ycbcr[1].stride; - v_row+=_ycbcr[2].stride; - rgb_row+=cstride; - } - }break; - /*case TH_PF_444:*/ - default:{ - for(y=0;y -#include -#include -#include "dequant.h" -#include "decint.h" - -int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){ - th_quant_base *base_mats; - long val; - int nbase_mats; - int sizes[64]; - int indices[64]; - int nbits; - int bmi; - int ci; - int qti; - int pli; - int qri; - int qi; - int i; - val=oc_pack_read(_opb,3); - nbits=(int)val; - for(qi=0;qi<64;qi++){ - val=oc_pack_read(_opb,nbits); - _qinfo->loop_filter_limits[qi]=(unsigned char)val; - } - val=oc_pack_read(_opb,4); - nbits=(int)val+1; - for(qi=0;qi<64;qi++){ - val=oc_pack_read(_opb,nbits); - _qinfo->ac_scale[qi]=(ogg_uint16_t)val; - } - val=oc_pack_read(_opb,4); - nbits=(int)val+1; - for(qi=0;qi<64;qi++){ - val=oc_pack_read(_opb,nbits); - _qinfo->dc_scale[qi]=(ogg_uint16_t)val; - } - val=oc_pack_read(_opb,9); - nbase_mats=(int)val+1; - base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0])); - if(base_mats==NULL)return TH_EFAULT; - for(bmi=0;bmiqi_ranges[qti]+pli; - if(i>0){ - val=oc_pack_read1(_opb); - if(!val){ - int qtj; - int plj; - if(qti>0){ - val=oc_pack_read1(_opb); - if(val){ - qtj=qti-1; - plj=pli; - } - else{ - qtj=(i-1)/3; - plj=(i-1)%3; - } - } - else{ - qtj=(i-1)/3; - plj=(i-1)%3; - } - *qranges=*(_qinfo->qi_ranges[qtj]+plj); - continue; - } - } - val=oc_pack_read(_opb,nbits); - indices[0]=(int)val; - for(qi=qri=0;qi<63;){ - val=oc_pack_read(_opb,oc_ilog(62-qi)); - sizes[qri]=(int)val+1; - qi+=(int)val+1; - val=oc_pack_read(_opb,nbits); - indices[++qri]=(int)val; - } - /*Note: The caller is responsible for cleaning up any partially - constructed qinfo.*/ - if(qi>63){ - _ogg_free(base_mats); - return TH_EBADHEADER; - } - qranges->nranges=qri; - qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0])); - if(qranges->sizes==NULL){ - /*Note: The caller is responsible for cleaning up any partially - constructed qinfo.*/ - _ogg_free(base_mats); - return TH_EFAULT; - } - memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0])); - qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0])); - if(qrbms==NULL){ - /*Note: The caller is responsible for cleaning up any partially - constructed qinfo.*/ - _ogg_free(base_mats); - return TH_EFAULT; - } - qranges->base_matrices=(const th_quant_base *)qrbms; - do{ - bmi=indices[qri]; - /*Note: The caller is responsible for cleaning up any partially - constructed qinfo.*/ - if(bmi>=nbase_mats){ - _ogg_free(base_mats); - return TH_EBADHEADER; - } - memcpy(qrbms[qri],base_mats[bmi],sizeof(qrbms[qri])); - } - while(qri-->0); - } - _ogg_free(base_mats); - return 0; -} - -void oc_quant_params_clear(th_quant_info *_qinfo){ - int i; - for(i=6;i-->0;){ - int qti; - int pli; - qti=i/3; - pli=i%3; - /*Clear any duplicate pointer references.*/ - if(i>0){ - int qtj; - int plj; - qtj=(i-1)/3; - plj=(i-1)%3; - if(_qinfo->qi_ranges[qti][pli].sizes== - _qinfo->qi_ranges[qtj][plj].sizes){ - _qinfo->qi_ranges[qti][pli].sizes=NULL; - } - if(_qinfo->qi_ranges[qti][pli].base_matrices== - _qinfo->qi_ranges[qtj][plj].base_matrices){ - _qinfo->qi_ranges[qti][pli].base_matrices=NULL; - } - } - if(qti>0){ - if(_qinfo->qi_ranges[1][pli].sizes== - _qinfo->qi_ranges[0][pli].sizes){ - _qinfo->qi_ranges[1][pli].sizes=NULL; - } - if(_qinfo->qi_ranges[1][pli].base_matrices== - _qinfo->qi_ranges[0][pli].base_matrices){ - _qinfo->qi_ranges[1][pli].base_matrices=NULL; - } - } - /*Now free all the non-duplicate storage.*/ - _ogg_free((void *)_qinfo->qi_ranges[qti][pli].sizes); - _ogg_free((void *)_qinfo->qi_ranges[qti][pli].base_matrices); - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/dequant.h b/src/add-ons/media/plugins/theora/libtheora/dequant.h deleted file mode 100644 index ef25838e35..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/dequant.h +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: dequant.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#if !defined(_dequant_H) -# define _dequant_H (1) -# include "quant.h" -# include "bitpack.h" - -int oc_quant_params_unpack(oc_pack_buf *_opb, - th_quant_info *_qinfo); -void oc_quant_params_clear(th_quant_info *_qinfo); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/encapiwrapper.c b/src/add-ons/media/plugins/theora/libtheora/encapiwrapper.c deleted file mode 100644 index 874f12442d..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/encapiwrapper.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include "apiwrapper.h" -#include "encint.h" -#include "theora/theoraenc.h" - - - -static void th_enc_api_clear(th_api_wrapper *_api){ - if(_api->encode)th_encode_free(_api->encode); - memset(_api,0,sizeof(*_api)); -} - -static void theora_encode_clear(theora_state *_te){ - if(_te->i!=NULL)theora_info_clear(_te->i); - memset(_te,0,sizeof(*_te)); -} - -static int theora_encode_control(theora_state *_te,int _req, - void *_buf,size_t _buf_sz){ - return th_encode_ctl(((th_api_wrapper *)_te->i->codec_setup)->encode, - _req,_buf,_buf_sz); -} - -static ogg_int64_t theora_encode_granule_frame(theora_state *_te, - ogg_int64_t _gp){ - return th_granule_frame(((th_api_wrapper *)_te->i->codec_setup)->encode,_gp); -} - -static double theora_encode_granule_time(theora_state *_te,ogg_int64_t _gp){ - return th_granule_time(((th_api_wrapper *)_te->i->codec_setup)->encode,_gp); -} - -static const oc_state_dispatch_vtable OC_ENC_DISPATCH_VTBL={ - (oc_state_clear_func)theora_encode_clear, - (oc_state_control_func)theora_encode_control, - (oc_state_granule_frame_func)theora_encode_granule_frame, - (oc_state_granule_time_func)theora_encode_granule_time, -}; - -int theora_encode_init(theora_state *_te,theora_info *_ci){ - th_api_info *apiinfo; - th_info info; - ogg_uint32_t keyframe_frequency_force; - /*Allocate our own combined API wrapper/theora_info struct. - We put them both in one malloc'd block so that when the API wrapper is - freed, the info struct goes with it. - This avoids having to figure out whether or not we need to free the info - struct in either theora_info_clear() or theora_clear().*/ - apiinfo=(th_api_info *)_ogg_malloc(sizeof(*apiinfo)); - if(apiinfo==NULL)return TH_EFAULT; - /*Make our own copy of the info struct, since its lifetime should be - independent of the one we were passed in.*/ - *&apiinfo->info=*_ci; - oc_theora_info2th_info(&info,_ci); - apiinfo->api.encode=th_encode_alloc(&info); - if(apiinfo->api.encode==NULL){ - _ogg_free(apiinfo); - return OC_EINVAL; - } - apiinfo->api.clear=(oc_setup_clear_func)th_enc_api_clear; - /*Provide entry points for ABI compatibility with old decoder shared libs.*/ - _te->internal_encode=(void *)&OC_ENC_DISPATCH_VTBL; - _te->internal_decode=NULL; - _te->granulepos=0; - _te->i=&apiinfo->info; - _te->i->codec_setup=&apiinfo->api; - /*Set the precise requested keyframe frequency.*/ - keyframe_frequency_force=_ci->keyframe_auto_p? - _ci->keyframe_frequency_force:_ci->keyframe_frequency; - th_encode_ctl(apiinfo->api.encode, - TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, - &keyframe_frequency_force,sizeof(keyframe_frequency_force)); - /*TODO: Additional codec setup using the extra fields in theora_info.*/ - return 0; -} - -int theora_encode_YUVin(theora_state *_te,yuv_buffer *_yuv){ - th_api_wrapper *api; - th_ycbcr_buffer buf; - int ret; - api=(th_api_wrapper *)_te->i->codec_setup; - buf[0].width=_yuv->y_width; - buf[0].height=_yuv->y_height; - buf[0].stride=_yuv->y_stride; - buf[0].data=_yuv->y; - buf[1].width=_yuv->uv_width; - buf[1].height=_yuv->uv_height; - buf[1].stride=_yuv->uv_stride; - buf[1].data=_yuv->u; - buf[2].width=_yuv->uv_width; - buf[2].height=_yuv->uv_height; - buf[2].stride=_yuv->uv_stride; - buf[2].data=_yuv->v; - ret=th_encode_ycbcr_in(api->encode,buf); - if(ret<0)return ret; - _te->granulepos=api->encode->state.granpos; - return ret; -} - -int theora_encode_packetout(theora_state *_te,int _last_p,ogg_packet *_op){ - th_api_wrapper *api; - api=(th_api_wrapper *)_te->i->codec_setup; - return th_encode_packetout(api->encode,_last_p,_op); -} - -int theora_encode_header(theora_state *_te,ogg_packet *_op){ - oc_enc_ctx *enc; - th_api_wrapper *api; - int ret; - api=(th_api_wrapper *)_te->i->codec_setup; - enc=api->encode; - /*If we've already started encoding, fail.*/ - if(enc->packet_state>OC_PACKET_EMPTY||enc->state.granpos!=0){ - return TH_EINVAL; - } - /*Reset the state to make sure we output an info packet.*/ - enc->packet_state=OC_PACKET_INFO_HDR; - ret=th_encode_flushheader(api->encode,NULL,_op); - return ret>=0?0:ret; -} - -int theora_encode_comment(theora_comment *_tc,ogg_packet *_op){ - oggpack_buffer opb; - void *buf; - int packet_state; - int ret; - packet_state=OC_PACKET_COMMENT_HDR; - oggpackB_writeinit(&opb); - ret=oc_state_flushheader(NULL,&packet_state,&opb,NULL,NULL, - th_version_string(),(th_comment *)_tc,_op); - if(ret>=0){ - /*The oggpack_buffer's lifetime ends with this function, so we have to - copy out the packet contents. - Presumably the application knows it is supposed to free this. - This part works nothing like the Vorbis API, and the documentation on it - has been wrong for some time, claiming libtheora owned the memory.*/ - buf=_ogg_malloc(_op->bytes); - if(buf==NULL){ - _op->packet=NULL; - ret=TH_EFAULT; - } - else{ - memcpy(buf,_op->packet,_op->bytes); - _op->packet=buf; - ret=0; - } - } - oggpack_writeclear(&opb); - return ret; -} - -int theora_encode_tables(theora_state *_te,ogg_packet *_op){ - oc_enc_ctx *enc; - th_api_wrapper *api; - int ret; - api=(th_api_wrapper *)_te->i->codec_setup; - enc=api->encode; - /*If we've already started encoding, fail.*/ - if(enc->packet_state>OC_PACKET_EMPTY||enc->state.granpos!=0){ - return TH_EINVAL; - } - /*Reset the state to make sure we output a setup packet.*/ - enc->packet_state=OC_PACKET_SETUP_HDR; - ret=th_encode_flushheader(api->encode,NULL,_op); - return ret>=0?0:ret; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/encfrag.c b/src/add-ons/media/plugins/theora/libtheora/encfrag.c deleted file mode 100644 index bb814c8e4a..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/encfrag.c +++ /dev/null @@ -1,388 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: encfrag.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include -#include -#include "encint.h" - - -void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,const unsigned char *_ref,int _ystride){ - (*_enc->opt_vtable.frag_sub)(_diff,_src,_ref,_ystride); -} - -void oc_enc_frag_sub_c(ogg_int16_t _diff[64],const unsigned char *_src, - const unsigned char *_ref,int _ystride){ - int i; - for(i=0;i<8;i++){ - int j; - for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-_ref[j]); - _src+=_ystride; - _ref+=_ystride; - } -} - -void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride){ - (*_enc->opt_vtable.frag_sub_128)(_diff,_src,_ystride); -} - -void oc_enc_frag_sub_128_c(ogg_int16_t *_diff, - const unsigned char *_src,int _ystride){ - int i; - for(i=0;i<8;i++){ - int j; - for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-128); - _src+=_ystride; - } -} - -unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_x, - const unsigned char *_y,int _ystride){ - return (*_enc->opt_vtable.frag_sad)(_x,_y,_ystride); -} - -unsigned oc_enc_frag_sad_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride){ - unsigned sad; - int i; - sad=0; - for(i=8;i-->0;){ - int j; - for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]); - _src+=_ystride; - _ref+=_ystride; - } - return sad; -} - -unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh){ - return (*_enc->opt_vtable.frag_sad_thresh)(_src,_ref,_ystride,_thresh); -} - -unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ - unsigned sad; - int i; - sad=0; - for(i=8;i-->0;){ - int j; - for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]); - if(sad>_thresh)break; - _src+=_ystride; - _ref+=_ystride; - } - return sad; -} - -unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh){ - return (*_enc->opt_vtable.frag_sad2_thresh)(_src,_ref1,_ref2,_ystride, - _thresh); -} - -unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ - unsigned sad; - int i; - sad=0; - for(i=8;i-->0;){ - int j; - for(j=0;j<8;j++)sad+=abs(_src[j]-(_ref1[j]+_ref2[j]>>1)); - if(sad>_thresh)break; - _src+=_ystride; - _ref1+=_ystride; - _ref2+=_ystride; - } - return sad; -} - -static void oc_diff_hadamard(ogg_int16_t _buf[64],const unsigned char *_src, - const unsigned char *_ref,int _ystride){ - int i; - for(i=0;i<8;i++){ - int t0; - int t1; - int t2; - int t3; - int t4; - int t5; - int t6; - int t7; - int r; - /*Hadamard stage 1:*/ - t0=_src[0]-_ref[0]+_src[4]-_ref[4]; - t4=_src[0]-_ref[0]-_src[4]+_ref[4]; - t1=_src[1]-_ref[1]+_src[5]-_ref[5]; - t5=_src[1]-_ref[1]-_src[5]+_ref[5]; - t2=_src[2]-_ref[2]+_src[6]-_ref[6]; - t6=_src[2]-_ref[2]-_src[6]+_ref[6]; - t3=_src[3]-_ref[3]+_src[7]-_ref[7]; - t7=_src[3]-_ref[3]-_src[7]+_ref[7]; - /*Hadamard stage 2:*/ - r=t0; - t0+=t2; - t2=r-t2; - r=t1; - t1+=t3; - t3=r-t3; - r=t4; - t4+=t6; - t6=r-t6; - r=t5; - t5+=t7; - t7=r-t7; - /*Hadamard stage 3:*/ - _buf[0*8+i]=(ogg_int16_t)(t0+t1); - _buf[1*8+i]=(ogg_int16_t)(t0-t1); - _buf[2*8+i]=(ogg_int16_t)(t2+t3); - _buf[3*8+i]=(ogg_int16_t)(t2-t3); - _buf[4*8+i]=(ogg_int16_t)(t4+t5); - _buf[5*8+i]=(ogg_int16_t)(t4-t5); - _buf[6*8+i]=(ogg_int16_t)(t6+t7); - _buf[7*8+i]=(ogg_int16_t)(t6-t7); - _src+=_ystride; - _ref+=_ystride; - } -} - -static void oc_diff_hadamard2(ogg_int16_t _buf[64],const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ - int i; - for(i=0;i<8;i++){ - int t0; - int t1; - int t2; - int t3; - int t4; - int t5; - int t6; - int t7; - int r; - /*Hadamard stage 1:*/ - r=_ref1[0]+_ref2[0]>>1; - t4=_ref1[4]+_ref2[4]>>1; - t0=_src[0]-r+_src[4]-t4; - t4=_src[0]-r-_src[4]+t4; - r=_ref1[1]+_ref2[1]>>1; - t5=_ref1[5]+_ref2[5]>>1; - t1=_src[1]-r+_src[5]-t5; - t5=_src[1]-r-_src[5]+t5; - r=_ref1[2]+_ref2[2]>>1; - t6=_ref1[6]+_ref2[6]>>1; - t2=_src[2]-r+_src[6]-t6; - t6=_src[2]-r-_src[6]+t6; - r=_ref1[3]+_ref2[3]>>1; - t7=_ref1[7]+_ref2[7]>>1; - t3=_src[3]-r+_src[7]-t7; - t7=_src[3]-r-_src[7]+t7; - /*Hadamard stage 2:*/ - r=t0; - t0+=t2; - t2=r-t2; - r=t1; - t1+=t3; - t3=r-t3; - r=t4; - t4+=t6; - t6=r-t6; - r=t5; - t5+=t7; - t7=r-t7; - /*Hadamard stage 3:*/ - _buf[0*8+i]=(ogg_int16_t)(t0+t1); - _buf[1*8+i]=(ogg_int16_t)(t0-t1); - _buf[2*8+i]=(ogg_int16_t)(t2+t3); - _buf[3*8+i]=(ogg_int16_t)(t2-t3); - _buf[4*8+i]=(ogg_int16_t)(t4+t5); - _buf[5*8+i]=(ogg_int16_t)(t4-t5); - _buf[6*8+i]=(ogg_int16_t)(t6+t7); - _buf[7*8+i]=(ogg_int16_t)(t6-t7); - _src+=_ystride; - _ref1+=_ystride; - _ref2+=_ystride; - } -} - -static void oc_intra_hadamard(ogg_int16_t _buf[64],const unsigned char *_src, - int _ystride){ - int i; - for(i=0;i<8;i++){ - int t0; - int t1; - int t2; - int t3; - int t4; - int t5; - int t6; - int t7; - int r; - /*Hadamard stage 1:*/ - t0=_src[0]+_src[4]; - t4=_src[0]-_src[4]; - t1=_src[1]+_src[5]; - t5=_src[1]-_src[5]; - t2=_src[2]+_src[6]; - t6=_src[2]-_src[6]; - t3=_src[3]+_src[7]; - t7=_src[3]-_src[7]; - /*Hadamard stage 2:*/ - r=t0; - t0+=t2; - t2=r-t2; - r=t1; - t1+=t3; - t3=r-t3; - r=t4; - t4+=t6; - t6=r-t6; - r=t5; - t5+=t7; - t7=r-t7; - /*Hadamard stage 3:*/ - _buf[0*8+i]=(ogg_int16_t)(t0+t1); - _buf[1*8+i]=(ogg_int16_t)(t0-t1); - _buf[2*8+i]=(ogg_int16_t)(t2+t3); - _buf[3*8+i]=(ogg_int16_t)(t2-t3); - _buf[4*8+i]=(ogg_int16_t)(t4+t5); - _buf[5*8+i]=(ogg_int16_t)(t4-t5); - _buf[6*8+i]=(ogg_int16_t)(t6+t7); - _buf[7*8+i]=(ogg_int16_t)(t6-t7); - _src+=_ystride; - } -} - -unsigned oc_hadamard_sad_thresh(const ogg_int16_t _buf[64],unsigned _thresh){ - unsigned sad; - int t0; - int t1; - int t2; - int t3; - int t4; - int t5; - int t6; - int t7; - int r; - int i; - sad=0; - for(i=0;i<8;i++){ - /*Hadamard stage 1:*/ - t0=_buf[i*8+0]+_buf[i*8+4]; - t4=_buf[i*8+0]-_buf[i*8+4]; - t1=_buf[i*8+1]+_buf[i*8+5]; - t5=_buf[i*8+1]-_buf[i*8+5]; - t2=_buf[i*8+2]+_buf[i*8+6]; - t6=_buf[i*8+2]-_buf[i*8+6]; - t3=_buf[i*8+3]+_buf[i*8+7]; - t7=_buf[i*8+3]-_buf[i*8+7]; - /*Hadamard stage 2:*/ - r=t0; - t0+=t2; - t2=r-t2; - r=t1; - t1+=t3; - t3=r-t3; - r=t4; - t4+=t6; - t6=r-t6; - r=t5; - t5+=t7; - t7=r-t7; - /*Hadamard stage 3:*/ - r=abs(t0+t1); - r+=abs(t0-t1); - r+=abs(t2+t3); - r+=abs(t2-t3); - r+=abs(t4+t5); - r+=abs(t4-t5); - r+=abs(t6+t7); - r+=abs(t6-t7); - sad+=r; - if(sad>_thresh)break; - } - return sad; -} - -unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh){ - return (*_enc->opt_vtable.frag_satd_thresh)(_src,_ref,_ystride,_thresh); -} - -unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ - ogg_int16_t buf[64]; - oc_diff_hadamard(buf,_src,_ref,_ystride); - return oc_hadamard_sad_thresh(buf,_thresh); -} - -unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh){ - return (*_enc->opt_vtable.frag_satd2_thresh)(_src,_ref1,_ref2,_ystride, - _thresh); -} - -unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ - ogg_int16_t buf[64]; - oc_diff_hadamard2(buf,_src,_ref1,_ref2,_ystride); - return oc_hadamard_sad_thresh(buf,_thresh); -} - -unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc, - const unsigned char *_src,int _ystride){ - return (*_enc->opt_vtable.frag_intra_satd)(_src,_ystride); -} - -unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride){ - ogg_int16_t buf[64]; - oc_intra_hadamard(buf,_src,_ystride); - return oc_hadamard_sad_thresh(buf,UINT_MAX) - -abs(buf[0]+buf[1]+buf[2]+buf[3]+buf[4]+buf[5]+buf[6]+buf[7]); -} - -void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride){ - (*_enc->opt_vtable.frag_copy2)(_dst,_src1,_src2,_ystride); -} - -void oc_enc_frag_copy2_c(unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride){ - int i; - int j; - for(i=8;i-->0;){ - for(j=0;j<8;j++)_dst[j]=_src1[j]+_src2[j]>>1; - _dst+=_ystride; - _src1+=_ystride; - _src2+=_ystride; - } -} - -void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc, - unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]){ - (*_enc->opt_vtable.frag_recon_intra)(_dst,_ystride,_residue); -} - -void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){ - (*_enc->opt_vtable.frag_recon_inter)(_dst,_src,_ystride,_residue); -} diff --git a/src/add-ons/media/plugins/theora/libtheora/encinfo.c b/src/add-ons/media/plugins/theora/libtheora/encinfo.c deleted file mode 100644 index 83be1dae72..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/encinfo.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include "internal.h" -#include "enquant.h" -#include "huffenc.h" - - - -/*Packs a series of octets from a given byte array into the pack buffer. - _opb: The pack buffer to store the octets in. - _buf: The byte array containing the bytes to pack. - _len: The number of octets to pack.*/ -static void oc_pack_octets(oggpack_buffer *_opb,const char *_buf,int _len){ - int i; - for(i=0;i<_len;i++)oggpackB_write(_opb,_buf[i],8); -} - - - -int oc_state_flushheader(oc_theora_state *_state,int *_packet_state, - oggpack_buffer *_opb,const th_quant_info *_qinfo, - const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS], - const char *_vendor,th_comment *_tc,ogg_packet *_op){ - unsigned char *packet; - int b_o_s; - if(_op==NULL)return TH_EFAULT; - switch(*_packet_state){ - /*Codec info header.*/ - case OC_PACKET_INFO_HDR:{ - if(_state==NULL)return TH_EFAULT; - oggpackB_reset(_opb); - /*Mark this packet as the info header.*/ - oggpackB_write(_opb,0x80,8); - /*Write the codec string.*/ - oc_pack_octets(_opb,"theora",6); - /*Write the codec bitstream version.*/ - oggpackB_write(_opb,TH_VERSION_MAJOR,8); - oggpackB_write(_opb,TH_VERSION_MINOR,8); - oggpackB_write(_opb,TH_VERSION_SUB,8); - /*Describe the encoded frame.*/ - oggpackB_write(_opb,_state->info.frame_width>>4,16); - oggpackB_write(_opb,_state->info.frame_height>>4,16); - oggpackB_write(_opb,_state->info.pic_width,24); - oggpackB_write(_opb,_state->info.pic_height,24); - oggpackB_write(_opb,_state->info.pic_x,8); - oggpackB_write(_opb,_state->info.pic_y,8); - oggpackB_write(_opb,_state->info.fps_numerator,32); - oggpackB_write(_opb,_state->info.fps_denominator,32); - oggpackB_write(_opb,_state->info.aspect_numerator,24); - oggpackB_write(_opb,_state->info.aspect_denominator,24); - oggpackB_write(_opb,_state->info.colorspace,8); - oggpackB_write(_opb,_state->info.target_bitrate,24); - oggpackB_write(_opb,_state->info.quality,6); - oggpackB_write(_opb,_state->info.keyframe_granule_shift,5); - oggpackB_write(_opb,_state->info.pixel_fmt,2); - /*Spare configuration bits.*/ - oggpackB_write(_opb,0,3); - b_o_s=1; - }break; - /*Comment header.*/ - case OC_PACKET_COMMENT_HDR:{ - int vendor_len; - int i; - if(_tc==NULL)return TH_EFAULT; - vendor_len=strlen(_vendor); - oggpackB_reset(_opb); - /*Mark this packet as the comment header.*/ - oggpackB_write(_opb,0x81,8); - /*Write the codec string.*/ - oc_pack_octets(_opb,"theora",6); - /*Write the vendor string.*/ - oggpack_write(_opb,vendor_len,32); - oc_pack_octets(_opb,_vendor,vendor_len); - oggpack_write(_opb,_tc->comments,32); - for(i=0;i<_tc->comments;i++){ - if(_tc->user_comments[i]!=NULL){ - oggpack_write(_opb,_tc->comment_lengths[i],32); - oc_pack_octets(_opb,_tc->user_comments[i],_tc->comment_lengths[i]); - } - else oggpack_write(_opb,0,32); - } - b_o_s=0; - }break; - /*Codec setup header.*/ - case OC_PACKET_SETUP_HDR:{ - int ret; - oggpackB_reset(_opb); - /*Mark this packet as the setup header.*/ - oggpackB_write(_opb,0x82,8); - /*Write the codec string.*/ - oc_pack_octets(_opb,"theora",6); - /*Write the quantizer tables.*/ - oc_quant_params_pack(_opb,_qinfo); - /*Write the huffman codes.*/ - ret=oc_huff_codes_pack(_opb,_codes); - /*This should never happen, because we validate the tables when they - are set. - If you see, it's a good chance memory is being corrupted.*/ - if(ret<0)return ret; - b_o_s=0; - }break; - /*No more headers to emit.*/ - default:return 0; - } - /*This is kind of fugly: we hand the user a buffer which they do not own. - We will overwrite it when the next packet is output, so the user better be - done with it by then. - Vorbis is little better: it hands back buffers that it will free the next - time the headers are requested, or when the encoder is cleared. - Hopefully libogg2 will make this much cleaner.*/ - packet=oggpackB_get_buffer(_opb); - /*If there's no packet, malloc failed while writing.*/ - if(packet==NULL)return TH_EFAULT; - _op->packet=packet; - _op->bytes=oggpackB_bytes(_opb); - _op->b_o_s=b_o_s; - _op->e_o_s=0; - _op->granulepos=0; - _op->packetno=*_packet_state+3; - return ++(*_packet_state)+3; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/encint.h b/src/add-ons/media/plugins/theora/libtheora/encint.h deleted file mode 100644 index 97897d5a04..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/encint.h +++ /dev/null @@ -1,493 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: encint.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#if !defined(_encint_H) -# define _encint_H (1) -# if defined(HAVE_CONFIG_H) -# include "config.h" -# endif -# include "theora/theoraenc.h" -# include "internal.h" -# include "ocintrin.h" -# include "mathops.h" -# include "enquant.h" -# include "huffenc.h" -/*# define OC_COLLECT_METRICS*/ - - - -typedef oc_mv oc_mv2[2]; - -typedef struct oc_enc_opt_vtable oc_enc_opt_vtable; -typedef struct oc_mb_enc_info oc_mb_enc_info; -typedef struct oc_mode_scheme_chooser oc_mode_scheme_chooser; -typedef struct oc_iir_filter oc_iir_filter; -typedef struct oc_frame_metrics oc_frame_metrics; -typedef struct oc_rc_state oc_rc_state; -typedef struct th_enc_ctx oc_enc_ctx; -typedef struct oc_token_checkpoint oc_token_checkpoint; - - - -/*Constants for the packet-out state machine specific to the encoder.*/ - -/*Next packet to emit: Data packet, but none are ready yet.*/ -#define OC_PACKET_EMPTY (0) -/*Next packet to emit: Data packet, and one is ready.*/ -#define OC_PACKET_READY (1) - -/*All features enabled.*/ -#define OC_SP_LEVEL_SLOW (0) -/*Enable early skip.*/ -#define OC_SP_LEVEL_EARLY_SKIP (1) -/*Disable motion compensation.*/ -#define OC_SP_LEVEL_NOMC (2) -/*Maximum valid speed level.*/ -#define OC_SP_LEVEL_MAX (2) - - -/*The bits used for each of the MB mode codebooks.*/ -extern const unsigned char OC_MODE_BITS[2][OC_NMODES]; - -/*The bits used for each of the MV codebooks.*/ -extern const unsigned char OC_MV_BITS[2][64]; - -/*The minimum value that can be stored in a SB run for each codeword. - The last entry is the upper bound on the length of a single SB run.*/ -extern const ogg_uint16_t OC_SB_RUN_VAL_MIN[8]; -/*The bits used for each SB run codeword.*/ -extern const unsigned char OC_SB_RUN_CODE_NBITS[7]; - -/*The bits used for each block run length (starting with 1).*/ -extern const unsigned char OC_BLOCK_RUN_CODE_NBITS[30]; - - - -/*Encoder specific functions with accelerated variants.*/ -struct oc_enc_opt_vtable{ - unsigned (*frag_sad)(const unsigned char *_src, - const unsigned char *_ref,int _ystride); - unsigned (*frag_sad_thresh)(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); - unsigned (*frag_sad2_thresh)(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); - unsigned (*frag_satd_thresh)(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); - unsigned (*frag_satd2_thresh)(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); - unsigned (*frag_intra_satd)(const unsigned char *_src,int _ystride); - void (*frag_sub)(ogg_int16_t _diff[64],const unsigned char *_src, - const unsigned char *_ref,int _ystride); - void (*frag_sub_128)(ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride); - void (*frag_copy2)(unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride); - void (*frag_recon_intra)(unsigned char *_dst,int _ystride, - const ogg_int16_t _residue[64]); - void (*frag_recon_inter)(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); - void (*fdct8x8)(ogg_int16_t _y[64],const ogg_int16_t _x[64]); -}; - - -void oc_enc_vtable_init(oc_enc_ctx *_enc); - - - -/*Encoder-specific macroblock information.*/ -struct oc_mb_enc_info{ - /*Neighboring macro blocks that have MVs available from the current frame.*/ - unsigned cneighbors[4]; - /*Neighboring macro blocks to use for MVs from the previous frame.*/ - unsigned pneighbors[4]; - /*The number of current-frame neighbors.*/ - unsigned char ncneighbors; - /*The number of previous-frame neighbors.*/ - unsigned char npneighbors; - /*Flags indicating which MB modes have been refined.*/ - unsigned char refined; - /*Motion vectors for a macro block for the current frame and the - previous two frames. - Each is a set of 2 vectors against OC_FRAME_GOLD and OC_FRAME_PREV, which - can be used to estimate constant velocity and constant acceleration - predictors. - Uninitialized MVs are (0,0).*/ - oc_mv2 analysis_mv[3]; - /*Current unrefined analysis MVs.*/ - oc_mv unref_mv[2]; - /*Unrefined block MVs.*/ - oc_mv block_mv[4]; - /*Refined block MVs.*/ - oc_mv ref_mv[4]; - /*Minimum motion estimation error from the analysis stage.*/ - ogg_uint16_t error[2]; - /*MB error for half-pel refinement for each frame type.*/ - unsigned satd[2]; - /*Block error for half-pel refinement.*/ - unsigned block_satd[4]; -}; - - - -/*State machine to estimate the opportunity cost of coding a MB mode.*/ -struct oc_mode_scheme_chooser{ - /*Pointers to the a list containing the index of each mode in the mode - alphabet used by each scheme. - The first entry points to the dynamic scheme0_ranks, while the remaining 7 - point to the constant entries stored in OC_MODE_SCHEMES.*/ - const unsigned char *mode_ranks[8]; - /*The ranks for each mode when coded with scheme 0. - These are optimized so that the more frequent modes have lower ranks.*/ - unsigned char scheme0_ranks[OC_NMODES]; - /*The list of modes, sorted in descending order of frequency, that - corresponds to the ranks above.*/ - unsigned char scheme0_list[OC_NMODES]; - /*The number of times each mode has been chosen so far.*/ - int mode_counts[OC_NMODES]; - /*The list of mode coding schemes, sorted in ascending order of bit cost.*/ - unsigned char scheme_list[8]; - /*The number of bits used by each mode coding scheme.*/ - ptrdiff_t scheme_bits[8]; -}; - - -void oc_mode_scheme_chooser_init(oc_mode_scheme_chooser *_chooser); - - - -/*A 2nd order low-pass Bessel follower. - We use this for rate control because it has fast reaction time, but is - critically damped.*/ -struct oc_iir_filter{ - ogg_int32_t c[2]; - ogg_int64_t g; - ogg_int32_t x[2]; - ogg_int32_t y[2]; -}; - - - -/*The 2-pass metrics associated with a single frame.*/ -struct oc_frame_metrics{ - /*The log base 2 of the scale factor for this frame in Q24 format.*/ - ogg_int32_t log_scale; - /*The number of application-requested duplicates of this frame.*/ - unsigned dup_count:31; - /*The frame type from pass 1.*/ - unsigned frame_type:1; -}; - - - -/*Rate control state information.*/ -struct oc_rc_state{ - /*The target average bits per frame.*/ - ogg_int64_t bits_per_frame; - /*The current buffer fullness (bits available to be used).*/ - ogg_int64_t fullness; - /*The target buffer fullness. - This is where we'd like to be by the last keyframe the appears in the next - buf_delay frames.*/ - ogg_int64_t target; - /*The maximum buffer fullness (total size of the buffer).*/ - ogg_int64_t max; - /*The log of the number of pixels in a frame in Q57 format.*/ - ogg_int64_t log_npixels; - /*The exponent used in the rate model in Q8 format.*/ - unsigned exp[2]; - /*The number of frames to distribute the buffer usage over.*/ - int buf_delay; - /*The total drop count from the previous frame. - This includes duplicates explicitly requested via the - TH_ENCCTL_SET_DUP_COUNT API as well as frames we chose to drop ourselves.*/ - ogg_uint32_t prev_drop_count; - /*The log of an estimated scale factor used to obtain the real framerate, for - VFR sources or, e.g., 12 fps content doubled to 24 fps, etc.*/ - ogg_int64_t log_drop_scale; - /*The log of estimated scale factor for the rate model in Q57 format.*/ - ogg_int64_t log_scale[2]; - /*The log of the target quantizer level in Q57 format.*/ - ogg_int64_t log_qtarget; - /*Will we drop frames to meet bitrate target?*/ - unsigned char drop_frames; - /*Do we respect the maximum buffer fullness?*/ - unsigned char cap_overflow; - /*Can the reservoir go negative?*/ - unsigned char cap_underflow; - /*Second-order lowpass filters to track scale and VFR.*/ - oc_iir_filter scalefilter[2]; - int inter_count; - int inter_delay; - int inter_delay_target; - oc_iir_filter vfrfilter; - /*Two-pass mode state. - 0 => 1-pass encoding. - 1 => 1st pass of 2-pass encoding. - 2 => 2nd pass of 2-pass encoding.*/ - int twopass; - /*Buffer for current frame metrics.*/ - unsigned char twopass_buffer[48]; - /*The number of bytes in the frame metrics buffer. - When 2-pass encoding is enabled, this is set to 0 after each frame is - submitted, and must be non-zero before the next frame will be accepted.*/ - int twopass_buffer_bytes; - int twopass_buffer_fill; - /*Whether or not to force the next frame to be a keyframe.*/ - unsigned char twopass_force_kf; - /*The metrics for the previous frame.*/ - oc_frame_metrics prev_metrics; - /*The metrics for the current frame.*/ - oc_frame_metrics cur_metrics; - /*The buffered metrics for future frames.*/ - oc_frame_metrics *frame_metrics; - int nframe_metrics; - int cframe_metrics; - /*The index of the current frame in the circular metric buffer.*/ - int frame_metrics_head; - /*The frame count of each type (keyframes, delta frames, and dup frames); - 32 bits limits us to 2.268 years at 60 fps.*/ - ogg_uint32_t frames_total[3]; - /*The number of frames of each type yet to be processed.*/ - ogg_uint32_t frames_left[3]; - /*The sum of the scale values for each frame type.*/ - ogg_int64_t scale_sum[2]; - /*The start of the window over which the current scale sums are taken.*/ - int scale_window0; - /*The end of the window over which the current scale sums are taken.*/ - int scale_window_end; - /*The frame count of each type in the current 2-pass window; this does not - include dup frames.*/ - int nframes[3]; - /*The total accumulated estimation bias.*/ - ogg_int64_t rate_bias; -}; - - -void oc_rc_state_init(oc_rc_state *_rc,oc_enc_ctx *_enc); -void oc_rc_state_clear(oc_rc_state *_rc); - -void oc_enc_rc_resize(oc_enc_ctx *_enc); -int oc_enc_select_qi(oc_enc_ctx *_enc,int _qti,int _clamp); -void oc_enc_calc_lambda(oc_enc_ctx *_enc,int _frame_type); -int oc_enc_update_rc_state(oc_enc_ctx *_enc, - long _bits,int _qti,int _qi,int _trial,int _droppable); -int oc_enc_rc_2pass_out(oc_enc_ctx *_enc,unsigned char **_buf); -int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes); - - - -/*The internal encoder state.*/ -struct th_enc_ctx{ - /*Shared encoder/decoder state.*/ - oc_theora_state state; - /*Buffer in which to assemble packets.*/ - oggpack_buffer opb; - /*Encoder-specific macroblock information.*/ - oc_mb_enc_info *mb_info; - /*DC coefficients after prediction.*/ - ogg_int16_t *frag_dc; - /*The list of coded macro blocks, in coded order.*/ - unsigned *coded_mbis; - /*The number of coded macro blocks.*/ - size_t ncoded_mbis; - /*Whether or not packets are ready to be emitted. - This takes on negative values while there are remaining header packets to - be emitted, reaches 0 when the codec is ready for input, and becomes - positive when a frame has been processed and data packets are ready.*/ - int packet_state; - /*The maximum distance between keyframes.*/ - ogg_uint32_t keyframe_frequency_force; - /*The number of duplicates to produce for the next frame.*/ - ogg_uint32_t dup_count; - /*The number of duplicates remaining to be emitted for the current frame.*/ - ogg_uint32_t nqueued_dups; - /*The number of duplicates emitted for the last frame.*/ - ogg_uint32_t prev_dup_count; - /*The current speed level.*/ - int sp_level; - /*Whether or not VP3 compatibility mode has been enabled.*/ - unsigned char vp3_compatible; - /*Whether or not any INTER frames have been coded.*/ - unsigned char coded_inter_frame; - /*Whether or not previous frame was dropped.*/ - unsigned char prevframe_dropped; - /*Stores most recently chosen Huffman tables for each frame type, DC and AC - coefficients, and luma and chroma tokens. - The actual Huffman table used for a given coefficient depends not only on - the choice made here, but also its index in the zig-zag ordering.*/ - unsigned char huff_idxs[2][2][2]; - /*Current count of bits used by each MV coding mode.*/ - size_t mv_bits[2]; - /*The mode scheme chooser for estimating mode coding costs.*/ - oc_mode_scheme_chooser chooser; - /*The number of vertical super blocks in an MCU.*/ - int mcu_nvsbs; - /*The SSD error for skipping each fragment in the current MCU.*/ - unsigned *mcu_skip_ssd; - /*The DCT token lists for each coefficient and each plane.*/ - unsigned char **dct_tokens[3]; - /*The extra bits associated with each DCT token.*/ - ogg_uint16_t **extra_bits[3]; - /*The number of DCT tokens for each coefficient for each plane.*/ - ptrdiff_t ndct_tokens[3][64]; - /*Pending EOB runs for each coefficient for each plane.*/ - ogg_uint16_t eob_run[3][64]; - /*The offset of the first DCT token for each coefficient for each plane.*/ - unsigned char dct_token_offs[3][64]; - /*The last DC coefficient for each plane and reference frame.*/ - int dc_pred_last[3][3]; -#if defined(OC_COLLECT_METRICS) - /*Fragment SATD statistics for MB mode estimation metrics.*/ - unsigned *frag_satd; - /*Fragment SSD statistics for MB mode estimation metrics.*/ - unsigned *frag_ssd; -#endif - /*The R-D optimization parameter.*/ - int lambda; - /*The huffman tables in use.*/ - th_huff_code huff_codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]; - /*The quantization parameters in use.*/ - th_quant_info qinfo; - oc_iquant *enquant_tables[64][3][2]; - oc_iquant_table enquant_table_data[64][3][2]; - /*An "average" quantizer for each quantizer type (INTRA or INTER) and qi - value. - This is used to paramterize the rate control decisions. - They are kept in the log domain to simplify later processing. - Keep in mind these are DCT domain quantizers, and so are scaled by an - additional factor of 4 from the pixel domain.*/ - ogg_int64_t log_qavg[2][64]; - /*The buffer state used to drive rate control.*/ - oc_rc_state rc; - /*Table for encoder acceleration functions.*/ - oc_enc_opt_vtable opt_vtable; -}; - - -void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode); -int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode); -#if defined(OC_COLLECT_METRICS) -void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc); -void oc_enc_mode_metrics_dump(oc_enc_ctx *_enc); -#endif - - - -/*Perform fullpel motion search for a single MB against both reference frames.*/ -void oc_mcenc_search(oc_enc_ctx *_enc,int _mbi); -/*Refine a MB MV for one frame.*/ -void oc_mcenc_refine1mv(oc_enc_ctx *_enc,int _mbi,int _frame); -/*Refine the block MVs.*/ -void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi); - - - -/*Used to rollback a tokenlog transaction when we retroactively decide to skip - a fragment. - A checkpoint is taken right before each token is added.*/ -struct oc_token_checkpoint{ - /*The color plane the token was added to.*/ - unsigned char pli; - /*The zig-zag index the token was added to.*/ - unsigned char zzi; - /*The outstanding EOB run count before the token was added.*/ - ogg_uint16_t eob_run; - /*The token count before the token was added.*/ - ptrdiff_t ndct_tokens; -}; - - - -void oc_enc_tokenize_start(oc_enc_ctx *_enc); -int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, - ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, - int _zzi,oc_token_checkpoint **_stack,int _acmin); -void oc_enc_tokenlog_rollback(oc_enc_ctx *_enc, - const oc_token_checkpoint *_stack,int _n); -void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, - int _pli,int _fragy0,int _frag_yend); -void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, - const ptrdiff_t *_coded_fragis,ptrdiff_t _ncoded_fragis, - int _prev_ndct_tokens1,int _prev_eob_run1); -void oc_enc_tokenize_finish(oc_enc_ctx *_enc); - - - -/*Utility routine to encode one of the header packets.*/ -int oc_state_flushheader(oc_theora_state *_state,int *_packet_state, - oggpack_buffer *_opb,const th_quant_info *_qinfo, - const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS], - const char *_vendor,th_comment *_tc,ogg_packet *_op); - - - -/*Encoder-specific accelerated functions.*/ -void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,const unsigned char *_ref,int _ystride); -void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride); -unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_src, - const unsigned char *_ref,int _ystride); -unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc, - const unsigned char *_src,const unsigned char *_ref1, - const unsigned char *_ref2,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc, - const unsigned char *_src,int _ystride); -void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride); -void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc, - unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]); -void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); -void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64], - const ogg_int16_t _x[64]); - -/*Default pure-C implementations.*/ -void oc_enc_vtable_init_c(oc_enc_ctx *_enc); - -void oc_enc_frag_sub_c(ogg_int16_t _diff[64], - const unsigned char *_src,const unsigned char *_ref,int _ystride); -void oc_enc_frag_sub_128_c(ogg_int16_t _diff[64], - const unsigned char *_src,int _ystride); -void oc_enc_frag_copy2_c(unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride); -unsigned oc_enc_frag_sad_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride); -unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride); -void oc_enc_fdct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/encode.c b/src/add-ons/media/plugins/theora/libtheora/encode.c deleted file mode 100644 index 10015204f2..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/encode.c +++ /dev/null @@ -1,1615 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: encode.c 33343 2009-09-29 00:37:35Z phoudoin $ - - ********************************************************************/ -#include -#include -#include "encint.h" -#if defined(OC_X86_ASM) -# include "x86/x86enc.h" -#endif - - - -/*The default quantization parameters used by VP3.1.*/ -static const int OC_VP31_RANGE_SIZES[1]={63}; -static const th_quant_base OC_VP31_BASES_INTRA_Y[2]={ - { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 58, 68,109,103, 77, - 24, 35, 55, 64, 81,104,113, 92, - 49, 64, 78, 87,103,121,120,101, - 72, 92, 95, 98,112,100,103, 99 - }, - { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 58, 68,109,103, 77, - 24, 35, 55, 64, 81,104,113, 92, - 49, 64, 78, 87,103,121,120,101, - 72, 92, 95, 98,112,100,103, 99 - } -}; -static const th_quant_base OC_VP31_BASES_INTRA_C[2]={ - { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - }, - { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - } -}; -static const th_quant_base OC_VP31_BASES_INTER[2]={ - { - 16, 16, 16, 20, 24, 28, 32, 40, - 16, 16, 20, 24, 28, 32, 40, 48, - 16, 20, 24, 28, 32, 40, 48, 64, - 20, 24, 28, 32, 40, 48, 64, 64, - 24, 28, 32, 40, 48, 64, 64, 64, - 28, 32, 40, 48, 64, 64, 64, 96, - 32, 40, 48, 64, 64, 64, 96,128, - 40, 48, 64, 64, 64, 96,128,128 - }, - { - 16, 16, 16, 20, 24, 28, 32, 40, - 16, 16, 20, 24, 28, 32, 40, 48, - 16, 20, 24, 28, 32, 40, 48, 64, - 20, 24, 28, 32, 40, 48, 64, 64, - 24, 28, 32, 40, 48, 64, 64, 64, - 28, 32, 40, 48, 64, 64, 64, 96, - 32, 40, 48, 64, 64, 64, 96,128, - 40, 48, 64, 64, 64, 96,128,128 - } -}; - -const th_quant_info TH_VP31_QUANT_INFO={ - { - 220,200,190,180,170,170,160,160, - 150,150,140,140,130,130,120,120, - 110,110,100,100, 90, 90, 90, 80, - 80, 80, 70, 70, 70, 60, 60, 60, - 60, 50, 50, 50, 50, 40, 40, 40, - 40, 40, 30, 30, 30, 30, 30, 30, - 30, 20, 20, 20, 20, 20, 20, 20, - 20, 10, 10, 10, 10, 10, 10, 10 - }, - { - 500,450,400,370,340,310,285,265, - 245,225,210,195,185,180,170,160, - 150,145,135,130,125,115,110,107, - 100, 96, 93, 89, 85, 82, 75, 74, - 70, 68, 64, 60, 57, 56, 52, 50, - 49, 45, 44, 43, 40, 38, 37, 35, - 33, 32, 30, 29, 28, 25, 24, 22, - 21, 19, 18, 17, 15, 13, 12, 10 - }, - { - 30,25,20,20,15,15,14,14, - 13,13,12,12,11,11,10,10, - 9, 9, 8, 8, 7, 7, 7, 7, - 6, 6, 6, 6, 5, 5, 5, 5, - 4, 4, 4, 4, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - }, - { - { - {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_Y}, - {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C}, - {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C} - }, - { - {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER}, - {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER}, - {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER} - } - } -}; - -/*The current default quantization parameters.*/ -static const int OC_DEF_QRANGE_SIZES[3]={32,16,15}; -static const th_quant_base OC_DEF_BASES_INTRA_Y[4]={ - { - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - }, - { - 15, 12, 12, 15, 18, 20, 20, 21, - 13, 13, 14, 17, 18, 21, 21, 20, - 14, 14, 15, 18, 20, 21, 21, 21, - 14, 16, 17, 19, 20, 21, 21, 21, - 16, 17, 20, 21, 21, 21, 21, 21, - 18, 19, 20, 21, 21, 21, 21, 21, - 20, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21 - }, - { - 16, 12, 11, 16, 20, 25, 27, 28, - 13, 13, 14, 18, 21, 28, 28, 27, - 14, 13, 16, 20, 25, 28, 28, 28, - 14, 16, 19, 22, 27, 29, 29, 28, - 17, 19, 25, 28, 28, 30, 30, 29, - 20, 24, 27, 28, 29, 30, 30, 29, - 27, 28, 29, 29, 30, 30, 30, 30, - 29, 29, 29, 29, 30, 30, 30, 29 - }, - { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 58, 68,109,103, 77, - 24, 35, 55, 64, 81,104,113, 92, - 49, 64, 78, 87,103,121,120,101, - 72, 92, 95, 98,112,100,103, 99 - } -}; -static const th_quant_base OC_DEF_BASES_INTRA_C[4]={ - { - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19 - }, - { - 18, 18, 21, 25, 26, 26, 26, 26, - 18, 20, 22, 26, 26, 26, 26, 26, - 21, 22, 25, 26, 26, 26, 26, 26, - 25, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26 - }, - { - 17, 18, 22, 31, 36, 36, 36, 36, - 18, 20, 24, 34, 36, 36, 36, 36, - 22, 24, 33, 36, 36, 36, 36, 36, - 31, 34, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36 - }, - { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - } -}; -static const th_quant_base OC_DEF_BASES_INTER[4]={ - { - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21 - }, - { - 18, 18, 18, 21, 23, 24, 25, 27, - 18, 18, 21, 23, 24, 25, 27, 28, - 18, 21, 23, 24, 25, 27, 28, 29, - 21, 23, 24, 25, 27, 28, 29, 29, - 23, 24, 25, 27, 28, 29, 29, 29, - 24, 25, 27, 28, 29, 29, 29, 30, - 25, 27, 28, 29, 29, 29, 30, 30, - 27, 28, 29, 29, 29, 30, 30, 30 - }, - { - 17, 17, 17, 20, 23, 26, 28, 32, - 17, 17, 20, 23, 26, 28, 32, 34, - 17, 20, 23, 26, 28, 32, 34, 37, - 20, 23, 26, 28, 32, 34, 37, 37, - 23, 26, 28, 32, 34, 37, 37, 37, - 26, 28, 32, 34, 37, 37, 37, 41, - 28, 32, 34, 37, 37, 37, 41, 42, - 32, 34, 37, 37, 37, 41, 42, 42 - }, - { - 16, 16, 16, 20, 24, 28, 32, 40, - 16, 16, 20, 24, 28, 32, 40, 48, - 16, 20, 24, 28, 32, 40, 48, 64, - 20, 24, 28, 32, 40, 48, 64, 64, - 24, 28, 32, 40, 48, 64, 64, 64, - 28, 32, 40, 48, 64, 64, 64, 96, - 32, 40, 48, 64, 64, 64, 96,128, - 40, 48, 64, 64, 64, 96,128,128 - } -}; - -const th_quant_info TH_DEF_QUANT_INFO={ - { - 365,348,333,316,300,287,277,265, - 252,240,229,219,206,197,189,180, - 171,168,160,153,146,139,132,127, - 121,115,110,107,101, 97, 94, 89, - 85, 83, 78, 73, 72, 67, 66, 62, - 60, 59, 56, 53, 52, 48, 47, 43, - 42, 40, 36, 35, 34, 33, 31, 30, - 28, 25, 24, 22, 20, 17, 14, 10 - }, - { - 365,348,333,316,300,287,277,265, - 252,240,229,219,206,197,189,180, - 171,168,160,153,146,139,132,127, - 121,115,110,107,101, 97, 94, 89, - 85, 83, 78, 73, 72, 67, 66, 62, - 60, 59, 56, 53, 52, 48, 47, 43, - 42, 40, 36, 35, 34, 33, 31, 30, - 28, 25, 24, 22, 20, 17, 14, 10 - }, - { - 30,25,20,20,15,15,14,14, - 13,13,12,12,11,11,10,10, - 9, 9, 8, 8, 7, 7, 7, 7, - 6, 6, 6, 6, 5, 5, 5, 5, - 4, 4, 4, 4, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - }, - { - { - {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTRA_Y}, - {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTRA_C}, - {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTRA_C} - }, - { - {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTER}, - {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTER}, - {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTER} - } - } -}; - - - -/*The Huffman codes used for macro block modes.*/ - -const unsigned char OC_MODE_BITS[2][OC_NMODES]={ - /*Codebook 0: a maximally skewed prefix code.*/ - {1,2,3,4,5,6,7,7}, - /*Codebook 1: a fixed-length code.*/ - {3,3,3,3,3,3,3,3} -}; - -static const unsigned char OC_MODE_CODES[2][OC_NMODES]={ - /*Codebook 0: a maximally skewed prefix code.*/ - {0x00,0x02,0x06,0x0E,0x1E,0x3E,0x7E,0x7F}, - /*Codebook 1: a fixed-length code.*/ - {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07} -}; - - -/*The Huffman codes used for motion vectors.*/ - -const unsigned char OC_MV_BITS[2][64]={ - /*Codebook 0: VLC code.*/ - { - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,7,7,7,7,7,7,7,7,6,6,6,6,4,4,3, - 3, - 3,4,4,6,6,6,6,7,7,7,7,7,7,7,7,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 - }, - /*Codebook 1: (5 bit magnitude, 1 bit sign). - This wastes a code word (0x01, negative zero), or a bit (0x00, positive - zero, requires only 5 bits to uniquely decode), but is hopefully not used - very often.*/ - { - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 - } -}; - -static const unsigned char OC_MV_CODES[2][64]={ - /*Codebook 0: VLC code.*/ - { - 0xFF,0xFD,0xFB,0xF9,0xF7,0xF5,0xF3, - 0xF1,0xEF,0xED,0xEB,0xE9,0xE7,0xE5,0xE3, - 0xE1,0x6F,0x6D,0x6B,0x69,0x67,0x65,0x63, - 0x61,0x2F,0x2D,0x2B,0x29,0x09,0x07,0x02, - 0x00, - 0x01,0x06,0x08,0x28,0x2A,0x2C,0x2E,0x60, - 0x62,0x64,0x66,0x68,0x6A,0x6C,0x6E,0xE0, - 0xE2,0xE4,0xE6,0xE8,0xEA,0xEC,0xEE,0xF0, - 0xF2,0xF4,0xF6,0xF8,0xFA,0xFC,0xFE - }, - /*Codebook 1: (5 bit magnitude, 1 bit sign).*/ - { - 0x3F,0x3D,0x3B,0x39,0x37,0x35,0x33, - 0x31,0x2F,0x2D,0x2B,0x29,0x27,0x25,0x23, - 0x21,0x1F,0x1D,0x1B,0x19,0x17,0x15,0x13, - 0x11,0x0F,0x0D,0x0B,0x09,0x07,0x05,0x03, - 0x00, - 0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10, - 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20, - 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30, - 0x32,0x34,0x36,0x38,0x3A,0x3C,0x3E - } -}; - - - -/*Super block run coding scheme: - Codeword Run Length - 0 1 - 10x 2-3 - 110x 4-5 - 1110xx 6-9 - 11110xxx 10-17 - 111110xxxx 18-33 - 111111xxxxxxxxxxxx 34-4129*/ -const ogg_uint16_t OC_SB_RUN_VAL_MIN[8]={1,2,4,6,10,18,34,4130}; -static const unsigned OC_SB_RUN_CODE_PREFIX[7]={ - 0,4,0xC,0x38,0xF0,0x3E0,0x3F000 -}; -const unsigned char OC_SB_RUN_CODE_NBITS[7]={1,3,4,6,8,10,18}; - - -/*Writes the bit pattern for the run length of a super block run to the given - oggpack_buffer. - _opb: The buffer to write to. - _run_count: The length of the run, which must be positive. - _flag: The current flag. - _done: Whether or not more flags are to be encoded.*/ -static void oc_sb_run_pack(oggpack_buffer *_opb,ptrdiff_t _run_count, - int _flag,int _done){ - int i; - if(_run_count>=4129){ - do{ - oggpackB_write(_opb,0x3FFFF,18); - _run_count-=4129; - if(_run_count>0)oggpackB_write(_opb,_flag,1); - else if(!_done)oggpackB_write(_opb,!_flag,1); - } - while(_run_count>=4129); - if(_run_count<=0)return; - } - for(i=0;_run_count>=OC_SB_RUN_VAL_MIN[i+1];i++); - oggpackB_write(_opb,OC_SB_RUN_CODE_PREFIX[i]+_run_count-OC_SB_RUN_VAL_MIN[i], - OC_SB_RUN_CODE_NBITS[i]); -} - - - -/*Block run coding scheme: - Codeword Run Length - 0x 1-2 - 10x 3-4 - 110x 5-6 - 1110xx 7-10 - 11110xx 11-14 - 11111xxxx 15-30*/ -const unsigned char OC_BLOCK_RUN_CODE_NBITS[30]={ - 2,2,3,3,4,4,6,6,6,6,7,7,7,7,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 -}; -static const ogg_uint16_t OC_BLOCK_RUN_CODE_PATTERN[30]={ - 0x000,0x001,0x004,0x005,0x00C,0x00D,0x038, - 0x039,0x03A,0x03B,0x078,0x079,0x07A,0x07B,0x1F0, - 0x1F1,0x1F2,0x1F3,0x1F4,0x1F5,0x1F6,0x1F7,0x1F8, - 0x1F9,0x1FA,0x1FB,0x1FC,0x1FD,0x1FE,0x1FF -}; - - -/*Writes the bit pattern for the run length of a block run to the given - oggpack_buffer. - _opb: The buffer to write to. - _run_count: The length of the run. - This must be positive, and no more than 30.*/ -static void oc_block_run_pack(oggpack_buffer *_opb,int _run_count){ - oggpackB_write(_opb,OC_BLOCK_RUN_CODE_PATTERN[_run_count-1], - OC_BLOCK_RUN_CODE_NBITS[_run_count-1]); -} - - - -static void oc_enc_frame_header_pack(oc_enc_ctx *_enc){ - /*Mark this as a data packet.*/ - oggpackB_write(&_enc->opb,0,1); - /*Output the frame type (key frame or delta frame).*/ - oggpackB_write(&_enc->opb,_enc->state.frame_type,1); - /*Write out the current qi list.*/ - oggpackB_write(&_enc->opb,_enc->state.qis[0],6); - if(_enc->state.nqis>1){ - oggpackB_write(&_enc->opb,1,1); - oggpackB_write(&_enc->opb,_enc->state.qis[1],6); - if(_enc->state.nqis>2){ - oggpackB_write(&_enc->opb,1,1); - oggpackB_write(&_enc->opb,_enc->state.qis[2],6); - } - else oggpackB_write(&_enc->opb,0,1); - } - else oggpackB_write(&_enc->opb,0,1); - if(_enc->state.frame_type==OC_INTRA_FRAME){ - /*Key frames have 3 unused configuration bits, holdovers from the VP3 days. - Most of the other unused bits in the VP3 headers were eliminated. - Monty kept these to leave us some wiggle room for future expansion, - though a single bit in all frames would have been far more useful.*/ - oggpackB_write(&_enc->opb,0,3); - } -} - -/*Writes the bit flags for whether or not each super block is partially coded - or not. - These flags are run-length encoded, with the flag value alternating between - each run. - Return: The number partially coded SBs.*/ -static unsigned oc_enc_partial_sb_flags_pack(oc_enc_ctx *_enc){ - const oc_sb_flags *sb_flags; - unsigned nsbs; - unsigned sbi; - unsigned npartial; - int flag; - sb_flags=_enc->state.sb_flags; - nsbs=_enc->state.nsbs; - flag=sb_flags[0].coded_partially; - oggpackB_write(&_enc->opb,flag,1); - sbi=npartial=0; - do{ - unsigned run_count; - for(run_count=0;sbiopb,run_count,flag,sbi>=nsbs); - flag=!flag; - } - while(sbistate.sb_flags; - nsbs=_enc->state.nsbs; - /*Skip partially coded super blocks; their flags have already been coded.*/ - for(sbi=0;sb_flags[sbi].coded_partially;sbi++); - flag=sb_flags[sbi].coded_fully; - oggpackB_write(&_enc->opb,flag,1); - do{ - unsigned run_count; - for(run_count=0;sbiopb,run_count,flag,sbi>=nsbs); - flag=!flag; - } - while(sbistate.nsbs)oc_enc_coded_sb_flags_pack(_enc); - sb_maps=(const oc_sb_map *)_enc->state.sb_maps; - sb_flags=_enc->state.sb_flags; - nsbs=_enc->state.nsbs; - frags=_enc->state.frags; - for(sbi=0;sbiopb,flag,1); - run_count=0; - nsbs=sbi=0; - for(pli=0;pli<3;pli++){ - nsbs+=_enc->state.fplanes[pli].nsbs; - for(;sbi=0){ - if(frags[fragi].coded!=flag){ - oc_block_run_pack(&_enc->opb,run_count); - flag=!flag; - run_count=1; - } - else run_count++; - } - } - } - } - } - } - /*Flush any trailing block coded run.*/ - if(run_count>0)oc_block_run_pack(&_enc->opb,run_count); - } -} - -static void oc_enc_mb_modes_pack(oc_enc_ctx *_enc){ - const unsigned char *mode_codes; - const unsigned char *mode_bits; - const unsigned char *mode_ranks; - unsigned *coded_mbis; - size_t ncoded_mbis; - const signed char *mb_modes; - unsigned mbii; - int scheme; - int mb_mode; - scheme=_enc->chooser.scheme_list[0]; - /*Encode the best scheme.*/ - oggpackB_write(&_enc->opb,scheme,3); - /*If the chosen scheme is scheme 0, send the mode frequency ordering.*/ - if(scheme==0){ - for(mb_mode=0;mb_modeopb,_enc->chooser.scheme0_ranks[mb_mode],3); - } - } - mode_ranks=_enc->chooser.mode_ranks[scheme]; - mode_bits=OC_MODE_BITS[scheme+1>>3]; - mode_codes=OC_MODE_CODES[scheme+1>>3]; - coded_mbis=_enc->coded_mbis; - ncoded_mbis=_enc->ncoded_mbis; - mb_modes=_enc->state.mb_modes; - for(mbii=0;mbiiopb,mode_codes[rank],mode_bits[rank]); - } -} - -static void oc_enc_mv_pack(oc_enc_ctx *_enc,int _mv_scheme,int _dx,int _dy){ - oggpackB_write(&_enc->opb, - OC_MV_CODES[_mv_scheme][_dx+31],OC_MV_BITS[_mv_scheme][_dx+31]); - oggpackB_write(&_enc->opb, - OC_MV_CODES[_mv_scheme][_dy+31],OC_MV_BITS[_mv_scheme][_dy+31]); -} - -static void oc_enc_mvs_pack(oc_enc_ctx *_enc){ - const unsigned *coded_mbis; - size_t ncoded_mbis; - const oc_mb_map *mb_maps; - const signed char *mb_modes; - const oc_fragment *frags; - const oc_mv *frag_mvs; - unsigned mbii; - int mv_scheme; - /*Choose the coding scheme.*/ - mv_scheme=_enc->mv_bits[1]<_enc->mv_bits[0]; - oggpackB_write(&_enc->opb,mv_scheme,1); - /*Encode the motion vectors. - Macro blocks are iterated in Hilbert scan order, but the MVs within the - macro block are coded in raster order.*/ - coded_mbis=_enc->coded_mbis; - ncoded_mbis=_enc->ncoded_mbis; - mb_modes=_enc->state.mb_modes; - mb_maps=(const oc_mb_map *)_enc->state.mb_maps; - frags=_enc->state.frags; - frag_mvs=(const oc_mv *)_enc->state.frag_mvs; - for(mbii=0;mbiistate.nqis<=1)return; - ncoded_fragis=_enc->state.ntotal_coded_fragis; - if(ncoded_fragis<=0)return; - coded_fragis=_enc->state.coded_fragis; - frags=_enc->state.frags; - flag=!!frags[coded_fragis[0]].qii; - oggpackB_write(&_enc->opb,flag,1); - nqi0=0; - for(fragii=0;fragiiopb,run_count,flag,fragii>=ncoded_fragis); - flag=!flag; - } - if(_enc->state.nqis<3||nqi0>=ncoded_fragis)return; - for(fragii=0;!frags[coded_fragis[fragii]].qii;fragii++); - flag=frags[coded_fragis[fragii]].qii-1; - oggpackB_write(&_enc->opb,flag,1); - while(fragiiopb,run_count,flag,fragii>=ncoded_fragis); - flag=!flag; - } -} - -/*Counts the tokens of each type used for the given range of coefficient - indices in zig-zag order. - _zzi_start: The first zig-zag index to include. - _zzi_end: The first zig-zag index to not include. - _token_counts_y: Returns the token counts for the Y' plane. - _token_counts_c: Returns the token counts for the Cb and Cr planes.*/ -static void oc_enc_count_tokens(oc_enc_ctx *_enc,int _zzi_start,int _zzi_end, - ptrdiff_t _token_counts_y[32],ptrdiff_t _token_counts_c[32]){ - const unsigned char *dct_tokens; - ptrdiff_t ndct_tokens; - int pli; - int zzi; - ptrdiff_t ti; - memset(_token_counts_y,0,32*sizeof(*_token_counts_y)); - memset(_token_counts_c,0,32*sizeof(*_token_counts_c)); - for(zzi=_zzi_start;zzi<_zzi_end;zzi++){ - dct_tokens=_enc->dct_tokens[0][zzi]; - ndct_tokens=_enc->ndct_tokens[0][zzi]; - for(ti=_enc->dct_token_offs[0][zzi];tidct_tokens[pli][zzi]; - ndct_tokens=_enc->ndct_tokens[pli][zzi]; - for(ti=_enc->dct_token_offs[pli][zzi];tihuff_codes[huffi+huff_offs][token].nbits; - } - } -} - -/*Returns the Huffman index using the fewest number of bits.*/ -static int oc_select_huff_idx(size_t _bit_counts[16]){ - int best_huffi; - int huffi; - best_huffi=0; - for(huffi=1;huffi<16;huffi++)if(_bit_counts[huffi]<_bit_counts[best_huffi]){ - best_huffi=huffi; - } - return best_huffi; -} - -static void oc_enc_huff_group_pack(oc_enc_ctx *_enc, - int _zzi_start,int _zzi_end,const int _huff_idxs[2]){ - int zzi; - for(zzi=_zzi_start;zzi<_zzi_end;zzi++){ - int pli; - for(pli=0;pli<3;pli++){ - const unsigned char *dct_tokens; - const ogg_uint16_t *extra_bits; - ptrdiff_t ndct_tokens; - const th_huff_code *huff_codes; - ptrdiff_t ti; - dct_tokens=_enc->dct_tokens[pli][zzi]; - extra_bits=_enc->extra_bits[pli][zzi]; - ndct_tokens=_enc->ndct_tokens[pli][zzi]; - huff_codes=_enc->huff_codes[_huff_idxs[pli+1>>1]]; - for(ti=_enc->dct_token_offs[pli][zzi];tiopb,huff_codes[token].pattern, - huff_codes[token].nbits); - neb=OC_DCT_TOKEN_EXTRA_BITS[token]; - if(neb)oggpackB_write(&_enc->opb,extra_bits[ti],neb); - } - } - } -} - -static void oc_enc_residual_tokens_pack(oc_enc_ctx *_enc){ - static const unsigned char OC_HUFF_GROUP_MIN[6]={0,1,6,15,28,64}; - static const unsigned char *OC_HUFF_GROUP_MAX=OC_HUFF_GROUP_MIN+1; - ptrdiff_t token_counts_y[32]; - ptrdiff_t token_counts_c[32]; - size_t bits_y[16]; - size_t bits_c[16]; - int huff_idxs[2]; - int frame_type; - int hgi; - frame_type=_enc->state.frame_type; - /*Choose which Huffman tables to use for the DC token list.*/ - oc_enc_count_tokens(_enc,0,1,token_counts_y,token_counts_c); - memset(bits_y,0,sizeof(bits_y)); - memset(bits_c,0,sizeof(bits_c)); - oc_enc_count_bits(_enc,0,token_counts_y,bits_y); - oc_enc_count_bits(_enc,0,token_counts_c,bits_c); - huff_idxs[0]=oc_select_huff_idx(bits_y); - huff_idxs[1]=oc_select_huff_idx(bits_c); - /*Write the DC token list with the chosen tables.*/ - oggpackB_write(&_enc->opb,huff_idxs[0],4); - oggpackB_write(&_enc->opb,huff_idxs[1],4); - _enc->huff_idxs[frame_type][0][0]=(unsigned char)huff_idxs[0]; - _enc->huff_idxs[frame_type][0][1]=(unsigned char)huff_idxs[1]; - oc_enc_huff_group_pack(_enc,0,1,huff_idxs); - /*Choose which Huffman tables to use for the AC token lists.*/ - memset(bits_y,0,sizeof(bits_y)); - memset(bits_c,0,sizeof(bits_c)); - for(hgi=1;hgi<5;hgi++){ - oc_enc_count_tokens(_enc,OC_HUFF_GROUP_MIN[hgi],OC_HUFF_GROUP_MAX[hgi], - token_counts_y,token_counts_c); - oc_enc_count_bits(_enc,hgi,token_counts_y,bits_y); - oc_enc_count_bits(_enc,hgi,token_counts_c,bits_c); - } - huff_idxs[0]=oc_select_huff_idx(bits_y); - huff_idxs[1]=oc_select_huff_idx(bits_c); - /*Write the AC token lists using the chosen tables.*/ - oggpackB_write(&_enc->opb,huff_idxs[0],4); - oggpackB_write(&_enc->opb,huff_idxs[1],4); - _enc->huff_idxs[frame_type][1][0]=(unsigned char)huff_idxs[0]; - _enc->huff_idxs[frame_type][1][1]=(unsigned char)huff_idxs[1]; - for(hgi=1;hgi<5;hgi++){ - huff_idxs[0]+=16; - huff_idxs[1]+=16; - oc_enc_huff_group_pack(_enc, - OC_HUFF_GROUP_MIN[hgi],OC_HUFF_GROUP_MAX[hgi],huff_idxs); - } -} - -static void oc_enc_frame_pack(oc_enc_ctx *_enc){ - oggpackB_reset(&_enc->opb); - /*Only proceed if we have some coded blocks. - If there are no coded blocks, we can drop this frame simply by emitting a - 0 byte packet.*/ - if(_enc->state.ntotal_coded_fragis>0){ - oc_enc_frame_header_pack(_enc); - if(_enc->state.frame_type==OC_INTER_FRAME){ - /*Coded block flags, MB modes, and MVs are only needed for delta frames.*/ - oc_enc_coded_flags_pack(_enc); - oc_enc_mb_modes_pack(_enc); - oc_enc_mvs_pack(_enc); - } - oc_enc_block_qis_pack(_enc); - oc_enc_tokenize_finish(_enc); - oc_enc_residual_tokens_pack(_enc); - } - /*Success: Mark the packet as ready to be flushed.*/ - _enc->packet_state=OC_PACKET_READY; -#if defined(OC_COLLECT_METRICS) - oc_enc_mode_metrics_collect(_enc); -#endif -} - - -void oc_enc_vtable_init_c(oc_enc_ctx *_enc){ - /*The implementations prefixed with oc_enc_ are encoder-specific. - The rest we re-use from the decoder.*/ - _enc->opt_vtable.frag_sad=oc_enc_frag_sad_c; - _enc->opt_vtable.frag_sad_thresh=oc_enc_frag_sad_thresh_c; - _enc->opt_vtable.frag_sad2_thresh=oc_enc_frag_sad2_thresh_c; - _enc->opt_vtable.frag_satd_thresh=oc_enc_frag_satd_thresh_c; - _enc->opt_vtable.frag_satd2_thresh=oc_enc_frag_satd2_thresh_c; - _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_c; - _enc->opt_vtable.frag_sub=oc_enc_frag_sub_c; - _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_c; - _enc->opt_vtable.frag_copy2=oc_enc_frag_copy2_c; - _enc->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c; - _enc->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c; - _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_c; -} - -/*Initialize the macro block neighbor lists for MC analysis. - This assumes that the entire mb_info memory region has been initialized with - zeros.*/ -static void oc_enc_mb_info_init(oc_enc_ctx *_enc){ - oc_mb_enc_info *embs; - const signed char *mb_modes; - unsigned nhsbs; - unsigned nvsbs; - unsigned nhmbs; - unsigned nvmbs; - unsigned sby; - mb_modes=_enc->state.mb_modes; - embs=_enc->mb_info; - nhsbs=_enc->state.fplanes[0].nhsbs; - nvsbs=_enc->state.fplanes[0].nvsbs; - nhmbs=_enc->state.nhmbs; - nvmbs=_enc->state.nvmbs; - for(sby=0;sby>1); - mby=2*sby+(quadi+1>>1&1); - /*Fill in the neighbors with current motion vectors available.*/ - for(ni=0;ni=nhmbs||nmby<0||nmby>=nvmbs)continue; - nmbi=(nmby&~1)*nhmbs+((nmbx&~1)<<1)+OC_MB_MAP[nmby&1][nmbx&1]; - if(mb_modes[nmbi]==OC_MODE_INVALID)continue; - embs[mbi].cneighbors[embs[mbi].ncneighbors++]=nmbi; - } - /*Fill in the neighbors with previous motion vectors available.*/ - for(ni=0;ni<4;ni++){ - nmbx=mbx+PDX[ni]; - nmby=mby+PDY[ni]; - if(nmbx<0||nmbx>=nhmbs||nmby<0||nmby>=nvmbs)continue; - nmbi=(nmby&~1)*nhmbs+((nmbx&~1)<<1)+OC_MB_MAP[nmby&1][nmbx&1]; - if(mb_modes[nmbi]==OC_MODE_INVALID)continue; - embs[mbi].pneighbors[embs[mbi].npneighbors++]=nmbi; - } - } - } - } -} - -static int oc_enc_set_huffman_codes(oc_enc_ctx *_enc, - const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]){ - int ret; - if(_enc==NULL)return TH_EFAULT; - if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL; - if(_codes==NULL)_codes=TH_VP31_HUFF_CODES; - /*Validate the codes.*/ - oggpackB_reset(&_enc->opb); - ret=oc_huff_codes_pack(&_enc->opb,_codes); - if(ret<0)return ret; - memcpy(_enc->huff_codes,_codes,sizeof(_enc->huff_codes)); - return 0; -} - -/*Sets the quantization parameters to use. - This may only be called before the setup header is written. - If it is called multiple times, only the last call has any effect. - _qinfo: The quantization parameters. - These are described in more detail in theoraenc.h. - This can be NULL, in which case the default quantization parameters - will be used.*/ -static int oc_enc_set_quant_params(oc_enc_ctx *_enc, - const th_quant_info *_qinfo){ - int qi; - int pli; - int qti; - if(_enc==NULL)return TH_EFAULT; - if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL; - if(_qinfo==NULL)_qinfo=&TH_DEF_QUANT_INFO; - /*TODO: Analyze for packing purposes instead of just doing a shallow copy.*/ - memcpy(&_enc->qinfo,_qinfo,sizeof(_enc->qinfo)); - for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){ - _enc->state.dequant_tables[qi][pli][qti]= - _enc->state.dequant_table_data[qi][pli][qti]; - _enc->enquant_tables[qi][pli][qti]=_enc->enquant_table_data[qi][pli][qti]; - } - oc_enquant_tables_init(_enc->state.dequant_tables, - _enc->enquant_tables,_qinfo); - memcpy(_enc->state.loop_filter_limits,_qinfo->loop_filter_limits, - sizeof(_enc->state.loop_filter_limits)); - oc_enquant_qavg_init(_enc->log_qavg,_enc->state.dequant_tables, - _enc->state.info.pixel_fmt); - return 0; -} - -static void oc_enc_clear(oc_enc_ctx *_enc); - -static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){ - th_info info; - size_t mcu_nmbs; - ptrdiff_t mcu_nfrags; - int hdec; - int vdec; - int ret; - int pli; - /*Clean up the requested settings.*/ - memcpy(&info,_info,sizeof(info)); - info.version_major=TH_VERSION_MAJOR; - info.version_minor=TH_VERSION_MINOR; - info.version_subminor=TH_VERSION_SUB; - if(info.quality>63)info.quality=63; - if(info.quality<0)info.quality=32; - if(info.target_bitrate<0)info.target_bitrate=0; - /*Initialize the shared encoder/decoder state.*/ - ret=oc_state_init(&_enc->state,&info,4); - if(ret<0)return ret; - _enc->mb_info=_ogg_calloc(_enc->state.nmbs,sizeof(*_enc->mb_info)); - _enc->frag_dc=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_dc)); - _enc->coded_mbis= - (unsigned *)_ogg_malloc(_enc->state.nmbs*sizeof(*_enc->coded_mbis)); - hdec=!(_enc->state.info.pixel_fmt&1); - vdec=!(_enc->state.info.pixel_fmt&2); - /*If chroma is sub-sampled in the vertical direction, we have to encode two - super block rows of Y' for each super block row of Cb and Cr.*/ - _enc->mcu_nvsbs=1<mcu_nvsbs*_enc->state.fplanes[0].nhsbs*(size_t)4; - mcu_nfrags=4*mcu_nmbs+(8*mcu_nmbs>>hdec+vdec); - _enc->mcu_skip_ssd=(unsigned *)_ogg_malloc( - mcu_nfrags*sizeof(*_enc->mcu_skip_ssd)); - for(pli=0;pli<3;pli++){ - _enc->dct_tokens[pli]=(unsigned char **)oc_malloc_2d(64, - _enc->state.fplanes[pli].nfrags,sizeof(**_enc->dct_tokens)); - _enc->extra_bits[pli]=(ogg_uint16_t **)oc_malloc_2d(64, - _enc->state.fplanes[pli].nfrags,sizeof(**_enc->extra_bits)); - } -#if defined(OC_COLLECT_METRICS) - _enc->frag_satd=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_satd)); - _enc->frag_ssd=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_ssd)); -#endif -#if defined(OC_X86_ASM) - oc_enc_vtable_init_x86(_enc); -#else - oc_enc_vtable_init_c(_enc); -#endif - _enc->keyframe_frequency_force=1<<_enc->state.info.keyframe_granule_shift; - _enc->state.qis[0]=_enc->state.info.quality; - _enc->state.nqis=1; - oc_rc_state_init(&_enc->rc,_enc); - oggpackB_writeinit(&_enc->opb); - if(_enc->mb_info==NULL||_enc->frag_dc==NULL||_enc->coded_mbis==NULL|| - _enc->mcu_skip_ssd==NULL||_enc->dct_tokens[0]==NULL|| - _enc->dct_tokens[1]==NULL||_enc->dct_tokens[2]==NULL|| - _enc->extra_bits[0]==NULL||_enc->extra_bits[1]==NULL|| - _enc->extra_bits[2]==NULL -#if defined(OC_COLLECT_METRICS) - ||_enc->frag_satd==NULL||_enc->frag_ssd==NULL -#endif - ){ - oc_enc_clear(_enc); - return TH_EFAULT; - } - oc_mode_scheme_chooser_init(&_enc->chooser); - oc_enc_mb_info_init(_enc); - memset(_enc->huff_idxs,0,sizeof(_enc->huff_idxs)); - /*Reset the packet-out state machine.*/ - _enc->packet_state=OC_PACKET_INFO_HDR; - _enc->dup_count=0; - _enc->nqueued_dups=0; - _enc->prev_dup_count=0; - /*Enable speed optimizations up through early skip by default.*/ - _enc->sp_level=OC_SP_LEVEL_EARLY_SKIP; - /*Disable VP3 compatibility by default.*/ - _enc->vp3_compatible=0; - /*No INTER frames coded yet.*/ - _enc->coded_inter_frame=0; - memcpy(_enc->huff_codes,TH_VP31_HUFF_CODES,sizeof(_enc->huff_codes)); - oc_enc_set_quant_params(_enc,NULL); - return 0; -} - -static void oc_enc_clear(oc_enc_ctx *_enc){ - int pli; - oc_rc_state_clear(&_enc->rc); -#if defined(OC_COLLECT_METRICS) - oc_enc_mode_metrics_dump(_enc); -#endif - oggpackB_writeclear(&_enc->opb); -#if defined(OC_COLLECT_METRICS) - _ogg_free(_enc->frag_ssd); - _ogg_free(_enc->frag_satd); -#endif - for(pli=3;pli-->0;){ - oc_free_2d(_enc->extra_bits[pli]); - oc_free_2d(_enc->dct_tokens[pli]); - } - _ogg_free(_enc->mcu_skip_ssd); - _ogg_free(_enc->coded_mbis); - _ogg_free(_enc->frag_dc); - _ogg_free(_enc->mb_info); - oc_state_clear(&_enc->state); -} - -static void oc_enc_drop_frame(th_enc_ctx *_enc){ - /*Use the previous frame's reconstruction.*/ - _enc->state.ref_frame_idx[OC_FRAME_SELF]= - _enc->state.ref_frame_idx[OC_FRAME_PREV]; - /*Flag motion vector analysis about the frame drop.*/ - _enc->prevframe_dropped=1; - /*Zero the packet.*/ - oggpackB_reset(&_enc->opb); -} - -static void oc_enc_compress_keyframe(oc_enc_ctx *_enc,int _recode){ - if(_enc->state.info.target_bitrate>0){ - _enc->state.qis[0]=oc_enc_select_qi(_enc,OC_INTRA_FRAME, - _enc->state.curframe_num>0); - _enc->state.nqis=1; - } - oc_enc_calc_lambda(_enc,OC_INTRA_FRAME); - oc_enc_analyze_intra(_enc,_recode); - oc_enc_frame_pack(_enc); - /*On the first frame, the previous call was an initial dry-run to prime - feed-forward statistics.*/ - if(!_recode&&_enc->state.curframe_num==0){ - if(_enc->state.info.target_bitrate>0){ - oc_enc_update_rc_state(_enc,oggpackB_bytes(&_enc->opb)<<3, - OC_INTRA_FRAME,_enc->state.qis[0],1,0); - } - oc_enc_compress_keyframe(_enc,1); - } -} - -static void oc_enc_compress_frame(oc_enc_ctx *_enc,int _recode){ - if(_enc->state.info.target_bitrate>0){ - _enc->state.qis[0]=oc_enc_select_qi(_enc,OC_INTER_FRAME,1); - _enc->state.nqis=1; - } - oc_enc_calc_lambda(_enc,OC_INTER_FRAME); - if(oc_enc_analyze_inter(_enc,_enc->rc.twopass!=2,_recode)){ - /*Mode analysis thinks this should have been a keyframe; start over.*/ - oc_enc_compress_keyframe(_enc,1); - } - else{ - oc_enc_frame_pack(_enc); - if(!_enc->coded_inter_frame){ - /*On the first INTER frame, the previous call was an initial dry-run to - prime feed-forward statistics.*/ - _enc->coded_inter_frame=1; - if(_enc->state.info.target_bitrate>0){ - /*Rate control also needs to prime.*/ - oc_enc_update_rc_state(_enc,oggpackB_bytes(&_enc->opb)<<3, - OC_INTER_FRAME,_enc->state.qis[0],1,0); - } - oc_enc_compress_frame(_enc,1); - } - } -} - -/*Set the granule position for the next packet to output based on the current - internal state.*/ -static void oc_enc_set_granpos(oc_enc_ctx *_enc){ - unsigned dup_offs; - /*Add an offset for the number of duplicate frames we've emitted so far.*/ - dup_offs=_enc->prev_dup_count-_enc->nqueued_dups; - /*If the current frame was a keyframe, use it for the high part.*/ - if(_enc->state.frame_type==OC_INTRA_FRAME){ - _enc->state.granpos=(_enc->state.curframe_num+_enc->state.granpos_bias<< - _enc->state.info.keyframe_granule_shift)+dup_offs; - } - /*Otherwise use the last keyframe in the high part and put the current frame - in the low part.*/ - else{ - _enc->state.granpos= - (_enc->state.keyframe_num+_enc->state.granpos_bias<< - _enc->state.info.keyframe_granule_shift) - +_enc->state.curframe_num-_enc->state.keyframe_num+dup_offs; - } -} - - -th_enc_ctx *th_encode_alloc(const th_info *_info){ - oc_enc_ctx *enc; - if(_info==NULL)return NULL; - enc=_ogg_malloc(sizeof(*enc)); - if(enc==NULL||oc_enc_init(enc,_info)<0){ - _ogg_free(enc); - return NULL; - } - return enc; -} - -void th_encode_free(th_enc_ctx *_enc){ - if(_enc!=NULL){ - oc_enc_clear(_enc); - _ogg_free(_enc); - } -} - -int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){ - switch(_req){ - case TH_ENCCTL_SET_HUFFMAN_CODES:{ - if(_buf==NULL&&_buf_sz!=0|| - _buf!=NULL&&_buf_sz!=sizeof(th_huff_table)*TH_NHUFFMAN_TABLES){ - return TH_EINVAL; - } - return oc_enc_set_huffman_codes(_enc,(const th_huff_table *)_buf); - }break; - case TH_ENCCTL_SET_QUANT_PARAMS:{ - if(_buf==NULL&&_buf_sz!=0|| - _buf!=NULL&&_buf_sz!=sizeof(th_quant_info)){ - return TH_EINVAL; - } - return oc_enc_set_quant_params(_enc,(th_quant_info *)_buf); - }break; - case TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE:{ - ogg_uint32_t keyframe_frequency_force; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(keyframe_frequency_force))return TH_EINVAL; - keyframe_frequency_force=*(ogg_uint32_t *)_buf; - if(keyframe_frequency_force<=0)keyframe_frequency_force=1; - if(_enc->packet_state==OC_PACKET_INFO_HDR){ - /*It's still early enough to enlarge keyframe_granule_shift.*/ - _enc->state.info.keyframe_granule_shift=OC_CLAMPI( - _enc->state.info.keyframe_granule_shift, - OC_ILOG_32(keyframe_frequency_force-1),31); - } - _enc->keyframe_frequency_force=OC_MINI(keyframe_frequency_force, - (ogg_uint32_t)1U<<_enc->state.info.keyframe_granule_shift); - *(ogg_uint32_t *)_buf=_enc->keyframe_frequency_force; - return 0; - }break; - case TH_ENCCTL_SET_VP3_COMPATIBLE:{ - int vp3_compatible; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(vp3_compatible))return TH_EINVAL; - vp3_compatible=*(int *)_buf; - _enc->vp3_compatible=vp3_compatible; - if(oc_enc_set_huffman_codes(_enc,TH_VP31_HUFF_CODES)<0)vp3_compatible=0; - if(oc_enc_set_quant_params(_enc,&TH_VP31_QUANT_INFO)<0)vp3_compatible=0; - if(_enc->state.info.pixel_fmt!=TH_PF_420|| - _enc->state.info.pic_width<_enc->state.info.frame_width|| - _enc->state.info.pic_height<_enc->state.info.frame_height|| - /*If we have more than 4095 super blocks, VP3's RLE coding might - overflow. - We could overcome this by ensuring we flip the coded/not-coded flags on - at least one super block in the frame, but we pick the simple solution - of just telling the user the stream will be incompatible instead. - It's unlikely the old VP3 codec would be able to decode streams at this - resolution in real time in the first place.*/ - _enc->state.nsbs>4095){ - vp3_compatible=0; - } - *(int *)_buf=vp3_compatible; - return 0; - }break; - case TH_ENCCTL_GET_SPLEVEL_MAX:{ - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - *(int *)_buf=OC_SP_LEVEL_MAX; - return 0; - }break; - case TH_ENCCTL_SET_SPLEVEL:{ - int speed; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(speed))return TH_EINVAL; - speed=*(int *)_buf; - if(speed<0||speed>OC_SP_LEVEL_MAX)return TH_EINVAL; - _enc->sp_level=speed; - return 0; - }break; - case TH_ENCCTL_GET_SPLEVEL:{ - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(int))return TH_EINVAL; - *(int *)_buf=_enc->sp_level; - return 0; - } - case TH_ENCCTL_SET_DUP_COUNT:{ - int dup_count; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(dup_count))return TH_EINVAL; - dup_count=*(int *)_buf; - if(dup_count>=_enc->keyframe_frequency_force)return TH_EINVAL; - _enc->dup_count=OC_MAXI(dup_count,0); - return 0; - }break; - case TH_ENCCTL_SET_QUALITY:{ - int qi; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_enc->state.info.target_bitrate>0)return TH_EINVAL; - qi=*(int *)_buf; - if(qi<0||qi>63)return TH_EINVAL; - _enc->state.info.quality=qi; - _enc->state.qis[0]=(unsigned char)qi; - _enc->state.nqis=1; - return 0; - }break; - case TH_ENCCTL_SET_BITRATE:{ - long bitrate; - int reset; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - bitrate=*(long *)_buf; - if(bitrate<=0)return TH_EINVAL; - reset=_enc->state.info.target_bitrate<=0; - _enc->state.info.target_bitrate=bitrate>INT_MAX?INT_MAX:bitrate; - if(reset)oc_rc_state_init(&_enc->rc,_enc); - else oc_enc_rc_resize(_enc); - return 0; - }break; - case TH_ENCCTL_SET_RATE_FLAGS:{ - int set; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(set))return TH_EINVAL; - if(_enc->state.info.target_bitrate<=0)return TH_EINVAL; - set=*(int *)_buf; - _enc->rc.drop_frames=set&TH_RATECTL_DROP_FRAMES; - _enc->rc.cap_overflow=set&TH_RATECTL_CAP_OVERFLOW; - _enc->rc.cap_underflow=set&TH_RATECTL_CAP_UNDERFLOW; - return 0; - }break; - case TH_ENCCTL_SET_RATE_BUFFER:{ - int set; - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_buf_sz!=sizeof(set))return TH_EINVAL; - if(_enc->state.info.target_bitrate<=0)return TH_EINVAL; - set=*(int *)_buf; - _enc->rc.buf_delay=set; - oc_enc_rc_resize(_enc); - *(int *)_buf=_enc->rc.buf_delay; - return 0; - }break; - case TH_ENCCTL_2PASS_OUT:{ - if(_enc==NULL||_buf==NULL)return TH_EFAULT; - if(_enc->state.info.target_bitrate<=0|| - _enc->state.curframe_num>=0&&_enc->rc.twopass!=1|| - _buf_sz!=sizeof(unsigned char *)){ - return TH_EINVAL; - } - return oc_enc_rc_2pass_out(_enc,(unsigned char **)_buf); - }break; - case TH_ENCCTL_2PASS_IN:{ - if(_enc==NULL)return TH_EFAULT; - if(_enc->state.info.target_bitrate<=0|| - _enc->state.curframe_num>=0&&_enc->rc.twopass!=2){ - return TH_EINVAL; - } - return oc_enc_rc_2pass_in(_enc,_buf,_buf_sz); - }break; - default:return TH_EIMPL; - } -} - -int th_encode_flushheader(th_enc_ctx *_enc,th_comment *_tc,ogg_packet *_op){ - if(_enc==NULL)return TH_EFAULT; - return oc_state_flushheader(&_enc->state,&_enc->packet_state,&_enc->opb, - &_enc->qinfo,(const th_huff_table *)_enc->huff_codes,th_version_string(), - _tc,_op); -} - -static void oc_img_plane_copy_pad(th_img_plane *_dst,th_img_plane *_src, - ogg_int32_t _pic_x,ogg_int32_t _pic_y, - ogg_int32_t _pic_width,ogg_int32_t _pic_height){ - unsigned char *dst; - int dstride; - ogg_uint32_t frame_width; - ogg_uint32_t frame_height; - ogg_uint32_t y; - frame_width=_dst->width; - frame_height=_dst->height; - /*If we have _no_ data, just encode a dull green.*/ - if(_pic_width==0||_pic_height==0){ - dst=_dst->data; - dstride=_dst->stride; - for(y=0;ystride; - sstride=_src->stride; - dst_data=_dst->data; - src_data=_src->data; - dst=dst_data+_pic_y*(ptrdiff_t)dstride+_pic_x; - src=src_data+_pic_y*(ptrdiff_t)sstride+_pic_x; - for(y=0;y<_pic_height;y++){ - memcpy(dst,src,_pic_width); - dst+=dstride; - src+=sstride; - } - /*Step 2: Perform a low-pass extension into the padding region.*/ - /*Left side.*/ - for(x=_pic_x;x-->0;){ - dst=dst_data+_pic_y*(ptrdiff_t)dstride+x; - for(y=0;y<_pic_height;y++){ - dst[0]=(dst[1]<<1)+(dst-(dstride&-(y>0)))[1] - +(dst+(dstride&-(y+1<_pic_height)))[1]+2>>2; - dst+=dstride; - } - } - /*Right side.*/ - for(x=_pic_x+_pic_width;x0)))[0] - +(dst+(dstride&-(y+1<_pic_height)))[0]+2>>2; - dst+=dstride; - } - } - /*Top.*/ - dst=dst_data+_pic_y*(ptrdiff_t)dstride; - for(y=_pic_y;y-->0;){ - for(x=0;x0)] - +dst[x+(x+1>2; - } - dst-=dstride; - } - /*Bottom.*/ - dst=dst_data+(_pic_y+_pic_height)*(ptrdiff_t)dstride; - for(y=_pic_y+_pic_height;y0)] - +(dst-dstride)[x+(x+1>2; - } - dst+=dstride; - } - } -} - -int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){ - th_ycbcr_buffer img; - int cframe_width; - int cframe_height; - int cpic_width; - int cpic_height; - int cpic_x; - int cpic_y; - int hdec; - int vdec; - int pli; - int refi; - int drop; - /*Step 1: validate parameters.*/ - if(_enc==NULL||_img==NULL)return TH_EFAULT; - if(_enc->packet_state==OC_PACKET_DONE)return TH_EINVAL; - if(_enc->rc.twopass&&_enc->rc.twopass_buffer_bytes==0)return TH_EINVAL; - if((ogg_uint32_t)_img[0].width!=_enc->state.info.frame_width|| - (ogg_uint32_t)_img[0].height!=_enc->state.info.frame_height){ - return TH_EINVAL; - } - hdec=!(_enc->state.info.pixel_fmt&1); - vdec=!(_enc->state.info.pixel_fmt&2); - cframe_width=_enc->state.info.frame_width>>hdec; - cframe_height=_enc->state.info.frame_height>>vdec; - if(_img[1].width!=cframe_width||_img[2].width!=cframe_width|| - _img[1].height!=cframe_height||_img[2].height!=cframe_height){ - return TH_EINVAL; - } - /*Step 2: Copy the input to our internal buffer. - This lets us add padding, if necessary, so we don't have to worry about - dereferencing possibly invalid addresses, and allows us to use the same - strides and fragment offsets for both the input frame and the reference - frames.*/ - /*Flip the input buffer upside down.*/ - oc_ycbcr_buffer_flip(img,_img); - oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[OC_FRAME_IO]+0,img+0, - _enc->state.info.pic_x,_enc->state.info.pic_y, - _enc->state.info.pic_width,_enc->state.info.pic_height); - cpic_x=_enc->state.info.pic_x>>hdec; - cpic_y=_enc->state.info.pic_y>>vdec; - cpic_width=(_enc->state.info.pic_x+_enc->state.info.pic_width+hdec>>hdec) - -cpic_x; - cpic_height=(_enc->state.info.pic_y+_enc->state.info.pic_height+vdec>>vdec) - -cpic_y; - for(pli=1;pli<3;pli++){ - oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[OC_FRAME_IO]+pli,img+pli, - cpic_x,cpic_y,cpic_width,cpic_height); - } - /*Step 3: Update the buffer state.*/ - if(_enc->state.ref_frame_idx[OC_FRAME_SELF]>=0){ - _enc->state.ref_frame_idx[OC_FRAME_PREV]= - _enc->state.ref_frame_idx[OC_FRAME_SELF]; - if(_enc->state.frame_type==OC_INTRA_FRAME){ - /*The new frame becomes both the previous and gold reference frames.*/ - _enc->state.keyframe_num=_enc->state.curframe_num; - _enc->state.ref_frame_idx[OC_FRAME_GOLD]= - _enc->state.ref_frame_idx[OC_FRAME_SELF]; - } - } - /*Select a free buffer to use for the reconstructed version of this frame.*/ - for(refi=0;refi==_enc->state.ref_frame_idx[OC_FRAME_GOLD]|| - refi==_enc->state.ref_frame_idx[OC_FRAME_PREV];refi++); - _enc->state.ref_frame_idx[OC_FRAME_SELF]=refi; - _enc->state.curframe_num+=_enc->prev_dup_count+1; - /*Step 4: Compress the frame.*/ - /*Start with a keyframe, and don't allow the generation of invalid files that - overflow the keyframe_granule_shift.*/ - if(_enc->rc.twopass_force_kf||_enc->state.curframe_num==0|| - _enc->state.curframe_num-_enc->state.keyframe_num+_enc->dup_count>= - _enc->keyframe_frequency_force){ - oc_enc_compress_keyframe(_enc,0); - drop=0; - } - else{ - oc_enc_compress_frame(_enc,0); - drop=1; - } - oc_restore_fpu(&_enc->state); - /*drop currently indicates if the frame is droppable.*/ - if(_enc->state.info.target_bitrate>0){ - drop=oc_enc_update_rc_state(_enc,oggpackB_bytes(&_enc->opb)<<3, - _enc->state.frame_type,_enc->state.qis[0],0,drop); - } - else drop=0; - /*drop now indicates if the frame was dropped.*/ - if(drop)oc_enc_drop_frame(_enc); - else _enc->prevframe_dropped=0; - _enc->packet_state=OC_PACKET_READY; - _enc->prev_dup_count=_enc->nqueued_dups=_enc->dup_count; - _enc->dup_count=0; -#if defined(OC_DUMP_IMAGES) - oc_enc_set_granpos(_enc); - oc_state_dump_frame(&_enc->state,OC_FRAME_IO,"src"); - oc_state_dump_frame(&_enc->state,OC_FRAME_SELF,"rec"); -#endif - return 0; -} - -int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){ - if(_enc==NULL||_op==NULL)return TH_EFAULT; - if(_enc->packet_state==OC_PACKET_READY){ - _enc->packet_state=OC_PACKET_EMPTY; - if(_enc->rc.twopass!=1){ - unsigned char *packet; - packet=oggpackB_get_buffer(&_enc->opb); - /*If there's no packet, malloc failed while writing; it's lost forever.*/ - if(packet==NULL)return TH_EFAULT; - _op->packet=packet; - _op->bytes=oggpackB_bytes(&_enc->opb); - } - /*For the first pass in 2-pass mode, don't emit any packet data.*/ - else{ - _op->packet=NULL; - _op->bytes=0; - } - } - else if(_enc->packet_state==OC_PACKET_EMPTY){ - if(_enc->nqueued_dups>0){ - _enc->nqueued_dups--; - _op->packet=NULL; - _op->bytes=0; - } - else{ - if(_last_p)_enc->packet_state=OC_PACKET_DONE; - return 0; - } - } - else return 0; - _last_p=_last_p&&_enc->nqueued_dups<=0; - _op->b_o_s=0; - _op->e_o_s=_last_p; - oc_enc_set_granpos(_enc); - _op->packetno=th_granule_frame(_enc,_enc->state.granpos)+3; - _op->granulepos=_enc->state.granpos; - if(_last_p)_enc->packet_state=OC_PACKET_DONE; - return 1+_enc->nqueued_dups; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/enquant.c b/src/add-ons/media/plugins/theora/libtheora/enquant.c deleted file mode 100644 index 3372fed221..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/enquant.c +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: enquant.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include -#include -#include "encint.h" - - - -void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo){ - const th_quant_ranges *qranges; - const th_quant_base *base_mats[2*3*64]; - int indices[2][3][64]; - int nbase_mats; - int nbits; - int ci; - int qi; - int qri; - int qti; - int pli; - int qtj; - int plj; - int bmi; - int i; - i=_qinfo->loop_filter_limits[0]; - for(qi=1;qi<64;qi++)i=OC_MAXI(i,_qinfo->loop_filter_limits[qi]); - nbits=OC_ILOG_32(i); - oggpackB_write(_opb,nbits,3); - for(qi=0;qi<64;qi++){ - oggpackB_write(_opb,_qinfo->loop_filter_limits[qi],nbits); - } - /*580 bits for VP3.*/ - i=1; - for(qi=0;qi<64;qi++)i=OC_MAXI(_qinfo->ac_scale[qi],i); - nbits=OC_ILOGNZ_32(i); - oggpackB_write(_opb,nbits-1,4); - for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->ac_scale[qi],nbits); - /*516 bits for VP3.*/ - i=1; - for(qi=0;qi<64;qi++)i=OC_MAXI(_qinfo->dc_scale[qi],i); - nbits=OC_ILOGNZ_32(i); - oggpackB_write(_opb,nbits-1,4); - for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->dc_scale[qi],nbits); - /*Consolidate any duplicate base matrices.*/ - nbase_mats=0; - for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){ - qranges=_qinfo->qi_ranges[qti]+pli; - for(qri=0;qri<=qranges->nranges;qri++){ - for(bmi=0;;bmi++){ - if(bmi>=nbase_mats){ - base_mats[bmi]=qranges->base_matrices+qri; - indices[qti][pli][qri]=nbase_mats++; - break; - } - else if(memcmp(base_mats[bmi][0],qranges->base_matrices[qri], - sizeof(base_mats[bmi][0]))==0){ - indices[qti][pli][qri]=bmi; - break; - } - } - } - } - /*Write out the list of unique base matrices. - 1545 bits for VP3 matrices.*/ - oggpackB_write(_opb,nbase_mats-1,9); - for(bmi=0;bmiqi_ranges[qti]+pli; - if(i>0){ - if(qti>0){ - if(qranges->nranges==_qinfo->qi_ranges[qti-1][pli].nranges&& - memcmp(qranges->sizes,_qinfo->qi_ranges[qti-1][pli].sizes, - qranges->nranges*sizeof(qranges->sizes[0]))==0&& - memcmp(indices[qti][pli],indices[qti-1][pli], - (qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){ - oggpackB_write(_opb,1,2); - continue; - } - } - qtj=(i-1)/3; - plj=(i-1)%3; - if(qranges->nranges==_qinfo->qi_ranges[qtj][plj].nranges&& - memcmp(qranges->sizes,_qinfo->qi_ranges[qtj][plj].sizes, - qranges->nranges*sizeof(qranges->sizes[0]))==0&& - memcmp(indices[qti][pli],indices[qtj][plj], - (qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){ - oggpackB_write(_opb,0,1+(qti>0)); - continue; - } - oggpackB_write(_opb,1,1); - } - oggpackB_write(_opb,indices[qti][pli][0],nbits); - for(qi=qri=0;qi<63;qri++){ - oggpackB_write(_opb,qranges->sizes[qri]-1,OC_ILOG_32(62-qi)); - qi+=qranges->sizes[qri]; - oggpackB_write(_opb,indices[qti][pli][qri+1],nbits); - } - } -} - -static void oc_iquant_init(oc_iquant *_this,ogg_uint16_t _d){ - ogg_uint32_t t; - int l; - _d<<=1; - l=OC_ILOGNZ_32(_d)-1; - t=1+((ogg_uint32_t)1<<16+l)/_d; - _this->m=(ogg_int16_t)(t-0x10000); - _this->l=l; -} - -/*See comments at oc_dequant_tables_init() for how the quantization tables' - storage should be initialized.*/ -void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2], - oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo){ - int qi; - int pli; - int qti; - /*Initialize the dequantization tables first.*/ - oc_dequant_tables_init(_dequant,NULL,_qinfo); - /*Derive the quantization tables directly from the dequantization tables.*/ - for(qi=0;qi<64;qi++)for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){ - int zzi; - int plj; - int qtj; - int dupe; - dupe=0; - for(qtj=0;qtj<=qti;qtj++){ - for(plj=0;plj<(qtj>1))/qd; - qp+=rq*(ogg_uint32_t)rq; - } - q2+=OC_PCD[_pixel_fmt][pli]*(ogg_int64_t)qp; - } - /*qavg=1.0/sqrt(q2).*/ - _log_qavg[qti][qi]=OC_Q57(48)-oc_blog64(q2)>>1; - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/enquant.h b/src/add-ons/media/plugins/theora/libtheora/enquant.h deleted file mode 100644 index d62df10d1a..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/enquant.h +++ /dev/null @@ -1,27 +0,0 @@ -#if !defined(_enquant_H) -# define _enquant_H (1) -# include "quant.h" - -typedef struct oc_iquant oc_iquant; - -#define OC_QUANT_MAX_LOG (OC_Q57(OC_STATIC_ILOG_32(OC_QUANT_MAX)-1)) - -/*Used to compute x/d via ((x*m>>16)+x>>l)+(x<0)) - (i.e., one 16x16->16 mul, 2 shifts, and 2 adds). - This is not an approximation; for 16-bit x and d, it is exact.*/ -struct oc_iquant{ - ogg_int16_t m; - ogg_int16_t l; -}; - -typedef oc_iquant oc_iquant_table[64]; - - - -void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo); -void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2], - oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo); -void oc_enquant_qavg_init(ogg_int64_t _log_qavg[2][64], - ogg_uint16_t *_dequant[64][3][2],int _pixel_fmt); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/fdct.c b/src/add-ons/media/plugins/theora/libtheora/fdct.c deleted file mode 100644 index dc3a66f245..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/fdct.c +++ /dev/null @@ -1,422 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: fdct.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include "encint.h" -#include "dct.h" - - - -/*Performs a forward 8 point Type-II DCT transform. - The output is scaled by a factor of 2 from the orthonormal version of the - transform. - _y: The buffer to store the result in. - Data will be placed the first 8 entries (e.g., in a row of an 8x8 block). - _x: The input coefficients. - Every 8th entry is used (e.g., from a column of an 8x8 block).*/ -static void oc_fdct8(ogg_int16_t _y[8],const ogg_int16_t *_x){ - int t0; - int t1; - int t2; - int t3; - int t4; - int t5; - int t6; - int t7; - int r; - int s; - int u; - int v; - /*Stage 1:*/ - /*0-7 butterfly.*/ - t0=_x[0<<3]+(int)_x[7<<3]; - t7=_x[0<<3]-(int)_x[7<<3]; - /*1-6 butterfly.*/ - t1=_x[1<<3]+(int)_x[6<<3]; - t6=_x[1<<3]-(int)_x[6<<3]; - /*2-5 butterfly.*/ - t2=_x[2<<3]+(int)_x[5<<3]; - t5=_x[2<<3]-(int)_x[5<<3]; - /*3-4 butterfly.*/ - t3=_x[3<<3]+(int)_x[4<<3]; - t4=_x[3<<3]-(int)_x[4<<3]; - /*Stage 2:*/ - /*0-3 butterfly.*/ - r=t0+t3; - t3=t0-t3; - t0=r; - /*1-2 butterfly.*/ - r=t1+t2; - t2=t1-t2; - t1=r; - /*6-5 butterfly.*/ - r=t6+t5; - t5=t6-t5; - t6=r; - /*Stages 3 and 4 are where all the approximation occurs. - These are chosen to be as close to an exact inverse of the approximations - made in the iDCT as possible, while still using mostly 16-bit arithmetic. - We use some 16x16->32 signed MACs, but those still commonly execute in 1 - cycle on a 16-bit DSP. - For example, s=(27146*t5+0x4000>>16)+t5+(t5!=0) is an exact inverse of - t5=(OC_C4S4*s>>16). - That is, applying the latter to the output of the former will recover t5 - exactly (over the valid input range of t5, -23171...23169). - We increase the rounding bias to 0xB500 in this particular case so that - errors inverting the subsequent butterfly are not one-sided (e.g., the - mean error is very close to zero). - The (t5!=0) term could be replaced simply by 1, but we want to send 0 to 0. - The fDCT of an all-zeros block will still not be zero, because of the - biases we added at the very beginning of the process, but it will be close - enough that it is guaranteed to round to zero.*/ - /*Stage 3:*/ - /*4-5 butterfly.*/ - s=(27146*t5+0xB500>>16)+t5+(t5!=0)>>1; - r=t4+s; - t5=t4-s; - t4=r; - /*7-6 butterfly.*/ - s=(27146*t6+0xB500>>16)+t6+(t6!=0)>>1; - r=t7+s; - t6=t7-s; - t7=r; - /*Stage 4:*/ - /*0-1 butterfly.*/ - r=(27146*t0+0x4000>>16)+t0+(t0!=0); - s=(27146*t1+0xB500>>16)+t1+(t1!=0); - u=r+s>>1; - v=r-u; - _y[0]=u; - _y[4]=v; - /*3-2 rotation by 6pi/16*/ - u=(OC_C6S2*t2+OC_C2S6*t3+0x6CB7>>16)+(t3!=0); - s=(OC_C6S2*u>>16)-t2; - v=(s*21600+0x2800>>18)+s+(s!=0); - _y[2]=u; - _y[6]=v; - /*6-5 rotation by 3pi/16*/ - u=(OC_C5S3*t6+OC_C3S5*t5+0x0E3D>>16)+(t5!=0); - s=t6-(OC_C5S3*u>>16); - v=(s*26568+0x3400>>17)+s+(s!=0); - _y[5]=u; - _y[3]=v; - /*7-4 rotation by 7pi/16*/ - u=(OC_C7S1*t4+OC_C1S7*t7+0x7B1B>>16)+(t7!=0); - s=(OC_C7S1*u>>16)-t4; - v=(s*20539+0x3000>>20)+s+(s!=0); - _y[1]=u; - _y[7]=v; -} - -void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64], - const ogg_int16_t _x[64]){ - (*_enc->opt_vtable.fdct8x8)(_y,_x); -} - -/*Performs a forward 8x8 Type-II DCT transform. - The output is scaled by a factor of 4 relative to the orthonormal version - of the transform. - _y: The buffer to store the result in. - This may be the same as _x. - _x: The input coefficients. */ -void oc_enc_fdct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; - int i; - /*Add two extra bits of working precision to improve accuracy; any more and - we could overflow.*/ - for(i=0;i<64;i++)w[i]=_x[i]<<2; - /*These biases correct for some systematic error that remains in the full - fDCT->iDCT round trip.*/ - w[0]+=(w[0]!=0)+1; - w[1]++; - w[8]--; - /*Transform columns of w into rows of _y.*/ - for(in=w,out=_y,end=out+64;out>2; -} - - - -/*This does not seem to outperform simple LFE border padding before MC. - It yields higher PSNR, but much higher bitrate usage.*/ -#if 0 -typedef struct oc_extension_info oc_extension_info; - - - -/*Information needed to pad boundary blocks. - We multiply each row/column by an extension matrix that fills in the padding - values as a linear combination of the active values, so that an equivalent - number of coefficients are forced to zero. - This costs at most 16 multiplies, the same as a 1-D fDCT itself, and as - little as 7 multiplies. - We compute the extension matrices for every possible shape in advance, as - there are only 35. - The coefficients for all matrices are stored in a single array to take - advantage of the overlap and repetitiveness of many of the shapes. - A similar technique is applied to the offsets into this array. - This reduces the required table storage by about 48%. - See tools/extgen.c for details. - We could conceivably do the same for all 256 possible shapes.*/ -struct oc_extension_info{ - /*The mask of the active pixels in the shape.*/ - short mask; - /*The number of active pixels in the shape.*/ - short na; - /*The extension matrix. - This is (8-na)xna*/ - const ogg_int16_t *const *ext; - /*The pixel indices: na active pixels followed by 8-na padding pixels.*/ - unsigned char pi[8]; - /*The coefficient indices: na unconstrained coefficients followed by 8-na - coefficients to be forced to zero.*/ - unsigned char ci[8]; -}; - - -/*The number of shapes we need.*/ -#define OC_NSHAPES (35) - -static const ogg_int16_t OC_EXT_COEFFS[229]={ - 0x7FFF,0xE1F8,0x6903,0xAA79,0x5587,0x7FFF,0x1E08,0x7FFF, - 0x5587,0xAA79,0x6903,0xE1F8,0x7FFF,0x0000,0x0000,0x0000, - 0x7FFF,0x0000,0x0000,0x7FFF,0x8000,0x7FFF,0x0000,0x0000, - 0x7FFF,0xE1F8,0x1E08,0xB0A7,0xAA1D,0x337C,0x7FFF,0x4345, - 0x2267,0x4345,0x7FFF,0x337C,0xAA1D,0xB0A7,0x8A8C,0x4F59, - 0x03B4,0xE2D6,0x7FFF,0x2CF3,0x7FFF,0xE2D6,0x03B4,0x4F59, - 0x8A8C,0x1103,0x7AEF,0x5225,0xDF60,0xC288,0xDF60,0x5225, - 0x7AEF,0x1103,0x668A,0xD6EE,0x3A16,0x0E6C,0xFA07,0x0E6C, - 0x3A16,0xD6EE,0x668A,0x2A79,0x2402,0x980F,0x50F5,0x4882, - 0x50F5,0x980F,0x2402,0x2A79,0xF976,0x2768,0x5F22,0x2768, - 0xF976,0x1F91,0x76C1,0xE9AE,0x76C1,0x1F91,0x7FFF,0xD185, - 0x0FC8,0xD185,0x7FFF,0x4F59,0x4345,0xED62,0x4345,0x4F59, - 0xF574,0x5D99,0x2CF3,0x5D99,0xF574,0x5587,0x3505,0x30FC, - 0xF482,0x953C,0xEAC4,0x7FFF,0x4F04,0x7FFF,0xEAC4,0x953C, - 0xF482,0x30FC,0x4F04,0x273D,0xD8C3,0x273D,0x1E09,0x61F7, - 0x1E09,0x273D,0xD8C3,0x273D,0x4F04,0x30FC,0xA57E,0x153C, - 0x6AC4,0x3C7A,0x1E08,0x3C7A,0x6AC4,0x153C,0xA57E,0x7FFF, - 0xA57E,0x5A82,0x6AC4,0x153C,0xC386,0xE1F8,0xC386,0x153C, - 0x6AC4,0x5A82,0xD8C3,0x273D,0x7FFF,0xE1F7,0x7FFF,0x273D, - 0xD8C3,0x4F04,0x30FC,0xD8C3,0x273D,0xD8C3,0x30FC,0x4F04, - 0x1FC8,0x67AD,0x1853,0xE038,0x1853,0x67AD,0x1FC8,0x4546, - 0xE038,0x1FC8,0x3ABA,0x1FC8,0xE038,0x4546,0x3505,0x5587, - 0xF574,0xBC11,0x78F4,0x4AFB,0xE6F3,0x4E12,0x3C11,0xF8F4, - 0x4AFB,0x3C7A,0xF88B,0x3C11,0x78F4,0xCAFB,0x7FFF,0x08CC, - 0x070C,0x236D,0x5587,0x236D,0x070C,0xF88B,0x3C7A,0x4AFB, - 0xF8F4,0x3C11,0x7FFF,0x153C,0xCAFB,0x153C,0x7FFF,0x1E08, - 0xE1F8,0x7FFF,0x08CC,0x7FFF,0xCAFB,0x78F4,0x3C11,0x4E12, - 0xE6F3,0x4AFB,0x78F4,0xBC11,0xFE3D,0x7FFF,0xFE3D,0x2F3A, - 0x7FFF,0x2F3A,0x89BC,0x7FFF,0x89BC -}; - -static const ogg_int16_t *const OC_EXT_ROWS[96]={ - OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0, - OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 6, - OC_EXT_COEFFS+ 27,OC_EXT_COEFFS+ 38,OC_EXT_COEFFS+ 43,OC_EXT_COEFFS+ 32, - OC_EXT_COEFFS+ 49,OC_EXT_COEFFS+ 58,OC_EXT_COEFFS+ 67,OC_EXT_COEFFS+ 71, - OC_EXT_COEFFS+ 62,OC_EXT_COEFFS+ 53,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15, - OC_EXT_COEFFS+ 14,OC_EXT_COEFFS+ 13,OC_EXT_COEFFS+ 76,OC_EXT_COEFFS+ 81, - OC_EXT_COEFFS+ 86,OC_EXT_COEFFS+ 91,OC_EXT_COEFFS+ 96,OC_EXT_COEFFS+ 98, - OC_EXT_COEFFS+ 93,OC_EXT_COEFFS+ 88,OC_EXT_COEFFS+ 83,OC_EXT_COEFFS+ 78, - OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 12, - OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15, - OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 103,OC_EXT_COEFFS+ 108, - OC_EXT_COEFFS+ 126,OC_EXT_COEFFS+ 16,OC_EXT_COEFFS+ 137,OC_EXT_COEFFS+ 141, - OC_EXT_COEFFS+ 20,OC_EXT_COEFFS+ 130,OC_EXT_COEFFS+ 113,OC_EXT_COEFFS+ 116, - OC_EXT_COEFFS+ 146,OC_EXT_COEFFS+ 153,OC_EXT_COEFFS+ 160,OC_EXT_COEFFS+ 167, - OC_EXT_COEFFS+ 170,OC_EXT_COEFFS+ 163,OC_EXT_COEFFS+ 156,OC_EXT_COEFFS+ 149, - OC_EXT_COEFFS+ 119,OC_EXT_COEFFS+ 122,OC_EXT_COEFFS+ 174,OC_EXT_COEFFS+ 177, - OC_EXT_COEFFS+ 182,OC_EXT_COEFFS+ 187,OC_EXT_COEFFS+ 192,OC_EXT_COEFFS+ 197, - OC_EXT_COEFFS+ 202,OC_EXT_COEFFS+ 207,OC_EXT_COEFFS+ 210,OC_EXT_COEFFS+ 215, - OC_EXT_COEFFS+ 179,OC_EXT_COEFFS+ 189,OC_EXT_COEFFS+ 24,OC_EXT_COEFFS+ 204, - OC_EXT_COEFFS+ 184,OC_EXT_COEFFS+ 194,OC_EXT_COEFFS+ 212,OC_EXT_COEFFS+ 199, - OC_EXT_COEFFS+ 217,OC_EXT_COEFFS+ 100,OC_EXT_COEFFS+ 134,OC_EXT_COEFFS+ 135, - OC_EXT_COEFFS+ 135,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 134, - OC_EXT_COEFFS+ 134,OC_EXT_COEFFS+ 135,OC_EXT_COEFFS+ 220,OC_EXT_COEFFS+ 223, - OC_EXT_COEFFS+ 226,OC_EXT_COEFFS+ 227,OC_EXT_COEFFS+ 224,OC_EXT_COEFFS+ 221 -}; - -static const oc_extension_info OC_EXTENSION_INFO[OC_NSHAPES]={ - {0x7F,7,OC_EXT_ROWS+ 0,{0,1,2,3,4,5,6,7},{0,1,2,4,5,6,7,3}}, - {0xFE,7,OC_EXT_ROWS+ 7,{1,2,3,4,5,6,7,0},{0,1,2,4,5,6,7,3}}, - {0x3F,6,OC_EXT_ROWS+ 8,{0,1,2,3,4,5,7,6},{0,1,3,4,6,7,5,2}}, - {0xFC,6,OC_EXT_ROWS+ 10,{2,3,4,5,6,7,1,0},{0,1,3,4,6,7,5,2}}, - {0x1F,5,OC_EXT_ROWS+ 12,{0,1,2,3,4,7,6,5},{0,2,3,5,7,6,4,1}}, - {0xF8,5,OC_EXT_ROWS+ 15,{3,4,5,6,7,2,1,0},{0,2,3,5,7,6,4,1}}, - {0x0F,4,OC_EXT_ROWS+ 18,{0,1,2,3,7,6,5,4},{0,2,4,6,7,5,3,1}}, - {0xF0,4,OC_EXT_ROWS+ 18,{4,5,6,7,3,2,1,0},{0,2,4,6,7,5,3,1}}, - {0x07,3,OC_EXT_ROWS+ 22,{0,1,2,7,6,5,4,3},{0,3,6,7,5,4,2,1}}, - {0xE0,3,OC_EXT_ROWS+ 27,{5,6,7,4,3,2,1,0},{0,3,6,7,5,4,2,1}}, - {0x03,2,OC_EXT_ROWS+ 32,{0,1,7,6,5,4,3,2},{0,4,7,6,5,3,2,1}}, - {0xC0,2,OC_EXT_ROWS+ 32,{6,7,5,4,3,2,1,0},{0,4,7,6,5,3,2,1}}, - {0x01,1,OC_EXT_ROWS+ 0,{0,7,6,5,4,3,2,1},{0,7,6,5,4,3,2,1}}, - {0x80,1,OC_EXT_ROWS+ 0,{7,6,5,4,3,2,1,0},{0,7,6,5,4,3,2,1}}, - {0x7E,6,OC_EXT_ROWS+ 42,{1,2,3,4,5,6,7,0},{0,1,2,5,6,7,4,3}}, - {0x7C,5,OC_EXT_ROWS+ 44,{2,3,4,5,6,7,1,0},{0,1,4,5,7,6,3,2}}, - {0x3E,5,OC_EXT_ROWS+ 47,{1,2,3,4,5,7,6,0},{0,1,4,5,7,6,3,2}}, - {0x78,4,OC_EXT_ROWS+ 50,{3,4,5,6,7,2,1,0},{0,4,5,7,6,3,2,1}}, - {0x3C,4,OC_EXT_ROWS+ 54,{2,3,4,5,7,6,1,0},{0,3,4,7,6,5,2,1}}, - {0x1E,4,OC_EXT_ROWS+ 58,{1,2,3,4,7,6,5,0},{0,4,5,7,6,3,2,1}}, - {0x70,3,OC_EXT_ROWS+ 62,{4,5,6,7,3,2,1,0},{0,5,7,6,4,3,2,1}}, - {0x38,3,OC_EXT_ROWS+ 67,{3,4,5,7,6,2,1,0},{0,5,6,7,4,3,2,1}}, - {0x1C,3,OC_EXT_ROWS+ 72,{2,3,4,7,6,5,1,0},{0,5,6,7,4,3,2,1}}, - {0x0E,3,OC_EXT_ROWS+ 77,{1,2,3,7,6,5,4,0},{0,5,7,6,4,3,2,1}}, - {0x60,2,OC_EXT_ROWS+ 82,{5,6,7,4,3,2,1,0},{0,2,7,6,5,4,3,1}}, - {0x30,2,OC_EXT_ROWS+ 36,{4,5,7,6,3,2,1,0},{0,4,7,6,5,3,2,1}}, - {0x18,2,OC_EXT_ROWS+ 90,{3,4,7,6,5,2,1,0},{0,1,7,6,5,4,3,2}}, - {0x0C,2,OC_EXT_ROWS+ 34,{2,3,7,6,5,4,1,0},{0,4,7,6,5,3,2,1}}, - {0x06,2,OC_EXT_ROWS+ 84,{1,2,7,6,5,4,3,0},{0,2,7,6,5,4,3,1}}, - {0x40,1,OC_EXT_ROWS+ 0,{6,7,5,4,3,2,1,0},{0,7,6,5,4,3,2,1}}, - {0x20,1,OC_EXT_ROWS+ 0,{5,7,6,4,3,2,1,0},{0,7,6,5,4,3,2,1}}, - {0x10,1,OC_EXT_ROWS+ 0,{4,7,6,5,3,2,1,0},{0,7,6,5,4,3,2,1}}, - {0x08,1,OC_EXT_ROWS+ 0,{3,7,6,5,4,2,1,0},{0,7,6,5,4,3,2,1}}, - {0x04,1,OC_EXT_ROWS+ 0,{2,7,6,5,4,3,1,0},{0,7,6,5,4,3,2,1}}, - {0x02,1,OC_EXT_ROWS+ 0,{1,7,6,5,4,3,2,0},{0,7,6,5,4,3,2,1}} -}; - - - -/*Pads a single column of a partial block and then performs a forward Type-II - DCT on the result. - The input is scaled by a factor of 4 and biased appropriately for the current - fDCT implementation. - The output is scaled by an additional factor of 2 from the orthonormal - version of the transform. - _y: The buffer to store the result in. - Data will be placed the first 8 entries (e.g., in a row of an 8x8 block). - _x: The input coefficients. - Every 8th entry is used (e.g., from a column of an 8x8 block). - _e: The extension information for the shape.*/ -static void oc_fdct8_ext(ogg_int16_t _y[8],ogg_int16_t *_x, - const oc_extension_info *_e){ - const unsigned char *pi; - int na; - na=_e->na; - pi=_e->pi; - if(na==1){ - int ci; - /*While the branch below is still correct for shapes with na==1, we can - perform the entire transform with just 1 multiply in this case instead - of 23.*/ - _y[0]=(ogg_int16_t)(OC_DIV2_16(OC_C4S4*(_x[pi[0]]))); - for(ci=1;ci<8;ci++)_y[ci]=0; - } - else{ - const ogg_int16_t *const *ext; - int zpi; - int api; - int nz; - /*First multiply by the extension matrix to compute the padding values.*/ - nz=8-na; - ext=_e->ext; - for(zpi=0;zpi>16)+1>>1; - } - oc_fdct8(_y,_x); - } -} - -/*Performs a forward 8x8 Type-II DCT transform on blocks which overlap the - border of the picture region. - This method ONLY works with rectangular regions. - _border: A description of which pixels are inside the border. - _y: The buffer to store the result in. - This may be the same as _x. - _x: The input pixel values. - Pixel values outside the border will be ignored.*/ -void oc_fdct8x8_border(const oc_border_info *_border, - ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - ogg_int16_t *in; - ogg_int16_t *out; - ogg_int16_t w[64]; - ogg_int64_t mask; - const oc_extension_info *cext; - const oc_extension_info *rext; - int cmask; - int rmask; - int ri; - int ci; - /*Identify the shapes of the non-zero rows and columns.*/ - rmask=cmask=0; - mask=_border->mask; - for(ri=0;ri<8;ri++){ - /*This aggregation is _only_ correct for rectangular masks.*/ - cmask|=((mask&0xFF)!=0)<>=8; - } - /*Find the associated extension info for these shapes.*/ - if(cmask==0xFF)cext=NULL; - else for(cext=OC_EXTENSION_INFO;cext->mask!=cmask;){ - /*If we somehow can't find the shape, then just do an unpadded fDCT. - It won't be efficient, but it should still be correct.*/ - if(++cext>=OC_EXTENSION_INFO+OC_NSHAPES){ - oc_enc_fdct8x8_c(_y,_x); - return; - } - } - if(rmask==0xFF)rext=NULL; - else for(rext=OC_EXTENSION_INFO;rext->mask!=rmask;){ - /*If we somehow can't find the shape, then just do an unpadded fDCT. - It won't be efficient, but it should still be correct.*/ - if(++rext>=OC_EXTENSION_INFO+OC_NSHAPES){ - oc_enc_fdct8x8_c(_y,_x); - return; - } - } - /*Add two extra bits of working precision to improve accuracy; any more and - we could overflow.*/ - for(ci=0;ci<64;ci++)w[ci]=_x[ci]<<2; - /*These biases correct for some systematic error that remains in the full - fDCT->iDCT round trip. - We can safely add them before padding, since if these pixel values are - overwritten, we didn't care what they were anyway (and the unbiased values - will usually yield smaller DCT coefficient magnitudes).*/ - w[0]+=(w[0]!=0)+1; - w[1]++; - w[8]--; - /*Transform the columns. - We can ignore zero columns without a problem.*/ - in=w; - out=_y; - if(cext==NULL)for(ci=0;ci<8;ci++)oc_fdct8(out+(ci<<3),in+ci); - else for(ci=0;ci<8;ci++)if(rmask&(1<>2; -} -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/fragment.c b/src/add-ons/media/plugins/theora/libtheora/fragment.c deleted file mode 100644 index 15372e9d9f..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/fragment.c +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: fragment.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include -#include "internal.h" - -void oc_frag_copy(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride){ - (*_state->opt_vtable.frag_copy)(_dst,_src,_ystride); -} - -void oc_frag_copy_c(unsigned char *_dst,const unsigned char *_src,int _ystride){ - int i; - for(i=8;i-->0;){ - memcpy(_dst,_src,8*sizeof(*_dst)); - _dst+=_ystride; - _src+=_ystride; - } -} - -void oc_frag_recon_intra(const oc_theora_state *_state,unsigned char *_dst, - int _ystride,const ogg_int16_t _residue[64]){ - _state->opt_vtable.frag_recon_intra(_dst,_ystride,_residue); -} - -void oc_frag_recon_intra_c(unsigned char *_dst,int _ystride, - const ogg_int16_t _residue[64]){ - int i; - for(i=0;i<8;i++){ - int j; - for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+128); - _dst+=_ystride; - } -} - -void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){ - _state->opt_vtable.frag_recon_inter(_dst,_src,_ystride,_residue); -} - -void oc_frag_recon_inter_c(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){ - int i; - for(i=0;i<8;i++){ - int j; - for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+_src[j]); - _dst+=_ystride; - _src+=_ystride; - } -} - -void oc_frag_recon_inter2(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride, - const ogg_int16_t _residue[64]){ - _state->opt_vtable.frag_recon_inter2(_dst,_src1,_src2,_ystride,_residue); -} - -void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]){ - int i; - for(i=0;i<8;i++){ - int j; - for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+(_src1[j]+_src2[j]>>1)); - _dst+=_ystride; - _src1+=_ystride; - _src2+=_ystride; - } -} - -void oc_restore_fpu(const oc_theora_state *_state){ - _state->opt_vtable.restore_fpu(); -} - -void oc_restore_fpu_c(void){} diff --git a/src/add-ons/media/plugins/theora/libtheora/huffdec.c b/src/add-ons/media/plugins/theora/libtheora/huffdec.c deleted file mode 100644 index 8cf27f0341..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/huffdec.c +++ /dev/null @@ -1,489 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: huffdec.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include -#include -#include -#include "huffdec.h" -#include "decint.h" - - -/*The ANSI offsetof macro is broken on some platforms (e.g., older DECs).*/ -#define _ogg_offsetof(_type,_field)\ - ((size_t)((char *)&((_type *)0)->_field-(char *)0)) - -/*The number of internal tokens associated with each of the spec tokens.*/ -static const unsigned char OC_DCT_TOKEN_MAP_ENTRIES[TH_NDCT_TOKENS]={ - 1,1,1,4,8,1,1,8,1,1,1,1,1,2,2,2,2,4,8,2,2,2,4,2,2,2,2,2,8,2,4,8 -}; - -/*The map from external spec-defined tokens to internal tokens. - This is constructed so that any extra bits read with the original token value - can be masked off the least significant bits of its internal token index. - In addition, all of the tokens which require additional extra bits are placed - at the start of the list, and grouped by type. - OC_DCT_REPEAT_RUN3_TOKEN is placed first, as it is an extra-special case, so - giving it index 0 may simplify comparisons on some architectures. - These requirements require some substantial reordering.*/ -static const unsigned char OC_DCT_TOKEN_MAP[TH_NDCT_TOKENS]={ - /*OC_DCT_EOB1_TOKEN (0 extra bits)*/ - 15, - /*OC_DCT_EOB2_TOKEN (0 extra bits)*/ - 16, - /*OC_DCT_EOB3_TOKEN (0 extra bits)*/ - 17, - /*OC_DCT_REPEAT_RUN0_TOKEN (2 extra bits)*/ - 88, - /*OC_DCT_REPEAT_RUN1_TOKEN (3 extra bits)*/ - 80, - /*OC_DCT_REPEAT_RUN2_TOKEN (4 extra bits)*/ - 1, - /*OC_DCT_REPEAT_RUN3_TOKEN (12 extra bits)*/ - 0, - /*OC_DCT_SHORT_ZRL_TOKEN (3 extra bits)*/ - 48, - /*OC_DCT_ZRL_TOKEN (6 extra bits)*/ - 14, - /*OC_ONE_TOKEN (0 extra bits)*/ - 56, - /*OC_MINUS_ONE_TOKEN (0 extra bits)*/ - 57, - /*OC_TWO_TOKEN (0 extra bits)*/ - 58, - /*OC_MINUS_TWO_TOKEN (0 extra bits)*/ - 59, - /*OC_DCT_VAL_CAT2 (1 extra bit)*/ - 60, - 62, - 64, - 66, - /*OC_DCT_VAL_CAT3 (2 extra bits)*/ - 68, - /*OC_DCT_VAL_CAT4 (3 extra bits)*/ - 72, - /*OC_DCT_VAL_CAT5 (4 extra bits)*/ - 2, - /*OC_DCT_VAL_CAT6 (5 extra bits)*/ - 4, - /*OC_DCT_VAL_CAT7 (6 extra bits)*/ - 6, - /*OC_DCT_VAL_CAT8 (10 extra bits)*/ - 8, - /*OC_DCT_RUN_CAT1A (1 extra bit)*/ - 18, - 20, - 22, - 24, - 26, - /*OC_DCT_RUN_CAT1B (3 extra bits)*/ - 32, - /*OC_DCT_RUN_CAT1C (4 extra bits)*/ - 12, - /*OC_DCT_RUN_CAT2A (2 extra bits)*/ - 28, - /*OC_DCT_RUN_CAT2B (3 extra bits)*/ - 40 -}; - -/*These three functions are really part of the bitpack.c module, but - they are only used here. - Declaring local static versions so they can be inlined saves considerable - function call overhead.*/ - -static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){ - const unsigned char *ptr; - const unsigned char *stop; - oc_pb_window window; - int available; - window=_b->window; - available=_b->bits; - ptr=_b->ptr; - stop=_b->stop; - /*This version of _refill() doesn't bother setting eof because we won't - check for it after we've started decoding DCT tokens.*/ - if(ptr>=stop)available=OC_LOTS_OF_BITS; - while(available<=OC_PB_WINDOW_SIZE-8){ - available+=8; - window|=(oc_pb_window)*ptr++<=stop)available=OC_LOTS_OF_BITS; - } - _b->ptr=ptr; - if(_bits>available)window|=*ptr>>(available&7); - _b->bits=available; - return window; -} - - -/*Read in bits without advancing the bit pointer. - Here we assume 0<=_bits&&_bits<=32.*/ -static long oc_pack_look(oc_pack_buf *_b,int _bits){ - oc_pb_window window; - int available; - long result; - window=_b->window; - available=_b->bits; - if(_bits==0)return 0; - if(_bits>available)_b->window=window=oc_pack_refill(_b,_bits); - result=window>>OC_PB_WINDOW_SIZE-_bits; - return result; -} - -/*Advance the bit pointer.*/ -static void oc_pack_adv(oc_pack_buf *_b,int _bits){ - /*We ignore the special cases for _bits==0 and _bits==32 here, since they are - never used actually used. - OC_HUFF_SLUSH (defined below) would have to be at least 27 to actually read - 32 bits in a single go, and would require a 32 GB lookup table (assuming - 8 byte pointers, since 4 byte pointers couldn't fit such a table).*/ - _b->window<<=_bits; - _b->bits-=_bits; -} - - -/*The log_2 of the size of a lookup table is allowed to grow to relative to - the number of unique nodes it contains. - E.g., if OC_HUFF_SLUSH is 2, then at most 75% of the space in the tree is - wasted (each node will have an amortized cost of at most 20 bytes when using - 4-byte pointers). - Larger numbers can decode tokens with fewer read operations, while smaller - numbers may save more space (requiring as little as 8 bytes amortized per - node, though there will be more nodes). - With a sample file: - 32233473 read calls are required when no tree collapsing is done (100.0%). - 19269269 read calls are required when OC_HUFF_SLUSH is 0 (59.8%). - 11144969 read calls are required when OC_HUFF_SLUSH is 1 (34.6%). - 10538563 read calls are required when OC_HUFF_SLUSH is 2 (32.7%). - 10192578 read calls are required when OC_HUFF_SLUSH is 3 (31.6%). - Since a value of 1 gets us the vast majority of the speed-up with only a - small amount of wasted memory, this is what we use.*/ -#define OC_HUFF_SLUSH (1) - - -/*Determines the size in bytes of a Huffman tree node that represents a - subtree of depth _nbits. - _nbits: The depth of the subtree. - If this is 0, the node is a leaf node. - Otherwise 1<<_nbits pointers are allocated for children. - Return: The number of bytes required to store the node.*/ -static size_t oc_huff_node_size(int _nbits){ - size_t size; - size=_ogg_offsetof(oc_huff_node,nodes); - if(_nbits>0)size+=sizeof(oc_huff_node *)*(1<<_nbits); - return size; -} - -static oc_huff_node *oc_huff_node_init(char **_storage,size_t _size,int _nbits){ - oc_huff_node *ret; - ret=(oc_huff_node *)*_storage; - ret->nbits=(unsigned char)_nbits; - (*_storage)+=_size; - return ret; -} - - -/*Determines the size in bytes of a Huffman tree. - _nbits: The depth of the subtree. - If this is 0, the node is a leaf node. - Otherwise storage for 1<<_nbits pointers are added for children. - Return: The number of bytes required to store the tree.*/ -static size_t oc_huff_tree_size(const oc_huff_node *_node){ - size_t size; - size=oc_huff_node_size(_node->nbits); - if(_node->nbits){ - int nchildren; - int i; - nchildren=1<<_node->nbits; - for(i=0;inbits-_node->nodes[i]->depth){ - size+=oc_huff_tree_size(_node->nodes[i]); - } - } - return size; -} - - -/*Unpacks a sub-tree from the given buffer. - _opb: The buffer to unpack from. - _binodes: The nodes to store the sub-tree in. - _nbinodes: The number of nodes available for the sub-tree. - Return: 0 on success, or a negative value on error.*/ -static int oc_huff_tree_unpack(oc_pack_buf *_opb, - oc_huff_node *_binodes,int _nbinodes){ - oc_huff_node *binode; - long bits; - int nused; - if(_nbinodes<1)return TH_EBADHEADER; - binode=_binodes; - nused=0; - bits=oc_pack_read1(_opb); - if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER; - /*Read an internal node:*/ - if(!bits){ - int ret; - nused++; - binode->nbits=1; - binode->depth=1; - binode->nodes[0]=_binodes+nused; - ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused); - if(ret>=0){ - nused+=ret; - binode->nodes[1]=_binodes+nused; - ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused); - } - if(ret<0)return ret; - nused+=ret; - } - /*Read a leaf node:*/ - else{ - int ntokens; - int token; - int i; - bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS); - if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER; - /*Find out how many internal tokens we translate this external token into.*/ - ntokens=OC_DCT_TOKEN_MAP_ENTRIES[bits]; - if(_nbinodes<2*ntokens-1)return TH_EBADHEADER; - /*Fill in a complete binary tree pointing to the internal tokens.*/ - for(i=1;inbits=0; - binode->depth=1; - binode->token=token+i; - } - } - return nused; -} - -/*Finds the depth of shortest branch of the given sub-tree. - The tree must be binary. - _binode: The root of the given sub-tree. - _binode->nbits must be 0 or 1. - Return: The smallest depth of a leaf node in this sub-tree. - 0 indicates this sub-tree is a leaf node.*/ -static int oc_huff_tree_mindepth(oc_huff_node *_binode){ - int depth0; - int depth1; - if(_binode->nbits==0)return 0; - depth0=oc_huff_tree_mindepth(_binode->nodes[0]); - depth1=oc_huff_tree_mindepth(_binode->nodes[1]); - return OC_MINI(depth0,depth1)+1; -} - -/*Finds the number of internal nodes at a given depth, plus the number of - leaves at that depth or shallower. - The tree must be binary. - _binode: The root of the given sub-tree. - _binode->nbits must be 0 or 1. - Return: The number of entries that would be contained in a jump table of the - given depth.*/ -static int oc_huff_tree_occupancy(oc_huff_node *_binode,int _depth){ - if(_binode->nbits==0||_depth<=0)return 1; - else{ - return oc_huff_tree_occupancy(_binode->nodes[0],_depth-1)+ - oc_huff_tree_occupancy(_binode->nodes[1],_depth-1); - } -} - -/*Makes a copy of the given Huffman tree. - _node: The Huffman tree to copy. - Return: The copy of the Huffman tree.*/ -static oc_huff_node *oc_huff_tree_copy(const oc_huff_node *_node, - char **_storage){ - oc_huff_node *ret; - ret=oc_huff_node_init(_storage,oc_huff_node_size(_node->nbits),_node->nbits); - ret->depth=_node->depth; - if(_node->nbits){ - int nchildren; - int i; - int inext; - nchildren=1<<_node->nbits; - for(i=0;inodes[i]=oc_huff_tree_copy(_node->nodes[i],_storage); - inext=i+(1<<_node->nbits-ret->nodes[i]->depth); - while(++inodes[i]=ret->nodes[i-1]; - } - } - else ret->token=_node->token; - return ret; -} - -static size_t oc_huff_tree_collapse_size(oc_huff_node *_binode,int _depth){ - size_t size; - int mindepth; - int depth; - int loccupancy; - int occupancy; - if(_binode->nbits!=0&&_depth>0){ - return oc_huff_tree_collapse_size(_binode->nodes[0],_depth-1)+ - oc_huff_tree_collapse_size(_binode->nodes[1],_depth-1); - } - depth=mindepth=oc_huff_tree_mindepth(_binode); - occupancy=1<loccupancy&&occupancy>=1<0){ - size+=oc_huff_tree_collapse_size(_binode->nodes[0],depth-1); - size+=oc_huff_tree_collapse_size(_binode->nodes[1],depth-1); - } - return size; -} - -static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode, - char **_storage); - -/*Fills the given nodes table with all the children in the sub-tree at the - given depth. - The nodes in the sub-tree with a depth less than that stored in the table - are freed. - The sub-tree must be binary and complete up until the given depth. - _nodes: The nodes table to fill. - _binode: The root of the sub-tree to fill it with. - _binode->nbits must be 0 or 1. - _level: The current level in the table. - 0 indicates that the current node should be stored, regardless of - whether it is a leaf node or an internal node. - _depth: The depth of the nodes to fill the table with, relative to their - parent.*/ -static void oc_huff_node_fill(oc_huff_node **_nodes, - oc_huff_node *_binode,int _level,int _depth,char **_storage){ - if(_level<=0||_binode->nbits==0){ - int i; - _binode->depth=(unsigned char)(_depth-_level); - _nodes[0]=oc_huff_tree_collapse(_binode,_storage); - for(i=1;i<1<<_level;i++)_nodes[i]=_nodes[0]; - } - else{ - _level--; - oc_huff_node_fill(_nodes,_binode->nodes[0],_level,_depth,_storage); - _nodes+=1<<_level; - oc_huff_node_fill(_nodes,_binode->nodes[1],_level,_depth,_storage); - } -} - -/*Finds the largest complete sub-tree rooted at the current node and collapses - it into a single node. - This procedure is then applied recursively to all the children of that node. - _binode: The root of the sub-tree to collapse. - _binode->nbits must be 0 or 1. - Return: The new root of the collapsed sub-tree.*/ -static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode, - char **_storage){ - oc_huff_node *root; - size_t size; - int mindepth; - int depth; - int loccupancy; - int occupancy; - depth=mindepth=oc_huff_tree_mindepth(_binode); - occupancy=1<loccupancy&&occupancy>=1<depth=_binode->depth; - oc_huff_node_fill(root->nodes,_binode,depth,depth,_storage); - return root; -} - -/*Unpacks a set of Huffman trees, and reduces them to a collapsed - representation. - _opb: The buffer to unpack the trees from. - _nodes: The table to fill with the Huffman trees. - Return: 0 on success, or a negative value on error.*/ -int oc_huff_trees_unpack(oc_pack_buf *_opb, - oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){ - int i; - for(i=0;i0)_ogg_free(_dst[i]); - return TH_EFAULT; - } - _dst[i]=oc_huff_tree_copy(_src[i],&storage); - } - return 0; -} - -/*Frees the memory used by a set of Huffman trees. - _nodes: The array of trees to free.*/ -void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){ - int i; - for(i=0;inbits!=0){ - bits=oc_pack_look(_opb,_node->nbits); - _node=_node->nodes[bits]; - oc_pack_adv(_opb,_node->depth); - } - return _node->token; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/huffdec.h b/src/add-ons/media/plugins/theora/libtheora/huffdec.h deleted file mode 100644 index d7ffa0e99b..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/huffdec.h +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: huffdec.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#if !defined(_huffdec_H) -# define _huffdec_H (1) -# include "huffman.h" -# include "bitpack.h" - - - -typedef struct oc_huff_node oc_huff_node; - -/*A node in the Huffman tree. - Instead of storing every branching in the tree, subtrees can be collapsed - into one node, with a table of size 1< -#include -#include -#include "huffenc.h" - - - -/*The default Huffman codes used for VP3.1.*/ -const th_huff_code TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]={ - { - {0x002D, 6},{0x0026, 7},{0x0166, 9},{0x004E, 8}, - {0x02CE,10},{0x059E,11},{0x027D,11},{0x0008, 5}, - {0x04F9,12},{0x000F, 4},{0x000E, 4},{0x001B, 5}, - {0x0006, 4},{0x0008, 4},{0x0005, 4},{0x001A, 5}, - {0x0015, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3}, - {0x0000, 3},{0x0009, 4},{0x0017, 5},{0x0029, 6}, - {0x0028, 6},{0x00B2, 8},{0x04F8,12},{0x059F,11}, - {0x009E, 9},{0x013F,10},{0x0012, 6},{0x0058, 7} - }, - { - {0x0010, 5},{0x0047, 7},{0x01FF, 9},{0x008C, 8}, - {0x03FC,10},{0x046A,11},{0x0469,11},{0x0022, 6}, - {0x11A1,13},{0x000E, 4},{0x000D, 4},{0x0004, 4}, - {0x0005, 4},{0x0009, 4},{0x0006, 4},{0x001E, 5}, - {0x0016, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3}, - {0x0000, 3},{0x000A, 4},{0x0017, 5},{0x007D, 7}, - {0x007E, 7},{0x011B, 9},{0x08D1,12},{0x03FD,10}, - {0x046B,11},{0x11A0,13},{0x007C, 7},{0x00FE, 8} - }, - { - {0x0016, 5},{0x0020, 6},{0x0086, 8},{0x0087, 8}, - {0x0367,10},{0x06CC,11},{0x06CB,11},{0x006E, 7}, - {0x366D,14},{0x000F, 4},{0x000E, 4},{0x0004, 4}, - {0x0005, 4},{0x000A, 4},{0x0006, 4},{0x001A, 5}, - {0x0011, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3}, - {0x0000, 3},{0x0009, 4},{0x0017, 5},{0x006F, 7}, - {0x006D, 7},{0x0364,10},{0x0D9A,12},{0x06CA,11}, - {0x1B37,13},{0x366C,14},{0x0042, 7},{0x00D8, 8} - }, - { - {0x0000, 4},{0x002D, 6},{0x00F7, 8},{0x0058, 7}, - {0x0167, 9},{0x02CB,10},{0x02CA,10},{0x000E, 6}, - {0x1661,13},{0x0003, 3},{0x0002, 3},{0x0008, 4}, - {0x0009, 4},{0x000D, 4},{0x0002, 4},{0x001F, 5}, - {0x0017, 5},{0x0001, 4},{0x000C, 4},{0x000E, 4}, - {0x000A, 4},{0x0006, 5},{0x0078, 7},{0x000F, 6}, - {0x007A, 7},{0x0164, 9},{0x0599,11},{0x02CD,10}, - {0x0B31,12},{0x1660,13},{0x0079, 7},{0x00F6, 8} - }, - { - {0x0003, 4},{0x003C, 6},{0x000F, 7},{0x007A, 7}, - {0x001D, 8},{0x0020, 9},{0x0072,10},{0x0006, 6}, - {0x0399,13},{0x0004, 3},{0x0005, 3},{0x0005, 4}, - {0x0006, 4},{0x000E, 4},{0x0004, 4},{0x0000, 4}, - {0x0019, 5},{0x0002, 4},{0x000D, 4},{0x0007, 4}, - {0x001F, 5},{0x0030, 6},{0x0011, 8},{0x0031, 6}, - {0x0005, 6},{0x0021, 9},{0x00E7,11},{0x0038, 9}, - {0x01CD,12},{0x0398,13},{0x007B, 7},{0x0009, 7} - }, - { - {0x0009, 4},{0x0002, 5},{0x0074, 7},{0x0007, 6}, - {0x00EC, 8},{0x00D1, 9},{0x01A6,10},{0x0006, 6}, - {0x0D21,13},{0x0005, 3},{0x0006, 3},{0x0008, 4}, - {0x0007, 4},{0x000F, 4},{0x0004, 4},{0x0000, 4}, - {0x001C, 5},{0x0002, 4},{0x0005, 4},{0x0003, 4}, - {0x000C, 5},{0x0035, 7},{0x01A7,10},{0x001B, 6}, - {0x0077, 7},{0x01A5,10},{0x0349,11},{0x00D0, 9}, - {0x0691,12},{0x0D20,13},{0x0075, 7},{0x00ED, 8} - }, - { - {0x000A, 4},{0x000C, 5},{0x0012, 6},{0x001B, 6}, - {0x00B7, 8},{0x016C, 9},{0x0099, 9},{0x005A, 7}, - {0x16D8,13},{0x0007, 3},{0x0006, 3},{0x0009, 4}, - {0x0008, 4},{0x0000, 3},{0x0005, 4},{0x0017, 5}, - {0x000E, 5},{0x0002, 4},{0x0003, 4},{0x000F, 5}, - {0x001A, 6},{0x004D, 8},{0x2DB3,14},{0x002C, 6}, - {0x0011, 6},{0x02DA,10},{0x05B7,11},{0x0098, 9}, - {0x0B6D,12},{0x2DB2,14},{0x0010, 6},{0x0027, 7} - }, - { - {0x000D, 4},{0x000F, 5},{0x001D, 6},{0x0008, 5}, - {0x0051, 7},{0x0056, 8},{0x00AF, 9},{0x002A, 7}, - {0x148A,13},{0x0007, 3},{0x0000, 2},{0x0008, 4}, - {0x0009, 4},{0x000C, 4},{0x0006, 4},{0x0017, 5}, - {0x000B, 5},{0x0016, 5},{0x0015, 5},{0x0009, 5}, - {0x0050, 7},{0x00AE, 9},{0x2917,14},{0x001C, 6}, - {0x0014, 6},{0x0290,10},{0x0523,11},{0x0149, 9}, - {0x0A44,12},{0x2916,14},{0x0053, 7},{0x00A5, 8} - }, - { - {0x0001, 4},{0x001D, 6},{0x00F5, 8},{0x00F4, 8}, - {0x024D,10},{0x0499,11},{0x0498,11},{0x0001, 5}, - {0x0021, 6},{0x0006, 3},{0x0005, 3},{0x0006, 4}, - {0x0005, 4},{0x0002, 4},{0x0007, 5},{0x0025, 6}, - {0x007B, 7},{0x001C, 6},{0x0020, 6},{0x000D, 6}, - {0x0048, 7},{0x0092, 8},{0x0127, 9},{0x000E, 4}, - {0x0004, 4},{0x0011, 5},{0x000C, 6},{0x003C, 6}, - {0x000F, 5},{0x0000, 5},{0x001F, 5},{0x0013, 5} - }, - { - {0x0005, 4},{0x003C, 6},{0x0040, 7},{0x000D, 7}, - {0x0031, 9},{0x0061,10},{0x0060,10},{0x0002, 5}, - {0x00F5, 8},{0x0006, 3},{0x0005, 3},{0x0007, 4}, - {0x0006, 4},{0x0002, 4},{0x0009, 5},{0x0025, 6}, - {0x0007, 6},{0x0021, 6},{0x0024, 6},{0x0010, 6}, - {0x0041, 7},{0x00F4, 8},{0x0019, 8},{0x000E, 4}, - {0x0003, 4},{0x0011, 5},{0x0011, 6},{0x003F, 6}, - {0x003E, 6},{0x007B, 7},{0x0000, 4},{0x0013, 5} - }, - { - {0x000A, 4},{0x0007, 5},{0x0001, 6},{0x0009, 6}, - {0x0131, 9},{0x0261,10},{0x0260,10},{0x0015, 6}, - {0x0001, 7},{0x0007, 3},{0x0006, 3},{0x0008, 4}, - {0x0007, 4},{0x0006, 4},{0x0012, 5},{0x002F, 6}, - {0x0014, 6},{0x0027, 6},{0x002D, 6},{0x0016, 6}, - {0x004D, 7},{0x0099, 8},{0x0000, 7},{0x0004, 4}, - {0x0001, 4},{0x0005, 5},{0x0017, 6},{0x002E, 6}, - {0x002C, 6},{0x0008, 6},{0x0006, 5},{0x0001, 5} - }, - { - {0x0000, 3},{0x000E, 5},{0x0017, 6},{0x002A, 6}, - {0x0010, 7},{0x00F9,10},{0x00F8,10},{0x001E, 7}, - {0x003F, 8},{0x0007, 3},{0x0006, 3},{0x0009, 4}, - {0x0008, 4},{0x0006, 4},{0x000F, 5},{0x0005, 5}, - {0x0016, 6},{0x0029, 6},{0x002B, 6},{0x0015, 6}, - {0x0050, 7},{0x0011, 7},{0x007D, 9},{0x0004, 4}, - {0x0017, 5},{0x0006, 5},{0x0014, 6},{0x002C, 6}, - {0x002D, 6},{0x000E, 6},{0x0009, 6},{0x0051, 7} - }, - { - {0x0002, 3},{0x0018, 5},{0x002F, 6},{0x000D, 5}, - {0x0053, 7},{0x0295,10},{0x0294,10},{0x00A4, 8}, - {0x007C, 8},{0x0000, 2},{0x0007, 3},{0x0009, 4}, - {0x0008, 4},{0x001B, 5},{0x000C, 5},{0x0028, 6}, - {0x006A, 7},{0x001E, 6},{0x001D, 6},{0x0069, 7}, - {0x00D7, 8},{0x007D, 8},{0x014B, 9},{0x0019, 5}, - {0x0016, 5},{0x002E, 6},{0x001C, 6},{0x002B, 6}, - {0x002A, 6},{0x0068, 7},{0x003F, 7},{0x00D6, 8} - }, - { - {0x0002, 3},{0x001B, 5},{0x000C, 5},{0x0018, 5}, - {0x0029, 6},{0x007F, 8},{0x02F0,10},{0x0198, 9}, - {0x0179, 9},{0x0000, 2},{0x0007, 3},{0x0009, 4}, - {0x0008, 4},{0x001A, 5},{0x000D, 5},{0x002A, 6}, - {0x0064, 7},{0x001E, 6},{0x0067, 7},{0x005F, 7}, - {0x00CD, 8},{0x007E, 8},{0x02F1,10},{0x0016, 5}, - {0x000E, 5},{0x002E, 6},{0x0065, 7},{0x002B, 6}, - {0x0028, 6},{0x003E, 7},{0x00BD, 8},{0x0199, 9} - }, - { - {0x0002, 3},{0x0007, 4},{0x0016, 5},{0x0006, 4}, - {0x0036, 6},{0x005C, 7},{0x015D, 9},{0x015C, 9}, - {0x02BF,10},{0x0000, 2},{0x0007, 3},{0x0009, 4}, - {0x0008, 4},{0x0018, 5},{0x0034, 6},{0x002A, 6}, - {0x005E, 7},{0x006A, 7},{0x0064, 7},{0x005D, 7}, - {0x00CB, 8},{0x00AD, 8},{0x02BE,10},{0x0014, 5}, - {0x0033, 6},{0x006E, 7},{0x005F, 7},{0x006F, 7}, - {0x006B, 7},{0x00CA, 8},{0x00AC, 8},{0x015E, 9} - }, - { - {0x000F, 4},{0x001D, 5},{0x0018, 5},{0x000B, 4}, - {0x0019, 5},{0x0029, 6},{0x00D6, 8},{0x0551,11}, - {0x0AA1,12},{0x0001, 2},{0x0000, 2},{0x0009, 4}, - {0x0008, 4},{0x001B, 5},{0x0038, 6},{0x0028, 6}, - {0x0057, 7},{0x006A, 7},{0x0068, 7},{0x0056, 7}, - {0x00E5, 8},{0x0155, 9},{0x0AA0,12},{0x0073, 7}, - {0x0069, 7},{0x00D7, 8},{0x00AB, 8},{0x00E4, 8}, - {0x00A9, 8},{0x0151, 9},{0x0150, 9},{0x02A9,10} - }, - { - {0x0008, 5},{0x0025, 7},{0x017A, 9},{0x02F7,10}, - {0x0BDB,12},{0x17B4,13},{0x2F6B,14},{0x001D, 5}, - {0x2F6A,14},{0x0008, 4},{0x0007, 4},{0x0001, 4}, - {0x0002, 4},{0x000A, 4},{0x0006, 4},{0x0000, 4}, - {0x001C, 5},{0x0009, 4},{0x000D, 4},{0x000F, 4}, - {0x000C, 4},{0x0003, 4},{0x000A, 5},{0x0016, 5}, - {0x0013, 6},{0x005D, 7},{0x0024, 7},{0x00BC, 8}, - {0x005C, 7},{0x05EC,11},{0x000B, 5},{0x005F, 7} - }, - { - {0x000F, 5},{0x0010, 6},{0x004B, 8},{0x00C6, 8}, - {0x031D,10},{0x0C71,12},{0x0C70,12},{0x0001, 4}, - {0x0C73,12},{0x0008, 4},{0x0009, 4},{0x0002, 4}, - {0x0003, 4},{0x000B, 4},{0x0006, 4},{0x0000, 4}, - {0x001C, 5},{0x0005, 4},{0x000D, 4},{0x000F, 4}, - {0x000A, 4},{0x0019, 5},{0x0013, 6},{0x001D, 5}, - {0x0030, 6},{0x0062, 7},{0x0024, 7},{0x004A, 8}, - {0x018F, 9},{0x0C72,12},{0x000E, 5},{0x0011, 6} - }, - { - {0x001B, 5},{0x0003, 6},{0x008D, 8},{0x0040, 7}, - {0x0239,10},{0x0471,11},{0x08E0,12},{0x0003, 4}, - {0x11C3,13},{0x000A, 4},{0x0009, 4},{0x0004, 4}, - {0x0005, 4},{0x000E, 4},{0x0007, 4},{0x0001, 4}, - {0x001E, 5},{0x0006, 4},{0x000C, 4},{0x000B, 4}, - {0x0002, 4},{0x0000, 5},{0x0041, 7},{0x001F, 5}, - {0x0022, 6},{0x0002, 6},{0x008F, 8},{0x008C, 8}, - {0x011D, 9},{0x11C2,13},{0x001A, 5},{0x0021, 6} - }, - { - {0x001F, 5},{0x0003, 6},{0x0003, 7},{0x0043, 7}, - {0x000B, 9},{0x0015,10},{0x0051,12},{0x0003, 4}, - {0x0050,12},{0x000D, 4},{0x000C, 4},{0x0004, 4}, - {0x0006, 4},{0x000E, 4},{0x000A, 4},{0x0001, 4}, - {0x001E, 5},{0x0005, 4},{0x0009, 4},{0x0007, 4}, - {0x0011, 5},{0x0002, 6},{0x0004, 8},{0x0002, 4}, - {0x002D, 6},{0x0020, 6},{0x0042, 7},{0x0001, 7}, - {0x0000, 7},{0x0029,11},{0x0017, 5},{0x002C, 6} - }, - { - {0x0003, 4},{0x001F, 6},{0x003A, 7},{0x005D, 7}, - {0x0173, 9},{0x02E4,10},{0x172D,13},{0x0004, 4}, - {0x172C,13},{0x000F, 4},{0x000E, 4},{0x0009, 4}, - {0x0008, 4},{0x000C, 4},{0x000A, 4},{0x0001, 4}, - {0x0016, 5},{0x0002, 4},{0x0005, 4},{0x001A, 5}, - {0x002F, 6},{0x0038, 7},{0x05CA,11},{0x0006, 4}, - {0x0037, 6},{0x001E, 6},{0x003B, 7},{0x0039, 7}, - {0x00B8, 8},{0x0B97,12},{0x0000, 4},{0x0036, 6} - }, - { - {0x0006, 4},{0x0037, 6},{0x005D, 7},{0x000C, 6}, - {0x00B9, 8},{0x02E3,10},{0x05C4,11},{0x0004, 4}, - {0x1715,13},{0x0000, 3},{0x000F, 4},{0x0008, 4}, - {0x0007, 4},{0x000C, 4},{0x0009, 4},{0x001D, 5}, - {0x0016, 5},{0x001C, 5},{0x001A, 5},{0x000B, 5}, - {0x005E, 7},{0x0170, 9},{0x1714,13},{0x000A, 4}, - {0x000A, 5},{0x0036, 6},{0x005F, 7},{0x001B, 7}, - {0x001A, 7},{0x0B8B,12},{0x0002, 4},{0x0007, 5} - }, - { - {0x000C, 4},{0x000B, 5},{0x0079, 7},{0x0022, 6}, - {0x00F0, 8},{0x0119, 9},{0x0230,10},{0x001D, 5}, - {0x08C4,12},{0x0001, 3},{0x0000, 3},{0x000A, 4}, - {0x0009, 4},{0x000B, 4},{0x0007, 4},{0x001C, 5}, - {0x003D, 6},{0x000D, 5},{0x0008, 5},{0x0015, 6}, - {0x008D, 8},{0x118B,13},{0x118A,13},{0x000D, 4}, - {0x0010, 5},{0x0009, 5},{0x0014, 6},{0x0047, 7}, - {0x00F1, 8},{0x0463,11},{0x001F, 5},{0x000C, 5} - }, - { - {0x0000, 3},{0x001A, 5},{0x0033, 6},{0x000C, 5}, - {0x0046, 7},{0x01E3, 9},{0x03C5,10},{0x0017, 5}, - {0x1E21,13},{0x0002, 3},{0x0001, 3},{0x0009, 4}, - {0x000A, 4},{0x0007, 4},{0x001B, 5},{0x003D, 6}, - {0x001B, 6},{0x0022, 6},{0x0079, 7},{0x00F0, 8}, - {0x1E20,13},{0x1E23,13},{0x1E22,13},{0x000E, 4}, - {0x0016, 5},{0x0018, 5},{0x0032, 6},{0x001A, 6}, - {0x0047, 7},{0x0789,11},{0x001F, 5},{0x0010, 5} - }, - { - {0x001D, 5},{0x0061, 7},{0x004E, 8},{0x009E, 9}, - {0x027C,11},{0x09F5,13},{0x09F4,13},{0x0003, 4}, - {0x0060, 7},{0x0000, 3},{0x000F, 4},{0x000B, 4}, - {0x000A, 4},{0x0009, 4},{0x0005, 4},{0x000D, 5}, - {0x0031, 6},{0x0008, 5},{0x0038, 6},{0x0012, 6}, - {0x0026, 7},{0x013F,10},{0x04FB,12},{0x000D, 4}, - {0x0002, 4},{0x000C, 5},{0x0039, 6},{0x001C, 6}, - {0x000F, 5},{0x001D, 6},{0x0008, 4},{0x0019, 5} - }, - { - {0x0007, 4},{0x0019, 6},{0x00AB, 8},{0x00AA, 8}, - {0x0119,10},{0x0461,12},{0x0460,12},{0x001B, 5}, - {0x0047, 8},{0x0001, 3},{0x0000, 3},{0x000C, 4}, - {0x000B, 4},{0x0009, 4},{0x0005, 4},{0x000D, 5}, - {0x0035, 6},{0x003D, 6},{0x003C, 6},{0x0018, 6}, - {0x0022, 7},{0x008D, 9},{0x0231,11},{0x000E, 4}, - {0x001F, 5},{0x0009, 5},{0x002B, 6},{0x0010, 6}, - {0x0034, 6},{0x0054, 7},{0x0008, 4},{0x0014, 5} - }, - { - {0x000C, 4},{0x0005, 5},{0x0008, 6},{0x005B, 7}, - {0x004D, 9},{0x0131,11},{0x0261,12},{0x001A, 5}, - {0x0012, 7},{0x0000, 3},{0x000F, 4},{0x000A, 4}, - {0x0009, 4},{0x0006, 4},{0x001B, 5},{0x0006, 5}, - {0x001C, 6},{0x002C, 6},{0x0015, 6},{0x005A, 7}, - {0x0027, 8},{0x0099,10},{0x0260,12},{0x000E, 4}, - {0x0004, 4},{0x000F, 5},{0x0007, 5},{0x001D, 6}, - {0x000B, 5},{0x0014, 6},{0x0008, 4},{0x0017, 5} - }, - { - {0x000F, 4},{0x0013, 5},{0x0075, 7},{0x0024, 6}, - {0x0095, 8},{0x0251,10},{0x04A0,11},{0x0010, 5}, - {0x00C8, 8},{0x0002, 3},{0x0001, 3},{0x0001, 4}, - {0x0000, 4},{0x001A, 5},{0x0011, 5},{0x002C, 6}, - {0x0065, 7},{0x0074, 7},{0x004B, 7},{0x00C9, 8}, - {0x0129, 9},{0x0943,12},{0x0942,12},{0x0003, 3}, - {0x000A, 4},{0x001C, 5},{0x0018, 5},{0x0033, 6}, - {0x0017, 5},{0x002D, 6},{0x001B, 5},{0x003B, 6} - }, - { - {0x0003, 3},{0x001A, 5},{0x002D, 6},{0x0038, 6}, - {0x0028, 7},{0x0395,10},{0x0E51,12},{0x0037, 6}, - {0x00E4, 8},{0x0001, 3},{0x0000, 3},{0x001F, 5}, - {0x001E, 5},{0x0017, 5},{0x003A, 6},{0x0073, 7}, - {0x002A, 7},{0x002B, 7},{0x0029, 7},{0x01CB, 9}, - {0x0729,11},{0x1CA1,13},{0x1CA0,13},{0x0004, 3}, - {0x000A, 4},{0x0004, 4},{0x0018, 5},{0x0036, 6}, - {0x000B, 5},{0x002C, 6},{0x0019, 5},{0x003B, 6} - }, - { - {0x0004, 3},{0x0004, 4},{0x003F, 6},{0x0017, 5}, - {0x0075, 7},{0x01F5, 9},{0x07D1,11},{0x0017, 6}, - {0x01F6, 9},{0x0001, 3},{0x0000, 3},{0x001B, 5}, - {0x001A, 5},{0x000A, 5},{0x0032, 6},{0x0074, 7}, - {0x00F8, 8},{0x00F9, 8},{0x01F7, 9},{0x03E9,10}, - {0x0FA0,12},{0x1F43,13},{0x1F42,13},{0x0003, 3}, - {0x000A, 4},{0x001E, 5},{0x001C, 5},{0x003B, 6}, - {0x0018, 5},{0x0016, 6},{0x0016, 5},{0x0033, 6} - }, - { - {0x0004, 3},{0x0007, 4},{0x0018, 5},{0x001E, 5}, - {0x0036, 6},{0x0031, 7},{0x0177, 9},{0x0077, 7}, - {0x0176, 9},{0x0001, 3},{0x0000, 3},{0x001A, 5}, - {0x0019, 5},{0x003A, 6},{0x0019, 6},{0x005C, 7}, - {0x00BA, 8},{0x0061, 8},{0x00C1, 9},{0x0180,10}, - {0x0302,11},{0x0607,12},{0x0606,12},{0x0002, 3}, - {0x000A, 4},{0x001F, 5},{0x001C, 5},{0x0037, 6}, - {0x0016, 5},{0x0076, 7},{0x000D, 5},{0x002F, 6} - }, - { - {0x0000, 3},{0x000A, 4},{0x001A, 5},{0x000C, 4}, - {0x001D, 5},{0x0039, 6},{0x0078, 7},{0x005E, 7}, - {0x0393,11},{0x0002, 3},{0x0001, 3},{0x0016, 5}, - {0x000F, 5},{0x002E, 6},{0x005F, 7},{0x0073, 8}, - {0x00E5, 9},{0x01C8,10},{0x0E4A,13},{0x1C97,14}, - {0x1C96,14},{0x0E49,13},{0x0E48,13},{0x0004, 3}, - {0x0006, 4},{0x001F, 5},{0x001B, 5},{0x001D, 6}, - {0x0038, 6},{0x0038, 7},{0x003D, 6},{0x0079, 7} - }, - { - {0x000B, 5},{0x002B, 7},{0x0054, 8},{0x01B7, 9}, - {0x06D9,11},{0x0DB1,12},{0x0DB0,12},{0x0002, 4}, - {0x00AB, 9},{0x0009, 4},{0x000A, 4},{0x0007, 4}, - {0x0008, 4},{0x000F, 4},{0x000C, 4},{0x0003, 4}, - {0x001D, 5},{0x0004, 4},{0x000B, 4},{0x0006, 4}, - {0x001A, 5},{0x0003, 6},{0x00AA, 9},{0x0001, 4}, - {0x0000, 5},{0x0014, 6},{0x006C, 7},{0x00DA, 8}, - {0x0002, 6},{0x036D,10},{0x001C, 5},{0x0037, 6} - }, - { - {0x001D, 5},{0x0004, 6},{0x00B6, 8},{0x006A, 8}, - {0x05B9,11},{0x16E1,13},{0x16E0,13},{0x0007, 4}, - {0x016F, 9},{0x000C, 4},{0x000D, 4},{0x0009, 4}, - {0x0008, 4},{0x000F, 4},{0x000A, 4},{0x0003, 4}, - {0x0017, 5},{0x0002, 4},{0x0004, 4},{0x001C, 5}, - {0x002C, 6},{0x006B, 8},{0x0B71,12},{0x0005, 4}, - {0x0003, 5},{0x001B, 6},{0x005A, 7},{0x0034, 7}, - {0x0005, 6},{0x02DD,10},{0x0000, 4},{0x000C, 5} - }, - { - {0x0003, 4},{0x007F, 7},{0x00A1, 8},{0x00A0, 8}, - {0x020C,10},{0x0834,12},{0x106B,13},{0x0007, 4}, - {0x0082, 8},{0x000E, 4},{0x000D, 4},{0x000B, 4}, - {0x000C, 4},{0x0000, 3},{0x0009, 4},{0x0002, 4}, - {0x0011, 5},{0x001E, 5},{0x0015, 5},{0x003E, 6}, - {0x0040, 7},{0x041B,11},{0x106A,13},{0x0006, 4}, - {0x000A, 5},{0x0029, 6},{0x007E, 7},{0x0051, 7}, - {0x0021, 6},{0x0107, 9},{0x0004, 4},{0x000B, 5} - }, - { - {0x0007, 4},{0x001B, 6},{0x00F6, 8},{0x00E9, 8}, - {0x03A1,10},{0x0740,11},{0x0E82,12},{0x001F, 5}, - {0x01EF, 9},{0x0001, 3},{0x0002, 3},{0x000B, 4}, - {0x000C, 4},{0x000D, 4},{0x0008, 4},{0x001C, 5}, - {0x0003, 5},{0x0012, 5},{0x0002, 5},{0x0075, 7}, - {0x01D1, 9},{0x1D07,13},{0x1D06,13},{0x000A, 4}, - {0x0013, 5},{0x003B, 6},{0x001A, 6},{0x007A, 7}, - {0x003C, 6},{0x01EE, 9},{0x0000, 4},{0x000C, 5} - }, - { - {0x000D, 4},{0x003D, 6},{0x0042, 7},{0x0037, 7}, - {0x00D9, 9},{0x0362,11},{0x06C6,12},{0x001F, 5}, - {0x0086, 8},{0x0001, 3},{0x0002, 3},{0x000C, 4}, - {0x000B, 4},{0x000A, 4},{0x0001, 4},{0x000F, 5}, - {0x0025, 6},{0x003C, 6},{0x001A, 6},{0x0087, 8}, - {0x01B0,10},{0x0D8F,13},{0x0D8E,13},{0x000E, 4}, - {0x0013, 5},{0x000C, 5},{0x0024, 6},{0x0020, 6}, - {0x0011, 5},{0x006D, 8},{0x0000, 4},{0x000E, 5} - }, - { - {0x0000, 3},{0x0012, 5},{0x0076, 7},{0x0077, 7}, - {0x014D, 9},{0x0533,11},{0x14C9,13},{0x0013, 5}, - {0x00A5, 8},{0x0002, 3},{0x0003, 3},{0x000B, 4}, - {0x000C, 4},{0x0008, 4},{0x001A, 5},{0x002B, 6}, - {0x0075, 7},{0x0074, 7},{0x00A7, 8},{0x0298,10}, - {0x14C8,13},{0x14CB,13},{0x14CA,13},{0x000F, 4}, - {0x001C, 5},{0x0007, 5},{0x002A, 6},{0x0028, 6}, - {0x001B, 5},{0x00A4, 8},{0x0002, 4},{0x0006, 5} - }, - { - {0x0002, 3},{0x001A, 5},{0x002B, 6},{0x003A, 6}, - {0x00ED, 8},{0x0283,10},{0x0A0A,12},{0x0004, 5}, - {0x00A1, 8},{0x0004, 3},{0x0003, 3},{0x000B, 4}, - {0x000C, 4},{0x001F, 5},{0x0006, 5},{0x0077, 7}, - {0x00A3, 8},{0x00A2, 8},{0x0140, 9},{0x1417,13}, - {0x1416,13},{0x0A09,12},{0x0A08,12},{0x0000, 3}, - {0x001E, 5},{0x0007, 5},{0x002A, 6},{0x0029, 6}, - {0x001C, 5},{0x00EC, 8},{0x001B, 5},{0x0005, 5} - }, - { - {0x0002, 3},{0x0002, 4},{0x0018, 5},{0x001D, 5}, - {0x0035, 6},{0x00E4, 8},{0x01CF,11},{0x001D, 7}, - {0x0072, 9},{0x0004, 3},{0x0005, 3},{0x0006, 4}, - {0x0007, 4},{0x0006, 5},{0x0073, 7},{0x0038, 8}, - {0x01CE,11},{0x039B,12},{0x0398,12},{0x0733,13}, - {0x0732,13},{0x0735,13},{0x0734,13},{0x0000, 3}, - {0x001F, 5},{0x001B, 5},{0x0034, 6},{0x000F, 6}, - {0x001E, 5},{0x00E5, 8},{0x0019, 5},{0x0038, 6} - }, - { - {0x0016, 5},{0x0050, 7},{0x0172, 9},{0x02E7,10}, - {0x1732,13},{0x2E67,14},{0x2E66,14},{0x0006, 4}, - {0x0051, 7},{0x0001, 3},{0x0000, 3},{0x000D, 4}, - {0x000C, 4},{0x0009, 4},{0x001C, 5},{0x0009, 5}, - {0x001C, 6},{0x001D, 6},{0x005D, 7},{0x00B8, 8}, - {0x05CD,11},{0x1731,13},{0x1730,13},{0x000F, 4}, - {0x0005, 4},{0x000F, 5},{0x0008, 5},{0x0029, 6}, - {0x001D, 5},{0x002F, 6},{0x0008, 4},{0x0015, 5} - }, - { - {0x0009, 4},{0x0021, 6},{0x0040, 7},{0x00AD, 8}, - {0x02B0,10},{0x1589,13},{0x1588,13},{0x001C, 5}, - {0x005F, 7},{0x0000, 3},{0x000F, 4},{0x000D, 4}, - {0x000C, 4},{0x0006, 4},{0x0011, 5},{0x002A, 6}, - {0x0057, 7},{0x005E, 7},{0x0041, 7},{0x0159, 9}, - {0x0563,11},{0x158B,13},{0x158A,13},{0x0001, 3}, - {0x0005, 4},{0x0014, 5},{0x003B, 6},{0x002E, 6}, - {0x0004, 4},{0x003A, 6},{0x0007, 4},{0x0016, 5} - }, - { - {0x000E, 4},{0x0007, 5},{0x0046, 7},{0x0045, 7}, - {0x0064, 9},{0x032A,12},{0x0657,13},{0x0018, 5}, - {0x000D, 6},{0x0000, 3},{0x000F, 4},{0x000A, 4}, - {0x000B, 4},{0x001A, 5},{0x0036, 6},{0x0047, 7}, - {0x0044, 7},{0x0018, 7},{0x0033, 8},{0x00CB,10}, - {0x0656,13},{0x0329,12},{0x0328,12},{0x0002, 3}, - {0x0006, 4},{0x0019, 5},{0x000E, 5},{0x0037, 6}, - {0x0009, 4},{0x000F, 5},{0x0002, 4},{0x0010, 5} - }, - { - {0x0003, 3},{0x0018, 5},{0x0023, 6},{0x0077, 7}, - {0x0194, 9},{0x1956,13},{0x32AF,14},{0x003A, 6}, - {0x0076, 7},{0x0002, 3},{0x0001, 3},{0x001F, 5}, - {0x001E, 5},{0x0014, 5},{0x0022, 6},{0x0064, 7}, - {0x0197, 9},{0x0196, 9},{0x032B,10},{0x0654,11}, - {0x32AE,14},{0x1955,13},{0x1954,13},{0x0000, 3}, - {0x0009, 4},{0x001C, 5},{0x0015, 5},{0x0010, 5}, - {0x000D, 4},{0x0017, 5},{0x0016, 5},{0x0033, 6} - }, - { - {0x0005, 3},{0x0006, 4},{0x003E, 6},{0x0010, 5}, - {0x0048, 7},{0x093F,12},{0x24FA,14},{0x0032, 6}, - {0x0067, 7},{0x0002, 3},{0x0001, 3},{0x001B, 5}, - {0x001E, 5},{0x0034, 6},{0x0066, 7},{0x0092, 8}, - {0x0126, 9},{0x024E,10},{0x049E,11},{0x49F7,15}, - {0x49F6,15},{0x24F9,14},{0x24F8,14},{0x0000, 3}, - {0x0007, 4},{0x0018, 5},{0x0011, 5},{0x003F, 6}, - {0x000E, 4},{0x0013, 5},{0x0035, 6},{0x0025, 6} - }, - { - {0x0005, 3},{0x0008, 4},{0x0012, 5},{0x001C, 5}, - {0x001C, 6},{0x00EA, 9},{0x1D75,14},{0x001E, 6}, - {0x0066, 7},{0x0001, 3},{0x0002, 3},{0x001B, 5}, - {0x001A, 5},{0x001F, 6},{0x003B, 7},{0x0074, 8}, - {0x01D6,10},{0x03AF,11},{0x1D74,14},{0x1D77,14}, - {0x1D76,14},{0x0EB9,13},{0x0EB8,13},{0x000F, 4}, - {0x0006, 4},{0x0013, 5},{0x003B, 6},{0x003A, 6}, - {0x0000, 3},{0x0018, 5},{0x0032, 6},{0x0067, 7} - }, - { - {0x0004, 3},{0x000A, 4},{0x001B, 5},{0x000C, 4}, - {0x000D, 5},{0x00E6, 8},{0x0684,11},{0x0072, 7}, - {0x00E7, 8},{0x0002, 3},{0x0001, 3},{0x0017, 5}, - {0x0016, 5},{0x0018, 6},{0x00D1, 8},{0x01A0, 9}, - {0x0686,11},{0x0D0F,12},{0x0D0A,12},{0x1A17,13}, - {0x1A16,13},{0x1A1D,13},{0x1A1C,13},{0x000F, 4}, - {0x001D, 5},{0x000E, 5},{0x0035, 6},{0x0038, 6}, - {0x0000, 3},{0x000F, 5},{0x0019, 6},{0x0069, 7} - }, - { - {0x0003, 3},{0x000C, 4},{0x001B, 5},{0x0000, 3}, - {0x0003, 4},{0x002E, 6},{0x0051, 9},{0x00BC, 8}, - {0x0053, 9},{0x0004, 3},{0x0002, 3},{0x0016, 5}, - {0x0015, 5},{0x0015, 7},{0x0050, 9},{0x00A4,10}, - {0x0294,12},{0x052B,13},{0x052A,13},{0x052D,13}, - {0x052C,13},{0x052F,13},{0x052E,13},{0x000E, 4}, - {0x001A, 5},{0x0004, 5},{0x0028, 6},{0x0029, 6}, - {0x000F, 4},{0x000B, 6},{0x005F, 7},{0x00BD, 8} - }, - { - {0x0003, 4},{0x0009, 6},{0x00D0, 8},{0x01A3, 9}, - {0x0344,10},{0x0D14,12},{0x1A2B,13},{0x0004, 4}, - {0x0015, 7},{0x0000, 3},{0x000F, 4},{0x000B, 4}, - {0x000C, 4},{0x000E, 4},{0x0009, 4},{0x001B, 5}, - {0x000A, 5},{0x0014, 5},{0x000D, 5},{0x002A, 6}, - {0x0014, 7},{0x068B,11},{0x1A2A,13},{0x0008, 4}, - {0x000B, 5},{0x002B, 6},{0x000B, 6},{0x0069, 7}, - {0x0035, 6},{0x0008, 6},{0x0007, 4},{0x000C, 5} - }, - { - {0x000A, 4},{0x003C, 6},{0x0032, 7},{0x0030, 7}, - {0x00C5, 9},{0x0621,12},{0x0620,12},{0x001F, 5}, - {0x0033, 7},{0x0001, 3},{0x0000, 3},{0x000E, 4}, - {0x000D, 4},{0x000C, 4},{0x0004, 4},{0x000D, 5}, - {0x0026, 6},{0x0027, 6},{0x0014, 6},{0x0063, 8}, - {0x0189,10},{0x0623,12},{0x0622,12},{0x000B, 4}, - {0x0012, 5},{0x003D, 6},{0x0022, 6},{0x0015, 6}, - {0x000B, 5},{0x0023, 6},{0x0007, 4},{0x0010, 5} - }, - { - {0x000F, 4},{0x000C, 5},{0x0043, 7},{0x0010, 6}, - {0x0044, 8},{0x0114,10},{0x0455,12},{0x0018, 5}, - {0x0023, 7},{0x0001, 3},{0x0000, 3},{0x000E, 4}, - {0x000D, 4},{0x0009, 4},{0x0019, 5},{0x0009, 5}, - {0x0017, 6},{0x0016, 6},{0x0042, 7},{0x008B, 9}, - {0x0454,12},{0x0457,12},{0x0456,12},{0x000B, 4}, - {0x0015, 5},{0x000A, 5},{0x0029, 6},{0x0020, 6}, - {0x000D, 5},{0x0028, 6},{0x0007, 4},{0x0011, 5} - }, - { - {0x0001, 3},{0x001A, 5},{0x0029, 6},{0x002A, 6}, - {0x00A0, 8},{0x0285,10},{0x1425,13},{0x0002, 5}, - {0x0000, 7},{0x0002, 3},{0x0003, 3},{0x000C, 4}, - {0x000B, 4},{0x0008, 4},{0x0012, 5},{0x0001, 6}, - {0x0051, 7},{0x0001, 7},{0x0143, 9},{0x0508,11}, - {0x1424,13},{0x1427,13},{0x1426,13},{0x000F, 4}, - {0x001C, 5},{0x0003, 5},{0x0037, 6},{0x002B, 6}, - {0x0013, 5},{0x0036, 6},{0x001D, 5},{0x0001, 5} - }, - { - {0x0004, 3},{0x001F, 5},{0x003D, 6},{0x0006, 5}, - {0x0016, 7},{0x0053, 9},{0x014A,11},{0x0034, 6}, - {0x002A, 8},{0x0002, 3},{0x0003, 3},{0x000B, 4}, - {0x000C, 4},{0x001C, 5},{0x0037, 6},{0x0017, 7}, - {0x002B, 8},{0x0028, 8},{0x00A4,10},{0x052D,13}, - {0x052C,13},{0x052F,13},{0x052E,13},{0x0000, 3}, - {0x001D, 5},{0x0007, 5},{0x0004, 5},{0x0035, 6}, - {0x0014, 5},{0x0036, 6},{0x0015, 5},{0x003C, 6} - }, - { - {0x0004, 3},{0x000A, 4},{0x0007, 5},{0x001D, 5}, - {0x0009, 6},{0x01F3, 9},{0x07C7,11},{0x0008, 6}, - {0x01F0, 9},{0x0003, 3},{0x0002, 3},{0x000D, 4}, - {0x000C, 4},{0x0017, 5},{0x007D, 7},{0x01F2, 9}, - {0x07C6,11},{0x07C5,11},{0x1F12,13},{0x3E27,14}, - {0x3E26,14},{0x1F11,13},{0x1F10,13},{0x0000, 3}, - {0x001E, 5},{0x0006, 5},{0x0039, 6},{0x0038, 6}, - {0x003F, 6},{0x002C, 6},{0x0005, 5},{0x002D, 6} - }, - { - {0x0002, 3},{0x0007, 4},{0x0018, 5},{0x0003, 4}, - {0x0005, 5},{0x0035, 7},{0x004F, 9},{0x0012, 7}, - {0x04E5,13},{0x0005, 3},{0x0004, 3},{0x000D, 4}, - {0x000E, 4},{0x0033, 6},{0x0026, 8},{0x009D,10}, - {0x04E4,13},{0x04E7,13},{0x04E6,13},{0x04E1,13}, - {0x04E0,13},{0x04E3,13},{0x04E2,13},{0x0000, 3}, - {0x001F, 5},{0x000C, 5},{0x003D, 6},{0x003C, 6}, - {0x0032, 6},{0x0034, 7},{0x001B, 6},{0x0008, 6} - }, - { - {0x0000, 3},{0x0004, 4},{0x001C, 5},{0x000F, 4}, - {0x0002, 4},{0x0007, 5},{0x0075, 7},{0x00E8, 8}, - {0x1D2A,13},{0x0005, 3},{0x0004, 3},{0x000D, 4}, - {0x000C, 4},{0x0077, 7},{0x0E96,12},{0x3A57,14}, - {0x3A56,14},{0x3A5D,14},{0x3A5C,14},{0x3A5F,14}, - {0x3A5E,14},{0x1D29,13},{0x1D28,13},{0x0003, 3}, - {0x0006, 5},{0x000A, 5},{0x002C, 7},{0x0017, 6}, - {0x0076, 7},{0x01D3, 9},{0x03A4,10},{0x002D, 7} - }, - { - {0x000A, 4},{0x0024, 6},{0x00BF, 8},{0x0085, 8}, - {0x0211,10},{0x0842,12},{0x1087,13},{0x0018, 5}, - {0x0020, 6},{0x0001, 3},{0x0002, 3},{0x000E, 4}, - {0x000D, 4},{0x0007, 4},{0x0013, 5},{0x0025, 6}, - {0x005E, 7},{0x0043, 7},{0x00BE, 8},{0x0109, 9}, - {0x1086,13},{0x0841,12},{0x0840,12},{0x000F, 4}, - {0x0001, 4},{0x0011, 5},{0x0000, 5},{0x002E, 6}, - {0x0019, 5},{0x0001, 5},{0x0006, 4},{0x0016, 5} - }, - { - {0x0002, 3},{0x000F, 5},{0x006F, 7},{0x0061, 7}, - {0x0374,10},{0x1BA8,13},{0x3753,14},{0x0012, 5}, - {0x0036, 6},{0x0000, 3},{0x0001, 3},{0x000A, 4}, - {0x000B, 4},{0x001A, 5},{0x0031, 6},{0x0060, 7}, - {0x00DC, 8},{0x01BB, 9},{0x06EB,11},{0x1BAB,13}, - {0x3752,14},{0x3755,14},{0x3754,14},{0x000E, 4}, - {0x0006, 4},{0x0013, 5},{0x000E, 5},{0x003E, 6}, - {0x0008, 4},{0x001E, 5},{0x0019, 5},{0x003F, 6} - }, - { - {0x0003, 3},{0x001C, 5},{0x0025, 6},{0x0024, 6}, - {0x01DA, 9},{0x1DBD,13},{0x3B7C,14},{0x003C, 6}, - {0x003D, 6},{0x0000, 3},{0x0001, 3},{0x000B, 4}, - {0x000A, 4},{0x000B, 5},{0x0077, 7},{0x00EC, 8}, - {0x03B6,10},{0x076E,11},{0x1DBF,13},{0x76FB,15}, - {0x76FA,15},{0x3B79,14},{0x3B78,14},{0x000D, 4}, - {0x001F, 5},{0x0013, 5},{0x000A, 5},{0x0008, 5}, - {0x000C, 4},{0x0008, 4},{0x0009, 5},{0x003A, 6} - }, - { - {0x0005, 3},{0x0003, 4},{0x0004, 5},{0x0010, 5}, - {0x008F, 8},{0x0475,11},{0x11D1,13},{0x0079, 7}, - {0x0027, 6},{0x0002, 3},{0x0003, 3},{0x0001, 4}, - {0x0000, 4},{0x0026, 6},{0x0046, 7},{0x011C, 9}, - {0x0477,11},{0x08ED,12},{0x11D0,13},{0x11D3,13}, - {0x11D2,13},{0x11D9,13},{0x11D8,13},{0x000D, 4}, - {0x001F, 5},{0x0012, 5},{0x0005, 5},{0x003D, 6}, - {0x000C, 4},{0x000E, 4},{0x0022, 6},{0x0078, 7} - }, - { - {0x0005, 3},{0x000C, 4},{0x001B, 5},{0x0000, 4}, - {0x0006, 6},{0x03E2,10},{0x3E3D,14},{0x000F, 7}, - {0x0034, 6},{0x0003, 3},{0x0002, 3},{0x001E, 5}, - {0x001D, 5},{0x007D, 7},{0x01F0, 9},{0x07C6,11}, - {0x3E3C,14},{0x3E3F,14},{0x3E3E,14},{0x3E39,14}, - {0x3E38,14},{0x3E3B,14},{0x3E3A,14},{0x0008, 4}, - {0x001C, 5},{0x0002, 5},{0x003F, 6},{0x0035, 6}, - {0x0009, 4},{0x0001, 3},{0x000E, 7},{0x00F9, 8} - }, - { - {0x0004, 3},{0x000B, 4},{0x0001, 4},{0x000A, 4}, - {0x001E, 6},{0x00E0, 9},{0x0E1E,13},{0x0071, 8}, - {0x0039, 7},{0x0007, 3},{0x0006, 3},{0x000D, 5}, - {0x000C, 5},{0x0020, 7},{0x01C2,10},{0x1C3F,14}, - {0x1C3E,14},{0x0E19,13},{0x0E18,13},{0x0E1B,13}, - {0x0E1A,13},{0x0E1D,13},{0x0E1C,13},{0x0000, 4}, - {0x0009, 5},{0x001D, 6},{0x001F, 6},{0x0011, 6}, - {0x0005, 4},{0x0001, 3},{0x0043, 8},{0x0042, 8} - }, - { - {0x0004, 3},{0x000D, 4},{0x0007, 4},{0x0002, 3}, - {0x0014, 5},{0x016C, 9},{0x16D1,13},{0x02DF,10}, - {0x016E, 9},{0x0000, 2},{0x0007, 3},{0x002C, 6}, - {0x002B, 6},{0x02DE,10},{0x16D0,13},{0x16D3,13}, - {0x16D2,13},{0x2DB5,14},{0x2DB4,14},{0x2DB7,14}, - {0x2DB6,14},{0x16D9,13},{0x16D8,13},{0x000C, 5}, - {0x002A, 6},{0x005A, 7},{0x001B, 6},{0x001A, 6}, - {0x0017, 5},{0x000C, 4},{0x05B7,11},{0x05B5,11} - }, - { - {0x0002, 2},{0x000F, 4},{0x001C, 5},{0x000C, 4}, - {0x003B, 6},{0x01AC, 9},{0x1AD8,13},{0x35B3,14}, - {0x35B2,14},{0x0001, 2},{0x0000, 2},{0x0069, 7}, - {0x0068, 7},{0x35BD,14},{0x35BC,14},{0x35BF,14}, - {0x35BE,14},{0x35B9,14},{0x35B8,14},{0x35BB,14}, - {0x35BA,14},{0x35B5,14},{0x35B4,14},{0x01A9, 9}, - {0x01A8, 9},{0x035A,10},{0x00D7, 8},{0x00D5, 8}, - {0x003A, 6},{0x001B, 5},{0x35B7,14},{0x35B6,14} - }, - { - {0x0000, 3},{0x0010, 5},{0x0072, 7},{0x0071, 7}, - {0x0154, 9},{0x0AAB,12},{0x0AA8,12},{0x0014, 5}, - {0x0070, 7},{0x0002, 3},{0x0003, 3},{0x000C, 4}, - {0x000B, 4},{0x0003, 4},{0x0011, 5},{0x0073, 7}, - {0x0054, 7},{0x00AB, 8},{0x02AB,10},{0x1553,13}, - {0x1552,13},{0x1555,13},{0x1554,13},{0x000D, 4}, - {0x001E, 5},{0x0012, 5},{0x003E, 6},{0x002B, 6}, - {0x0002, 4},{0x003F, 6},{0x001D, 5},{0x0013, 5} - }, - { - {0x0003, 3},{0x001F, 5},{0x0029, 6},{0x003D, 6}, - {0x000C, 7},{0x0069,10},{0x0345,13},{0x0002, 5}, - {0x0028, 6},{0x0002, 3},{0x0001, 3},{0x000E, 4}, - {0x000C, 4},{0x0015, 5},{0x0007, 6},{0x001B, 8}, - {0x006B,10},{0x006A,10},{0x0344,13},{0x0347,13}, - {0x0346,13},{0x01A1,12},{0x01A0,12},{0x000B, 4}, - {0x001A, 5},{0x0012, 5},{0x0000, 5},{0x003C, 6}, - {0x0008, 4},{0x001B, 5},{0x0013, 5},{0x0001, 5} - }, - { - {0x0004, 3},{0x0004, 4},{0x003F, 6},{0x0014, 5}, - {0x0056, 7},{0x015C, 9},{0x15D5,13},{0x003C, 6}, - {0x002A, 6},{0x0000, 3},{0x0001, 3},{0x000E, 4}, - {0x000D, 4},{0x000C, 5},{0x00AF, 8},{0x02BB,10}, - {0x15D4,13},{0x15D7,13},{0x15D6,13},{0x15D1,13}, - {0x15D0,13},{0x15D3,13},{0x15D2,13},{0x000B, 4}, - {0x0019, 5},{0x000D, 5},{0x003E, 6},{0x0031, 6}, - {0x0007, 4},{0x0005, 4},{0x003D, 6},{0x0030, 6} - }, - { - {0x0005, 3},{0x0008, 4},{0x001A, 5},{0x0000, 4}, - {0x0036, 6},{0x0011, 8},{0x0106,12},{0x000A, 7}, - {0x006E, 7},{0x0002, 3},{0x0003, 3},{0x0003, 4}, - {0x0002, 4},{0x006F, 7},{0x0021, 9},{0x020F,13}, - {0x020E,13},{0x0101,12},{0x0100,12},{0x0103,12}, - {0x0102,12},{0x0105,12},{0x0104,12},{0x000C, 4}, - {0x001E, 5},{0x0003, 5},{0x003E, 6},{0x003F, 6}, - {0x0009, 4},{0x000E, 4},{0x000B, 7},{0x0009, 7} - }, - { - {0x0002, 3},{0x000E, 4},{0x001E, 5},{0x000C, 4}, - {0x001F, 5},{0x006E, 7},{0x00AD,10},{0x00AF,10}, - {0x0014, 7},{0x0004, 3},{0x0003, 3},{0x001A, 5}, - {0x0017, 5},{0x002A, 8},{0x0576,13},{0x0AEF,14}, - {0x0AEE,14},{0x0571,13},{0x0570,13},{0x0573,13}, - {0x0572,13},{0x0575,13},{0x0574,13},{0x0003, 4}, - {0x0016, 5},{0x0004, 5},{0x0036, 6},{0x000B, 6}, - {0x000A, 4},{0x0000, 3},{0x006F, 7},{0x00AC,10} - }, - { - {0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3}, - {0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13}, - {0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6}, - {0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13}, - {0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13}, - {0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3}, - {0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8}, - {0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14} - }, - { - {0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3}, - {0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13}, - {0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6}, - {0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13}, - {0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13}, - {0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3}, - {0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8}, - {0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14} - }, - { - {0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3}, - {0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13}, - {0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6}, - {0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13}, - {0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13}, - {0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3}, - {0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8}, - {0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14} - }, - { - {0x0003, 3},{0x0011, 5},{0x0020, 6},{0x0074, 7}, - {0x010D, 9},{0x0863,12},{0x0860,12},{0x000A, 5}, - {0x0075, 7},{0x0001, 3},{0x0000, 3},{0x000B, 4}, - {0x000A, 4},{0x0018, 5},{0x0038, 6},{0x0042, 7}, - {0x010F, 9},{0x010E, 9},{0x0219,10},{0x10C3,13}, - {0x10C2,13},{0x10C5,13},{0x10C4,13},{0x000F, 4}, - {0x0004, 4},{0x0019, 5},{0x000B, 5},{0x0039, 6}, - {0x0009, 4},{0x001B, 5},{0x001A, 5},{0x003B, 6} - }, - { - {0x0005, 3},{0x0001, 4},{0x003E, 6},{0x0001, 5}, - {0x00E2, 8},{0x1C6F,13},{0x38D9,14},{0x0039, 6}, - {0x001F, 6},{0x0002, 3},{0x0001, 3},{0x0009, 4}, - {0x0008, 4},{0x0000, 5},{0x0070, 7},{0x01C7, 9}, - {0x038C,10},{0x071A,11},{0x38D8,14},{0x38DB,14}, - {0x38DA,14},{0x38DD,14},{0x38DC,14},{0x000D, 4}, - {0x001D, 5},{0x000E, 5},{0x003F, 6},{0x003C, 6}, - {0x000C, 4},{0x0006, 4},{0x003D, 6},{0x001E, 6} - }, - { - {0x0006, 3},{0x000B, 4},{0x0011, 5},{0x001E, 5}, - {0x0074, 7},{0x03AA,10},{0x1D5C,13},{0x0001, 6}, - {0x0021, 6},{0x0001, 3},{0x0002, 3},{0x0007, 4}, - {0x0006, 4},{0x003E, 6},{0x00EB, 8},{0x01D4, 9}, - {0x0EAF,12},{0x3ABB,14},{0x3ABA,14},{0x1D59,13}, - {0x1D58,13},{0x1D5B,13},{0x1D5A,13},{0x000A, 4}, - {0x001C, 5},{0x0001, 5},{0x003F, 6},{0x003B, 6}, - {0x0001, 4},{0x0009, 4},{0x0020, 6},{0x0000, 6} - }, - { - {0x0004, 3},{0x000A, 4},{0x0017, 5},{0x0004, 4}, - {0x0016, 6},{0x016A, 9},{0x16B1,13},{0x0017, 7}, - {0x005B, 7},{0x0006, 3},{0x0007, 3},{0x0001, 4}, - {0x0000, 4},{0x000A, 6},{0x02D7,10},{0x0B5A,12}, - {0x16B0,13},{0x16B3,13},{0x16B2,13},{0x2D6D,14}, - {0x2D6C,14},{0x2D6F,14},{0x2D6E,14},{0x0006, 4}, - {0x000A, 5},{0x0004, 5},{0x002C, 6},{0x0017, 6}, - {0x0003, 4},{0x0007, 4},{0x0016, 7},{0x00B4, 8} - }, - { - {0x0005, 3},{0x000D, 4},{0x0005, 4},{0x0009, 4}, - {0x0033, 6},{0x0193, 9},{0x192C,13},{0x0061, 8}, - {0x0031, 7},{0x0000, 2},{0x0007, 3},{0x0010, 5}, - {0x0011, 5},{0x00C8, 8},{0x192F,13},{0x325B,14}, - {0x325A,14},{0x1929,13},{0x1928,13},{0x192B,13}, - {0x192A,13},{0x325D,14},{0x325C,14},{0x0018, 5}, - {0x001A, 6},{0x001B, 6},{0x0065, 7},{0x0019, 6}, - {0x0004, 4},{0x0007, 4},{0x0060, 8},{0x0324,10} - }, - { - {0x0006, 3},{0x0000, 3},{0x0002, 4},{0x000F, 4}, - {0x0039, 6},{0x01D9, 9},{0x1D82,13},{0x0761,11}, - {0x03BE,10},{0x0001, 2},{0x0002, 2},{0x000F, 6}, - {0x000E, 6},{0x0762,11},{0x3B07,14},{0x3B06,14}, - {0x3B1D,14},{0x3B1C,14},{0x3B1F,14},{0x3B1E,14}, - {0x3B19,14},{0x3B18,14},{0x3B1B,14},{0x0038, 6}, - {0x01DE, 9},{0x00ED, 8},{0x03BF,10},{0x00EE, 8}, - {0x003A, 6},{0x0006, 5},{0x0EC0,12},{0x3B1A,14} - }, - { - {0x0000, 2},{0x0002, 3},{0x000F, 5},{0x0006, 4}, - {0x001C, 6},{0x01D0,10},{0x0E8C,13},{0x1D1B,14}, - {0x1D1A,14},{0x0003, 2},{0x0002, 2},{0x00EA, 9}, - {0x00E9, 9},{0x0E89,13},{0x0E88,13},{0x0E8B,13}, - {0x0E8A,13},{0x1D65,14},{0x1D64,14},{0x1D67,14}, - {0x1D66,14},{0x1D61,14},{0x1D60,14},{0x03AD,11}, - {0x1D63,14},{0x1D62,14},{0x1D1D,14},{0x1D1C,14}, - {0x003B, 7},{0x01D7,10},{0x1D1F,14},{0x1D1E,14} - }, - { - {0x0002, 2},{0x000F, 4},{0x001C, 5},{0x000C, 4}, - {0x003B, 6},{0x01AC, 9},{0x1AD8,13},{0x35B3,14}, - {0x35B2,14},{0x0001, 2},{0x0000, 2},{0x0069, 7}, - {0x0068, 7},{0x35BD,14},{0x35BC,14},{0x35BF,14}, - {0x35BE,14},{0x35B9,14},{0x35B8,14},{0x35BB,14}, - {0x35BA,14},{0x35B5,14},{0x35B4,14},{0x01A9, 9}, - {0x01A8, 9},{0x035A,10},{0x00D7, 8},{0x00D5, 8}, - {0x003A, 6},{0x001B, 5},{0x35B7,14},{0x35B6,14} - } -}; - - - -/*A description of a Huffman code value used when encoding the tree.*/ -typedef struct{ - /*The bit pattern, left-shifted so that the MSB of all patterns is - aligned.*/ - ogg_uint32_t pattern; - /*The amount the bit pattern was shifted.*/ - int shift; - /*The token this bit pattern represents.*/ - int token; -}oc_huff_entry; - - - -/*Compares two oc_huff_entry structures by their bit patterns. - _c1: The first entry to compare. - _c2: The second entry to compare. - Return: <0 if _c1<_c2, >0 if _c1>_c2.*/ -static int huff_entry_cmp(const void *_c1,const void *_c2){ - ogg_uint32_t b1; - ogg_uint32_t b2; - b1=((const oc_huff_entry *)_c1)->pattern; - b2=((const oc_huff_entry *)_c2)->pattern; - return b1b2?1:0; -} - -/*Encodes a description of the given Huffman tables. - Although the codes are stored in the encoder as flat arrays, in the bit - stream and in the decoder they are structured as a tree. - This function recovers the tree structure from the flat array and then - writes it out. - Note that the codes MUST form a Huffman code, and not merely a prefix-free - code, since the binary tree is assumed to be full. - _opb: The buffer to store the tree in. - _codes: The Huffman tables to pack. - Return: 0 on success, or a negative value if one of the given Huffman tables - does not form a full, prefix-free code.*/ -int oc_huff_codes_pack(oggpack_buffer *_opb, - const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]){ - int i; - for(i=0;i>1)<<(maxlen+1>>1))-1; - /*Copy over the codes into our temporary workspace. - The bit patterns are aligned, and the original entry each code is from - is stored as well.*/ - for(j=0;jentries[j].shift;bpos--)oggpackB_write(_opb,0,1); - /*Mark this as a leaf node, and write its value.*/ - oggpackB_write(_opb,1,1); - oggpackB_write(_opb,entries[j].token,5); - /*For each 1 branch we've descended, back up the tree until we reach a - 0 branch.*/ - bit=1< -#include "internal.h" -#include "dct.h" - -/*Performs an inverse 8 point Type-II DCT transform. - The output is scaled by a factor of 2 relative to the orthonormal version of - the transform. - _y: The buffer to store the result in. - Data will be placed in every 8th entry (e.g., in a column of an 8x8 - block). - _x: The input coefficients. - The first 8 entries are used (e.g., from a row of an 8x8 block).*/ -static void idct8(ogg_int16_t *_y,const ogg_int16_t _x[8]){ - ogg_int32_t t[8]; - ogg_int32_t r; - /*Stage 1:*/ - /*0-1 butterfly.*/ - t[0]=OC_C4S4*(ogg_int16_t)(_x[0]+_x[4])>>16; - t[1]=OC_C4S4*(ogg_int16_t)(_x[0]-_x[4])>>16; - /*2-3 rotation by 6pi/16.*/ - t[2]=(OC_C6S2*_x[2]>>16)-(OC_C2S6*_x[6]>>16); - t[3]=(OC_C2S6*_x[2]>>16)+(OC_C6S2*_x[6]>>16); - /*4-7 rotation by 7pi/16.*/ - t[4]=(OC_C7S1*_x[1]>>16)-(OC_C1S7*_x[7]>>16); - /*5-6 rotation by 3pi/16.*/ - t[5]=(OC_C3S5*_x[5]>>16)-(OC_C5S3*_x[3]>>16); - t[6]=(OC_C5S3*_x[5]>>16)+(OC_C3S5*_x[3]>>16); - t[7]=(OC_C1S7*_x[1]>>16)+(OC_C7S1*_x[7]>>16); - /*Stage 2:*/ - /*4-5 butterfly.*/ - r=t[4]+t[5]; - t[5]=OC_C4S4*(ogg_int16_t)(t[4]-t[5])>>16; - t[4]=r; - /*7-6 butterfly.*/ - r=t[7]+t[6]; - t[6]=OC_C4S4*(ogg_int16_t)(t[7]-t[6])>>16; - t[7]=r; - /*Stage 3:*/ - /*0-3 butterfly.*/ - r=t[0]+t[3]; - t[3]=t[0]-t[3]; - t[0]=r; - /*1-2 butterfly.*/ - r=t[1]+t[2]; - t[2]=t[1]-t[2]; - t[1]=r; - /*6-5 butterfly.*/ - r=t[6]+t[5]; - t[5]=t[6]-t[5]; - t[6]=r; - /*Stage 4:*/ - /*0-7 butterfly.*/ - _y[0<<3]=(ogg_int16_t)(t[0]+t[7]); - /*1-6 butterfly.*/ - _y[1<<3]=(ogg_int16_t)(t[1]+t[6]); - /*2-5 butterfly.*/ - _y[2<<3]=(ogg_int16_t)(t[2]+t[5]); - /*3-4 butterfly.*/ - _y[3<<3]=(ogg_int16_t)(t[3]+t[4]); - _y[4<<3]=(ogg_int16_t)(t[3]-t[4]); - _y[5<<3]=(ogg_int16_t)(t[2]-t[5]); - _y[6<<3]=(ogg_int16_t)(t[1]-t[6]); - _y[7<<3]=(ogg_int16_t)(t[0]-t[7]); -} - -/*Performs an inverse 8 point Type-II DCT transform. - The output is scaled by a factor of 2 relative to the orthonormal version of - the transform. - _y: The buffer to store the result in. - Data will be placed in every 8th entry (e.g., in a column of an 8x8 - block). - _x: The input coefficients. - Only the first 4 entries are used. - The other 4 are assumed to be 0.*/ -static void idct8_4(ogg_int16_t *_y,const ogg_int16_t _x[8]){ - ogg_int32_t t[8]; - ogg_int32_t r; - /*Stage 1:*/ - t[0]=OC_C4S4*_x[0]>>16; - t[2]=OC_C6S2*_x[2]>>16; - t[3]=OC_C2S6*_x[2]>>16; - t[4]=OC_C7S1*_x[1]>>16; - t[5]=-(OC_C5S3*_x[3]>>16); - t[6]=OC_C3S5*_x[3]>>16; - t[7]=OC_C1S7*_x[1]>>16; - /*Stage 2:*/ - r=t[4]+t[5]; - t[5]=OC_C4S4*(ogg_int16_t)(t[4]-t[5])>>16; - t[4]=r; - r=t[7]+t[6]; - t[6]=OC_C4S4*(ogg_int16_t)(t[7]-t[6])>>16; - t[7]=r; - /*Stage 3:*/ - t[1]=t[0]+t[2]; - t[2]=t[0]-t[2]; - r=t[0]+t[3]; - t[3]=t[0]-t[3]; - t[0]=r; - r=t[6]+t[5]; - t[5]=t[6]-t[5]; - t[6]=r; - /*Stage 4:*/ - _y[0<<3]=(ogg_int16_t)(t[0]+t[7]); - _y[1<<3]=(ogg_int16_t)(t[1]+t[6]); - _y[2<<3]=(ogg_int16_t)(t[2]+t[5]); - _y[3<<3]=(ogg_int16_t)(t[3]+t[4]); - _y[4<<3]=(ogg_int16_t)(t[3]-t[4]); - _y[5<<3]=(ogg_int16_t)(t[2]-t[5]); - _y[6<<3]=(ogg_int16_t)(t[1]-t[6]); - _y[7<<3]=(ogg_int16_t)(t[0]-t[7]); -} - -/*Performs an inverse 8 point Type-II DCT transform. - The output is scaled by a factor of 2 relative to the orthonormal version of - the transform. - _y: The buffer to store the result in. - Data will be placed in every 8th entry (e.g., in a column of an 8x8 - block). - _x: The input coefficients. - Only the first 3 entries are used. - The other 5 are assumed to be 0.*/ -static void idct8_3(ogg_int16_t *_y,const ogg_int16_t _x[8]){ - ogg_int32_t t[8]; - ogg_int32_t r; - /*Stage 1:*/ - t[0]=OC_C4S4*_x[0]>>16; - t[2]=OC_C6S2*_x[2]>>16; - t[3]=OC_C2S6*_x[2]>>16; - t[4]=OC_C7S1*_x[1]>>16; - t[7]=OC_C1S7*_x[1]>>16; - /*Stage 2:*/ - t[5]=OC_C4S4*t[4]>>16; - t[6]=OC_C4S4*t[7]>>16; - /*Stage 3:*/ - t[1]=t[0]+t[2]; - t[2]=t[0]-t[2]; - r=t[0]+t[3]; - t[3]=t[0]-t[3]; - t[0]=r; - r=t[6]+t[5]; - t[5]=t[6]-t[5]; - t[6]=r; - /*Stage 4:*/ - _y[0<<3]=(ogg_int16_t)(t[0]+t[7]); - _y[1<<3]=(ogg_int16_t)(t[1]+t[6]); - _y[2<<3]=(ogg_int16_t)(t[2]+t[5]); - _y[3<<3]=(ogg_int16_t)(t[3]+t[4]); - _y[4<<3]=(ogg_int16_t)(t[3]-t[4]); - _y[5<<3]=(ogg_int16_t)(t[2]-t[5]); - _y[6<<3]=(ogg_int16_t)(t[1]-t[6]); - _y[7<<3]=(ogg_int16_t)(t[0]-t[7]); -} - -/*Performs an inverse 8 point Type-II DCT transform. - The output is scaled by a factor of 2 relative to the orthonormal version of - the transform. - _y: The buffer to store the result in. - Data will be placed in every 8th entry (e.g., in a column of an 8x8 - block). - _x: The input coefficients. - Only the first 2 entries are used. - The other 6 are assumed to be 0.*/ -static void idct8_2(ogg_int16_t *_y,const ogg_int16_t _x[8]){ - ogg_int32_t t[8]; - ogg_int32_t r; - /*Stage 1:*/ - t[0]=OC_C4S4*_x[0]>>16; - t[4]=OC_C7S1*_x[1]>>16; - t[7]=OC_C1S7*_x[1]>>16; - /*Stage 2:*/ - t[5]=OC_C4S4*t[4]>>16; - t[6]=OC_C4S4*t[7]>>16; - /*Stage 3:*/ - r=t[6]+t[5]; - t[5]=t[6]-t[5]; - t[6]=r; - /*Stage 4:*/ - _y[0<<3]=(ogg_int16_t)(t[0]+t[7]); - _y[1<<3]=(ogg_int16_t)(t[0]+t[6]); - _y[2<<3]=(ogg_int16_t)(t[0]+t[5]); - _y[3<<3]=(ogg_int16_t)(t[0]+t[4]); - _y[4<<3]=(ogg_int16_t)(t[0]-t[4]); - _y[5<<3]=(ogg_int16_t)(t[0]-t[5]); - _y[6<<3]=(ogg_int16_t)(t[0]-t[6]); - _y[7<<3]=(ogg_int16_t)(t[0]-t[7]); -} - -/*Performs an inverse 8 point Type-II DCT transform. - The output is scaled by a factor of 2 relative to the orthonormal version of - the transform. - _y: The buffer to store the result in. - Data will be placed in every 8th entry (e.g., in a column of an 8x8 - block). - _x: The input coefficients. - Only the first entry is used. - The other 7 are assumed to be 0.*/ -static void idct8_1(ogg_int16_t *_y,const ogg_int16_t _x[1]){ - _y[0<<3]=_y[1<<3]=_y[2<<3]=_y[3<<3]= - _y[4<<3]=_y[5<<3]=_y[6<<3]=_y[7<<3]=(ogg_int16_t)(OC_C4S4*_x[0]>>16); -} - -/*Performs an inverse 8x8 Type-II DCT transform. - The input is assumed to be scaled by a factor of 4 relative to orthonormal - version of the transform. - All coefficients but the first 3 in zig-zag scan order are assumed to be 0: - x x 0 0 0 0 0 0 - x 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 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 - _y: The buffer to store the result in. - This may be the same as _x. - _x: The input coefficients.*/ -static void oc_idct8x8_3(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; - /*Transform rows of x into columns of w.*/ - idct8_2(w,_x); - idct8_1(w+1,_x+8); - /*Transform rows of w into columns of y.*/ - for(in=w,out=_y,end=out+8;out>4); -} - -/*Performs an inverse 8x8 Type-II DCT transform. - The input is assumed to be scaled by a factor of 4 relative to orthonormal - version of the transform. - All coefficients but the first 10 in zig-zag scan order are assumed to be 0: - x x x x 0 0 0 0 - x x x 0 0 0 0 0 - x x 0 0 0 0 0 0 - x 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 0 0 - 0 0 0 0 0 0 0 0 - _y: The buffer to store the result in. - This may be the same as _x. - _x: The input coefficients.*/ -static void oc_idct8x8_10(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; - /*Transform rows of x into columns of w.*/ - idct8_4(w,_x); - idct8_3(w+1,_x+8); - idct8_2(w+2,_x+16); - idct8_1(w+3,_x+24); - /*Transform rows of w into columns of y.*/ - for(in=w,out=_y,end=out+8;out>4); -} - -/*Performs an inverse 8x8 Type-II DCT transform. - The input is assumed to be scaled by a factor of 4 relative to orthonormal - version of the transform. - _y: The buffer to store the result in. - This may be the same as _x. - _x: The input coefficients.*/ -static void oc_idct8x8_slow(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - const ogg_int16_t *in; - ogg_int16_t *end; - ogg_int16_t *out; - ogg_int16_t w[64]; - /*Transform rows of x into columns of w.*/ - for(in=_x,out=w,end=out+8;out>4); -} - -void oc_idct8x8(const oc_theora_state *_state,ogg_int16_t _y[64], - int _last_zzi){ - (*_state->opt_vtable.idct8x8)(_y,_last_zzi); -} - -/*Performs an inverse 8x8 Type-II DCT transform. - The input is assumed to be scaled by a factor of 4 relative to orthonormal - version of the transform.*/ -void oc_idct8x8_c(ogg_int16_t _y[64],int _last_zzi){ - /*_last_zzi is subtly different from an actual count of the number of - coefficients we decoded for this block. - It contains the value of zzi BEFORE the final token in the block was - decoded. - In most cases this is an EOB token (the continuation of an EOB run from a - previous block counts), and so this is the same as the coefficient count. - However, in the case that the last token was NOT an EOB token, but filled - the block up with exactly 64 coefficients, _last_zzi will be less than 64. - Provided the last token was not a pure zero run, the minimum value it can - be is 46, and so that doesn't affect any of the cases in this routine. - However, if the last token WAS a pure zero run of length 63, then _last_zzi - will be 1 while the number of coefficients decoded is 64. - Thus, we will trigger the following special case, where the real - coefficient count would not. - Note also that a zero run of length 64 will give _last_zzi a value of 0, - but we still process the DC coefficient, which might have a non-zero value - due to DC prediction. - Although convoluted, this is arguably the correct behavior: it allows us to - use a smaller transform when the block ends with a long zero run instead - of a normal EOB token. - It could be smarter... multiple separate zero runs at the end of a block - will fool it, but an encoder that generates these really deserves what it - gets. - Needless to say we inherited this approach from VP3.*/ - /*Then perform the iDCT.*/ - if(_last_zzi<3)oc_idct8x8_3(_y,_y); - else if(_last_zzi<10)oc_idct8x8_10(_y,_y); - else oc_idct8x8_slow(_y,_y); -} diff --git a/src/add-ons/media/plugins/theora/libtheora/info.c b/src/add-ons/media/plugins/theora/libtheora/info.c deleted file mode 100644 index 6b9762978b..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/info.c +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: info.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include -#include -#include -#include "internal.h" - - - -/*This is more or less the same as strncasecmp, but that doesn't exist - everywhere, and this is a fairly trivial function, so we include it. - Note: We take advantage of the fact that we know _n is less than or equal to - the length of at least one of the strings.*/ -static int oc_tagcompare(const char *_s1,const char *_s2,int _n){ - int c; - for(c=0;c<_n;c++){ - if(toupper(_s1[c])!=toupper(_s2[c]))return !0; - } - return _s1[c]!='='; -} - - - -void th_info_init(th_info *_info){ - memset(_info,0,sizeof(*_info)); - _info->version_major=TH_VERSION_MAJOR; - _info->version_minor=TH_VERSION_MINOR; - _info->version_subminor=TH_VERSION_SUB; - _info->keyframe_granule_shift=6; -} - -void th_info_clear(th_info *_info){ - memset(_info,0,sizeof(*_info)); -} - - - -void th_comment_init(th_comment *_tc){ - memset(_tc,0,sizeof(*_tc)); -} - -void th_comment_add(th_comment *_tc,char *_comment){ - char **user_comments; - int *comment_lengths; - int comment_len; - user_comments=_ogg_realloc(_tc->user_comments, - (_tc->comments+2)*sizeof(*_tc->user_comments)); - if(user_comments==NULL)return; - _tc->user_comments=user_comments; - comment_lengths=_ogg_realloc(_tc->comment_lengths, - (_tc->comments+2)*sizeof(*_tc->comment_lengths)); - if(comment_lengths==NULL)return; - _tc->comment_lengths=comment_lengths; - comment_len=strlen(_comment); - comment_lengths[_tc->comments]=comment_len; - user_comments[_tc->comments]=_ogg_malloc(comment_len+1); - if(user_comments[_tc->comments]==NULL)return; - memcpy(_tc->user_comments[_tc->comments],_comment,comment_len+1); - _tc->comments++; - _tc->user_comments[_tc->comments]=NULL; -} - -void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){ - char *comment; - int tag_len; - int val_len; - tag_len=strlen(_tag); - val_len=strlen(_val); - /*+2 for '=' and '\0'.*/ - comment=_ogg_malloc(tag_len+val_len+2); - if(comment==NULL)return; - memcpy(comment,_tag,tag_len); - comment[tag_len]='='; - memcpy(comment+tag_len+1,_val,val_len+1); - th_comment_add(_tc,comment); - _ogg_free(comment); -} - -char *th_comment_query(th_comment *_tc,char *_tag,int _count){ - long i; - int found; - int tag_len; - tag_len=strlen(_tag); - found=0; - for(i=0;i<_tc->comments;i++){ - if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len)){ - /*We return a pointer to the data, not a copy.*/ - if(_count==found++)return _tc->user_comments[i]+tag_len+1; - } - } - /*Didn't find anything.*/ - return NULL; -} - -int th_comment_query_count(th_comment *_tc,char *_tag){ - long i; - int tag_len; - int count; - tag_len=strlen(_tag); - count=0; - for(i=0;i<_tc->comments;i++){ - if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len))count++; - } - return count; -} - -void th_comment_clear(th_comment *_tc){ - if(_tc!=NULL){ - long i; - for(i=0;i<_tc->comments;i++)_ogg_free(_tc->user_comments[i]); - _ogg_free(_tc->user_comments); - _ogg_free(_tc->comment_lengths); - _ogg_free(_tc->vendor); - memset(_tc,0,sizeof(*_tc)); - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/internal.c b/src/add-ons/media/plugins/theora/libtheora/internal.c deleted file mode 100644 index 0fe4f63e72..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/internal.c +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: internal.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include -#include -#include -#include "internal.h" - - - -/*A map from the index in the zig zag scan to the coefficient number in a - block. - All zig zag indices beyond 63 are sent to coefficient 64, so that zero runs - past the end of a block in bogus streams get mapped to a known location.*/ -const unsigned char OC_FZIG_ZAG[128]={ - 0, 1, 8,16, 9, 2, 3,10, - 17,24,32,25,18,11, 4, 5, - 12,19,26,33,40,48,41,34, - 27,20,13, 6, 7,14,21,28, - 35,42,49,56,57,50,43,36, - 29,22,15,23,30,37,44,51, - 58,59,52,45,38,31,39,46, - 53,60,61,54,47,55,62,63, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64 -}; - -/*A map from the coefficient number in a block to its index in the zig zag - scan.*/ -const unsigned char OC_IZIG_ZAG[64]={ - 0, 1, 5, 6,14,15,27,28, - 2, 4, 7,13,16,26,29,42, - 3, 8,12,17,25,30,41,43, - 9,11,18,24,31,40,44,53, - 10,19,23,32,39,45,52,54, - 20,22,33,38,46,51,55,60, - 21,34,37,47,50,56,59,61, - 35,36,48,49,57,58,62,63 -}; - -/*A map from physical macro block ordering to bitstream macro block - ordering within a super block.*/ -const unsigned char OC_MB_MAP[2][2]={{0,3},{1,2}}; - -/*A list of the indices in the oc_mb.map array that can be valid for each of - the various chroma decimation types.*/ -const unsigned char OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]={ - {0,1,2,3,4,8}, - {0,1,2,3,4,5,8,9}, - {0,1,2,3,4,6,8,10}, - {0,1,2,3,4,5,6,7,8,9,10,11} -}; - -/*The number of indices in the oc_mb.map array that can be valid for each of - the various chroma decimation types.*/ -const unsigned char OC_MB_MAP_NIDXS[TH_PF_NFORMATS]={6,8,8,12}; - -/*The number of extra bits that are coded with each of the DCT tokens. - Each DCT token has some fixed number of additional bits (possibly 0) stored - after the token itself, containing, for example, coefficient magnitude, - sign bits, etc.*/ -const unsigned char OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS]={ - 0,0,0,2,3,4,12,3,6, - 0,0,0,0, - 1,1,1,1,2,3,4,5,6,10, - 1,1,1,1,1,3,4, - 2,3 -}; - - - -int oc_ilog(unsigned _v){ - int ret; - for(ret=0;_v;ret++)_v>>=1; - return ret; -} - - - -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with chroma decimated in the X and Y directions - (4:2:0). - _cbmvs: The chroma block-level motion vectors to fill in. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - int dx; - int dy; - dx=_lbmvs[0][0]+_lbmvs[1][0]+_lbmvs[2][0]+_lbmvs[3][0]; - dy=_lbmvs[0][1]+_lbmvs[1][1]+_lbmvs[2][1]+_lbmvs[3][1]; - _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,2,2); - _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,2,2); -} - -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with chroma decimated in the Y direction. - _cbmvs: The chroma block-level motion vectors to fill in. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs01(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - int dx; - int dy; - dx=_lbmvs[0][0]+_lbmvs[2][0]; - dy=_lbmvs[0][1]+_lbmvs[2][1]; - _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); - dx=_lbmvs[1][0]+_lbmvs[3][0]; - dy=_lbmvs[1][1]+_lbmvs[3][1]; - _cbmvs[1][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[1][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); -} - -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with chroma decimated in the X direction (4:2:2). - _cbmvs: The chroma block-level motion vectors to fill in. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs10(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - int dx; - int dy; - dx=_lbmvs[0][0]+_lbmvs[1][0]; - dy=_lbmvs[0][1]+_lbmvs[1][1]; - _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); - dx=_lbmvs[2][0]+_lbmvs[3][0]; - dy=_lbmvs[2][1]+_lbmvs[3][1]; - _cbmvs[2][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1); - _cbmvs[2][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1); -} - -/*The function used to fill in the chroma plane motion vectors for a macro - block when 4 different motion vectors are specified in the luma plane. - This version is for use with no chroma decimation (4:4:4). - _cbmvs: The chroma block-level motion vectors to fill in. - _lmbmv: The luma macro-block level motion vector to fill in for use in - prediction. - _lbmvs: The luma block-level motion vectors.*/ -static void oc_set_chroma_mvs11(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ - memcpy(_cbmvs,_lbmvs,4*sizeof(_lbmvs[0])); -} - -/*A table of functions used to fill in the chroma plane motion vectors for a - macro block when 4 different motion vectors are specified in the luma - plane.*/ -const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]={ - (oc_set_chroma_mvs_func)oc_set_chroma_mvs00, - (oc_set_chroma_mvs_func)oc_set_chroma_mvs01, - (oc_set_chroma_mvs_func)oc_set_chroma_mvs10, - (oc_set_chroma_mvs_func)oc_set_chroma_mvs11 -}; - - - -void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz){ - size_t rowsz; - size_t colsz; - size_t datsz; - char *ret; - colsz=_height*sizeof(void *); - rowsz=_sz*_width; - datsz=rowsz*_height; - /*Alloc array and row pointers.*/ - ret=(char *)_ogg_malloc(datsz+colsz); - if(ret==NULL)return NULL; - /*Initialize the array.*/ - if(ret!=NULL){ - size_t i; - void **p; - char *datptr; - p=(void **)ret; - i=_height; - for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr; - } - return (void **)ret; -} - -void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz){ - size_t colsz; - size_t rowsz; - size_t datsz; - char *ret; - colsz=_height*sizeof(void *); - rowsz=_sz*_width; - datsz=rowsz*_height; - /*Alloc array and row pointers.*/ - ret=(char *)_ogg_calloc(datsz+colsz,1); - if(ret==NULL)return NULL; - /*Initialize the array.*/ - if(ret!=NULL){ - size_t i; - void **p; - char *datptr; - p=(void **)ret; - i=_height; - for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr; - } - return (void **)ret; -} - -void oc_free_2d(void *_ptr){ - _ogg_free(_ptr); -} - -/*Fills in a Y'CbCr buffer with a pointer to the image data in the first - buffer, but with the opposite vertical orientation. - _dst: The destination buffer. - This can be the same as _src. - _src: The source buffer.*/ -void oc_ycbcr_buffer_flip(th_ycbcr_buffer _dst, - const th_ycbcr_buffer _src){ - int pli; - for(pli=0;pli<3;pli++){ - _dst[pli].width=_src[pli].width; - _dst[pli].height=_src[pli].height; - _dst[pli].stride=-_src[pli].stride; - _dst[pli].data=_src[pli].data - +(1-_dst[pli].height)*(ptrdiff_t)_dst[pli].stride; - } -} - -const char *th_version_string(void){ - return OC_VENDOR_STRING; -} - -ogg_uint32_t th_version_number(void){ - return (TH_VERSION_MAJOR<<16)+(TH_VERSION_MINOR<<8)+TH_VERSION_SUB; -} - -/*Determines the packet type. - Note that this correctly interprets a 0-byte packet as a video data packet. - Return: 1 for a header packet, 0 for a data packet.*/ -int th_packet_isheader(ogg_packet *_op){ - return _op->bytes>0?_op->packet[0]>>7:0; -} - -/*Determines the frame type of a video data packet. - Note that this correctly interprets a 0-byte packet as a delta frame. - Return: 1 for a key frame, 0 for a delta frame, and -1 for a header - packet.*/ -int th_packet_iskeyframe(ogg_packet *_op){ - return _op->bytes<=0?0:_op->packet[0]&0x80?-1:!(_op->packet[0]&0x40); -} diff --git a/src/add-ons/media/plugins/theora/libtheora/internal.h b/src/add-ons/media/plugins/theora/libtheora/internal.h deleted file mode 100644 index d81263e13e..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/internal.h +++ /dev/null @@ -1,509 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: internal.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#if !defined(_internal_H) -# define _internal_H (1) -# include -# include -# if defined(HAVE_CONFIG_H) -# include -# endif -# include "theora/codec.h" -# include "theora/theora.h" - -# if defined(_MSC_VER) -/*Disable missing EMMS warnings.*/ -# pragma warning(disable:4799) -/*Thank you Microsoft, I know the order of operations.*/ -# pragma warning(disable:4554) -# endif -/*You, too, gcc.*/ -# if defined(__GNUC_PREREQ) -# if __GNUC_PREREQ(4,2) -# pragma GCC diagnostic ignored "-Wparentheses" -# endif -# endif - -# include "ocintrin.h" -# include "huffman.h" -# include "quant.h" - -/*Some assembly constructs require aligned operands.*/ -# if defined(OC_X86_ASM) -# if defined(__GNUC__) -# define OC_ALIGN8(expr) expr __attribute__((aligned(8))) -# define OC_ALIGN16(expr) expr __attribute__((aligned(16))) -# elif defined(_MSC_VER) -# define OC_ALIGN8(expr) __declspec (align(8)) expr -# define OC_ALIGN16(expr) __declspec (align(16)) expr -# endif -# endif -# if !defined(OC_ALIGN8) -# define OC_ALIGN8(expr) expr -# endif -# if !defined(OC_ALIGN16) -# define OC_ALIGN16(expr) expr -# endif - - - -typedef struct oc_sb_flags oc_sb_flags; -typedef struct oc_border_info oc_border_info; -typedef struct oc_fragment oc_fragment; -typedef struct oc_fragment_plane oc_fragment_plane; -typedef struct oc_base_opt_vtable oc_base_opt_vtable; -typedef struct oc_base_opt_data oc_base_opt_data; -typedef struct oc_state_dispatch_vtable oc_state_dispatch_vtable; -typedef struct oc_theora_state oc_theora_state; - - - -/*This library's version.*/ -# define OC_VENDOR_STRING "Xiph.Org libtheora 1.1 20090822 (Thusnelda)" - -/*Theora bitstream version.*/ -# define TH_VERSION_MAJOR (3) -# define TH_VERSION_MINOR (2) -# define TH_VERSION_SUB (1) -# define TH_VERSION_CHECK(_info,_maj,_min,_sub) \ - ((_info)->version_major>(_maj)||(_info)->version_major==(_maj)&& \ - ((_info)->version_minor>(_min)||(_info)->version_minor==(_min)&& \ - (_info)->version_subminor>=(_sub))) - -/*A keyframe.*/ -#define OC_INTRA_FRAME (0) -/*A predicted frame.*/ -#define OC_INTER_FRAME (1) -/*A frame of unknown type (frame type decision has not yet been made).*/ -#define OC_UNKWN_FRAME (-1) - -/*The amount of padding to add to the reconstructed frame buffers on all - sides. - This is used to allow unrestricted motion vectors without special casing. - This must be a multiple of 2.*/ -#define OC_UMV_PADDING (16) - -/*Frame classification indices.*/ -/*The previous golden frame.*/ -#define OC_FRAME_GOLD (0) -/*The previous frame.*/ -#define OC_FRAME_PREV (1) -/*The current frame.*/ -#define OC_FRAME_SELF (2) - -/*The input or output buffer.*/ -#define OC_FRAME_IO (3) - -/*Macroblock modes.*/ -/*Macro block is invalid: It is never coded.*/ -#define OC_MODE_INVALID (-1) -/*Encoded difference from the same macro block in the previous frame.*/ -#define OC_MODE_INTER_NOMV (0) -/*Encoded with no motion compensated prediction.*/ -#define OC_MODE_INTRA (1) -/*Encoded difference from the previous frame offset by the given motion - vector.*/ -#define OC_MODE_INTER_MV (2) -/*Encoded difference from the previous frame offset by the last coded motion - vector.*/ -#define OC_MODE_INTER_MV_LAST (3) -/*Encoded difference from the previous frame offset by the second to last - coded motion vector.*/ -#define OC_MODE_INTER_MV_LAST2 (4) -/*Encoded difference from the same macro block in the previous golden - frame.*/ -#define OC_MODE_GOLDEN_NOMV (5) -/*Encoded difference from the previous golden frame offset by the given motion - vector.*/ -#define OC_MODE_GOLDEN_MV (6) -/*Encoded difference from the previous frame offset by the individual motion - vectors given for each block.*/ -#define OC_MODE_INTER_MV_FOUR (7) -/*The number of (coded) modes.*/ -#define OC_NMODES (8) - -/*Determines the reference frame used for a given MB mode.*/ -#define OC_FRAME_FOR_MODE(_x) \ - OC_UNIBBLE_TABLE32(OC_FRAME_PREV,OC_FRAME_SELF,OC_FRAME_PREV,OC_FRAME_PREV, \ - OC_FRAME_PREV,OC_FRAME_GOLD,OC_FRAME_GOLD,OC_FRAME_PREV,(_x)) - -/*Constants for the packet state machine common between encoder and decoder.*/ - -/*Next packet to emit/read: Codec info header.*/ -#define OC_PACKET_INFO_HDR (-3) -/*Next packet to emit/read: Comment header.*/ -#define OC_PACKET_COMMENT_HDR (-2) -/*Next packet to emit/read: Codec setup header.*/ -#define OC_PACKET_SETUP_HDR (-1) -/*No more packets to emit/read.*/ -#define OC_PACKET_DONE (INT_MAX) - - - -/*Super blocks are 32x32 segments of pixels in a single color plane indexed - in image order. - Internally, super blocks are broken up into four quadrants, each of which - contains a 2x2 pattern of blocks, each of which is an 8x8 block of pixels. - Quadrants, and the blocks within them, are indexed in a special order called - a "Hilbert curve" within the super block. - - In order to differentiate between the Hilbert-curve indexing strategy and - the regular image order indexing strategy, blocks indexed in image order - are called "fragments". - Fragments are indexed in image order, left to right, then bottom to top, - from Y' plane to Cb plane to Cr plane. - - The co-located fragments in all image planes corresponding to the location - of a single quadrant of a luma plane super block form a macro block. - Thus there is only a single set of macro blocks for all planes, each of which - contains between 6 and 12 fragments, depending on the pixel format. - Therefore macro block information is kept in a separate set of arrays from - super blocks to avoid unused space in the other planes. - The lists are indexed in super block order. - That is, the macro block corresponding to the macro block mbi in (luma plane) - super block sbi is at index (sbi<<2|mbi). - Thus the number of macro blocks in each dimension is always twice the number - of super blocks, even when only an odd number fall inside the coded frame. - These "extra" macro blocks are just an artifact of our internal data layout, - and not part of the coded stream; they are flagged with a negative MB mode.*/ - - - -/*A single quadrant of the map from a super block to fragment numbers.*/ -typedef ptrdiff_t oc_sb_map_quad[4]; -/*A map from a super block to fragment numbers.*/ -typedef oc_sb_map_quad oc_sb_map[4]; -/*A single plane of the map from a macro block to fragment numbers.*/ -typedef ptrdiff_t oc_mb_map_plane[4]; -/*A map from a macro block to fragment numbers.*/ -typedef oc_mb_map_plane oc_mb_map[3]; -/*A motion vector.*/ -typedef signed char oc_mv[2]; - - - -/*Super block information.*/ -struct oc_sb_flags{ - unsigned char coded_fully:1; - unsigned char coded_partially:1; - unsigned char quad_valid:4; -}; - - - -/*Information about a fragment which intersects the border of the displayable - region. - This marks which pixels belong to the displayable region.*/ -struct oc_border_info{ - /*A bit mask marking which pixels are in the displayable region. - Pixel (x,y) corresponds to bit (y<<3|x).*/ - ogg_int64_t mask; - /*The number of pixels in the displayable region. - This is always positive, and always less than 64.*/ - int npixels; -}; - - - -/*Fragment information.*/ -struct oc_fragment{ - /*A flag indicating whether or not this fragment is coded.*/ - unsigned coded:1; - /*A flag indicating that this entire fragment lies outside the displayable - region of the frame. - Note the contrast with an invalid macro block, which is outside the coded - frame, not just the displayable one. - There are no fragments outside the coded frame by construction.*/ - unsigned invalid:1; - /*The index of the quality index used for this fragment's AC coefficients.*/ - unsigned qii:6; - /*The mode of the macroblock this fragment belongs to.*/ - unsigned mb_mode:3; - /*The index of the associated border information for fragments which lie - partially outside the displayable region. - For fragments completely inside or outside this region, this is -1. - Note that the C standard requires an explicit signed keyword for bitfield - types, since some compilers may treat them as unsigned without it.*/ - signed int borderi:5; - /*The prediction-corrected DC component. - Note that the C standard requires an explicit signed keyword for bitfield - types, since some compilers may treat them as unsigned without it.*/ - signed int dc:16; -}; - - - -/*A description of each fragment plane.*/ -struct oc_fragment_plane{ - /*The number of fragments in the horizontal direction.*/ - int nhfrags; - /*The number of fragments in the vertical direction.*/ - int nvfrags; - /*The offset of the first fragment in the plane.*/ - ptrdiff_t froffset; - /*The total number of fragments in the plane.*/ - ptrdiff_t nfrags; - /*The number of super blocks in the horizontal direction.*/ - unsigned nhsbs; - /*The number of super blocks in the vertical direction.*/ - unsigned nvsbs; - /*The offset of the first super block in the plane.*/ - unsigned sboffset; - /*The total number of super blocks in the plane.*/ - unsigned nsbs; -}; - - - -/*The shared (encoder and decoder) functions that have accelerated variants.*/ -struct oc_base_opt_vtable{ - void (*frag_copy)(unsigned char *_dst, - const unsigned char *_src,int _ystride); - void (*frag_recon_intra)(unsigned char *_dst,int _ystride, - const ogg_int16_t _residue[64]); - void (*frag_recon_inter)(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); - void (*frag_recon_inter2)(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]); - void (*idct8x8)(ogg_int16_t _y[64],int _last_zzi); - void (*state_frag_recon)(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); - void (*state_frag_copy_list)(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); - void (*state_loop_filter_frag_rows)(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); - void (*restore_fpu)(void); -}; - -/*The shared (encoder and decoder) tables that vary according to which variants - of the above functions are used.*/ -struct oc_base_opt_data{ - const unsigned char *dct_fzig_zag; -}; - - -/*State information common to both the encoder and decoder.*/ -struct oc_theora_state{ - /*The stream information.*/ - th_info info; - /*Table for shared accelerated functions.*/ - oc_base_opt_vtable opt_vtable; - /*Table for shared data used by accelerated functions.*/ - oc_base_opt_data opt_data; - /*CPU flags to detect the presence of extended instruction sets.*/ - ogg_uint32_t cpu_flags; - /*The fragment plane descriptions.*/ - oc_fragment_plane fplanes[3]; - /*The list of fragments, indexed in image order.*/ - oc_fragment *frags; - /*The the offset into the reference frame buffer to the upper-left pixel of - each fragment.*/ - ptrdiff_t *frag_buf_offs; - /*The motion vector for each fragment.*/ - oc_mv *frag_mvs; - /*The total number of fragments in a single frame.*/ - ptrdiff_t nfrags; - /*The list of super block maps, indexed in image order.*/ - oc_sb_map *sb_maps; - /*The list of super block flags, indexed in image order.*/ - oc_sb_flags *sb_flags; - /*The total number of super blocks in a single frame.*/ - unsigned nsbs; - /*The fragments from each color plane that belong to each macro block. - Fragments are stored in image order (left to right then top to bottom). - When chroma components are decimated, the extra fragments have an index of - -1.*/ - oc_mb_map *mb_maps; - /*The list of macro block modes. - A negative number indicates the macro block lies entirely outside the - coded frame.*/ - signed char *mb_modes; - /*The number of macro blocks in the X direction.*/ - unsigned nhmbs; - /*The number of macro blocks in the Y direction.*/ - unsigned nvmbs; - /*The total number of macro blocks.*/ - size_t nmbs; - /*The list of coded fragments, in coded order. - Uncoded fragments are stored in reverse order from the end of the list.*/ - ptrdiff_t *coded_fragis; - /*The number of coded fragments in each plane.*/ - ptrdiff_t ncoded_fragis[3]; - /*The total number of coded fragments.*/ - ptrdiff_t ntotal_coded_fragis; - /*The index of the buffers being used for each OC_FRAME_* reference frame.*/ - int ref_frame_idx[4]; - /*The actual buffers used for the previously decoded frames.*/ - th_ycbcr_buffer ref_frame_bufs[4]; - /*The storage for the reference frame buffers.*/ - unsigned char *ref_frame_data[4]; - /*The strides for each plane in the reference frames.*/ - int ref_ystride[3]; - /*The number of unique border patterns.*/ - int nborders; - /*The unique border patterns for all border fragments. - The borderi field of fragments which straddle the border indexes this - list.*/ - oc_border_info borders[16]; - /*The frame number of the last keyframe.*/ - ogg_int64_t keyframe_num; - /*The frame number of the current frame.*/ - ogg_int64_t curframe_num; - /*The granpos of the current frame.*/ - ogg_int64_t granpos; - /*The type of the current frame.*/ - unsigned char frame_type; - /*The bias to add to the frame count when computing granule positions.*/ - unsigned char granpos_bias; - /*The number of quality indices used in the current frame.*/ - unsigned char nqis; - /*The quality indices of the current frame.*/ - unsigned char qis[3]; - /*The dequantization tables, stored in zig-zag order, and indexed by - qi, pli, qti, and zzi.*/ - ogg_uint16_t *dequant_tables[64][3][2]; - OC_ALIGN16(oc_quant_table dequant_table_data[64][3][2]); - /*Loop filter strength parameters.*/ - unsigned char loop_filter_limits[64]; -}; - - - -/*The function type used to fill in the chroma plane motion vectors for a - macro block when 4 different motion vectors are specified in the luma - plane. - _cbmvs: The chroma block-level motion vectors to fill in. - _lmbmv: The luma macro-block level motion vector to fill in for use in - prediction. - _lbmvs: The luma block-level motion vectors.*/ -typedef void (*oc_set_chroma_mvs_func)(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]); - - - -/*A map from the index in the zig zag scan to the coefficient number in a - block.*/ -extern const unsigned char OC_FZIG_ZAG[128]; -/*A map from the coefficient number in a block to its index in the zig zag - scan.*/ -extern const unsigned char OC_IZIG_ZAG[64]; -/*A map from physical macro block ordering to bitstream macro block - ordering within a super block.*/ -extern const unsigned char OC_MB_MAP[2][2]; -/*A list of the indices in the oc_mb_map array that can be valid for each of - the various chroma decimation types.*/ -extern const unsigned char OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]; -/*The number of indices in the oc_mb_map array that can be valid for each of - the various chroma decimation types.*/ -extern const unsigned char OC_MB_MAP_NIDXS[TH_PF_NFORMATS]; -/*A table of functions used to fill in the Cb,Cr plane motion vectors for a - macro block when 4 different motion vectors are specified in the luma - plane.*/ -extern const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]; - - - -int oc_ilog(unsigned _v); -void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz); -void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz); -void oc_free_2d(void *_ptr); - -void oc_ycbcr_buffer_flip(th_ycbcr_buffer _dst, - const th_ycbcr_buffer _src); - -int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs); -void oc_state_clear(oc_theora_state *_state); -void oc_state_vtable_init_c(oc_theora_state *_state); -void oc_state_borders_fill_rows(oc_theora_state *_state,int _refi,int _pli, - int _y0,int _yend); -void oc_state_borders_fill_caps(oc_theora_state *_state,int _refi,int _pli); -void oc_state_borders_fill(oc_theora_state *_state,int _refi); -void oc_state_fill_buffer_ptrs(oc_theora_state *_state,int _buf_idx, - th_ycbcr_buffer _img); -int oc_state_mbi_for_pos(oc_theora_state *_state,int _mbx,int _mby); -int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], - int _pli,int _dx,int _dy); - -int oc_state_loop_filter_init(oc_theora_state *_state,int *_bv); -void oc_state_loop_filter(oc_theora_state *_state,int _frame); -#if defined(OC_DUMP_IMAGES) -int oc_state_dump_frame(const oc_theora_state *_state,int _frame, - const char *_suf); -#endif - -/*Shared accelerated functions.*/ -void oc_frag_copy(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride); -void oc_frag_recon_intra(const oc_theora_state *_state, - unsigned char *_dst,int _dst_ystride,const ogg_int16_t _residue[64]); -void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); -void oc_frag_recon_inter2(const oc_theora_state *_state, - unsigned char *_dst,const unsigned char *_src1,const unsigned char *_src2, - int _ystride,const ogg_int16_t _residue[64]); -void oc_idct8x8(const oc_theora_state *_state,ogg_int16_t _y[64],int _last_zzi); -void oc_state_frag_recon(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); -void oc_state_loop_filter_frag_rows(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); -void oc_restore_fpu(const oc_theora_state *_state); - -/*Default pure-C implementations.*/ -void oc_frag_copy_c(unsigned char *_dst, - const unsigned char *_src,int _src_ystride); -void oc_frag_recon_intra_c(unsigned char *_dst,int _dst_ystride, - const ogg_int16_t _residue[64]); -void oc_frag_recon_inter_c(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]); -void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]); -void oc_idct8x8_c(ogg_int16_t _y[64],int _last_zzi); -void oc_state_frag_recon_c(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list_c(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); -void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); -void oc_restore_fpu_c(void); - -/*We need a way to call a few encoder functions without introducing a link-time - dependency into the decoder, while still allowing the old alpha API which - does not distinguish between encoder and decoder objects to be used. - We do this by placing a function table at the start of the encoder object - which can dispatch into the encoder library. - We do a similar thing for the decoder in case we ever decide to split off a - common base library.*/ -typedef void (*oc_state_clear_func)(theora_state *_th); -typedef int (*oc_state_control_func)(theora_state *th,int _req, - void *_buf,size_t _buf_sz); -typedef ogg_int64_t (*oc_state_granule_frame_func)(theora_state *_th, - ogg_int64_t _granulepos); -typedef double (*oc_state_granule_time_func)(theora_state *_th, - ogg_int64_t _granulepos); - - -struct oc_state_dispatch_vtable{ - oc_state_clear_func clear; - oc_state_control_func control; - oc_state_granule_frame_func granule_frame; - oc_state_granule_time_func granule_time; -}; - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/mathops.c b/src/add-ons/media/plugins/theora/libtheora/mathops.c deleted file mode 100644 index d3fb909194..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/mathops.c +++ /dev/null @@ -1,296 +0,0 @@ -#include "mathops.h" -#include - -/*The fastest fallback strategy for platforms with fast multiplication appears - to be based on de Bruijn sequences~\cite{LP98}. - Tests confirmed this to be true even on an ARM11, where it is actually faster - than using the native clz instruction. - Define OC_ILOG_NODEBRUIJN to use a simpler fallback on platforms where - multiplication or table lookups are too expensive. - - @UNPUBLISHED{LP98, - author="Charles E. Leiserson and Harald Prokop", - title="Using de {Bruijn} Sequences to Index a 1 in a Computer Word", - month=Jun, - year=1998, - note="\url{http://supertech.csail.mit.edu/papers/debruijn.pdf}" - }*/ -#if !defined(OC_ILOG_NODEBRUIJN)&& \ - !defined(OC_CLZ32)||!defined(OC_CLZ64)&&LONG_MAX<9223372036854775807LL -static const unsigned char OC_DEBRUIJN_IDX32[32]={ - 0, 1,28, 2,29,14,24, 3,30,22,20,15,25,17, 4, 8, - 31,27,13,23,21,19,16, 7,26,12,18, 6,11, 5,10, 9 -}; -#endif - -int oc_ilog32(ogg_uint32_t _v){ -#if defined(OC_CLZ32) - return (OC_CLZ32_OFFS-OC_CLZ32(_v))&-!!_v; -#else -/*On a Pentium M, this branchless version tested as the fastest version without - multiplications on 1,000,000,000 random 32-bit integers, edging out a - similar version with branches, and a 256-entry LUT version.*/ -# if defined(OC_ILOG_NODEBRUIJN) - int ret; - int m; - ret=_v>0; - m=(_v>0xFFFFU)<<4; - _v>>=m; - ret|=m; - m=(_v>0xFFU)<<3; - _v>>=m; - ret|=m; - m=(_v>0xFU)<<2; - _v>>=m; - ret|=m; - m=(_v>3)<<1; - _v>>=m; - ret|=m; - ret+=_v>1; - return ret; -/*This de Bruijn sequence version is faster if you have a fast multiplier.*/ -# else - int ret; - ret=_v>0; - _v|=_v>>1; - _v|=_v>>2; - _v|=_v>>4; - _v|=_v>>8; - _v|=_v>>16; - _v=(_v>>1)+1; - ret+=OC_DEBRUIJN_IDX32[_v*0x77CB531U>>27&0x1F]; - return ret; -# endif -#endif -} - -int oc_ilog64(ogg_int64_t _v){ -#if defined(OC_CLZ64) - return (OC_CLZ64_OFFS-OC_CLZ64(_v))&-!!_v; -#else -# if defined(OC_ILOG_NODEBRUIJN) - ogg_uint32_t v; - int ret; - int m; - ret=_v>0; - m=(_v>0xFFFFFFFFU)<<5; - v=(ogg_uint32_t)(_v>>m); - ret|=m; - m=(v>0xFFFFU)<<4; - v>>=m; - ret|=m; - m=(v>0xFFU)<<3; - v>>=m; - ret|=m; - m=(v>0xFU)<<2; - v>>=m; - ret|=m; - m=(v>3)<<1; - v>>=m; - ret|=m; - ret+=v>1; - return ret; -# else -/*If we don't have a 64-bit word, split it into two 32-bit halves.*/ -# if LONG_MAX<9223372036854775807LL - ogg_uint32_t v; - int ret; - int m; - ret=_v>0; - m=(_v>0xFFFFFFFFU)<<5; - v=(ogg_uint32_t)(_v>>m); - ret|=m; - v|=v>>1; - v|=v>>2; - v|=v>>4; - v|=v>>8; - v|=v>>16; - v=(v>>1)+1; - ret+=OC_DEBRUIJN_IDX32[v*0x77CB531U>>27&0x1F]; - return ret; -/*Otherwise do it in one 64-bit operation.*/ -# else - static const unsigned char OC_DEBRUIJN_IDX64[64]={ - 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, - 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, - 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, - 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 - }; - int ret; - ret=_v>0; - _v|=_v>>1; - _v|=_v>>2; - _v|=_v>>4; - _v|=_v>>8; - _v|=_v>>16; - _v|=_v>>32; - _v=(_v>>1)+1; - ret+=OC_DEBRUIJN_IDX64[_v*0x218A392CD3D5DBF>>58&0x3F]; - return ret; -# endif -# endif -#endif -} - -/*round(2**(62+i)*atanh(2**(-(i+1)))/log(2))*/ -static const ogg_int64_t OC_ATANH_LOG2[32]={ - 0x32B803473F7AD0F4LL,0x2F2A71BD4E25E916LL,0x2E68B244BB93BA06LL, - 0x2E39FB9198CE62E4LL,0x2E2E683F68565C8FLL,0x2E2B850BE2077FC1LL, - 0x2E2ACC58FE7B78DBLL,0x2E2A9E2DE52FD5F2LL,0x2E2A92A338D53EECLL, - 0x2E2A8FC08F5E19B6LL,0x2E2A8F07E51A485ELL,0x2E2A8ED9BA8AF388LL, - 0x2E2A8ECE2FE7384ALL,0x2E2A8ECB4D3E4B1ALL,0x2E2A8ECA94940FE8LL, - 0x2E2A8ECA6669811DLL,0x2E2A8ECA5ADEDD6ALL,0x2E2A8ECA57FC347ELL, - 0x2E2A8ECA57438A43LL,0x2E2A8ECA57155FB4LL,0x2E2A8ECA5709D510LL, - 0x2E2A8ECA5706F267LL,0x2E2A8ECA570639BDLL,0x2E2A8ECA57060B92LL, - 0x2E2A8ECA57060008LL,0x2E2A8ECA5705FD25LL,0x2E2A8ECA5705FC6CLL, - 0x2E2A8ECA5705FC3ELL,0x2E2A8ECA5705FC33LL,0x2E2A8ECA5705FC30LL, - 0x2E2A8ECA5705FC2FLL,0x2E2A8ECA5705FC2FLL -}; - -/*Computes the binary exponential of _z, a log base 2 in Q57 format.*/ -ogg_int64_t oc_bexp64(ogg_int64_t _z){ - ogg_int64_t w; - ogg_int64_t z; - int ipart; - ipart=(int)(_z>>57); - if(ipart<0)return 0; - if(ipart>=63)return 0x7FFFFFFFFFFFFFFFLL; - z=_z-OC_Q57(ipart); - if(z){ - ogg_int64_t mask; - long wlo; - int i; - /*C doesn't give us 64x64->128 muls, so we use CORDIC. - This is not particularly fast, but it's not being used in time-critical - code; it is very accurate.*/ - /*z is the fractional part of the log in Q62 format. - We need 1 bit of headroom since the magnitude can get larger than 1 - during the iteration, and a sign bit.*/ - z<<=5; - /*w is the exponential in Q61 format (since it also needs headroom and can - get as large as 2.0); we could get another bit if we dropped the sign, - but we'll recover that bit later anyway. - Ideally this should start out as - \lim_{n->\infty} 2^{61}/\product_{i=1}^n \sqrt{1-2^{-2i}} - but in order to guarantee convergence we have to repeat iterations 4, - 13 (=3*4+1), and 40 (=3*13+1, etc.), so it winds up somewhat larger.*/ - w=0x26A3D0E401DD846DLL; - for(i=0;;i++){ - mask=-(z<0); - w+=(w>>i+1)+mask^mask; - z-=OC_ATANH_LOG2[i]+mask^mask; - /*Repeat iteration 4.*/ - if(i>=3)break; - z<<=1; - } - for(;;i++){ - mask=-(z<0); - w+=(w>>i+1)+mask^mask; - z-=OC_ATANH_LOG2[i]+mask^mask; - /*Repeat iteration 13.*/ - if(i>=12)break; - z<<=1; - } - for(;i<32;i++){ - mask=-(z<0); - w+=(w>>i+1)+mask^mask; - z=z-(OC_ATANH_LOG2[i]+mask^mask)<<1; - } - wlo=0; - /*Skip the remaining iterations unless we really require that much - precision. - We could have bailed out earlier for smaller iparts, but that would - require initializing w from a table, as the limit doesn't converge to - 61-bit precision until n=30.*/ - if(ipart>30){ - /*For these iterations, we just update the low bits, as the high bits - can't possibly be affected. - OC_ATANH_LOG2 has also converged (it actually did so one iteration - earlier, but that's no reason for an extra special case).*/ - for(;;i++){ - mask=-(z<0); - wlo+=(w>>i)+mask^mask; - z-=OC_ATANH_LOG2[31]+mask^mask; - /*Repeat iteration 40.*/ - if(i>=39)break; - z<<=1; - } - for(;i<61;i++){ - mask=-(z<0); - wlo+=(w>>i)+mask^mask; - z=z-(OC_ATANH_LOG2[31]+mask^mask)<<1; - } - } - w=(w<<1)+wlo; - } - else w=(ogg_int64_t)1<<62; - if(ipart<62)w=(w>>61-ipart)+1>>1; - return w; -} - -/*Computes the binary logarithm of _w, returned in Q57 format.*/ -ogg_int64_t oc_blog64(ogg_int64_t _w){ - ogg_int64_t z; - int ipart; - if(_w<=0)return -1; - ipart=OC_ILOGNZ_64(_w)-1; - if(ipart>61)_w>>=ipart-61; - else _w<<=61-ipart; - z=0; - if(_w&_w-1){ - ogg_int64_t x; - ogg_int64_t y; - ogg_int64_t u; - ogg_int64_t mask; - int i; - /*C doesn't give us 64x64->128 muls, so we use CORDIC. - This is not particularly fast, but it's not being used in time-critical - code; it is very accurate.*/ - /*z is the fractional part of the log in Q61 format.*/ - /*x and y are the cosh() and sinh(), respectively, in Q61 format. - We are computing z=2*atanh(y/x)=2*atanh((_w-1)/(_w+1)).*/ - x=_w+((ogg_int64_t)1<<61); - y=_w-((ogg_int64_t)1<<61); - for(i=0;i<4;i++){ - mask=-(y<0); - z+=(OC_ATANH_LOG2[i]>>i)+mask^mask; - u=x>>i+1; - x-=(y>>i+1)+mask^mask; - y-=u+mask^mask; - } - /*Repeat iteration 4.*/ - for(i--;i<13;i++){ - mask=-(y<0); - z+=(OC_ATANH_LOG2[i]>>i)+mask^mask; - u=x>>i+1; - x-=(y>>i+1)+mask^mask; - y-=u+mask^mask; - } - /*Repeat iteration 13.*/ - for(i--;i<32;i++){ - mask=-(y<0); - z+=(OC_ATANH_LOG2[i]>>i)+mask^mask; - u=x>>i+1; - x-=(y>>i+1)+mask^mask; - y-=u+mask^mask; - } - /*OC_ATANH_LOG2 has converged.*/ - for(;i<40;i++){ - mask=-(y<0); - z+=(OC_ATANH_LOG2[31]>>i)+mask^mask; - u=x>>i+1; - x-=(y>>i+1)+mask^mask; - y-=u+mask^mask; - } - /*Repeat iteration 40.*/ - for(i--;i<62;i++){ - mask=-(y<0); - z+=(OC_ATANH_LOG2[31]>>i)+mask^mask; - u=x>>i+1; - x-=(y>>i+1)+mask^mask; - y-=u+mask^mask; - } - z=z+8>>4; - } - return OC_Q57(ipart)+z; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/mathops.h b/src/add-ons/media/plugins/theora/libtheora/mathops.h deleted file mode 100644 index efbc5377b0..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/mathops.h +++ /dev/null @@ -1,141 +0,0 @@ -#if !defined(_mathops_H) -# define _mathops_H (1) -# include - -# ifdef __GNUC_PREREQ -# if __GNUC_PREREQ(3,4) -# include -/*Note the casts to (int) below: this prevents OC_CLZ{32|64}_OFFS from - "upgrading" the type of an entire expression to an (unsigned) size_t.*/ -# if INT_MAX>=2147483647 -# define OC_CLZ32_OFFS ((int)sizeof(unsigned)*CHAR_BIT) -# define OC_CLZ32(_x) (__builtin_clz(_x)) -# elif LONG_MAX>=2147483647L -# define OC_CLZ32_OFFS ((int)sizeof(unsigned long)*CHAR_BIT) -# define OC_CLZ32(_x) (__builtin_clzl(_x)) -# endif -# if INT_MAX>=9223372036854775807LL -# define OC_CLZ64_OFFS ((int)sizeof(unsigned)*CHAR_BIT) -# define OC_CLZ64(_x) (__builtin_clz(_x)) -# elif LONG_MAX>=9223372036854775807LL -# define OC_CLZ64_OFFS ((int)sizeof(unsigned long)*CHAR_BIT) -# define OC_CLZ64(_x) (__builtin_clzl(_x)) -# elif LLONG_MAX>=9223372036854775807LL|| \ - __LONG_LONG_MAX__>=9223372036854775807LL -# define OC_CLZ64_OFFS ((int)sizeof(unsigned long long)*CHAR_BIT) -# define OC_CLZ64(_x) (__builtin_clzll(_x)) -# endif -# endif -# endif - - - -/** - * oc_ilog32 - Integer binary logarithm of a 32-bit value. - * @_v: A 32-bit value. - * Returns floor(log2(_v))+1, or 0 if _v==0. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - * The OC_ILOG_32() or OC_ILOGNZ_32() macros may be able to use a builtin - * function instead, which should be faster. - */ -int oc_ilog32(ogg_uint32_t _v); -/** - * oc_ilog64 - Integer binary logarithm of a 64-bit value. - * @_v: A 64-bit value. - * Returns floor(log2(_v))+1, or 0 if _v==0. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - * The OC_ILOG_64() or OC_ILOGNZ_64() macros may be able to use a builtin - * function instead, which should be faster. - */ -int oc_ilog64(ogg_int64_t _v); - - -# if defined(OC_CLZ32) -/** - * OC_ILOGNZ_32 - Integer binary logarithm of a non-zero 32-bit value. - * @_v: A non-zero 32-bit value. - * Returns floor(log2(_v))+1. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - * If _v is zero, the return value is undefined; use OC_ILOG_32() instead. - */ -# define OC_ILOGNZ_32(_v) (OC_CLZ32_OFFS-OC_CLZ32(_v)) -/** - * OC_ILOG_32 - Integer binary logarithm of a 32-bit value. - * @_v: A 32-bit value. - * Returns floor(log2(_v))+1, or 0 if _v==0. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - */ -# define OC_ILOG_32(_v) (OC_ILOGNZ_32(_v)&-!!(_v)) -# else -# define OC_ILOGNZ_32(_v) (oc_ilog32(_v)) -# define OC_ILOG_32(_v) (oc_ilog32(_v)) -# endif - -# if defined(CLZ64) -/** - * OC_ILOGNZ_64 - Integer binary logarithm of a non-zero 64-bit value. - * @_v: A non-zero 64-bit value. - * Returns floor(log2(_v))+1. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - * If _v is zero, the return value is undefined; use OC_ILOG_64() instead. - */ -# define OC_ILOGNZ_64(_v) (CLZ64_OFFS-CLZ64(_v)) -/** - * OC_ILOG_64 - Integer binary logarithm of a 64-bit value. - * @_v: A 64-bit value. - * Returns floor(log2(_v))+1, or 0 if _v==0. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - */ -# define OC_ILOG_64(_v) (OC_ILOGNZ_64(_v)&-!!(_v)) -# else -# define OC_ILOGNZ_64(_v) (oc_ilog64(_v)) -# define OC_ILOG_64(_v) (oc_ilog64(_v)) -# endif - -# define OC_STATIC_ILOG0(_v) (!!(_v)) -# define OC_STATIC_ILOG1(_v) (((_v)&0x2)?2:OC_STATIC_ILOG0(_v)) -# define OC_STATIC_ILOG2(_v) \ - (((_v)&0xC)?2+OC_STATIC_ILOG1((_v)>>2):OC_STATIC_ILOG1(_v)) -# define OC_STATIC_ILOG3(_v) \ - (((_v)&0xF0)?4+OC_STATIC_ILOG2((_v)>>4):OC_STATIC_ILOG2(_v)) -# define OC_STATIC_ILOG4(_v) \ - (((_v)&0xFF00)?8+OC_STATIC_ILOG3((_v)>>8):OC_STATIC_ILOG3(_v)) -# define OC_STATIC_ILOG5(_v) \ - (((_v)&0xFFFF0000)?16+OC_STATIC_ILOG4((_v)>>16):OC_STATIC_ILOG4(_v)) -# define OC_STATIC_ILOG6(_v) \ - (((_v)&0xFFFFFFFF00000000ULL)?32+OC_STATIC_ILOG5((_v)>>32):OC_STATIC_ILOG5(_v)) -/** - * OC_STATIC_ILOG_32 - The integer logarithm of an (unsigned, 32-bit) constant. - * @_v: A non-negative 32-bit constant. - * Returns floor(log2(_v))+1, or 0 if _v==0. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - * This macro is suitable for evaluation at compile time, but it should not be - * used on values that can change at runtime, as it operates via exhaustive - * search. - */ -# define OC_STATIC_ILOG_32(_v) (OC_STATIC_ILOG5((ogg_uint32_t)(_v))) -/** - * OC_STATIC_ILOG_64 - The integer logarithm of an (unsigned, 64-bit) constant. - * @_v: A non-negative 64-bit constant. - * Returns floor(log2(_v))+1, or 0 if _v==0. - * This is the number of bits that would be required to represent _v in two's - * complement notation with all of the leading zeros stripped. - * This macro is suitable for evaluation at compile time, but it should not be - * used on values that can change at runtime, as it operates via exhaustive - * search. - */ -# define OC_STATIC_ILOG_64(_v) (OC_STATIC_ILOG6((ogg_int64_t)(_v))) - -#define OC_Q57(_v) ((ogg_int64_t)(_v)<<57) - -ogg_int64_t oc_bexp64(ogg_int64_t _z); -ogg_int64_t oc_blog64(ogg_int64_t _w); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/mcenc.c b/src/add-ons/media/plugins/theora/libtheora/mcenc.c deleted file mode 100644 index 797e81f4f9..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/mcenc.c +++ /dev/null @@ -1,767 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id$ - - ********************************************************************/ -#include -#include -#include -#include "encint.h" - - - -typedef struct oc_mcenc_ctx oc_mcenc_ctx; - - - -/*Temporary state used for motion estimation.*/ -struct oc_mcenc_ctx{ - /*The candidate motion vectors.*/ - int candidates[13][2]; - /*The start of the Set B candidates.*/ - int setb0; - /*The total number of candidates.*/ - int ncandidates; -}; - - - -/*The maximum Y plane SAD value for accepting the median predictor.*/ -#define OC_YSAD_THRESH1 (256) -/*The amount to right shift the minimum error by when inflating it for - computing the second maximum Y plane SAD threshold.*/ -#define OC_YSAD_THRESH2_SCALE_BITS (4) -/*The amount to add to the second maximum Y plane threshold when inflating - it.*/ -#define OC_YSAD_THRESH2_OFFSET (64) - -/*The vector offsets in the X direction for each search site in the square - pattern.*/ -static const int OC_SQUARE_DX[9]={-1,0,1,-1,0,1,-1,0,1}; -/*The vector offsets in the Y direction for each search site in the square - pattern.*/ -static const int OC_SQUARE_DY[9]={-1,-1,-1,0,0,0,1,1,1}; -/*The number of sites to search for each boundary condition in the square - pattern. - Bit flags for the boundary conditions are as follows: - 1: -16==dx - 2: dx==15(.5) - 4: -16==dy - 8: dy==15(.5)*/ -static const int OC_SQUARE_NSITES[11]={8,5,5,0,5,3,3,0,5,3,3}; -/*The list of sites to search for each boundary condition in the square - pattern.*/ -static const int OC_SQUARE_SITES[11][8]={ - /* -15.5mb_info; - /*Skip a position to store the median predictor in.*/ - ncandidates=1; - if(embs[_mbi].ncneighbors>0){ - /*Fill in the first part of set A: the vectors from adjacent blocks.*/ - for(i=0;icandidates[ncandidates][0]=embs[nmbi].analysis_mv[0][_frame][0]; - _mcenc->candidates[ncandidates][1]=embs[nmbi].analysis_mv[0][_frame][1]; - ncandidates++; - } - } - /*Add a few additional vectors to set A: the vectors used in the previous - frames and the (0,0) vector.*/ - _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,_accum[0],31); - _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,_accum[1],31); - ncandidates++; - _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, - embs[_mbi].analysis_mv[1][_frame][0]+_accum[0],31); - _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, - embs[_mbi].analysis_mv[1][_frame][1]+_accum[1],31); - ncandidates++; - _mcenc->candidates[ncandidates][0]=0; - _mcenc->candidates[ncandidates][1]=0; - ncandidates++; - /*Use the first three vectors of set A to find our best predictor: their - median.*/ - memcpy(a,_mcenc->candidates+1,sizeof(a)); - OC_SORT2I(a[0][0],a[1][0]); - OC_SORT2I(a[0][1],a[1][1]); - OC_SORT2I(a[1][0],a[2][0]); - OC_SORT2I(a[1][1],a[2][1]); - OC_SORT2I(a[0][0],a[1][0]); - OC_SORT2I(a[0][1],a[1][1]); - _mcenc->candidates[0][0]=a[1][0]; - _mcenc->candidates[0][1]=a[1][1]; - /*Fill in set B: accelerated predictors for this and adjacent macro blocks.*/ - _mcenc->setb0=ncandidates; - /*The first time through the loop use the current macro block.*/ - nmbi=_mbi; - for(i=0;;i++){ - _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, - 2*embs[_mbi].analysis_mv[1][_frame][0] - -embs[_mbi].analysis_mv[2][_frame][0]+_accum[0],31); - _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, - 2*embs[_mbi].analysis_mv[1][_frame][1] - -embs[_mbi].analysis_mv[2][_frame][1]+_accum[1],31); - ncandidates++; - if(i>=embs[_mbi].npneighbors)break; - nmbi=embs[_mbi].pneighbors[i]; - } - /*Truncate to full-pel positions.*/ - for(i=0;icandidates[i][0]=OC_DIV2(_mcenc->candidates[i][0]); - _mcenc->candidates[i][1]=OC_DIV2(_mcenc->candidates[i][1]); - } - _mcenc->ncandidates=ncandidates; -} - -#if 0 -static unsigned oc_sad16_halfpel(const oc_enc_ctx *_enc, - const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4], - int _mvoffset0,int _mvoffset1,const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _best_err){ - unsigned err; - int bi; - err=0; - for(bi=0;bi<4;bi++){ - ptrdiff_t frag_offs; - frag_offs=_frag_buf_offs[_fragis[bi]]; - err+=oc_enc_frag_sad2_thresh(_enc,_src+frag_offs,_ref+frag_offs+_mvoffset0, - _ref+frag_offs+_mvoffset1,_ystride,_best_err-err); - } - return err; -} -#endif - -static unsigned oc_satd16_halfpel(const oc_enc_ctx *_enc, - const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4], - int _mvoffset0,int _mvoffset1,const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _best_err){ - unsigned err; - int bi; - err=0; - for(bi=0;bi<4;bi++){ - ptrdiff_t frag_offs; - frag_offs=_frag_buf_offs[_fragis[bi]]; - err+=oc_enc_frag_satd2_thresh(_enc,_src+frag_offs,_ref+frag_offs+_mvoffset0, - _ref+frag_offs+_mvoffset1,_ystride,_best_err-err); - } - return err; -} - -static unsigned oc_mcenc_ysad_check_mbcandidate_fullpel(const oc_enc_ctx *_enc, - const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4],int _dx,int _dy, - const unsigned char *_src,const unsigned char *_ref,int _ystride, - unsigned _block_err[4]){ - unsigned err; - int mvoffset; - int bi; - mvoffset=_dx+_dy*_ystride; - err=0; - for(bi=0;bi<4;bi++){ - ptrdiff_t frag_offs; - unsigned block_err; - frag_offs=_frag_buf_offs[_fragis[bi]]; - block_err=oc_enc_frag_sad(_enc, - _src+frag_offs,_ref+frag_offs+mvoffset,_ystride); - _block_err[bi]=block_err; - err+=block_err; - } - return err; -} - -static int oc_mcenc_ysatd_check_mbcandidate_fullpel(const oc_enc_ctx *_enc, - const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4],int _dx,int _dy, - const unsigned char *_src,const unsigned char *_ref,int _ystride){ - int mvoffset; - int err; - int bi; - mvoffset=_dx+_dy*_ystride; - err=0; - for(bi=0;bi<4;bi++){ - ptrdiff_t frag_offs; - frag_offs=_frag_buf_offs[_fragis[bi]]; - err+=oc_enc_frag_satd_thresh(_enc, - _src+frag_offs,_ref+frag_offs+mvoffset,_ystride,UINT_MAX); - } - return err; -} - -static unsigned oc_mcenc_ysatd_check_bcandidate_fullpel(const oc_enc_ctx *_enc, - ptrdiff_t _frag_offs,int _dx,int _dy, - const unsigned char *_src,const unsigned char *_ref,int _ystride){ - return oc_enc_frag_satd_thresh(_enc, - _src+_frag_offs,_ref+_frag_offs+_dx+_dy*_ystride,_ystride,UINT_MAX); -} - -/*Perform a motion vector search for this macro block against a single - reference frame. - As a bonus, individual block motion vectors are computed as well, as much of - the work can be shared. - The actual motion vector is stored in the appropriate place in the - oc_mb_enc_info structure. - _mcenc: The motion compensation context. - _accum: Drop frame/golden MV accumulators. - _mbi: The macro block index. - _frame: The frame to search, either OC_FRAME_PREV or OC_FRAME_GOLD.*/ -void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame){ - /*Note: Traditionally this search is done using a rate-distortion objective - function of the form D+lambda*R. - However, xiphmont tested this and found it produced a small degredation, - while requiring extra computation. - This is most likely due to Theora's peculiar MV encoding scheme: MVs are - not coded relative to a predictor, and the only truly cheap way to use a - MV is in the LAST or LAST2 MB modes, which are not being considered here. - Therefore if we use the MV found here, it's only because both LAST and - LAST2 performed poorly, and therefore the MB is not likely to be uniform - or suffer from the aperture problem. - Furthermore we would like to re-use the MV found here for as many MBs as - possible, so picking a slightly sub-optimal vector to save a bit or two - may cause increased degredation in many blocks to come. - We could artificially reduce lambda to compensate, but it's faster to just - disable it entirely, and use D (the distortion) as the sole criterion.*/ - oc_mcenc_ctx mcenc; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *fragis; - const unsigned char *src; - const unsigned char *ref; - int ystride; - oc_mb_enc_info *embs; - ogg_int32_t hit_cache[31]; - ogg_int32_t hitbit; - unsigned best_block_err[4]; - unsigned block_err[4]; - unsigned best_err; - int best_vec[2]; - int best_block_vec[4][2]; - int candx; - int candy; - int bi; - embs=_enc->mb_info; - /*Find some candidate motion vectors.*/ - oc_mcenc_find_candidates(_enc,&mcenc,_accum,_mbi,_frame); - /*Clear the cache of locations we've examined.*/ - memset(hit_cache,0,sizeof(hit_cache)); - /*Start with the median predictor.*/ - candx=mcenc.candidates[0][0]; - candy=mcenc.candidates[0][1]; - hit_cache[candy+15]|=(ogg_int32_t)1<state.frag_buf_offs; - fragis=_enc->state.mb_maps[_mbi][0]; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[_frame]]; - ystride=_enc->state.ref_ystride[0]; - /*TODO: customize error function for speed/(quality+size) tradeoff.*/ - best_err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc, - frag_buf_offs,fragis,candx,candy,src,ref,ystride,block_err); - best_vec[0]=candx; - best_vec[1]=candy; - if(_frame==OC_FRAME_PREV){ - for(bi=0;bi<4;bi++){ - best_block_err[bi]=block_err[bi]; - best_block_vec[bi][0]=candx; - best_block_vec[bi][1]=candy; - } - } - /*If this predictor fails, move on to set A.*/ - if(best_err>OC_YSAD_THRESH1){ - unsigned err; - unsigned t2; - int ncs; - int ci; - /*Compute the early termination threshold for set A.*/ - t2=embs[_mbi].error[_frame]; - ncs=OC_MINI(3,embs[_mbi].ncneighbors); - for(ci=0;ci>OC_YSAD_THRESH2_SCALE_BITS)+OC_YSAD_THRESH2_OFFSET; - /*Examine the candidates in set A.*/ - for(ci=1;cit2){ - /*Examine the candidates in set B.*/ - for(;cit2){ - int best_site; - int nsites; - int sitei; - int site; - int b; - /*Square pattern search.*/ - for(;;){ - best_site=4; - /*Compose the bit flags for boundary conditions.*/ - b=OC_DIV16(-best_vec[0]+1)|OC_DIV16(best_vec[0]+1)<<1| - OC_DIV16(-best_vec[1]+1)<<2|OC_DIV16(best_vec[1]+1)<<3; - nsites=OC_SQUARE_NSITES[b]; - for(sitei=0;sitei>=2; - for(bi=0;bi<4;bi++){ - if(best_block_err[bi]>t2){ - /*Square pattern search. - We do this in a slightly interesting manner. - We continue to check the SAD of all four blocks in the - macro block. - This gives us two things: - 1) We can continue to use the hit_cache to avoid duplicate - checks. - Otherwise we could continue to read it, but not write to it - without saving and restoring it for each block. - Note that we could still eliminate a large number of - duplicate checks by taking into account the site we came - from when choosing the site list. - We can still do that to avoid extra hit_cache queries, and - it might even be a speed win. - 2) It gives us a slightly better chance of escaping local - minima. - We would not be here if we weren't doing a fairly bad job - in finding a good vector, and checking these vectors can - save us from 100 to several thousand points off our SAD 1 - in 15 times. - TODO: Is this a good idea? - Who knows. - It needs more testing.*/ - for(;;){ - int bestx; - int besty; - int bj; - bestx=best_block_vec[bi][0]; - besty=best_block_vec[bi][1]; - /*Compose the bit flags for boundary conditions.*/ - b=OC_DIV16(-bestx+1)|OC_DIV16(bestx+1)<<1| - OC_DIV16(-besty+1)<<2|OC_DIV16(besty+1)<<3; - nsites=OC_SQUARE_NSITES[b]; - for(sitei=0;siteimb_info[_mbi].analysis_mv; - if(_enc->prevframe_dropped){ - accum_p[0]=mvs[0][OC_FRAME_PREV][0]; - accum_p[1]=mvs[0][OC_FRAME_PREV][1]; - } - else accum_p[1]=accum_p[0]=0; - accum_g[0]=mvs[2][OC_FRAME_GOLD][0]; - accum_g[1]=mvs[2][OC_FRAME_GOLD][1]; - mvs[0][OC_FRAME_PREV][0]-=mvs[2][OC_FRAME_PREV][0]; - mvs[0][OC_FRAME_PREV][1]-=mvs[2][OC_FRAME_PREV][1]; - /*Move the motion vector predictors back a frame.*/ - memmove(mvs+1,mvs,2*sizeof(*mvs)); - /*Search the last frame.*/ - oc_mcenc_search_frame(_enc,accum_p,_mbi,OC_FRAME_PREV); - mvs[2][OC_FRAME_PREV][0]=accum_p[0]; - mvs[2][OC_FRAME_PREV][1]=accum_p[1]; - /*GOLDEN MVs are different from PREV MVs in that they're each absolute - offsets from some frame in the past rather than relative offsets from the - frame before. - For predictor calculation to make sense, we need them to be in the same - form as PREV MVs.*/ - mvs[1][OC_FRAME_GOLD][0]-=mvs[2][OC_FRAME_GOLD][0]; - mvs[1][OC_FRAME_GOLD][1]-=mvs[2][OC_FRAME_GOLD][1]; - mvs[2][OC_FRAME_GOLD][0]-=accum_g[0]; - mvs[2][OC_FRAME_GOLD][1]-=accum_g[1]; - /*Search the golden frame.*/ - oc_mcenc_search_frame(_enc,accum_g,_mbi,OC_FRAME_GOLD); - /*Put GOLDEN MVs back into absolute offset form. - The newest MV is already an absolute offset.*/ - mvs[2][OC_FRAME_GOLD][0]+=accum_g[0]; - mvs[2][OC_FRAME_GOLD][1]+=accum_g[1]; - mvs[1][OC_FRAME_GOLD][0]+=mvs[2][OC_FRAME_GOLD][0]; - mvs[1][OC_FRAME_GOLD][1]+=mvs[2][OC_FRAME_GOLD][1]; -} - -#if 0 -static int oc_mcenc_ysad_halfpel_mbrefine(const oc_enc_ctx *_enc,int _mbi, - int _vec[2],int _best_err,int _frame){ - const unsigned char *src; - const unsigned char *ref; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *fragis; - int offset_y[9]; - int ystride; - int mvoffset_base; - int best_site; - int sitei; - int err; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[_framei]]; - frag_buf_offs=_enc->state.frag_buf_offs; - fragis=_enc->state.mb_maps[_mbi][0]; - ystride=_enc->state.ref_ystride[0]; - mvoffset_base=_vec[0]+_vec[1]*ystride; - offset_y[0]=offset_y[1]=offset_y[2]=-ystride; - offset_y[3]=offset_y[5]=0; - offset_y[6]=offset_y[7]=offset_y[8]=ystride; - best_site=4; - for(sitei=0;sitei<8;sitei++){ - int site; - int xmask; - int ymask; - int dx; - int dy; - int mvoffset0; - int mvoffset1; - site=OC_SQUARE_SITES[0][sitei]; - dx=OC_SQUARE_DX[site]; - dy=OC_SQUARE_DY[site]; - /*The following code SHOULD be equivalent to - oc_state_get_mv_offsets(&_mcenc->enc.state,&mvoffset0,&mvoffset1, - (_vec[0]<<1)+dx,(_vec[1]<<1)+dy,ref_ystride,0); - However, it should also be much faster, as it involves no multiplies and - doesn't have to handle chroma vectors.*/ - xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx); - ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy); - mvoffset0=mvoffset_base+(dx&xmask)+(offset_y[site]&ymask); - mvoffset1=mvoffset_base+(dx&~xmask)+(offset_y[site]&~ymask); - err=oc_sad16_halfpel(_enc,frag_buf_offs,fragis, - mvoffset0,mvoffset1,src,ref,ystride,_best_err); - if(err<_best_err){ - _best_err=err; - best_site=site; - } - } - _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site]; - _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site]; - return _best_err; -} -#endif - -static unsigned oc_mcenc_ysatd_halfpel_mbrefine(const oc_enc_ctx *_enc, - int _mbi,int _vec[2],unsigned _best_err,int _frame){ - const unsigned char *src; - const unsigned char *ref; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *fragis; - int offset_y[9]; - int ystride; - int mvoffset_base; - int best_site; - int sitei; - int err; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[_frame]]; - frag_buf_offs=_enc->state.frag_buf_offs; - fragis=_enc->state.mb_maps[_mbi][0]; - ystride=_enc->state.ref_ystride[0]; - mvoffset_base=_vec[0]+_vec[1]*ystride; - offset_y[0]=offset_y[1]=offset_y[2]=-ystride; - offset_y[3]=offset_y[5]=0; - offset_y[6]=offset_y[7]=offset_y[8]=ystride; - best_site=4; - for(sitei=0;sitei<8;sitei++){ - int site; - int xmask; - int ymask; - int dx; - int dy; - int mvoffset0; - int mvoffset1; - site=OC_SQUARE_SITES[0][sitei]; - dx=OC_SQUARE_DX[site]; - dy=OC_SQUARE_DY[site]; - /*The following code SHOULD be equivalent to - oc_state_get_mv_offsets(&_mcenc->enc.state,&mvoffset0,&mvoffset1, - (_vec[0]<<1)+dx,(_vec[1]<<1)+dy,ref_ystride,0); - However, it should also be much faster, as it involves no multiplies and - doesn't have to handle chroma vectors.*/ - xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx); - ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy); - mvoffset0=mvoffset_base+(dx&xmask)+(offset_y[site]&ymask); - mvoffset1=mvoffset_base+(dx&~xmask)+(offset_y[site]&~ymask); - err=oc_satd16_halfpel(_enc,frag_buf_offs,fragis, - mvoffset0,mvoffset1,src,ref,ystride,_best_err); - if(err<_best_err){ - _best_err=err; - best_site=site; - } - } - _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site]; - _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site]; - return _best_err; -} - -void oc_mcenc_refine1mv(oc_enc_ctx *_enc,int _mbi,int _frame){ - oc_mb_enc_info *embs; - int vec[2]; - embs=_enc->mb_info; - vec[0]=OC_DIV2(embs[_mbi].analysis_mv[0][_frame][0]); - vec[1]=OC_DIV2(embs[_mbi].analysis_mv[0][_frame][1]); - embs[_mbi].satd[_frame]=oc_mcenc_ysatd_halfpel_mbrefine(_enc, - _mbi,vec,embs[_mbi].satd[_frame],_frame); - embs[_mbi].analysis_mv[0][_frame][0]=(signed char)vec[0]; - embs[_mbi].analysis_mv[0][_frame][1]=(signed char)vec[1]; -} - -#if 0 -static int oc_mcenc_ysad_halfpel_brefine(const oc_enc_ctx *_enc, - int _vec[2],const unsigned char *_src,const unsigned char *_ref,int _ystride, - int _offset_y[9],unsigned _best_err){ - int mvoffset_base; - int best_site; - int sitei; - mvoffset_base=_vec[0]+_vec[1]*_ystride; - best_site=4; - for(sitei=0;sitei<8;sitei++){ - unsigned err; - int site; - int xmask; - int ymask; - int dx; - int dy; - int mvoffset0; - int mvoffset1; - site=OC_SQUARE_SITES[0][sitei]; - dx=OC_SQUARE_DX[site]; - dy=OC_SQUARE_DY[site]; - /*The following code SHOULD be equivalent to - oc_state_get_mv_offsets(&_mcenc->enc.state,&mvoffset0,&mvoffset1, - (_vec[0]<<1)+dx,(_vec[1]<<1)+dy,ref_ystride,0); - However, it should also be much faster, as it involves no multiplies and - doesn't have to handle chroma vectors.*/ - xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx); - ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy); - mvoffset0=mvoffset_base+(dx&xmask)+(_offset_y[site]&ymask); - mvoffset1=mvoffset_base+(dx&~xmask)+(_offset_y[site]&~ymask); - err=oc_enc_frag_sad2_thresh(_enc,_src, - _ref+mvoffset0,_ref+mvoffset1,ystride,_best_err); - if(err<_best_err){ - _best_err=err; - best_site=site; - } - } - _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site]; - _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site]; - return _best_err; -} -#endif - -static unsigned oc_mcenc_ysatd_halfpel_brefine(const oc_enc_ctx *_enc, - int _vec[2],const unsigned char *_src,const unsigned char *_ref,int _ystride, - int _offset_y[9],unsigned _best_err){ - int mvoffset_base; - int best_site; - int sitei; - mvoffset_base=_vec[0]+_vec[1]*_ystride; - best_site=4; - for(sitei=0;sitei<8;sitei++){ - unsigned err; - int site; - int xmask; - int ymask; - int dx; - int dy; - int mvoffset0; - int mvoffset1; - site=OC_SQUARE_SITES[0][sitei]; - dx=OC_SQUARE_DX[site]; - dy=OC_SQUARE_DY[site]; - /*The following code SHOULD be equivalent to - oc_state_get_mv_offsets(&_enc->state,&mvoffsets,0, - (_vec[0]<<1)+dx,(_vec[1]<<1)+dy); - However, it should also be much faster, as it involves no multiplies and - doesn't have to handle chroma vectors.*/ - xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx); - ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy); - mvoffset0=mvoffset_base+(dx&xmask)+(_offset_y[site]&ymask); - mvoffset1=mvoffset_base+(dx&~xmask)+(_offset_y[site]&~ymask); - err=oc_enc_frag_satd2_thresh(_enc,_src, - _ref+mvoffset0,_ref+mvoffset1,_ystride,_best_err); - if(err<_best_err){ - _best_err=err; - best_site=site; - } - } - _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site]; - _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site]; - return _best_err; -} - -void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi){ - oc_mb_enc_info *embs; - const ptrdiff_t *frag_buf_offs; - const ptrdiff_t *fragis; - const unsigned char *src; - const unsigned char *ref; - int offset_y[9]; - int ystride; - int bi; - ystride=_enc->state.ref_ystride[0]; - frag_buf_offs=_enc->state.frag_buf_offs; - fragis=_enc->state.mb_maps[_mbi][0]; - src=_enc->state.ref_frame_data[OC_FRAME_IO]; - ref=_enc->state.ref_frame_data[_enc->state.ref_frame_idx[OC_FRAME_PREV]]; - offset_y[0]=offset_y[1]=offset_y[2]=-ystride; - offset_y[3]=offset_y[5]=0; - offset_y[6]=offset_y[7]=offset_y[8]=ystride; - embs=_enc->mb_info; - for(bi=0;bi<4;bi++){ - ptrdiff_t frag_offs; - int vec[2]; - frag_offs=frag_buf_offs[fragis[bi]]; - vec[0]=OC_DIV2(embs[_mbi].block_mv[bi][0]); - vec[1]=OC_DIV2(embs[_mbi].block_mv[bi][1]); - embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_halfpel_brefine(_enc,vec, - src+frag_offs,ref+frag_offs,ystride,offset_y,embs[_mbi].block_satd[bi]); - embs[_mbi].ref_mv[bi][0]=(signed char)vec[0]; - embs[_mbi].ref_mv[bi][1]=(signed char)vec[1]; - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/modedec.h b/src/add-ons/media/plugins/theora/libtheora/modedec.h deleted file mode 100644 index ea12c64afd..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/modedec.h +++ /dev/null @@ -1,4027 +0,0 @@ -/*File generated by libtheora with OC_COLLECT_METRICS defined at compile time.*/ -#if !defined(_modedec_H) -# define _modedec_H (1) - - - -# if defined(OC_COLLECT_METRICS) -typedef struct oc_mode_metrics oc_mode_metrics; -# endif -typedef struct oc_mode_rd oc_mode_rd; - - - -/*The number of extra bits of precision at which to store rate metrics.*/ -# define OC_BIT_SCALE (6) -/*The number of extra bits of precision at which to store RMSE metrics. - This must be at least half OC_BIT_SCALE (rounded up).*/ -# define OC_RMSE_SCALE (5) -/*The number of bins to partition statistics into.*/ -# define OC_SAD_BINS (24) -/*The number of bits of precision to drop from SAD scores to assign them to a - bin.*/ -# define OC_SAD_SHIFT (9) - - - -# if defined(OC_COLLECT_METRICS) -struct oc_mode_metrics{ - double fragw; - double satd; - double rate; - double rmse; - double satd2; - double satdrate; - double rate2; - double satdrmse; - double rmse2; -}; - - -int oc_has_mode_metrics; -oc_mode_metrics OC_MODE_METRICS[64][3][2][OC_SAD_BINS]; -# endif - - - -struct oc_mode_rd{ - ogg_int16_t rate; - ogg_int16_t rmse; -}; - - -# if !defined(OC_COLLECT_METRICS) -static const -# endif -oc_mode_rd OC_MODE_RD[64][3][2][OC_SAD_BINS]={ - { - { - /*Y' qi=0 INTRA*/ - { - { 87, -66},{ 132, 1611},{ 197, 3474},{ 285, 5130}, - { 376, 6419},{ 450, 7545},{ 521, 8587},{ 600, 9587}, - { 689,10498},{ 790,11348},{ 899,12158},{ 1030,12855}, - { 1166,13459},{ 1276,14052},{ 1353,14732},{ 1444,15425}, - { 1535,16101},{ 1609,16856},{ 1697,17532},{ 1823,17995}, - { 1962,18426},{ 2085,18919},{ 2201,19503},{ 2304,20307} - }, - /*Y' qi=0 INTER*/ - { - { 32, -105},{ 40, 1268},{ 54, 2919},{ 91, 4559}, - { 118, 6244},{ 132, 7932},{ 142, 9514},{ 149,10989}, - { 155,12375},{ 161,13679},{ 168,14958},{ 176,16215}, - { 187,17431},{ 196,18623},{ 207,19790},{ 218,20941}, - { 230,22083},{ 246,23213},{ 265,24333},{ 292,25439}, - { 328,26512},{ 372,27538},{ 427,28522},{ 494,29479} - } - }, - { - /*Cb qi=0 INTRA*/ - { - { 1, 6},{ 27, 368},{ 52, 738},{ 67, 1171}, - { 80, 1642},{ 99, 2134},{ 110, 2642},{ 112, 3144}, - { 126, 3578},{ 154, 3967},{ 167, 4387},{ 172, 4839}, - { 191, 5278},{ 208, 5666},{ 220, 6036},{ 223, 6398}, - { 227, 6814},{ 253, 7157},{ 284, 7403},{ 292, 7699}, - { 314, 7983},{ 339, 8203},{ 363, 8460},{ 399, 8919} - }, - /*Cb qi=0 INTER*/ - { - { 68, -55},{ 63, 275},{ 58, 602},{ 53, 936}, - { 50, 1290},{ 54, 1691},{ 58, 2116},{ 62, 2553}, - { 67, 2992},{ 72, 3422},{ 78, 3843},{ 84, 4253}, - { 89, 4658},{ 94, 5062},{ 98, 5455},{ 100, 5848}, - { 102, 6231},{ 104, 6604},{ 104, 6982},{ 105, 7359}, - { 105, 7733},{ 104, 8104},{ 105, 8465},{ 111, 8828} - } - }, - { - /*Cr qi=0 INTRA*/ - { - { 1, 8},{ 23, 375},{ 47, 759},{ 63, 1220}, - { 71, 1693},{ 82, 2171},{ 94, 2652},{ 109, 3103}, - { 125, 3567},{ 133, 3995},{ 151, 4375},{ 168, 4819}, - { 174, 5244},{ 190, 5635},{ 215, 6005},{ 242, 6347}, - { 257, 6758},{ 280, 7068},{ 311, 7336},{ 326, 7652}, - { 346, 7968},{ 372, 8213},{ 388, 8515},{ 408, 9060} - }, - /*Cr qi=0 INTER*/ - { - { 69, 0},{ 60, 314},{ 49, 624},{ 45, 943}, - { 45, 1285},{ 49, 1691},{ 55, 2130},{ 62, 2560}, - { 71, 2973},{ 79, 3385},{ 85, 3800},{ 89, 4207}, - { 92, 4620},{ 95, 5037},{ 96, 5436},{ 97, 5839}, - { 98, 6252},{ 99, 6653},{ 99, 7038},{ 103, 7426}, - { 107, 7810},{ 108, 8178},{ 107, 8539},{ 106, 8937} - } - } - }, - { - { - /*Y' qi=1 INTRA*/ - { - { 81, -71},{ 133, 1610},{ 203, 3460},{ 296, 5083}, - { 392, 6342},{ 467, 7454},{ 541, 8486},{ 625, 9466}, - { 716,10352},{ 823,11181},{ 940,11961},{ 1074,12643}, - { 1211,13233},{ 1324,13807},{ 1408,14489},{ 1504,15167}, - { 1598,15824},{ 1679,16544},{ 1788,17161},{ 1928,17579}, - { 2070,17991},{ 2202,18456},{ 2324,19021},{ 2425,19894} - }, - /*Y' qi=1 INTER*/ - { - { 34, 4},{ 40, 1307},{ 55, 2914},{ 93, 4555}, - { 120, 6243},{ 134, 7912},{ 144, 9468},{ 152,10918}, - { 158,12275},{ 164,13569},{ 171,14846},{ 180,16098}, - { 191,17310},{ 204,18484},{ 216,19636},{ 228,20779}, - { 242,21912},{ 261,23036},{ 286,24146},{ 320,25221}, - { 363,26265},{ 418,27261},{ 485,28203},{ 551,29148} - } - }, - { - /*Cb qi=1 INTRA*/ - { - { 1, 6},{ 28, 367},{ 52, 738},{ 68, 1172}, - { 86, 1644},{ 106, 2135},{ 115, 2642},{ 119, 3141}, - { 132, 3569},{ 157, 3951},{ 172, 4366},{ 177, 4819}, - { 194, 5258},{ 211, 5638},{ 224, 6006},{ 233, 6367}, - { 236, 6784},{ 258, 7121},{ 299, 7357},{ 319, 7637}, - { 337, 7921},{ 358, 8141},{ 381, 8367},{ 401, 8768} - }, - /*Cb qi=1 INTER*/ - { - { 95, -31},{ 81, 295},{ 67, 614},{ 53, 953}, - { 48, 1305},{ 51, 1700},{ 56, 2125},{ 61, 2563}, - { 67, 3008},{ 73, 3435},{ 79, 3844},{ 85, 4251}, - { 90, 4663},{ 95, 5073},{ 98, 5458},{ 100, 5844}, - { 101, 6231},{ 102, 6606},{ 102, 6980},{ 103, 7347}, - { 104, 7726},{ 105, 8096},{ 105, 8453},{ 105, 8789} - } - }, - { - /*Cr qi=1 INTRA*/ - { - { 1, 8},{ 25, 375},{ 50, 759},{ 65, 1221}, - { 74, 1695},{ 86, 2172},{ 101, 2651},{ 117, 3101}, - { 129, 3561},{ 135, 3985},{ 153, 4368},{ 171, 4807}, - { 182, 5223},{ 202, 5608},{ 225, 5964},{ 251, 6300}, - { 271, 6697},{ 295, 6978},{ 324, 7235},{ 348, 7558}, - { 367, 7877},{ 394, 8101},{ 413, 8386},{ 409, 8945} - }, - /*Cr qi=1 INTER*/ - { - { 66, 11},{ 59, 323},{ 51, 631},{ 44, 949}, - { 44, 1292},{ 49, 1703},{ 56, 2140},{ 62, 2566}, - { 69, 2991},{ 77, 3397},{ 84, 3799},{ 89, 4211}, - { 93, 4634},{ 94, 5049},{ 95, 5444},{ 96, 5854}, - { 94, 6260},{ 95, 6640},{ 96, 7032},{ 101, 7423}, - { 104, 7790},{ 105, 8158},{ 109, 8527},{ 108, 8872} - } - } - }, - { - { - /*Y' qi=2 INTRA*/ - { - { 87, -72},{ 139, 1607},{ 213, 3426},{ 315, 4992}, - { 416, 6217},{ 495, 7315},{ 574, 8317},{ 666, 9265}, - { 763,10124},{ 875,10906},{ 1001,11654},{ 1147,12305}, - { 1289,12865},{ 1407,13424},{ 1503,14076},{ 1610,14724}, - { 1720,15342},{ 1815,16020},{ 1937,16579},{ 2084,16981}, - { 2236,17371},{ 2385,17779},{ 2536,18250},{ 2689,18931} - }, - /*Y' qi=2 INTER*/ - { - { 30, -2},{ 40, 1308},{ 57, 2921},{ 96, 4567}, - { 122, 6260},{ 136, 7902},{ 148, 9418},{ 156,10826}, - { 162,12157},{ 169,13448},{ 177,14709},{ 188,15938}, - { 200,17133},{ 213,18295},{ 228,19433},{ 245,20564}, - { 264,21685},{ 289,22790},{ 323,23876},{ 368,24916}, - { 427,25906},{ 499,26837},{ 585,27700},{ 680,28514} - } - }, - { - /*Cb qi=2 INTRA*/ - { - { 1, 6},{ 30, 367},{ 58, 738},{ 77, 1172}, - { 93, 1645},{ 111, 2137},{ 123, 2642},{ 126, 3133}, - { 136, 3553},{ 162, 3934},{ 178, 4352},{ 183, 4803}, - { 199, 5231},{ 220, 5596},{ 235, 5957},{ 245, 6314}, - { 256, 6718},{ 286, 7048},{ 320, 7285},{ 336, 7568}, - { 366, 7829},{ 387, 8045},{ 405, 8261},{ 445, 8550} - }, - /*Cb qi=2 INTER*/ - { - { 115, -61},{ 93, 277},{ 71, 609},{ 54, 963}, - { 49, 1329},{ 53, 1715},{ 58, 2138},{ 63, 2583}, - { 69, 3017},{ 75, 3442},{ 81, 3857},{ 88, 4263}, - { 93, 4667},{ 96, 5065},{ 101, 5451},{ 101, 5832}, - { 102, 6213},{ 103, 6593},{ 103, 6968},{ 104, 7336}, - { 104, 7710},{ 105, 8076},{ 106, 8440},{ 106, 8822} - } - }, - { - /*Cr qi=2 INTRA*/ - { - { 1, 8},{ 27, 375},{ 54, 759},{ 70, 1222}, - { 79, 1696},{ 89, 2173},{ 106, 2652},{ 123, 3098}, - { 135, 3553},{ 143, 3972},{ 161, 4348},{ 181, 4782}, - { 194, 5189},{ 213, 5565},{ 235, 5907},{ 266, 6229}, - { 286, 6618},{ 311, 6897},{ 339, 7152},{ 362, 7454}, - { 392, 7721},{ 416, 7946},{ 429, 8227},{ 458, 8540} - }, - /*Cr qi=2 INTER*/ - { - { 74, 20},{ 63, 330},{ 51, 635},{ 44, 942}, - { 47, 1287},{ 54, 1710},{ 59, 2147},{ 65, 2571}, - { 72, 2996},{ 79, 3413},{ 86, 3820},{ 91, 4230}, - { 93, 4642},{ 95, 5046},{ 95, 5442},{ 95, 5839}, - { 96, 6243},{ 97, 6641},{ 99, 7021},{ 101, 7396}, - { 103, 7764},{ 106, 8138},{ 109, 8507},{ 114, 8851} - } - } - }, - { - { - /*Y' qi=3 INTRA*/ - { - { 91, -67},{ 141, 1606},{ 219, 3405},{ 328, 4929}, - { 433, 6122},{ 515, 7209},{ 598, 8204},{ 693, 9145}, - { 796, 9986},{ 912,10756},{ 1045,11471},{ 1200,12079}, - { 1345,12640},{ 1471,13179},{ 1571,13809},{ 1678,14450}, - { 1798,15047},{ 1905,15701},{ 2043,16205},{ 2202,16569}, - { 2351,16971},{ 2501,17393},{ 2660,17851},{ 2825,18455} - }, - /*Y' qi=3 INTER*/ - { - { 53, -164},{ 38, 1314},{ 59, 2917},{ 99, 4563}, - { 124, 6253},{ 139, 7882},{ 150, 9375},{ 159,10749}, - { 166,12059},{ 173,13349},{ 183,14608},{ 194,15826}, - { 208,17003},{ 223,18150},{ 240,19287},{ 259,20411}, - { 284,21508},{ 317,22593},{ 359,23656},{ 414,24671}, - { 483,25634},{ 569,26519},{ 670,27332},{ 786,28072} - } - }, - { - /*Cb qi=3 INTRA*/ - { - { 1, 5},{ 31, 367},{ 58, 739},{ 78, 1173}, - { 96, 1645},{ 113, 2134},{ 125, 2638},{ 133, 3127}, - { 148, 3542},{ 171, 3915},{ 184, 4328},{ 192, 4776}, - { 209, 5197},{ 230, 5556},{ 245, 5909},{ 252, 6261}, - { 272, 6641},{ 304, 6942},{ 330, 7184},{ 342, 7477}, - { 380, 7736},{ 404, 7962},{ 428, 8151},{ 469, 8430} - }, - /*Cb qi=3 INTER*/ - { - { 86, -29},{ 72, 296},{ 58, 618},{ 46, 964}, - { 47, 1338},{ 51, 1743},{ 56, 2158},{ 63, 2594}, - { 69, 3035},{ 77, 3455},{ 84, 3859},{ 89, 4266}, - { 94, 4673},{ 98, 5074},{ 101, 5460},{ 101, 5842}, - { 101, 6217},{ 101, 6593},{ 102, 6964},{ 104, 7325}, - { 103, 7696},{ 103, 8056},{ 104, 8430},{ 103, 8792} - } - }, - { - /*Cr qi=3 INTRA*/ - { - { 1, 8},{ 27, 374},{ 56, 759},{ 74, 1221}, - { 83, 1696},{ 96, 2173},{ 113, 2650},{ 127, 3091}, - { 140, 3542},{ 151, 3960},{ 164, 4334},{ 188, 4764}, - { 208, 5144},{ 224, 5493},{ 250, 5841},{ 278, 6162}, - { 298, 6548},{ 334, 6816},{ 365, 7045},{ 388, 7343}, - { 419, 7613},{ 443, 7836},{ 455, 8105},{ 484, 8445} - }, - /*Cr qi=3 INTER*/ - { - { 76, 26},{ 65, 332},{ 53, 638},{ 45, 945}, - { 45, 1304},{ 53, 1725},{ 60, 2153},{ 68, 2584}, - { 74, 3007},{ 81, 3425},{ 87, 3844},{ 91, 4253}, - { 94, 4657},{ 95, 5061},{ 94, 5462},{ 94, 5856}, - { 95, 6250},{ 96, 6635},{ 97, 7014},{ 101, 7393}, - { 104, 7761},{ 106, 8137},{ 109, 8506},{ 111, 8823} - } - } - }, - { - { - /*Y' qi=4 INTRA*/ - { - { 80, -67},{ 143, 1603},{ 227, 3378},{ 344, 4861}, - { 454, 6026},{ 537, 7104},{ 626, 8089},{ 725, 9006}, - { 830, 9827},{ 950,10581},{ 1089,11270},{ 1257,11826}, - { 1409,12366},{ 1535,12912},{ 1640,13528},{ 1753,14173}, - { 1884,14756},{ 2007,15368},{ 2148,15852},{ 2307,16212}, - { 2464,16591},{ 2614,17019},{ 2785,17455},{ 2970,17963} - }, - /*Y' qi=4 INTER*/ - { - { 50, -145},{ 38, 1324},{ 61, 2921},{ 102, 4566}, - { 127, 6248},{ 142, 7845},{ 154, 9300},{ 163,10656}, - { 169,11965},{ 177,13246},{ 188,14495},{ 202,15702}, - { 218,16864},{ 236,18003},{ 256,19124},{ 278,20233}, - { 307,21330},{ 347,22398},{ 398,23437},{ 463,24429}, - { 546,25343},{ 649,26170},{ 767,26935},{ 888,27674} - } - }, - { - /*Cb qi=4 INTRA*/ - { - { 1, 5},{ 33, 367},{ 61, 739},{ 80, 1173}, - { 98, 1646},{ 114, 2136},{ 126, 2639},{ 137, 3124}, - { 152, 3535},{ 176, 3903},{ 194, 4307},{ 206, 4753}, - { 222, 5165},{ 242, 5508},{ 260, 5857},{ 272, 6205}, - { 294, 6559},{ 332, 6848},{ 356, 7104},{ 364, 7389}, - { 396, 7637},{ 415, 7878},{ 446, 8064},{ 506, 8294} - }, - /*Cb qi=4 INTER*/ - { - { 86, -15},{ 73, 308},{ 60, 627},{ 46, 967}, - { 47, 1343},{ 51, 1754},{ 56, 2183},{ 63, 2615}, - { 70, 3044},{ 79, 3459},{ 85, 3866},{ 90, 4276}, - { 94, 4686},{ 97, 5088},{ 100, 5467},{ 102, 5837}, - { 102, 6205},{ 101, 6569},{ 103, 6939},{ 104, 7317}, - { 105, 7690},{ 107, 8043},{ 107, 8394},{ 111, 8736} - } - }, - { - /*Cr qi=4 INTRA*/ - { - { 1, 7},{ 28, 375},{ 57, 759},{ 79, 1221}, - { 92, 1697},{ 105, 2174},{ 122, 2648},{ 135, 3085}, - { 146, 3530},{ 157, 3947},{ 171, 4316},{ 195, 4737}, - { 218, 5117},{ 239, 5445},{ 268, 5767},{ 295, 6074}, - { 315, 6460},{ 355, 6735},{ 392, 6933},{ 418, 7218}, - { 448, 7495},{ 471, 7688},{ 481, 7954},{ 504, 8313} - }, - /*Cr qi=4 INTER*/ - { - { 68, 28},{ 57, 334},{ 47, 639},{ 43, 953}, - { 48, 1314},{ 54, 1736},{ 59, 2169},{ 69, 2592}, - { 78, 3017},{ 84, 3434},{ 88, 3850},{ 92, 4260}, - { 95, 4663},{ 96, 5068},{ 95, 5455},{ 95, 5839}, - { 96, 6243},{ 97, 6626},{ 98, 7006},{ 101, 7390}, - { 104, 7755},{ 108, 8115},{ 111, 8471},{ 110, 8825} - } - } - }, - { - { - /*Y' qi=5 INTRA*/ - { - { 84, -69},{ 147, 1599},{ 237, 3350},{ 360, 4796}, - { 475, 5934},{ 562, 6992},{ 657, 7953},{ 765, 8837}, - { 874, 9641},{ 998,10384},{ 1146,11047},{ 1322,11572}, - { 1484,12076},{ 1617,12609},{ 1731,13203},{ 1856,13806}, - { 1995,14367},{ 2132,14936},{ 2289,15386},{ 2460,15721}, - { 2635,16066},{ 2802,16442},{ 2980,16805},{ 3177,17272} - }, - /*Y' qi=5 INTER*/ - { - { 38, -86},{ 37, 1349},{ 64, 2920},{ 105, 4563}, - { 129, 6236},{ 145, 7809},{ 158, 9236},{ 167,10572}, - { 174,11871},{ 182,13141},{ 195,14368},{ 212,15558}, - { 230,16706},{ 250,17828},{ 274,18944},{ 303,20041}, - { 342,21116},{ 394,22152},{ 460,23144},{ 543,24073}, - { 648,24919},{ 773,25673},{ 922,26323},{ 1084,26924} - } - }, - { - /*Cb qi=5 INTRA*/ - { - { 1, 5},{ 34, 367},{ 63, 739},{ 82, 1174}, - { 102, 1647},{ 119, 2137},{ 134, 2639},{ 145, 3121}, - { 161, 3529},{ 189, 3891},{ 207, 4290},{ 216, 4721}, - { 232, 5113},{ 258, 5455},{ 277, 5798},{ 294, 6124}, - { 322, 6427},{ 352, 6697},{ 370, 6982},{ 384, 7283}, - { 423, 7529},{ 448, 7766},{ 478, 7943},{ 527, 8151} - }, - /*Cb qi=5 INTER*/ - { - { 83, -49},{ 69, 284},{ 55, 611},{ 48, 961}, - { 49, 1355},{ 52, 1769},{ 58, 2191},{ 65, 2616}, - { 73, 3041},{ 80, 3460},{ 87, 3868},{ 92, 4276}, - { 95, 4682},{ 98, 5077},{ 100, 5459},{ 102, 5827}, - { 102, 6200},{ 102, 6568},{ 103, 6930},{ 103, 7303}, - { 104, 7672},{ 106, 8032},{ 106, 8391},{ 106, 8727} - } - }, - { - /*Cr qi=5 INTRA*/ - { - { 1, 8},{ 28, 375},{ 57, 760},{ 81, 1222}, - { 99, 1696},{ 111, 2175},{ 125, 2648},{ 140, 3079}, - { 152, 3520},{ 162, 3927},{ 179, 4294},{ 203, 4714}, - { 225, 5080},{ 254, 5389},{ 286, 5703},{ 318, 5997}, - { 342, 6364},{ 380, 6640},{ 416, 6837},{ 445, 7103}, - { 473, 7370},{ 497, 7562},{ 514, 7811},{ 549, 8148} - }, - /*Cr qi=5 INTER*/ - { - { 60, 6},{ 54, 323},{ 46, 638},{ 43, 958}, - { 45, 1329},{ 54, 1749},{ 61, 2175},{ 70, 2600}, - { 79, 3021},{ 85, 3437},{ 89, 3847},{ 93, 4254}, - { 95, 4660},{ 96, 5065},{ 95, 5456},{ 95, 5849}, - { 96, 6243},{ 96, 6621},{ 97, 6996},{ 101, 7366}, - { 104, 7722},{ 107, 8088},{ 111, 8448},{ 119, 8816} - } - } - }, - { - { - /*Y' qi=6 INTRA*/ - { - { 88, -69},{ 151, 1593},{ 251, 3294},{ 387, 4681}, - { 507, 5790},{ 601, 6837},{ 702, 7787},{ 813, 8648}, - { 927, 9427},{ 1059,10152},{ 1213,10787},{ 1399,11284}, - { 1568,11781},{ 1705,12312},{ 1823,12890},{ 1957,13482}, - { 2106,14036},{ 2249,14600},{ 2411,15042},{ 2588,15359}, - { 2772,15699},{ 2947,16062},{ 3127,16429},{ 3320,16849} - }, - /*Y' qi=6 INTER*/ - { - { 44, -80},{ 36, 1346},{ 69, 2919},{ 111, 4563}, - { 136, 6216},{ 154, 7746},{ 168, 9139},{ 178,10461}, - { 185,11747},{ 195,13007},{ 211,14229},{ 230,15408}, - { 250,16547},{ 274,17663},{ 302,18769},{ 339,19851}, - { 386,20907},{ 446,21933},{ 527,22884},{ 631,23746}, - { 760,24512},{ 914,25178},{ 1087,25758},{ 1278,26262} - } - }, - { - /*Cb qi=6 INTRA*/ - { - { 1, 4},{ 36, 367},{ 66, 739},{ 84, 1174}, - { 105, 1648},{ 126, 2139},{ 140, 2639},{ 149, 3116}, - { 164, 3523},{ 194, 3880},{ 217, 4271},{ 226, 4694}, - { 243, 5077},{ 270, 5407},{ 291, 5742},{ 310, 6061}, - { 340, 6340},{ 373, 6609},{ 394, 6890},{ 409, 7189}, - { 444, 7434},{ 469, 7652},{ 499, 7853},{ 559, 8135} - }, - /*Cb qi=6 INTER*/ - { - { 68, -46},{ 60, 291},{ 50, 623},{ 49, 971}, - { 50, 1357},{ 55, 1781},{ 61, 2211},{ 69, 2634}, - { 78, 3052},{ 86, 3466},{ 91, 3882},{ 95, 4292}, - { 98, 4691},{ 101, 5080},{ 102, 5458},{ 103, 5830}, - { 103, 6192},{ 104, 6554},{ 104, 6916},{ 106, 7278}, - { 108, 7641},{ 110, 8004},{ 112, 8371},{ 112, 8758} - } - }, - { - /*Cr qi=6 INTRA*/ - { - { 1, 8},{ 29, 375},{ 59, 760},{ 84, 1223}, - { 99, 1698},{ 112, 2176},{ 129, 2647},{ 143, 3076}, - { 156, 3510},{ 168, 3906},{ 189, 4269},{ 220, 4682}, - { 241, 5047},{ 266, 5342},{ 299, 5649},{ 331, 5954}, - { 357, 6309},{ 393, 6579},{ 431, 6765},{ 467, 6997}, - { 501, 7276},{ 520, 7488},{ 525, 7749},{ 548, 8146} - }, - /*Cr qi=6 INTER*/ - { - { 94, 31},{ 69, 335},{ 47, 641},{ 43, 967}, - { 50, 1350},{ 57, 1772},{ 65, 2197},{ 74, 2625}, - { 83, 3043},{ 90, 3454},{ 94, 3867},{ 97, 4273}, - { 98, 4671},{ 99, 5068},{ 99, 5461},{ 98, 5857}, - { 98, 6245},{ 99, 6610},{ 103, 6975},{ 105, 7345}, - { 108, 7712},{ 111, 8073},{ 113, 8415},{ 119, 8768} - } - } - }, - { - { - /*Y' qi=7 INTRA*/ - { - { 92, -70},{ 156, 1590},{ 261, 3267},{ 403, 4618}, - { 529, 5704},{ 628, 6730},{ 736, 7657},{ 856, 8491}, - { 978, 9246},{ 1118, 9943},{ 1281,10550},{ 1472,11028}, - { 1645,11507},{ 1793,12008},{ 1924,12565},{ 2067,13130}, - { 2229,13638},{ 2388,14160},{ 2558,14584},{ 2744,14886}, - { 2932,15194},{ 3116,15531},{ 3311,15858},{ 3538,16197} - }, - /*Y' qi=7 INTER*/ - { - { 43, -8},{ 36, 1351},{ 71, 2923},{ 112, 4568}, - { 138, 6201},{ 157, 7705},{ 171, 9083},{ 181,10390}, - { 189,11664},{ 202,12910},{ 220,14121},{ 241,15281}, - { 266,16401},{ 295,17507},{ 328,18608},{ 371,19677}, - { 430,20701},{ 508,21676},{ 604,22588},{ 727,23397}, - { 878,24093},{ 1055,24690},{ 1263,25151},{ 1496,25504} - } - }, - { - /*Cb qi=7 INTRA*/ - { - { 1, 5},{ 40, 367},{ 72, 740},{ 89, 1175}, - { 108, 1649},{ 129, 2140},{ 143, 2637},{ 154, 3110}, - { 169, 3507},{ 198, 3860},{ 224, 4237},{ 235, 4652}, - { 253, 5037},{ 282, 5358},{ 307, 5674},{ 329, 5986}, - { 361, 6273},{ 393, 6527},{ 419, 6777},{ 435, 7078}, - { 467, 7342},{ 495, 7554},{ 529, 7757},{ 591, 8053} - }, - /*Cb qi=7 INTER*/ - { - { 79, -33},{ 68, 299},{ 56, 627},{ 50, 978}, - { 51, 1366},{ 55, 1786},{ 61, 2213},{ 70, 2642}, - { 80, 3062},{ 87, 3474},{ 92, 3886},{ 96, 4292}, - { 99, 4684},{ 102, 5072},{ 103, 5450},{ 104, 5814}, - { 104, 6176},{ 104, 6538},{ 107, 6905},{ 110, 7270}, - { 110, 7625},{ 110, 7978},{ 111, 8340},{ 117, 8674} - } - }, - { - /*Cr qi=7 INTRA*/ - { - { 2, 7},{ 31, 375},{ 62, 760},{ 87, 1223}, - { 103, 1698},{ 115, 2175},{ 131, 2644},{ 147, 3066}, - { 161, 3494},{ 175, 3889},{ 199, 4250},{ 229, 4653}, - { 250, 5001},{ 279, 5275},{ 311, 5577},{ 343, 5889}, - { 376, 6227},{ 417, 6486},{ 457, 6689},{ 484, 6925}, - { 518, 7174},{ 544, 7393},{ 549, 7662},{ 577, 8050} - }, - /*Cr qi=7 INTER*/ - { - { 89, 22},{ 62, 332},{ 45, 641},{ 47, 976}, - { 52, 1363},{ 59, 1779},{ 67, 2203},{ 76, 2628}, - { 84, 3046},{ 90, 3460},{ 94, 3875},{ 98, 4272}, - { 99, 4666},{ 98, 5063},{ 98, 5459},{ 98, 5849}, - { 99, 6226},{ 101, 6594},{ 104, 6957},{ 109, 7324}, - { 109, 7686},{ 111, 8042},{ 115, 8379},{ 119, 8699} - } - } - }, - { - { - /*Y' qi=8 INTRA*/ - { - { 91, -69},{ 160, 1585},{ 274, 3226},{ 423, 4538}, - { 557, 5596},{ 664, 6595},{ 778, 7506},{ 905, 8319}, - { 1038, 9035},{ 1186, 9701},{ 1355,10292},{ 1554,10754}, - { 1739,11196},{ 1904,11639},{ 2047,12184},{ 2194,12763}, - { 2361,13256},{ 2529,13753},{ 2709,14155},{ 2902,14433}, - { 3100,14723},{ 3292,15026},{ 3489,15327},{ 3714,15705} - }, - /*Y' qi=8 INTER*/ - { - { 32, -157},{ 33, 1346},{ 74, 2914},{ 116, 4554}, - { 142, 6172},{ 162, 7648},{ 177, 9004},{ 186,10300}, - { 196,11570},{ 210,12808},{ 231,14001},{ 256,15150}, - { 285,16259},{ 319,17352},{ 359,18435},{ 415,19475}, - { 489,20470},{ 584,21400},{ 703,22246},{ 852,22968}, - { 1038,23556},{ 1253,24032},{ 1503,24367},{ 1778,24628} - } - }, - { - /*Cb qi=8 INTRA*/ - { - { 1, 4},{ 42, 367},{ 75, 740},{ 93, 1176}, - { 111, 1649},{ 128, 2139},{ 144, 2635},{ 157, 3103}, - { 174, 3494},{ 206, 3844},{ 233, 4207},{ 251, 4605}, - { 277, 4980},{ 304, 5284},{ 335, 5584},{ 359, 5888}, - { 393, 6152},{ 432, 6398},{ 455, 6656},{ 471, 6956}, - { 502, 7193},{ 528, 7405},{ 562, 7630},{ 603, 7922} - }, - /*Cb qi=8 INTER*/ - { - { 77, -37},{ 68, 299},{ 58, 632},{ 50, 991}, - { 50, 1382},{ 55, 1799},{ 62, 2226},{ 73, 2647}, - { 82, 3066},{ 90, 3480},{ 94, 3891},{ 96, 4296}, - { 98, 4687},{ 101, 5073},{ 103, 5456},{ 104, 5817}, - { 105, 6170},{ 106, 6523},{ 107, 6886},{ 108, 7250}, - { 109, 7600},{ 110, 7955},{ 111, 8305},{ 112, 8641} - } - }, - { - /*Cr qi=8 INTRA*/ - { - { 2, 7},{ 33, 375},{ 64, 760},{ 92, 1224}, - { 111, 1700},{ 122, 2173},{ 137, 2637},{ 156, 3055}, - { 172, 3476},{ 186, 3856},{ 211, 4211},{ 242, 4597}, - { 263, 4939},{ 292, 5214},{ 335, 5489},{ 376, 5772}, - { 406, 6099},{ 440, 6378},{ 483, 6578},{ 517, 6797}, - { 550, 7049},{ 571, 7283},{ 583, 7560},{ 618, 7967} - }, - /*Cr qi=8 INTER*/ - { - { 74, 25},{ 58, 328},{ 43, 637},{ 45, 980}, - { 51, 1371},{ 59, 1788},{ 69, 2207},{ 79, 2630}, - { 86, 3051},{ 91, 3470},{ 95, 3880},{ 97, 4280}, - { 98, 4680},{ 97, 5074},{ 96, 5456},{ 97, 5839}, - { 99, 6219},{ 101, 6583},{ 103, 6945},{ 106, 7312}, - { 110, 7671},{ 114, 8009},{ 115, 8345},{ 117, 8686} - } - } - }, - { - { - /*Y' qi=9 INTRA*/ - { - { 104, -68},{ 164, 1580},{ 288, 3173},{ 448, 4439}, - { 587, 5485},{ 702, 6465},{ 824, 7351},{ 958, 8148}, - { 1096, 8845},{ 1253, 9480},{ 1432,10047},{ 1640,10494}, - { 1835,10926},{ 2015,11350},{ 2166,11871},{ 2321,12428}, - { 2508,12876},{ 2684,13345},{ 2866,13741},{ 3069,13991}, - { 3281,14243},{ 3487,14518},{ 3689,14813},{ 3911,15175} - }, - /*Y' qi=9 INTER*/ - { - { 47, -140},{ 34, 1348},{ 77, 2915},{ 119, 4552}, - { 145, 6150},{ 166, 7600},{ 182, 8936},{ 192,10221}, - { 203,11482},{ 220,12711},{ 244,13886},{ 274,15012}, - { 308,16111},{ 349,17190},{ 401,18244},{ 470,19257}, - { 561,20209},{ 680,21069},{ 830,21822},{ 1010,22463}, - { 1227,22971},{ 1482,23328},{ 1769,23544},{ 2077,23655} - } - }, - { - /*Cb qi=9 INTRA*/ - { - { 1, 5},{ 43, 367},{ 76, 740},{ 95, 1176}, - { 114, 1649},{ 135, 2138},{ 153, 2629},{ 165, 3091}, - { 184, 3481},{ 217, 3831},{ 244, 4187},{ 260, 4572}, - { 290, 4930},{ 320, 5231},{ 351, 5521},{ 379, 5812}, - { 414, 6055},{ 452, 6307},{ 483, 6564},{ 502, 6848}, - { 525, 7115},{ 554, 7321},{ 589, 7533},{ 626, 7833} - }, - /*Cb qi=9 INTER*/ - { - { 101, -43},{ 81, 298},{ 62, 637},{ 49, 989}, - { 51, 1381},{ 56, 1806},{ 65, 2231},{ 74, 2653}, - { 84, 3071},{ 91, 3482},{ 95, 3892},{ 97, 4293}, - { 99, 4684},{ 101, 5066},{ 103, 5437},{ 103, 5793}, - { 103, 6148},{ 104, 6511},{ 105, 6867},{ 107, 7221}, - { 110, 7572},{ 111, 7926},{ 112, 8283},{ 116, 8625} - } - }, - { - /*Cr qi=9 INTRA*/ - { - { 2, 7},{ 35, 375},{ 66, 761},{ 93, 1224}, - { 112, 1700},{ 126, 2173},{ 144, 2633},{ 165, 3047}, - { 183, 3458},{ 199, 3835},{ 224, 4191},{ 257, 4558}, - { 283, 4887},{ 309, 5176},{ 351, 5446},{ 397, 5713}, - { 433, 6017},{ 469, 6283},{ 508, 6480},{ 546, 6687}, - { 579, 6945},{ 600, 7182},{ 610, 7434},{ 623, 7793} - }, - /*Cr qi=9 INTER*/ - { - { 77, 15},{ 57, 330},{ 45, 640},{ 48, 980}, - { 54, 1380},{ 61, 1802},{ 70, 2220},{ 80, 2639}, - { 87, 3057},{ 92, 3474},{ 94, 3882},{ 98, 4282}, - { 98, 4675},{ 97, 5062},{ 97, 5450},{ 98, 5829}, - { 100, 6197},{ 101, 6561},{ 104, 6927},{ 107, 7289}, - { 113, 7638},{ 117, 7978},{ 119, 8311},{ 117, 8629} - } - } - }, - { - { - /*Y' qi=10 INTRA*/ - { - { 101, -69},{ 168, 1574},{ 299, 3143},{ 465, 4386}, - { 610, 5410},{ 736, 6353},{ 866, 7207},{ 1006, 7982}, - { 1153, 8655},{ 1319, 9261},{ 1504, 9812},{ 1719,10248}, - { 1928,10653},{ 2116,11056},{ 2282,11550},{ 2458,12070}, - { 2654,12492},{ 2846,12923},{ 3043,13291},{ 3249,13537}, - { 3466,13764},{ 3682,13999},{ 3896,14268},{ 4145,14548} - }, - /*Y' qi=10 INTER*/ - { - { 48, -94},{ 34, 1355},{ 81, 2920},{ 124, 4545}, - { 151, 6113},{ 174, 7532},{ 190, 8850},{ 201,10125}, - { 214,11379},{ 235,12591},{ 264,13745},{ 299,14859}, - { 338,15948},{ 388,17008},{ 456,18029},{ 546,18988}, - { 661,19877},{ 808,20666},{ 993,21321},{ 1218,21835}, - { 1481,22203},{ 1783,22420},{ 2117,22504},{ 2469,22481} - } - }, - { - /*Cb qi=10 INTRA*/ - { - { 2, 4},{ 44, 367},{ 79, 740},{ 99, 1178}, - { 117, 1652},{ 137, 2141},{ 156, 2630},{ 170, 3089}, - { 192, 3474},{ 227, 3813},{ 259, 4157},{ 282, 4526}, - { 310, 4860},{ 342, 5140},{ 377, 5425},{ 400, 5714}, - { 436, 5952},{ 475, 6194},{ 496, 6468},{ 522, 6748}, - { 559, 6996},{ 587, 7216},{ 617, 7433},{ 673, 7678} - }, - /*Cb qi=10 INTER*/ - { - { 87, -37},{ 72, 301},{ 58, 636},{ 49, 995}, - { 51, 1394},{ 57, 1819},{ 66, 2241},{ 78, 2660}, - { 87, 3074},{ 93, 3482},{ 97, 3891},{ 99, 4294}, - { 101, 4678},{ 103, 5050},{ 105, 5414},{ 106, 5773}, - { 107, 6134},{ 108, 6485},{ 110, 6832},{ 113, 7187}, - { 113, 7547},{ 114, 7887},{ 117, 8230},{ 112, 8590} - } - }, - { - /*Cr qi=10 INTRA*/ - { - { 2, 7},{ 38, 375},{ 69, 761},{ 96, 1224}, - { 116, 1701},{ 131, 2175},{ 148, 2634},{ 168, 3041}, - { 190, 3439},{ 211, 3802},{ 238, 4151},{ 271, 4506}, - { 297, 4824},{ 331, 5103},{ 373, 5360},{ 415, 5632}, - { 459, 5928},{ 500, 6176},{ 535, 6386},{ 573, 6586}, - { 608, 6834},{ 629, 7079},{ 642, 7337},{ 686, 7680} - }, - /*Cr qi=10 INTER*/ - { - { 81, 34},{ 63, 333},{ 50, 633},{ 48, 987}, - { 53, 1397},{ 61, 1820},{ 71, 2237},{ 83, 2651}, - { 91, 3065},{ 95, 3479},{ 98, 3882},{ 100, 4279}, - { 101, 4673},{ 101, 5054},{ 100, 5429},{ 101, 5801}, - { 102, 6173},{ 104, 6541},{ 108, 6904},{ 110, 7264}, - { 114, 7609},{ 119, 7945},{ 123, 8275},{ 128, 8615} - } - } - }, - { - { - /*Y' qi=11 INTRA*/ - { - { 110, -66},{ 176, 1564},{ 316, 3087},{ 492, 4296}, - { 645, 5299},{ 781, 6217},{ 924, 7039},{ 1075, 7776}, - { 1232, 8421},{ 1410, 9005},{ 1607, 9532},{ 1834, 9929}, - { 2053,10300},{ 2249,10697},{ 2427,11184},{ 2619,11682}, - { 2826,12083},{ 3019,12508},{ 3225,12869},{ 3452,13064}, - { 3670,13280},{ 3890,13519},{ 4123,13750},{ 4367,14059} - }, - /*Y' qi=11 INTER*/ - { - { 72, -115},{ 32, 1354},{ 83, 2911},{ 126, 4534}, - { 154, 6080},{ 178, 7475},{ 194, 8779},{ 205,10047}, - { 222,11290},{ 246,12488},{ 281,13621},{ 322,14714}, - { 372,15786},{ 436,16821},{ 519,17813},{ 628,18728}, - { 770,19549},{ 950,20254},{ 1175,20800},{ 1443,21197}, - { 1752,21446},{ 2095,21555},{ 2457,21553},{ 2808,21544} - } - }, - { - /*Cb qi=11 INTRA*/ - { - { 2, 4},{ 45, 367},{ 81, 740},{ 101, 1177}, - { 121, 1650},{ 142, 2136},{ 159, 2621},{ 174, 3075}, - { 199, 3451},{ 234, 3778},{ 265, 4117},{ 297, 4473}, - { 333, 4789},{ 367, 5054},{ 402, 5319},{ 427, 5613}, - { 462, 5871},{ 503, 6107},{ 532, 6336},{ 560, 6584}, - { 601, 6842},{ 631, 7092},{ 662, 7292},{ 721, 7497} - }, - /*Cb qi=11 INTER*/ - { - { 117, -24},{ 93, 308},{ 69, 638},{ 52, 993}, - { 52, 1395},{ 58, 1822},{ 68, 2246},{ 80, 2665}, - { 89, 3082},{ 94, 3492},{ 96, 3900},{ 98, 4299}, - { 101, 4679},{ 103, 5047},{ 104, 5405},{ 106, 5763}, - { 106, 6120},{ 107, 6474},{ 109, 6823},{ 112, 7163}, - { 115, 7516},{ 117, 7868},{ 118, 8213},{ 119, 8561} - } - }, - { - /*Cr qi=11 INTRA*/ - { - { 2, 7},{ 40, 375},{ 75, 761},{ 100, 1224}, - { 119, 1700},{ 137, 2169},{ 154, 2622},{ 178, 3025}, - { 198, 3416},{ 220, 3770},{ 255, 4114},{ 294, 4459}, - { 323, 4756},{ 359, 5028},{ 399, 5292},{ 438, 5556}, - { 483, 5827},{ 518, 6073},{ 551, 6298},{ 598, 6501}, - { 634, 6754},{ 652, 6997},{ 670, 7211},{ 689, 7560} - }, - /*Cr qi=11 INTER*/ - { - { 75, 30},{ 61, 334},{ 51, 639},{ 49, 995}, - { 53, 1403},{ 62, 1821},{ 73, 2237},{ 84, 2654}, - { 91, 3070},{ 95, 3485},{ 96, 3890},{ 98, 4287}, - { 98, 4672},{ 99, 5050},{ 99, 5427},{ 100, 5798}, - { 103, 6169},{ 105, 6528},{ 107, 6881},{ 113, 7233}, - { 118, 7580},{ 121, 7916},{ 125, 8240},{ 130, 8551} - } - } - }, - { - { - /*Y' qi=12 INTRA*/ - { - { 104, -69},{ 182, 1557},{ 335, 3040},{ 521, 4205}, - { 684, 5178},{ 831, 6068},{ 986, 6854},{ 1151, 7559}, - { 1323, 8169},{ 1523, 8704},{ 1736, 9192},{ 1978, 9558}, - { 2213, 9908},{ 2421,10298},{ 2613,10757},{ 2822,11208}, - { 3042,11585},{ 3250,11991},{ 3474,12308},{ 3710,12480}, - { 3939,12687},{ 4174,12902},{ 4416,13102},{ 4672,13369} - }, - /*Y' qi=12 INTER*/ - { - { 52, -91},{ 34, 1355},{ 86, 2911},{ 129, 4518}, - { 159, 6037},{ 184, 7405},{ 200, 8694},{ 213, 9955}, - { 232,11185},{ 263,12360},{ 304,13479},{ 354,14555}, - { 415,15601},{ 495,16608},{ 601,17549},{ 738,18400}, - { 915,19136},{ 1139,19724},{ 1414,20150},{ 1731,20412}, - { 2090,20520},{ 2473,20509},{ 2851,20442},{ 3227,20328} - } - }, - { - /*Cb qi=12 INTRA*/ - { - { 1, 4},{ 46, 367},{ 85, 740},{ 109, 1178}, - { 126, 1650},{ 145, 2134},{ 165, 2617},{ 182, 3061}, - { 209, 3428},{ 245, 3749},{ 281, 4077},{ 316, 4417}, - { 354, 4718},{ 392, 4970},{ 430, 5217},{ 456, 5501}, - { 490, 5771},{ 534, 5996},{ 571, 6207},{ 600, 6458}, - { 644, 6697},{ 675, 6942},{ 707, 7151},{ 766, 7342} - }, - /*Cb qi=12 INTER*/ - { - { 84, -24},{ 73, 311},{ 60, 644},{ 52, 998}, - { 53, 1398},{ 60, 1825},{ 71, 2249},{ 83, 2665}, - { 90, 3081},{ 94, 3490},{ 97, 3893},{ 99, 4286}, - { 102, 4663},{ 104, 5032},{ 105, 5393},{ 106, 5751}, - { 107, 6102},{ 108, 6445},{ 111, 6788},{ 113, 7136}, - { 114, 7483},{ 117, 7828},{ 121, 8163},{ 122, 8496} - } - }, - { - /*Cr qi=12 INTRA*/ - { - { 3, 7},{ 41, 375},{ 78, 761},{ 106, 1225}, - { 124, 1700},{ 140, 2167},{ 163, 2616},{ 188, 3010}, - { 213, 3385},{ 240, 3718},{ 271, 4062},{ 309, 4406}, - { 345, 4691},{ 387, 4956},{ 430, 5212},{ 469, 5467}, - { 513, 5729},{ 554, 5970},{ 587, 6176},{ 633, 6395}, - { 673, 6659},{ 692, 6868},{ 712, 7061},{ 758, 7259} - }, - /*Cr qi=12 INTER*/ - { - { 73, 31},{ 59, 335},{ 48, 638},{ 50, 998}, - { 56, 1410},{ 65, 1827},{ 75, 2240},{ 85, 2657}, - { 92, 3073},{ 95, 3485},{ 97, 3888},{ 99, 4279}, - { 98, 4663},{ 99, 5042},{ 101, 5412},{ 102, 5779}, - { 105, 6142},{ 107, 6498},{ 108, 6848},{ 113, 7198}, - { 118, 7540},{ 121, 7867},{ 127, 8188},{ 132, 8508} - } - } - }, - { - { - /*Y' qi=13 INTRA*/ - { - { 109, -68},{ 187, 1551},{ 347, 3010},{ 541, 4153}, - { 709, 5107},{ 864, 5975},{ 1026, 6745},{ 1194, 7433}, - { 1375, 8021},{ 1581, 8550},{ 1803, 9026},{ 2054, 9371}, - { 2301, 9713},{ 2522,10082},{ 2728,10515},{ 2949,10956}, - { 3184,11297},{ 3408,11653},{ 3643,11946},{ 3886,12100}, - { 4124,12277},{ 4377,12459},{ 4632,12635},{ 4898,12861} - }, - /*Y' qi=13 INTER*/ - { - { 48, -78},{ 35, 1357},{ 89, 2914},{ 133, 4512}, - { 164, 6004},{ 190, 7348},{ 207, 8627},{ 222, 9881}, - { 247,11096},{ 284,12251},{ 333,13350},{ 392,14407}, - { 466,15426},{ 565,16391},{ 696,17279},{ 865,18058}, - { 1085,18689},{ 1358,19156},{ 1684,19456},{ 2050,19605}, - { 2447,19614},{ 2855,19524},{ 3243,19398},{ 3611,19201} - } - }, - { - /*Cb qi=13 INTRA*/ - { - { 2, 4},{ 47, 367},{ 86, 741},{ 108, 1179}, - { 127, 1651},{ 150, 2133},{ 173, 2611},{ 194, 3050}, - { 222, 3417},{ 262, 3733},{ 303, 4048},{ 337, 4375}, - { 378, 4657},{ 420, 4897},{ 456, 5148},{ 486, 5422}, - { 518, 5682},{ 558, 5903},{ 592, 6113},{ 623, 6372}, - { 662, 6628},{ 700, 6833},{ 751, 6989},{ 805, 7147} - }, - /*Cb qi=13 INTER*/ - { - { 94, -34},{ 78, 303},{ 60, 638},{ 51, 994}, - { 54, 1406},{ 61, 1836},{ 73, 2253},{ 84, 2668}, - { 92, 3082},{ 96, 3492},{ 99, 3894},{ 101, 4284}, - { 103, 4659},{ 105, 5023},{ 106, 5376},{ 108, 5726}, - { 109, 6070},{ 110, 6418},{ 113, 6765},{ 117, 7105}, - { 119, 7448},{ 122, 7784},{ 126, 8119},{ 131, 8463} - } - }, - { - /*Cr qi=13 INTRA*/ - { - { 3, 7},{ 43, 375},{ 80, 762},{ 110, 1226}, - { 131, 1701},{ 149, 2166},{ 172, 2610},{ 196, 2999}, - { 221, 3359},{ 254, 3679},{ 292, 4005},{ 332, 4329}, - { 369, 4612},{ 408, 4880},{ 456, 5139},{ 500, 5388}, - { 544, 5631},{ 581, 5877},{ 615, 6101},{ 660, 6316}, - { 692, 6594},{ 714, 6795},{ 736, 6997},{ 789, 7290} - }, - /*Cr qi=13 INTER*/ - { - { 73, 28},{ 61, 336},{ 46, 642},{ 50, 1003}, - { 58, 1414},{ 67, 1832},{ 79, 2245},{ 87, 2660}, - { 93, 3075},{ 97, 3484},{ 99, 3888},{ 100, 4277}, - { 100, 4651},{ 100, 5027},{ 101, 5403},{ 102, 5765}, - { 105, 6116},{ 109, 6470},{ 113, 6825},{ 119, 7163}, - { 124, 7497},{ 127, 7827},{ 131, 8137},{ 135, 8437} - } - } - }, - { - { - /*Y' qi=14 INTRA*/ - { - { 113, -68},{ 191, 1545},{ 358, 2981},{ 559, 4104}, - { 733, 5044},{ 896, 5890},{ 1066, 6636},{ 1241, 7304}, - { 1428, 7886},{ 1642, 8402},{ 1872, 8871},{ 2128, 9219}, - { 2380, 9547},{ 2609, 9908},{ 2825,10321},{ 3055,10728}, - { 3294,11076},{ 3523,11425},{ 3766,11689},{ 4013,11845}, - { 4254,12022},{ 4506,12209},{ 4759,12383},{ 5013,12637} - }, - /*Y' qi=14 INTER*/ - { - { 58, -82},{ 38, 1362},{ 93, 2914},{ 138, 4492}, - { 171, 5962},{ 198, 7289},{ 216, 8559},{ 234, 9804}, - { 263,11005},{ 306,12143},{ 363,13222},{ 434,14259}, - { 523,15255},{ 639,16188},{ 794,17021},{ 1000,17717}, - { 1262,18260},{ 1575,18645},{ 1943,18841},{ 2356,18872}, - { 2782,18802},{ 3194,18682},{ 3576,18559},{ 3923,18447} - } - }, - { - /*Cb qi=14 INTRA*/ - { - { 2, 3},{ 50, 367},{ 91, 741},{ 114, 1180}, - { 134, 1651},{ 157, 2131},{ 181, 2601},{ 208, 3028}, - { 239, 3391},{ 279, 3706},{ 322, 4000},{ 361, 4309}, - { 406, 4587},{ 445, 4822},{ 482, 5067},{ 515, 5344}, - { 546, 5612},{ 589, 5821},{ 626, 6020},{ 655, 6276}, - { 701, 6523},{ 748, 6717},{ 796, 6876},{ 815, 7151} - }, - /*Cb qi=14 INTER*/ - { - { 80, -43},{ 68, 301},{ 56, 644},{ 50, 1004}, - { 54, 1412},{ 63, 1836},{ 75, 2253},{ 87, 2670}, - { 94, 3083},{ 98, 3487},{ 101, 3885},{ 103, 4271}, - { 106, 4645},{ 107, 5004},{ 108, 5358},{ 109, 5705}, - { 112, 6047},{ 115, 6388},{ 118, 6731},{ 121, 7081}, - { 126, 7421},{ 129, 7747},{ 132, 8076},{ 137, 8419} - } - }, - { - /*Cr qi=14 INTRA*/ - { - { 3, 6},{ 45, 375},{ 85, 762},{ 116, 1226}, - { 138, 1700},{ 158, 2163},{ 180, 2602},{ 206, 2985}, - { 236, 3333},{ 270, 3639},{ 310, 3956},{ 359, 4258}, - { 397, 4524},{ 430, 4802},{ 478, 5068},{ 527, 5316}, - { 572, 5560},{ 613, 5802},{ 654, 6012},{ 699, 6216}, - { 734, 6489},{ 755, 6707},{ 775, 6898},{ 841, 7111} - }, - /*Cr qi=14 INTER*/ - { - { 78, 0},{ 59, 322},{ 46, 649},{ 51, 1016}, - { 58, 1422},{ 68, 1839},{ 81, 2253},{ 90, 2666}, - { 95, 3080},{ 98, 3486},{ 101, 3881},{ 102, 4268}, - { 102, 4644},{ 103, 5017},{ 105, 5382},{ 106, 5743}, - { 108, 6093},{ 112, 6442},{ 118, 6791},{ 124, 7130}, - { 127, 7463},{ 133, 7784},{ 138, 8085},{ 142, 8395} - } - } - }, - { - { - /*Y' qi=15 INTRA*/ - { - { 111, -66},{ 197, 1538},{ 370, 2949},{ 579, 4050}, - { 762, 4968},{ 933, 5798},{ 1112, 6520},{ 1299, 7161}, - { 1497, 7725},{ 1723, 8219},{ 1967, 8654},{ 2234, 8990}, - { 2499, 9302},{ 2740, 9637},{ 2968,10039},{ 3215,10414}, - { 3473,10709},{ 3721,11015},{ 3971,11270},{ 4228,11402}, - { 4487,11543},{ 4752,11707},{ 5011,11871},{ 5290,12099} - }, - /*Y' qi=15 INTER*/ - { - { 59, -113},{ 37, 1349},{ 95, 2904},{ 139, 4478}, - { 174, 5929},{ 201, 7244},{ 220, 8505},{ 241, 9736}, - { 275,10922},{ 327,12040},{ 395,13097},{ 477,14114}, - { 585,15071},{ 730,15947},{ 917,16714},{ 1162,17326}, - { 1468,17770},{ 1833,18029},{ 2251,18111},{ 2694,18068}, - { 3125,17968},{ 3529,17845},{ 3908,17713},{ 4260,17587} - } - }, - { - /*Cb qi=15 INTRA*/ - { - { 2, 3},{ 51, 367},{ 94, 741},{ 120, 1180}, - { 140, 1651},{ 160, 2129},{ 184, 2591},{ 213, 3010}, - { 246, 3371},{ 289, 3680},{ 335, 3969},{ 374, 4274}, - { 418, 4546},{ 460, 4783},{ 498, 5019},{ 532, 5280}, - { 565, 5553},{ 608, 5765},{ 647, 5958},{ 683, 6193}, - { 732, 6433},{ 782, 6620},{ 832, 6769},{ 848, 7027} - }, - /*Cb qi=15 INTER*/ - { - { 71, -52},{ 63, 296},{ 54, 644},{ 50, 1010}, - { 53, 1417},{ 64, 1837},{ 77, 2253},{ 88, 2666}, - { 95, 3079},{ 98, 3487},{ 100, 3882},{ 103, 4264}, - { 106, 4633},{ 108, 4991},{ 109, 5343},{ 109, 5693}, - { 112, 6038},{ 114, 6371},{ 119, 6709},{ 123, 7051}, - { 125, 7385},{ 130, 7716},{ 135, 8050},{ 140, 8374} - } - }, - { - /*Cr qi=15 INTRA*/ - { - { 2, 6},{ 47, 375},{ 87, 763},{ 119, 1225}, - { 143, 1699},{ 162, 2158},{ 185, 2595},{ 213, 2971}, - { 246, 3315},{ 279, 3618},{ 320, 3920},{ 372, 4210}, - { 409, 4480},{ 446, 4756},{ 496, 5017},{ 542, 5263}, - { 590, 5487},{ 639, 5721},{ 687, 5923},{ 724, 6132}, - { 753, 6417},{ 781, 6622},{ 805, 6806},{ 856, 6977} - }, - /*Cr qi=15 INTER*/ - { - { 71, 3},{ 61, 326},{ 52, 651},{ 50, 1017}, - { 58, 1422},{ 69, 1837},{ 82, 2251},{ 90, 2668}, - { 95, 3080},{ 98, 3484},{ 101, 3877},{ 102, 4257}, - { 102, 4632},{ 101, 5005},{ 103, 5370},{ 106, 5733}, - { 110, 6082},{ 116, 6424},{ 120, 6774},{ 124, 7106}, - { 130, 7427},{ 135, 7748},{ 141, 8052},{ 147, 8333} - } - } - }, - { - { - /*Y' qi=16 INTRA*/ - { - { 114, -63},{ 206, 1525},{ 396, 2887},{ 618, 3945}, - { 816, 4832},{ 1002, 5626},{ 1196, 6319},{ 1401, 6923}, - { 1616, 7458},{ 1857, 7928},{ 2121, 8334},{ 2405, 8645}, - { 2685, 8934},{ 2938, 9255},{ 3175, 9638},{ 3433, 9990}, - { 3707,10263},{ 3958,10577},{ 4218,10807},{ 4488,10906}, - { 4760,11028},{ 5037,11148},{ 5306,11286},{ 5625,11463} - }, - /*Y' qi=16 INTER*/ - { - { 69, -153},{ 39, 1348},{ 98, 2894},{ 144, 4448}, - { 181, 5872},{ 209, 7167},{ 228, 8422},{ 254, 9644}, - { 297,10810},{ 359,11908},{ 438,12944},{ 539,13930}, - { 672,14842},{ 850,15650},{ 1085,16318},{ 1391,16793}, - { 1769,17082},{ 2200,17198},{ 2659,17174},{ 3116,17072}, - { 3547,16948},{ 3943,16819},{ 4299,16701},{ 4611,16644} - } - }, - { - /*Cb qi=16 INTRA*/ - { - { 3, 4},{ 54, 367},{ 97, 742},{ 122, 1181}, - { 143, 1651},{ 168, 2123},{ 197, 2575},{ 226, 2985}, - { 263, 3338},{ 314, 3631},{ 367, 3903},{ 409, 4200}, - { 453, 4468},{ 491, 4703},{ 528, 4932},{ 566, 5188}, - { 601, 5459},{ 647, 5672},{ 693, 5844},{ 734, 6058}, - { 784, 6305},{ 836, 6460},{ 882, 6602},{ 905, 6891} - }, - /*Cb qi=16 INTER*/ - { - { 75, -64},{ 67, 292},{ 56, 645},{ 51, 1016}, - { 54, 1421},{ 66, 1842},{ 79, 2257},{ 89, 2670}, - { 95, 3082},{ 98, 3488},{ 101, 3879},{ 104, 4258}, - { 106, 4623},{ 108, 4974},{ 109, 5321},{ 113, 5664}, - { 116, 6001},{ 117, 6341},{ 123, 6677},{ 128, 7004}, - { 130, 7336},{ 136, 7671},{ 143, 7996},{ 148, 8310} - } - }, - { - /*Cr qi=16 INTRA*/ - { - { 4, 7},{ 50, 375},{ 90, 763},{ 124, 1225}, - { 148, 1698},{ 168, 2154},{ 195, 2582},{ 227, 2948}, - { 263, 3279},{ 302, 3575},{ 343, 3865},{ 394, 4137}, - { 439, 4402},{ 482, 4672},{ 533, 4925},{ 579, 5165}, - { 626, 5382},{ 675, 5616},{ 725, 5812},{ 769, 5991}, - { 810, 6242},{ 848, 6430},{ 868, 6615},{ 944, 6732} - }, - /*Cr qi=16 INTER*/ - { - { 78, 11},{ 62, 327},{ 49, 650},{ 50, 1025}, - { 59, 1431},{ 72, 1841},{ 83, 2253},{ 90, 2671}, - { 95, 3084},{ 98, 3487},{ 100, 3879},{ 101, 4254}, - { 102, 4625},{ 103, 4994},{ 106, 5355},{ 108, 5708}, - { 111, 6058},{ 115, 6400},{ 121, 6733},{ 128, 7058}, - { 134, 7374},{ 140, 7691},{ 146, 7993},{ 146, 8317} - } - } - }, - { - { - /*Y' qi=17 INTRA*/ - { - { 112, -59},{ 210, 1515},{ 409, 2850},{ 640, 3882}, - { 844, 4748},{ 1038, 5529},{ 1240, 6206},{ 1452, 6803}, - { 1676, 7330},{ 1925, 7792},{ 2194, 8201},{ 2483, 8512}, - { 2766, 8801},{ 3027, 9121},{ 3279, 9482},{ 3548, 9810}, - { 3825,10069},{ 4088,10345},{ 4362,10544},{ 4638,10644}, - { 4915,10744},{ 5196,10850},{ 5471,10981},{ 5802,11136} - }, - /*Y' qi=17 INTER*/ - { - { 70, -147},{ 45, 1349},{ 106, 2894},{ 155, 4425}, - { 195, 5818},{ 225, 7099},{ 247, 8348},{ 278, 9565}, - { 328,10717},{ 399,11794},{ 491,12807},{ 609,13760}, - { 766,14623},{ 984,15349},{ 1274,15902},{ 1642,16256}, - { 2082,16411},{ 2563,16409},{ 3048,16315},{ 3508,16194}, - { 3924,16064},{ 4306,15938},{ 4656,15828},{ 4966,15733} - } - }, - { - /*Cb qi=17 INTRA*/ - { - { 3, 4},{ 57, 367},{ 101, 742},{ 126, 1182}, - { 148, 1650},{ 175, 2118},{ 207, 2565},{ 241, 2966}, - { 279, 3307},{ 331, 3588},{ 389, 3845},{ 435, 4132}, - { 474, 4408},{ 517, 4641},{ 560, 4869},{ 602, 5122}, - { 638, 5389},{ 672, 5610},{ 716, 5787},{ 758, 6002}, - { 817, 6226},{ 869, 6393},{ 916, 6530},{ 950, 6799} - }, - /*Cb qi=17 INTER*/ - { - { 105, -65},{ 86, 288},{ 66, 638},{ 54, 1014}, - { 59, 1427},{ 71, 1844},{ 86, 2257},{ 95, 2668}, - { 100, 3075},{ 103, 3476},{ 106, 3867},{ 110, 4241}, - { 112, 4598},{ 114, 4948},{ 117, 5294},{ 121, 5633}, - { 123, 5968},{ 126, 6301},{ 131, 6637},{ 136, 6968}, - { 144, 7287},{ 152, 7606},{ 158, 7931},{ 162, 8262} - } - }, - { - /*Cr qi=17 INTRA*/ - { - { 4, 6},{ 55, 376},{ 97, 765},{ 128, 1226}, - { 152, 1696},{ 175, 2144},{ 204, 2568},{ 241, 2928}, - { 282, 3250},{ 323, 3530},{ 368, 3811},{ 420, 4089}, - { 463, 4347},{ 505, 4609},{ 562, 4860},{ 609, 5094}, - { 655, 5303},{ 709, 5535},{ 759, 5740},{ 803, 5913}, - { 844, 6153},{ 879, 6350},{ 905, 6527},{ 972, 6637} - }, - /*Cr qi=17 INTER*/ - { - { 88, 8},{ 68, 330},{ 51, 653},{ 54, 1028}, - { 65, 1433},{ 77, 1845},{ 89, 2257},{ 96, 2669}, - { 100, 3081},{ 102, 3481},{ 105, 3867},{ 106, 4245}, - { 108, 4613},{ 110, 4971},{ 112, 5328},{ 115, 5679}, - { 120, 6019},{ 127, 6355},{ 133, 6686},{ 140, 7007}, - { 149, 7316},{ 158, 7618},{ 166, 7924},{ 170, 8232} - } - } - }, - { - { - /*Y' qi=18 INTRA*/ - { - { 122, -58},{ 216, 1506},{ 425, 2815},{ 665, 3822}, - { 882, 4666},{ 1088, 5425},{ 1301, 6084},{ 1529, 6653}, - { 1766, 7162},{ 2026, 7611},{ 2312, 7987},{ 2612, 8278}, - { 2913, 8551},{ 3196, 8840},{ 3454, 9184},{ 3734, 9490}, - { 4030, 9725},{ 4305, 9973},{ 4585,10162},{ 4864,10251}, - { 5150,10324},{ 5443,10420},{ 5727,10536},{ 6053,10682} - }, - /*Y' qi=18 INTER*/ - { - { 66, -143},{ 47, 1351},{ 108, 2886},{ 158, 4401}, - { 200, 5775},{ 232, 7044},{ 256, 8288},{ 292, 9493}, - { 351,10625},{ 434,11679},{ 541,12665},{ 681,13578}, - { 875,14379},{ 1136,15025},{ 1483,15475},{ 1914,15709}, - { 2399,15767},{ 2907,15699},{ 3400,15579},{ 3852,15453}, - { 4259,15332},{ 4630,15221},{ 4976,15121},{ 5294,15061} - } - }, - { - /*Cb qi=18 INTRA*/ - { - { 2, 3},{ 61, 367},{ 107, 743},{ 131, 1182}, - { 155, 1648},{ 183, 2110},{ 220, 2542},{ 260, 2927}, - { 303, 3265},{ 359, 3540},{ 416, 3785},{ 462, 4063}, - { 506, 4334},{ 553, 4567},{ 595, 4797},{ 636, 5049}, - { 676, 5304},{ 717, 5516},{ 759, 5698},{ 801, 5904}, - { 861, 6133},{ 911, 6311},{ 962, 6443},{ 1021, 6645} - }, - /*Cb qi=18 INTER*/ - { - { 126, 5},{ 95, 326},{ 66, 643},{ 55, 1015}, - { 60, 1427},{ 73, 1843},{ 87, 2256},{ 96, 2667}, - { 101, 3073},{ 104, 3470},{ 108, 3853},{ 111, 4226}, - { 114, 4584},{ 117, 4928},{ 119, 5274},{ 122, 5612}, - { 126, 5942},{ 130, 6271},{ 136, 6606},{ 141, 6931}, - { 148, 7247},{ 156, 7568},{ 164, 7891},{ 173, 8211} - } - }, - { - /*Cr qi=18 INTRA*/ - { - { 4, 6},{ 59, 376},{ 104, 765},{ 133, 1226}, - { 156, 1692},{ 184, 2136},{ 218, 2548},{ 260, 2893}, - { 308, 3204},{ 348, 3481},{ 397, 3751},{ 448, 4024}, - { 490, 4281},{ 541, 4523},{ 593, 4776},{ 634, 5022}, - { 685, 5236},{ 748, 5455},{ 812, 5638},{ 856, 5818}, - { 891, 6048},{ 928, 6230},{ 961, 6405},{ 1055, 6449} - }, - /*Cr qi=18 INTER*/ - { - { 81, 34},{ 68, 342},{ 57, 652},{ 59, 1027}, - { 67, 1439},{ 80, 1848},{ 91, 2257},{ 97, 2670}, - { 100, 3076},{ 103, 3473},{ 106, 3857},{ 108, 4231}, - { 109, 4599},{ 110, 4958},{ 113, 5307},{ 119, 5650}, - { 125, 5991},{ 130, 6325},{ 138, 6651},{ 147, 6971}, - { 153, 7278},{ 162, 7578},{ 172, 7874},{ 177, 8156} - } - } - }, - { - { - /*Y' qi=19 INTRA*/ - { - { 128, -55},{ 228, 1495},{ 448, 2775},{ 699, 3758}, - { 931, 4571},{ 1154, 5296},{ 1386, 5914},{ 1636, 6450}, - { 1894, 6930},{ 2177, 7342},{ 2479, 7698},{ 2792, 7976}, - { 3099, 8235},{ 3392, 8517},{ 3658, 8853},{ 3938, 9155}, - { 4242, 9371},{ 4527, 9605},{ 4810, 9781},{ 5089, 9853}, - { 5378, 9920},{ 5674,10009},{ 5972,10110},{ 6336,10196} - }, - /*Y' qi=19 INTER*/ - { - { 69, -147},{ 49, 1353},{ 111, 2883},{ 162, 4381}, - { 205, 5737},{ 237, 6996},{ 264, 8232},{ 307, 9421}, - { 376,10534},{ 472,11567},{ 596,12525},{ 761,13395}, - { 990,14130},{ 1298,14694},{ 1695,15053},{ 2172,15195}, - { 2696,15173},{ 3213,15075},{ 3696,14948},{ 4141,14829}, - { 4541,14721},{ 4910,14609},{ 5245,14506},{ 5536,14399} - } - }, - { - /*Cb qi=19 INTRA*/ - { - { 3, 3},{ 61, 367},{ 109, 743},{ 135, 1182}, - { 161, 1646},{ 191, 2101},{ 229, 2524},{ 273, 2898}, - { 318, 3221},{ 376, 3490},{ 436, 3731},{ 487, 3994}, - { 539, 4251},{ 584, 4485},{ 621, 4721},{ 664, 4967}, - { 709, 5225},{ 752, 5431},{ 801, 5595},{ 846, 5796}, - { 912, 6011},{ 959, 6193},{ 1015, 6321},{ 1121, 6504} - }, - /*Cb qi=19 INTER*/ - { - { 126, 4},{ 97, 329},{ 69, 649},{ 56, 1017}, - { 61, 1432},{ 74, 1846},{ 88, 2255},{ 98, 2663}, - { 103, 3065},{ 106, 3460},{ 110, 3844},{ 114, 4211}, - { 117, 4564},{ 120, 4911},{ 122, 5253},{ 125, 5588}, - { 129, 5916},{ 135, 6241},{ 142, 6567},{ 149, 6885}, - { 155, 7206},{ 163, 7527},{ 174, 7843},{ 188, 8145} - } - }, - { - /*Cr qi=19 INTRA*/ - { - { 5, 6},{ 61, 376},{ 106, 765},{ 135, 1225}, - { 160, 1689},{ 192, 2126},{ 229, 2531},{ 271, 2869}, - { 321, 3168},{ 370, 3433},{ 421, 3704},{ 476, 3965}, - { 520, 4212},{ 572, 4452},{ 629, 4691},{ 671, 4939}, - { 724, 5152},{ 792, 5347},{ 858, 5510},{ 895, 5696}, - { 939, 5905},{ 991, 6056},{ 1027, 6244},{ 1127, 6333} - }, - /*Cr qi=19 INTER*/ - { - { 80, 45},{ 66, 344},{ 55, 654},{ 56, 1030}, - { 66, 1440},{ 80, 1850},{ 91, 2259},{ 98, 2668}, - { 102, 3072},{ 104, 3466},{ 107, 3845},{ 109, 4215}, - { 110, 4578},{ 112, 4933},{ 116, 5283},{ 122, 5625}, - { 129, 5963},{ 136, 6287},{ 143, 6611},{ 151, 6927}, - { 160, 7229},{ 170, 7528},{ 181, 7818},{ 191, 8092} - } - } - }, - { - { - /*Y' qi=20 INTRA*/ - { - { 129, -50},{ 238, 1481},{ 469, 2728},{ 730, 3684}, - { 974, 4473},{ 1213, 5171},{ 1463, 5763},{ 1729, 6281}, - { 2002, 6744},{ 2299, 7146},{ 2613, 7492},{ 2940, 7746}, - { 3265, 7978},{ 3571, 8228},{ 3853, 8543},{ 4156, 8815}, - { 4476, 9001},{ 4775, 9218},{ 5070, 9373},{ 5352, 9446}, - { 5649, 9510},{ 5956, 9580},{ 6268, 9660},{ 6647, 9705} - }, - /*Y' qi=20 INTER*/ - { - { 64, -93},{ 52, 1340},{ 116, 2862},{ 170, 4344}, - { 216, 5678},{ 249, 6928},{ 281, 8155},{ 333, 9326}, - { 418,10410},{ 533,11411},{ 683,12329},{ 890,13127}, - { 1183,13750},{ 1579,14162},{ 2066,14357},{ 2611,14370}, - { 3159,14284},{ 3675,14167},{ 4142,14053},{ 4568,13953}, - { 4961,13852},{ 5320,13755},{ 5649,13675},{ 5933,13610} - } - }, - { - /*Cb qi=20 INTRA*/ - { - { 3, 3},{ 62, 367},{ 112, 743},{ 140, 1183}, - { 165, 1646},{ 196, 2099},{ 235, 2517},{ 284, 2883}, - { 334, 3198},{ 393, 3460},{ 457, 3690},{ 509, 3945}, - { 560, 4198},{ 605, 4435},{ 647, 4658},{ 699, 4888}, - { 742, 5155},{ 788, 5350},{ 835, 5517},{ 880, 5730}, - { 956, 5914},{ 1007, 6060},{ 1053, 6199},{ 1158, 6358} - }, - /*Cb qi=20 INTER*/ - { - { 128, -6},{ 96, 322},{ 66, 653},{ 54, 1025}, - { 63, 1431},{ 79, 1844},{ 91, 2256},{ 99, 2665}, - { 104, 3065},{ 107, 3455},{ 111, 3831},{ 115, 4189}, - { 120, 4539},{ 123, 4885},{ 126, 5219},{ 130, 5548}, - { 135, 5876},{ 141, 6199},{ 149, 6519},{ 156, 6837}, - { 166, 7153},{ 179, 7468},{ 189, 7784},{ 194, 8102} - } - }, - { - /*Cr qi=20 INTRA*/ - { - { 4, 6},{ 63, 376},{ 109, 765},{ 139, 1225}, - { 165, 1689},{ 199, 2124},{ 239, 2523},{ 285, 2852}, - { 340, 3140},{ 388, 3398},{ 438, 3662},{ 499, 3914}, - { 547, 4155},{ 596, 4392},{ 652, 4634},{ 699, 4877}, - { 759, 5074},{ 824, 5257},{ 883, 5428},{ 936, 5589}, - { 986, 5790},{ 1030, 5960},{ 1074, 6119},{ 1172, 6191} - }, - /*Cr qi=20 INTER*/ - { - { 92, 40},{ 70, 345},{ 55, 658},{ 57, 1034}, - { 69, 1441},{ 84, 1852},{ 94, 2261},{ 98, 2669}, - { 102, 3074},{ 105, 3465},{ 107, 3841},{ 110, 4206}, - { 112, 4562},{ 116, 4915},{ 121, 5260},{ 127, 5591}, - { 134, 5920},{ 142, 6246},{ 153, 6562},{ 163, 6870}, - { 173, 7170},{ 186, 7463},{ 198, 7746},{ 199, 8030} - } - } - }, - { - { - /*Y' qi=21 INTRA*/ - { - { 130, -51},{ 244, 1476},{ 483, 2705},{ 756, 3635}, - { 1013, 4396},{ 1266, 5070},{ 1530, 5647},{ 1806, 6153}, - { 2093, 6600},{ 2411, 6976},{ 2739, 7299},{ 3079, 7534}, - { 3422, 7744},{ 3738, 7987},{ 4032, 8274},{ 4348, 8533}, - { 4675, 8721},{ 4989, 8909},{ 5291, 9051},{ 5577, 9111}, - { 5879, 9163},{ 6190, 9228},{ 6506, 9286},{ 6899, 9295} - }, - /*Y' qi=21 INTER*/ - { - { 64, -56},{ 55, 1341},{ 119, 2859},{ 174, 4324}, - { 223, 5640},{ 258, 6880},{ 295, 8096},{ 359, 9246}, - { 460,10302},{ 595,11268},{ 778,12131},{ 1032,12857}, - { 1387,13385},{ 1850,13683},{ 2399,13774},{ 2976,13729}, - { 3527,13619},{ 4034,13504},{ 4492,13401},{ 4912,13291}, - { 5298,13209},{ 5648,13137},{ 5974,13046},{ 6308,12977} - } - }, - { - /*Cb qi=21 INTRA*/ - { - { 4, 3},{ 64, 367},{ 114, 743},{ 141, 1183}, - { 166, 1645},{ 201, 2092},{ 247, 2502},{ 299, 2856}, - { 352, 3158},{ 413, 3412},{ 480, 3642},{ 536, 3893}, - { 588, 4137},{ 637, 4367},{ 678, 4598},{ 725, 4834}, - { 774, 5083},{ 827, 5269},{ 883, 5420},{ 930, 5633}, - { 999, 5829},{ 1057, 5959},{ 1113, 6082},{ 1200, 6265} - }, - /*Cb qi=21 INTER*/ - { - { 109, -8},{ 84, 321},{ 62, 654},{ 54, 1028}, - { 64, 1434},{ 80, 1847},{ 92, 2259},{ 100, 2664}, - { 105, 3060},{ 109, 3445},{ 114, 3815},{ 118, 4172}, - { 122, 4519},{ 126, 4861},{ 128, 5194},{ 133, 5520}, - { 139, 5847},{ 146, 6169},{ 155, 6487},{ 166, 6801}, - { 177, 7114},{ 189, 7423},{ 201, 7729},{ 208, 8035} - } - }, - { - /*Cr qi=21 INTRA*/ - { - { 4, 6},{ 64, 377},{ 111, 766},{ 144, 1225}, - { 174, 1683},{ 206, 2114},{ 248, 2506},{ 302, 2824}, - { 357, 3099},{ 404, 3357},{ 455, 3622},{ 519, 3867}, - { 573, 4098},{ 625, 4331},{ 683, 4571},{ 733, 4802}, - { 793, 4994},{ 863, 5173},{ 926, 5337},{ 978, 5492}, - { 1030, 5685},{ 1079, 5856},{ 1126, 6027},{ 1217, 6159} - }, - /*Cr qi=21 INTER*/ - { - { 82, 29},{ 67, 341},{ 55, 660},{ 58, 1038}, - { 71, 1443},{ 85, 1851},{ 95, 2258},{ 99, 2666}, - { 103, 3069},{ 107, 3456},{ 110, 3826},{ 112, 4188}, - { 114, 4544},{ 118, 4891},{ 124, 5231},{ 132, 5567}, - { 139, 5894},{ 148, 6210},{ 159, 6520},{ 171, 6822}, - { 185, 7111},{ 196, 7403},{ 209, 7691},{ 225, 7945} - } - } - }, - { - { - /*Y' qi=22 INTRA*/ - { - { 128, -45},{ 254, 1463},{ 507, 2662},{ 794, 3562}, - { 1070, 4292},{ 1340, 4941},{ 1622, 5492},{ 1920, 5968}, - { 2229, 6387},{ 2565, 6742},{ 2911, 7047},{ 3263, 7264}, - { 3615, 7464},{ 3944, 7689},{ 4258, 7950},{ 4591, 8183}, - { 4934, 8347},{ 5259, 8517},{ 5573, 8634},{ 5870, 8683}, - { 6186, 8723},{ 6508, 8762},{ 6831, 8801},{ 7232, 8830} - }, - /*Y' qi=22 INTER*/ - { - { 77, -48},{ 57, 1343},{ 122, 2853},{ 180, 4299}, - { 231, 5597},{ 269, 6826},{ 314, 8025},{ 393, 9150}, - { 512,10179},{ 673,11103},{ 894,11908},{ 1207,12542}, - { 1635,12956},{ 2166,13148},{ 2755,13167},{ 3345,13088}, - { 3895,12966},{ 4386,12848},{ 4832,12746},{ 5252,12647}, - { 5634,12563},{ 5978,12497},{ 6299,12412},{ 6633,12338} - } - }, - { - /*Cb qi=22 INTRA*/ - { - { 4, 3},{ 66, 367},{ 122, 744},{ 153, 1182}, - { 177, 1640},{ 213, 2080},{ 263, 2475},{ 323, 2811}, - { 382, 3103},{ 451, 3346},{ 522, 3568},{ 581, 3814}, - { 633, 4054},{ 674, 4288},{ 719, 4523},{ 768, 4756}, - { 823, 4979},{ 883, 5162},{ 937, 5325},{ 996, 5510}, - { 1070, 5687},{ 1129, 5807},{ 1193, 5929},{ 1311, 6099} - }, - /*Cb qi=22 INTER*/ - { - { 107, -5},{ 83, 322},{ 61, 653},{ 55, 1030}, - { 66, 1436},{ 81, 1845},{ 94, 2253},{ 102, 2656}, - { 107, 3050},{ 111, 3435},{ 115, 3804},{ 119, 4158}, - { 124, 4501},{ 128, 4835},{ 132, 5164},{ 138, 5490}, - { 146, 5812},{ 154, 6128},{ 163, 6442},{ 174, 6754}, - { 188, 7060},{ 205, 7361},{ 219, 7662},{ 233, 7953} - } - }, - { - /*Cr qi=22 INTRA*/ - { - { 4, 6},{ 67, 378},{ 118, 767},{ 151, 1222}, - { 182, 1675},{ 221, 2097},{ 269, 2476},{ 329, 2774}, - { 389, 3039},{ 444, 3292},{ 500, 3545},{ 560, 3788}, - { 615, 4020},{ 671, 4251},{ 734, 4484},{ 781, 4712}, - { 850, 4887},{ 925, 5060},{ 981, 5229},{ 1031, 5369}, - { 1092, 5549},{ 1148, 5715},{ 1200, 5861},{ 1291, 5943} - }, - /*Cr qi=22 INTER*/ - { - { 88, 34},{ 69, 340},{ 57, 657},{ 60, 1039}, - { 73, 1445},{ 87, 1851},{ 96, 2257},{ 100, 2662}, - { 103, 3058},{ 107, 3442},{ 111, 3812},{ 115, 4172}, - { 118, 4524},{ 123, 4864},{ 129, 5199},{ 136, 5531}, - { 145, 5855},{ 156, 6168},{ 170, 6468},{ 184, 6765}, - { 193, 7066},{ 207, 7353},{ 222, 7628},{ 230, 7900} - } - } - }, - { - { - /*Y' qi=23 INTRA*/ - { - { 126, -40},{ 257, 1458},{ 521, 2636},{ 825, 3501}, - { 1111, 4207},{ 1391, 4842},{ 1684, 5385},{ 1992, 5858}, - { 2311, 6277},{ 2653, 6626},{ 3005, 6929},{ 3366, 7134}, - { 3729, 7311},{ 4071, 7526},{ 4396, 7770},{ 4734, 7986}, - { 5086, 8131},{ 5421, 8286},{ 5735, 8404},{ 6033, 8456}, - { 6357, 8486},{ 6682, 8525},{ 7003, 8573},{ 7387, 8604} - }, - /*Y' qi=23 INTER*/ - { - { 64, -57},{ 60, 1345},{ 124, 2853},{ 185, 4284}, - { 239, 5565},{ 282, 6783},{ 336, 7967},{ 429, 9069}, - { 568,10063},{ 758,10943},{ 1028,11679},{ 1407,12216}, - { 1909,12520},{ 2502,12616},{ 3126,12573},{ 3722,12461}, - { 4258,12344},{ 4742,12236},{ 5185,12136},{ 5590,12052}, - { 5970,11980},{ 6315,11901},{ 6631,11826},{ 6954,11769} - } - }, - { - /*Cb qi=23 INTRA*/ - { - { 3, 3},{ 70, 367},{ 124, 744},{ 151, 1182}, - { 181, 1637},{ 222, 2071},{ 276, 2460},{ 343, 2785}, - { 403, 3072},{ 468, 3317},{ 542, 3534},{ 605, 3773}, - { 659, 4009},{ 703, 4243},{ 747, 4479},{ 795, 4707}, - { 852, 4923},{ 908, 5105},{ 972, 5254},{ 1043, 5423}, - { 1118, 5594},{ 1172, 5731},{ 1240, 5853},{ 1365, 6005} - }, - /*Cb qi=23 INTER*/ - { - { 109, -10},{ 87, 325},{ 63, 650},{ 57, 1031}, - { 67, 1439},{ 83, 1847},{ 96, 2253},{ 103, 2652}, - { 109, 3041},{ 114, 3421},{ 117, 3789},{ 122, 4141}, - { 128, 4480},{ 134, 4811},{ 139, 5138},{ 144, 5463}, - { 152, 5781},{ 161, 6096},{ 174, 6404},{ 185, 6714}, - { 198, 7023},{ 216, 7320},{ 233, 7621},{ 245, 7935} - } - }, - { - /*Cr qi=23 INTRA*/ - { - { 5, 6},{ 70, 379},{ 122, 768},{ 155, 1222}, - { 187, 1671},{ 231, 2088},{ 283, 2459},{ 346, 2750}, - { 411, 3009},{ 465, 3261},{ 523, 3509},{ 585, 3746}, - { 639, 3980},{ 695, 4219},{ 754, 4449},{ 803, 4671}, - { 873, 4840},{ 953, 5001},{ 1015, 5156},{ 1071, 5286}, - { 1137, 5464},{ 1191, 5629},{ 1249, 5782},{ 1359, 5885} - }, - /*Cr qi=23 INTER*/ - { - { 84, 29},{ 69, 343},{ 58, 660},{ 62, 1041}, - { 75, 1448},{ 88, 1853},{ 97, 2258},{ 102, 2659}, - { 105, 3050},{ 108, 3430},{ 113, 3799},{ 116, 4155}, - { 121, 4505},{ 126, 4845},{ 132, 5176},{ 142, 5504}, - { 153, 5826},{ 165, 6133},{ 180, 6432},{ 197, 6722}, - { 212, 7005},{ 226, 7287},{ 244, 7555},{ 258, 7828} - } - } - }, - { - { - /*Y' qi=24 INTRA*/ - { - { 125, -34},{ 268, 1444},{ 547, 2590},{ 866, 3422}, - { 1172, 4098},{ 1476, 4702},{ 1790, 5222},{ 2117, 5678}, - { 2453, 6080},{ 2811, 6418},{ 3178, 6700},{ 3552, 6895}, - { 3928, 7055},{ 4286, 7243},{ 4627, 7477},{ 4981, 7674}, - { 5344, 7802},{ 5683, 7944},{ 6009, 8043},{ 6313, 8082}, - { 6633, 8111},{ 6959, 8151},{ 7280, 8197},{ 7660, 8221} - }, - /*Y' qi=24 INTER*/ - { - { 62, -63},{ 68, 1345},{ 134, 2840},{ 199, 4245}, - { 256, 5508},{ 304, 6715},{ 371, 7880},{ 484, 8950}, - { 652, 9899},{ 892,10709},{ 1238,11334},{ 1722,11722}, - { 2326,11875},{ 2983,11864},{ 3616,11783},{ 4189,11678}, - { 4707,11570},{ 5178,11476},{ 5617,11395},{ 6017,11319}, - { 6380,11252},{ 6720,11185},{ 7044,11126},{ 7377,11118} - } - }, - { - /*Cb qi=24 INTRA*/ - { - { 4, 3},{ 75, 367},{ 132, 745},{ 159, 1182}, - { 187, 1634},{ 230, 2061},{ 289, 2439},{ 361, 2753}, - { 425, 3034},{ 492, 3278},{ 566, 3490},{ 630, 3720}, - { 686, 3956},{ 732, 4190},{ 777, 4420},{ 829, 4637}, - { 894, 4840},{ 958, 5012},{ 1023, 5155},{ 1090, 5326}, - { 1165, 5502},{ 1226, 5622},{ 1299, 5717},{ 1408, 5887} - }, - /*Cb qi=24 INTER*/ - { - { 110, 35},{ 92, 337},{ 70, 651},{ 63, 1033}, - { 74, 1440},{ 91, 1846},{ 102, 2248},{ 109, 2644}, - { 114, 3031},{ 120, 3404},{ 127, 3762},{ 133, 4109}, - { 138, 4445},{ 144, 4772},{ 151, 5094},{ 159, 5411}, - { 168, 5728},{ 180, 6037},{ 195, 6338},{ 210, 6640}, - { 227, 6944},{ 249, 7236},{ 272, 7528},{ 299, 7809} - } - }, - { - /*Cr qi=24 INTRA*/ - { - { 5, 6},{ 72, 380},{ 124, 770},{ 158, 1222}, - { 195, 1668},{ 240, 2079},{ 297, 2438},{ 367, 2715}, - { 433, 2966},{ 488, 3218},{ 549, 3467},{ 609, 3701}, - { 664, 3935},{ 728, 4165},{ 792, 4379},{ 845, 4586}, - { 917, 4744},{ 995, 4898},{ 1063, 5049},{ 1120, 5187}, - { 1190, 5359},{ 1249, 5522},{ 1304, 5672},{ 1397, 5806} - }, - /*Cr qi=24 INTER*/ - { - { 91, 56},{ 73, 353},{ 61, 664},{ 66, 1045}, - { 80, 1449},{ 95, 1851},{ 103, 2250},{ 107, 2648}, - { 111, 3038},{ 116, 3413},{ 120, 3774},{ 124, 4128}, - { 130, 4471},{ 138, 4802},{ 145, 5130},{ 156, 5453}, - { 171, 5764},{ 187, 6061},{ 204, 6355},{ 220, 6643}, - { 238, 6923},{ 254, 7204},{ 275, 7475},{ 289, 7752} - } - } - }, - { - { - /*Y' qi=25 INTRA*/ - { - { 125, -28},{ 285, 1426},{ 582, 2540},{ 917, 3351}, - { 1244, 3997},{ 1569, 4570},{ 1903, 5071},{ 2258, 5498}, - { 2626, 5866},{ 3002, 6182},{ 3382, 6448},{ 3770, 6623}, - { 4162, 6760},{ 4528, 6934},{ 4882, 7144},{ 5249, 7328}, - { 5610, 7453},{ 5958, 7578},{ 6291, 7672},{ 6597, 7708}, - { 6928, 7715},{ 7258, 7737},{ 7575, 7781},{ 7950, 7829} - }, - /*Y' qi=25 INTER*/ - { - { 64, -16},{ 72, 1348},{ 139, 2832},{ 206, 4218}, - { 268, 5465},{ 322, 6659},{ 403, 7803},{ 540, 8838}, - { 747, 9734},{ 1044,10465},{ 1473,10981},{ 2048,11249}, - { 2717,11311},{ 3397,11257},{ 4025,11161},{ 4589,11052}, - { 5099,10947},{ 5560,10859},{ 5989,10786},{ 6389,10717}, - { 6753,10652},{ 7078,10592},{ 7389,10535},{ 7697,10460} - } - }, - { - /*Cb qi=25 INTRA*/ - { - { 3, 3},{ 78, 368},{ 133, 745},{ 159, 1180}, - { 193, 1627},{ 242, 2046},{ 304, 2411},{ 381, 2714}, - { 456, 2983},{ 527, 3224},{ 598, 3437},{ 667, 3655}, - { 726, 3888},{ 776, 4117},{ 826, 4333},{ 883, 4543}, - { 954, 4727},{ 1019, 4878},{ 1095, 5014},{ 1171, 5187}, - { 1255, 5342},{ 1319, 5458},{ 1396, 5546},{ 1536, 5678} - }, - /*Cb qi=25 INTER*/ - { - { 117, 32},{ 89, 342},{ 67, 660},{ 64, 1037}, - { 77, 1441},{ 93, 1845},{ 105, 2243},{ 113, 2633}, - { 120, 3016},{ 125, 3387},{ 131, 3739},{ 137, 4080}, - { 144, 4416},{ 152, 4741},{ 160, 5057},{ 169, 5369}, - { 180, 5680},{ 193, 5990},{ 209, 6294},{ 227, 6594}, - { 249, 6888},{ 269, 7180},{ 294, 7467},{ 317, 7768} - } - }, - { - /*Cr qi=25 INTRA*/ - { - { 6, 6},{ 74, 380},{ 129, 770},{ 165, 1220}, - { 201, 1658},{ 253, 2061},{ 315, 2410},{ 388, 2676}, - { 462, 2920},{ 523, 3166},{ 584, 3404},{ 647, 3637}, - { 701, 3870},{ 769, 4086},{ 838, 4296},{ 898, 4491}, - { 980, 4627},{ 1065, 4759},{ 1126, 4920},{ 1187, 5058}, - { 1283, 5180},{ 1347, 5332},{ 1404, 5475},{ 1527, 5534} - }, - /*Cr qi=25 INTER*/ - { - { 92, 41},{ 75, 347},{ 64, 664},{ 70, 1045}, - { 85, 1448},{ 98, 1849},{ 105, 2245},{ 110, 2637}, - { 115, 3023},{ 120, 3395},{ 126, 3753},{ 131, 4102}, - { 136, 4439},{ 145, 4768},{ 156, 5094},{ 168, 5410}, - { 184, 5717},{ 203, 6010},{ 221, 6300},{ 239, 6577}, - { 262, 6847},{ 282, 7123},{ 303, 7390},{ 322, 7665} - } - } - }, - { - { - /*Y' qi=26 INTRA*/ - { - { 130, -24},{ 292, 1423},{ 594, 2525},{ 943, 3307}, - { 1289, 3921},{ 1633, 4467},{ 1991, 4943},{ 2368, 5348}, - { 2753, 5696},{ 3148, 5991},{ 3545, 6247},{ 3942, 6415}, - { 4342, 6535},{ 4726, 6690},{ 5093, 6883},{ 5466, 7047}, - { 5840, 7159},{ 6202, 7274},{ 6545, 7351},{ 6855, 7375}, - { 7186, 7384},{ 7517, 7416},{ 7840, 7447},{ 8238, 7450} - }, - /*Y' qi=26 INTER*/ - { - { 52, 16},{ 75, 1336},{ 143, 2815},{ 213, 4191}, - { 278, 5427},{ 339, 6611},{ 436, 7734},{ 600, 8732}, - { 843, 9579},{ 1195,10243},{ 1702,10660},{ 2355,10825}, - { 3070,10820},{ 3755,10743},{ 4372,10643},{ 4925,10538}, - { 5426,10440},{ 5882,10354},{ 6296,10290},{ 6686,10224}, - { 7049,10163},{ 7380,10113},{ 7672,10062},{ 7937,10021} - } - }, - { - /*Cb qi=26 INTRA*/ - { - { 4, 3},{ 79, 368},{ 138, 745},{ 167, 1180}, - { 200, 1623},{ 252, 2034},{ 322, 2389},{ 403, 2682}, - { 480, 2941},{ 558, 3176},{ 631, 3393},{ 700, 3608}, - { 766, 3825},{ 819, 4046},{ 868, 4265},{ 926, 4472}, - { 1002, 4645},{ 1070, 4800},{ 1151, 4924},{ 1242, 5063}, - { 1325, 5221},{ 1393, 5338},{ 1464, 5431},{ 1595, 5559} - }, - /*Cb qi=26 INTER*/ - { - { 98, 33},{ 83, 343},{ 65, 662},{ 65, 1037}, - { 80, 1437},{ 96, 1839},{ 107, 2238},{ 115, 2628}, - { 122, 3007},{ 128, 3373},{ 134, 3722},{ 142, 4060}, - { 149, 4390},{ 158, 4713},{ 167, 5029},{ 178, 5341}, - { 191, 5647},{ 208, 5948},{ 227, 6244},{ 247, 6539}, - { 269, 6833},{ 295, 7114},{ 328, 7388},{ 369, 7658} - } - }, - { - /*Cr qi=26 INTRA*/ - { - { 5, 6},{ 75, 380},{ 133, 769},{ 172, 1217}, - { 212, 1652},{ 266, 2048},{ 333, 2384},{ 412, 2643}, - { 490, 2880},{ 552, 3124},{ 616, 3365},{ 681, 3594}, - { 739, 3816},{ 810, 4024},{ 880, 4224},{ 945, 4405}, - { 1029, 4538},{ 1114, 4674},{ 1183, 4822},{ 1254, 4946}, - { 1346, 5063},{ 1417, 5201},{ 1478, 5345},{ 1597, 5411} - }, - /*Cr qi=26 INTER*/ - { - { 97, 29},{ 75, 342},{ 62, 667},{ 70, 1047}, - { 87, 1447},{ 100, 1846},{ 107, 2242},{ 113, 2633}, - { 118, 3016},{ 123, 3382},{ 128, 3737},{ 135, 4082}, - { 142, 4417},{ 151, 4746},{ 162, 5066},{ 176, 5377}, - { 194, 5679},{ 217, 5963},{ 239, 6244},{ 260, 6522}, - { 284, 6789},{ 309, 7052},{ 335, 7313},{ 355, 7582} - } - } - }, - { - { - /*Y' qi=27 INTRA*/ - { - { 118, -10},{ 308, 1404},{ 630, 2473},{ 997, 3227}, - { 1360, 3819},{ 1719, 4354},{ 2086, 4829},{ 2470, 5233}, - { 2863, 5576},{ 3267, 5870},{ 3677, 6117},{ 4085, 6268}, - { 4499, 6376},{ 4888, 6521},{ 5257, 6705},{ 5638, 6865}, - { 6020, 6962},{ 6394, 7056},{ 6744, 7130},{ 7051, 7158}, - { 7386, 7164},{ 7717, 7185},{ 8042, 7209},{ 8444, 7206} - }, - /*Y' qi=27 INTER*/ - { - { 54, 19},{ 77, 1333},{ 147, 2806},{ 221, 4166}, - { 290, 5390},{ 360, 6564},{ 474, 7665},{ 664, 8630}, - { 949, 9423},{ 1370,10002},{ 1958,10323},{ 2670,10414}, - { 3406,10375},{ 4086,10285},{ 4691,10182},{ 5233,10085}, - { 5724, 9994},{ 6169, 9918},{ 6582, 9863},{ 6962, 9813}, - { 7316, 9759},{ 7645, 9707},{ 7948, 9660},{ 8262, 9623} - } - }, - { - /*Cb qi=27 INTRA*/ - { - { 4, 3},{ 79, 368},{ 137, 745},{ 166, 1180}, - { 200, 1622},{ 253, 2030},{ 324, 2381},{ 407, 2671}, - { 487, 2925},{ 567, 3156},{ 640, 3372},{ 712, 3580}, - { 782, 3792},{ 833, 4015},{ 887, 4227},{ 954, 4422}, - { 1031, 4592},{ 1103, 4738},{ 1187, 4856},{ 1280, 4990}, - { 1371, 5135},{ 1442, 5244},{ 1520, 5321},{ 1684, 5398} - }, - /*Cb qi=27 INTER*/ - { - { 113, 20},{ 90, 338},{ 66, 661},{ 67, 1034}, - { 82, 1438},{ 97, 1842},{ 108, 2238},{ 115, 2624}, - { 123, 3000},{ 130, 3361},{ 138, 3708},{ 146, 4040}, - { 155, 4367},{ 164, 4688},{ 174, 4999},{ 186, 5306}, - { 203, 5609},{ 222, 5908},{ 243, 6202},{ 268, 6494}, - { 295, 6781},{ 326, 7058},{ 367, 7319},{ 420, 7551} - } - }, - { - /*Cr qi=27 INTRA*/ - { - { 5, 6},{ 75, 380},{ 133, 770},{ 173, 1217}, - { 214, 1650},{ 268, 2040},{ 337, 2375},{ 418, 2631}, - { 496, 2862},{ 558, 3104},{ 625, 3346},{ 692, 3571}, - { 753, 3786},{ 825, 3989},{ 896, 4182},{ 969, 4352}, - { 1059, 4479},{ 1144, 4614},{ 1212, 4757},{ 1284, 4871}, - { 1380, 4982},{ 1457, 5125},{ 1528, 5267},{ 1651, 5346} - }, - /*Cr qi=27 INTER*/ - { - { 92, 24},{ 74, 341},{ 61, 669},{ 71, 1049}, - { 88, 1448},{ 100, 1849},{ 107, 2243},{ 113, 2631}, - { 119, 3010},{ 125, 3373},{ 131, 3723},{ 137, 4064}, - { 146, 4396},{ 159, 4720},{ 172, 5033},{ 189, 5340}, - { 210, 5636},{ 233, 5920},{ 256, 6197},{ 282, 6465}, - { 310, 6730},{ 332, 7000},{ 359, 7259},{ 385, 7515} - } - } - }, - { - { - /*Y' qi=28 INTRA*/ - { - { 116, -8},{ 314, 1400},{ 640, 2458},{ 1013, 3197}, - { 1386, 3768},{ 1762, 4279},{ 2151, 4733},{ 2558, 5117}, - { 2970, 5442},{ 3393, 5714},{ 3820, 5935},{ 4243, 6069}, - { 4671, 6161},{ 5074, 6289},{ 5456, 6457},{ 5849, 6598}, - { 6244, 6689},{ 6632, 6777},{ 6984, 6833},{ 7294, 6855}, - { 7625, 6862},{ 7961, 6875},{ 8302, 6890},{ 8720, 6883} - }, - /*Y' qi=28 INTER*/ - { - { 54, 8},{ 81, 1333},{ 154, 2793},{ 231, 4138}, - { 304, 5352},{ 384, 6512},{ 519, 7585},{ 743, 8508}, - { 1082, 9236},{ 1587, 9717},{ 2267, 9928},{ 3034, 9944}, - { 3775, 9878},{ 4438, 9786},{ 5031, 9686},{ 5563, 9601}, - { 6042, 9523},{ 6481, 9456},{ 6890, 9405},{ 7266, 9356}, - { 7614, 9313},{ 7933, 9265},{ 8238, 9220},{ 8545, 9193} - } - }, - { - /*Cb qi=28 INTRA*/ - { - { 3, 3},{ 80, 368},{ 138, 746},{ 168, 1179}, - { 208, 1615},{ 268, 2014},{ 345, 2354},{ 432, 2637}, - { 515, 2884},{ 595, 3108},{ 669, 3323},{ 745, 3533}, - { 818, 3740},{ 876, 3953},{ 932, 4160},{ 1003, 4349}, - { 1088, 4501},{ 1154, 4648},{ 1241, 4768},{ 1349, 4889}, - { 1441, 5023},{ 1524, 5113},{ 1611, 5187},{ 1783, 5283} - }, - /*Cb qi=28 INTER*/ - { - { 117, 29},{ 91, 341},{ 65, 663},{ 68, 1038}, - { 85, 1440},{ 100, 1841},{ 110, 2234},{ 119, 2616}, - { 127, 2985},{ 135, 3342},{ 142, 3685},{ 151, 4015}, - { 162, 4337},{ 174, 4652},{ 186, 4960},{ 201, 5264}, - { 218, 5567},{ 239, 5863},{ 266, 6149},{ 295, 6434}, - { 328, 6715},{ 371, 6976},{ 409, 7239},{ 460, 7477} - } - }, - { - /*Cr qi=28 INTRA*/ - { - { 6, 7},{ 79, 381},{ 138, 771},{ 178, 1215}, - { 222, 1644},{ 285, 2026},{ 359, 2347},{ 441, 2597}, - { 521, 2827},{ 588, 3066},{ 655, 3303},{ 725, 3523}, - { 791, 3728},{ 870, 3920},{ 950, 4103},{ 1030, 4265}, - { 1121, 4388},{ 1198, 4520},{ 1266, 4659},{ 1356, 4759}, - { 1461, 4865},{ 1540, 4993},{ 1619, 5115},{ 1786, 5160} - }, - /*Cr qi=28 INTER*/ - { - { 96, 18},{ 78, 340},{ 66, 672},{ 74, 1051}, - { 90, 1450},{ 103, 1845},{ 110, 2235},{ 116, 2619}, - { 122, 2995},{ 129, 3356},{ 137, 3702},{ 146, 4038}, - { 156, 4365},{ 168, 4684},{ 182, 4995},{ 203, 5297}, - { 227, 5588},{ 253, 5866},{ 282, 6131},{ 311, 6394}, - { 339, 6664},{ 366, 6918},{ 400, 7171},{ 424, 7450} - } - } - }, - { - { - /*Y' qi=29 INTRA*/ - { - { 112, 7},{ 334, 1382},{ 681, 2410},{ 1081, 3112}, - { 1484, 3650},{ 1894, 4128},{ 2316, 4547},{ 2749, 4905}, - { 3188, 5208},{ 3634, 5458},{ 4079, 5666},{ 4517, 5791}, - { 4952, 5870},{ 5359, 5983},{ 5754, 6137},{ 6165, 6268}, - { 6568, 6351},{ 6958, 6423},{ 7320, 6471},{ 7638, 6490}, - { 7979, 6490},{ 8313, 6499},{ 8651, 6517},{ 9085, 6499} - }, - /*Y' qi=29 INTER*/ - { - { 55, 15},{ 85, 1336},{ 160, 2780},{ 242, 4104}, - { 323, 5302},{ 418, 6443},{ 586, 7480},{ 859, 8342}, - { 1278, 8982},{ 1888, 9347},{ 2658, 9457},{ 3457, 9425}, - { 4192, 9343},{ 4842, 9247},{ 5417, 9162},{ 5935, 9086}, - { 6404, 9011},{ 6841, 8952},{ 7241, 8907},{ 7609, 8867}, - { 7953, 8832},{ 8267, 8792},{ 8562, 8740},{ 8836, 8701} - } - }, - { - /*Cb qi=29 INTRA*/ - { - { 5, 3},{ 84, 368},{ 144, 746},{ 176, 1175}, - { 219, 1604},{ 285, 1991},{ 372, 2318},{ 462, 2591}, - { 546, 2833},{ 628, 3058},{ 704, 3274},{ 788, 3473}, - { 870, 3664},{ 935, 3865},{ 995, 4059},{ 1072, 4239}, - { 1167, 4388},{ 1248, 4518},{ 1334, 4634},{ 1429, 4765}, - { 1536, 4884},{ 1628, 4964},{ 1716, 5038},{ 1885, 5128} - }, - /*Cb qi=29 INTER*/ - { - { 126, 25},{ 95, 340},{ 69, 662},{ 71, 1039}, - { 88, 1440},{ 102, 1839},{ 113, 2227},{ 122, 2604}, - { 132, 2969},{ 141, 3320},{ 151, 3659},{ 161, 3985}, - { 172, 4301},{ 186, 4612},{ 200, 4917},{ 219, 5213}, - { 241, 5509},{ 265, 5800},{ 296, 6081},{ 329, 6360}, - { 369, 6633},{ 414, 6899},{ 465, 7148},{ 520, 7387} - } - }, - { - /*Cr qi=29 INTRA*/ - { - { 6, 7},{ 82, 382},{ 142, 772},{ 185, 1211}, - { 233, 1632},{ 303, 2000},{ 388, 2306},{ 475, 2550}, - { 556, 2779},{ 627, 3007},{ 707, 3237},{ 778, 3459}, - { 843, 3654},{ 927, 3834},{ 1012, 4012},{ 1101, 4152}, - { 1197, 4262},{ 1275, 4399},{ 1359, 4511},{ 1455, 4596}, - { 1562, 4708},{ 1644, 4833},{ 1719, 4954},{ 1888, 4988} - }, - /*Cr qi=29 INTER*/ - { - { 101, 28},{ 81, 343},{ 67, 673},{ 75, 1053}, - { 93, 1450},{ 106, 1844},{ 113, 2230},{ 119, 2610}, - { 127, 2980},{ 135, 3334},{ 143, 3676},{ 153, 4007}, - { 165, 4330},{ 180, 4645},{ 201, 4951},{ 224, 5243}, - { 253, 5522},{ 284, 5794},{ 314, 6060},{ 345, 6322}, - { 381, 6578},{ 419, 6828},{ 455, 7073},{ 495, 7316} - } - } - }, - { - { - /*Y' qi=30 INTRA*/ - { - { 112, 8},{ 335, 1380},{ 682, 2401},{ 1083, 3093}, - { 1489, 3619},{ 1902, 4092},{ 2332, 4511},{ 2777, 4865}, - { 3231, 5156},{ 3693, 5394},{ 4153, 5585},{ 4605, 5689}, - { 5049, 5764},{ 5468, 5871},{ 5875, 6004},{ 6295, 6120}, - { 6706, 6201},{ 7099, 6273},{ 7461, 6311},{ 7785, 6320}, - { 8128, 6322},{ 8469, 6331},{ 8806, 6342},{ 9220, 6338} - }, - /*Y' qi=30 INTER*/ - { - { 58, 8},{ 90, 1340},{ 169, 2771},{ 257, 4079}, - { 345, 5266},{ 459, 6387},{ 660, 7383},{ 990, 8180}, - { 1496, 8726},{ 2203, 8992},{ 3029, 9038},{ 3833, 8984}, - { 4549, 8900},{ 5183, 8813},{ 5745, 8735},{ 6250, 8674}, - { 6715, 8619},{ 7138, 8565},{ 7529, 8528},{ 7899, 8495}, - { 8234, 8465},{ 8550, 8429},{ 8856, 8395},{ 9160, 8374} - } - }, - { - /*Cb qi=30 INTRA*/ - { - { 7, 3},{ 88, 369},{ 149, 747},{ 185, 1175}, - { 232, 1599},{ 304, 1976},{ 392, 2293},{ 486, 2557}, - { 573, 2797},{ 656, 3027},{ 735, 3243},{ 819, 3442}, - { 903, 3629},{ 966, 3828},{ 1025, 4027},{ 1105, 4204}, - { 1201, 4343},{ 1282, 4469},{ 1379, 4575},{ 1486, 4689}, - { 1588, 4813},{ 1678, 4900},{ 1767, 4969},{ 1911, 5080} - }, - /*Cb qi=30 INTER*/ - { - { 120, 23},{ 96, 336},{ 72, 661},{ 75, 1043}, - { 91, 1441},{ 105, 1837},{ 117, 2221},{ 127, 2592}, - { 137, 2953},{ 148, 3301},{ 159, 3635},{ 170, 3959}, - { 184, 4271},{ 199, 4578},{ 216, 4879},{ 238, 5175}, - { 262, 5466},{ 294, 5750},{ 332, 6027},{ 373, 6298}, - { 421, 6559},{ 473, 6805},{ 526, 7053},{ 587, 7298} - } - }, - { - /*Cr qi=30 INTRA*/ - { - { 10, 7},{ 89, 384},{ 147, 773},{ 192, 1211}, - { 245, 1627},{ 322, 1984},{ 412, 2280},{ 501, 2520}, - { 583, 2750},{ 654, 2982},{ 736, 3207},{ 810, 3419}, - { 873, 3614},{ 957, 3794},{ 1048, 3965},{ 1139, 4102}, - { 1237, 4208},{ 1327, 4328},{ 1408, 4448},{ 1496, 4545}, - { 1604, 4652},{ 1699, 4760},{ 1780, 4877},{ 1937, 4942} - }, - /*Cr qi=30 INTER*/ - { - { 115, 26},{ 89, 342},{ 70, 672},{ 79, 1055}, - { 96, 1451},{ 108, 1841},{ 116, 2222},{ 124, 2599}, - { 132, 2965},{ 141, 3316},{ 151, 3655},{ 163, 3984}, - { 178, 4301},{ 197, 4609},{ 219, 4909},{ 247, 5195}, - { 280, 5469},{ 317, 5734},{ 351, 5991},{ 383, 6248}, - { 423, 6500},{ 467, 6744},{ 502, 6995},{ 558, 7226} - } - } - }, - { - { - /*Y' qi=31 INTRA*/ - { - { 116, 20},{ 359, 1361},{ 732, 2350},{ 1162, 3010}, - { 1597, 3507},{ 2042, 3950},{ 2503, 4339},{ 2974, 4670}, - { 3446, 4951},{ 3922, 5179},{ 4394, 5357},{ 4858, 5454}, - { 5313, 5519},{ 5734, 5626},{ 6154, 5755},{ 6585, 5859}, - { 7004, 5928},{ 7408, 5998},{ 7775, 6039},{ 8102, 6048}, - { 8442, 6051},{ 8790, 6054},{ 9136, 6057},{ 9554, 6041} - }, - /*Y' qi=31 INTER*/ - { - { 53, 12},{ 90, 1340},{ 169, 2765},{ 259, 4062}, - { 353, 5236},{ 483, 6340},{ 713, 7305},{ 1086, 8059}, - { 1651, 8548},{ 2423, 8751},{ 3288, 8754},{ 4106, 8674}, - { 4827, 8572},{ 5451, 8482},{ 6007, 8407},{ 6514, 8344}, - { 6970, 8282},{ 7397, 8225},{ 7795, 8193},{ 8159, 8161}, - { 8498, 8120},{ 8814, 8093},{ 9127, 8066},{ 9432, 8040} - } - }, - { - /*Cb qi=31 INTRA*/ - { - { 7, 3},{ 88, 369},{ 149, 746},{ 185, 1173}, - { 234, 1595},{ 308, 1967},{ 399, 2278},{ 494, 2537}, - { 583, 2774},{ 669, 2997},{ 755, 3204},{ 847, 3390}, - { 936, 3569},{ 1008, 3759},{ 1078, 3942},{ 1162, 4104}, - { 1262, 4238},{ 1352, 4364},{ 1442, 4470},{ 1557, 4567}, - { 1676, 4674},{ 1759, 4781},{ 1850, 4853},{ 2043, 4897} - }, - /*Cb qi=31 INTER*/ - { - { 121, 23},{ 96, 335},{ 72, 660},{ 74, 1043}, - { 90, 1440},{ 105, 1834},{ 116, 2217},{ 127, 2586}, - { 138, 2945},{ 148, 3293},{ 159, 3626},{ 172, 3945}, - { 185, 4256},{ 202, 4559},{ 223, 4856},{ 245, 5150}, - { 272, 5440},{ 306, 5719},{ 346, 5989},{ 391, 6253}, - { 443, 6511},{ 510, 6743},{ 583, 6965},{ 651, 7182} - } - }, - { - /*Cr qi=31 INTRA*/ - { - { 10, 7},{ 88, 384},{ 147, 773},{ 192, 1209}, - { 247, 1622},{ 326, 1974},{ 417, 2262},{ 509, 2500}, - { 596, 2726},{ 670, 2949},{ 754, 3170},{ 836, 3370}, - { 912, 3548},{ 999, 3724},{ 1093, 3888},{ 1198, 4000}, - { 1304, 4095},{ 1384, 4230},{ 1470, 4347},{ 1577, 4422}, - { 1696, 4513},{ 1798, 4620},{ 1869, 4746},{ 1991, 4798} - }, - /*Cr qi=31 INTER*/ - { - { 113, 32},{ 88, 345},{ 69, 674},{ 79, 1055}, - { 96, 1451},{ 108, 1839},{ 115, 2218},{ 123, 2592}, - { 132, 2957},{ 141, 3308},{ 151, 3643},{ 163, 3968}, - { 179, 4285},{ 200, 4590},{ 225, 4886},{ 254, 5169}, - { 291, 5436},{ 330, 5696},{ 368, 5951},{ 409, 6200}, - { 452, 6448},{ 493, 6695},{ 536, 6940},{ 571, 7204} - } - } - }, - { - { - /*Y' qi=32 INTRA*/ - { - { 123, 26},{ 370, 1356},{ 756, 2321},{ 1211, 2944}, - { 1674, 3408},{ 2148, 3826},{ 2639, 4193},{ 3138, 4504}, - { 3634, 4765},{ 4133, 4973},{ 4625, 5137},{ 5101, 5225}, - { 5567, 5274},{ 6002, 5363},{ 6437, 5482},{ 6885, 5566}, - { 7312, 5625},{ 7723, 5686},{ 8101, 5721},{ 8429, 5732}, - { 8769, 5728},{ 9120, 5726},{ 9472, 5723},{ 9918, 5700} - }, - /*Y' qi=32 INTER*/ - { - { 54, -3},{ 95, 1343},{ 179, 2750},{ 276, 4027}, - { 382, 5185},{ 543, 6256},{ 830, 7161},{ 1301, 7815}, - { 2003, 8172},{ 2883, 8266},{ 3779, 8217},{ 4578, 8127}, - { 5274, 8035},{ 5886, 7952},{ 6430, 7887},{ 6929, 7835}, - { 7380, 7779},{ 7796, 7737},{ 8190, 7705},{ 8552, 7672}, - { 8896, 7640},{ 9210, 7612},{ 9510, 7589},{ 9746, 7552} - } - }, - { - /*Cb qi=32 INTRA*/ - { - { 6, 3},{ 89, 369},{ 153, 746},{ 193, 1167}, - { 247, 1577},{ 330, 1935},{ 429, 2236},{ 528, 2494}, - { 620, 2732},{ 712, 2948},{ 801, 3146},{ 898, 3325}, - { 999, 3489},{ 1078, 3664},{ 1155, 3832},{ 1251, 3985}, - { 1360, 4115},{ 1451, 4236},{ 1549, 4338},{ 1667, 4433}, - { 1797, 4522},{ 1891, 4613},{ 1989, 4687},{ 2162, 4776} - }, - /*Cb qi=32 INTER*/ - { - { 116, -1},{ 98, 321},{ 80, 656},{ 80, 1042}, - { 96, 1438},{ 110, 1827},{ 122, 2205},{ 133, 2570}, - { 144, 2925},{ 157, 3268},{ 170, 3597},{ 185, 3911}, - { 202, 4216},{ 221, 4516},{ 244, 4809},{ 273, 5096}, - { 308, 5376},{ 350, 5644},{ 401, 5907},{ 459, 6160}, - { 520, 6401},{ 592, 6630},{ 676, 6837},{ 758, 7050} - } - }, - { - /*Cr qi=32 INTRA*/ - { - { 12, 7},{ 91, 386},{ 152, 773},{ 201, 1202}, - { 261, 1603},{ 347, 1942},{ 447, 2223},{ 540, 2460}, - { 626, 2684},{ 711, 2901},{ 801, 3115},{ 887, 3312}, - { 969, 3480},{ 1068, 3633},{ 1176, 3779},{ 1283, 3885}, - { 1392, 3969},{ 1485, 4090},{ 1573, 4206},{ 1686, 4274}, - { 1813, 4354},{ 1911, 4459},{ 2004, 4563},{ 2162, 4590} - }, - /*Cr qi=32 INTER*/ - { - { 129, 5},{ 98, 334},{ 75, 673},{ 84, 1055}, - { 101, 1448},{ 113, 1832},{ 121, 2206},{ 129, 2577}, - { 140, 2937},{ 151, 3282},{ 163, 3614},{ 179, 3932}, - { 198, 4240},{ 221, 4542},{ 252, 4830},{ 290, 5102}, - { 329, 5364},{ 373, 5618},{ 420, 5864},{ 468, 6105}, - { 513, 6351},{ 564, 6587},{ 624, 6810},{ 697, 7017} - } - } - }, - { - { - /*Y' qi=33 INTRA*/ - { - { 115, 36},{ 388, 1338},{ 791, 2289},{ 1258, 2899}, - { 1732, 3352},{ 2220, 3760},{ 2730, 4117},{ 3244, 4415}, - { 3751, 4662},{ 4261, 4858},{ 4766, 5012},{ 5249, 5094}, - { 5719, 5141},{ 6159, 5225},{ 6597, 5333},{ 7044, 5416}, - { 7474, 5472},{ 7893, 5531},{ 8268, 5570},{ 8591, 5580}, - { 8931, 5578},{ 9283, 5579},{ 9634, 5582},{10067, 5560} - }, - /*Y' qi=33 INTER*/ - { - { 65, -14},{ 102, 1345},{ 190, 2736},{ 294, 3999}, - { 411, 5146},{ 597, 6192},{ 934, 7045},{ 1488, 7622}, - { 2281, 7895},{ 3213, 7937},{ 4108, 7871},{ 4883, 7784}, - { 5556, 7709},{ 6150, 7643},{ 6685, 7585},{ 7176, 7539}, - { 7620, 7502},{ 8034, 7466},{ 8427, 7435},{ 8793, 7409}, - { 9136, 7386},{ 9446, 7364},{ 9743, 7339},{10025, 7303} - } - }, - { - /*Cb qi=33 INTRA*/ - { - { 5, 3},{ 92, 369},{ 159, 746},{ 203, 1163}, - { 263, 1564},{ 353, 1911},{ 458, 2204},{ 557, 2460}, - { 650, 2697},{ 744, 2913},{ 836, 3110},{ 934, 3292}, - { 1036, 3454},{ 1125, 3616},{ 1204, 3781},{ 1298, 3932}, - { 1410, 4058},{ 1507, 4170},{ 1606, 4265},{ 1725, 4358}, - { 1853, 4445},{ 1955, 4535},{ 2067, 4597},{ 2258, 4663} - }, - /*Cb qi=33 INTER*/ - { - { 109, 37},{ 94, 343},{ 81, 662},{ 85, 1042}, - { 102, 1436},{ 116, 1823},{ 128, 2195},{ 141, 2554}, - { 154, 2906},{ 167, 3246},{ 183, 3570},{ 202, 3881}, - { 220, 4185},{ 241, 4482},{ 268, 4772},{ 302, 5053}, - { 341, 5328},{ 388, 5592},{ 446, 5846},{ 507, 6096}, - { 581, 6328},{ 670, 6534},{ 762, 6731},{ 842, 6922} - } - }, - { - /*Cr qi=33 INTRA*/ - { - { 11, 7},{ 93, 387},{ 158, 774},{ 211, 1197}, - { 278, 1589},{ 372, 1917},{ 475, 2191},{ 569, 2429}, - { 658, 2655},{ 744, 2868},{ 835, 3083},{ 926, 3271}, - { 1010, 3430},{ 1110, 3586},{ 1224, 3724},{ 1336, 3826}, - { 1449, 3908},{ 1547, 4021},{ 1636, 4136},{ 1751, 4200}, - { 1886, 4277},{ 1977, 4384},{ 2070, 4474},{ 2232, 4510} - }, - /*Cr qi=33 INTER*/ - { - { 77, 9},{ 90, 347},{ 80, 674},{ 91, 1053}, - { 107, 1444},{ 119, 1825},{ 127, 2196},{ 137, 2563}, - { 149, 2919},{ 161, 3259},{ 176, 3588},{ 194, 3905}, - { 217, 4209},{ 246, 4504},{ 280, 4786},{ 320, 5055}, - { 364, 5316},{ 409, 5565},{ 460, 5804},{ 517, 6039}, - { 578, 6264},{ 640, 6489},{ 701, 6721},{ 772, 6948} - } - } - }, - { - { - /*Y' qi=34 INTRA*/ - { - { 124, 40},{ 401, 1333},{ 823, 2262},{ 1318, 2842}, - { 1823, 3265},{ 2339, 3650},{ 2872, 3991},{ 3405, 4274}, - { 3926, 4513},{ 4448, 4704},{ 4961, 4845},{ 5450, 4921}, - { 5925, 4971},{ 6372, 5053},{ 6813, 5160},{ 7264, 5242}, - { 7704, 5291},{ 8124, 5346},{ 8500, 5382},{ 8831, 5384}, - { 9178, 5380},{ 9525, 5387},{ 9869, 5389},{10310, 5356} - }, - /*Y' qi=34 INTER*/ - { - { 64, -17},{ 101, 1344},{ 190, 2730},{ 299, 3981}, - { 430, 5110},{ 648, 6127},{ 1036, 6933},{ 1664, 7445}, - { 2535, 7652},{ 3504, 7653},{ 4402, 7572},{ 5173, 7479}, - { 5843, 7400},{ 6441, 7334},{ 6976, 7280},{ 7464, 7231}, - { 7910, 7189},{ 8332, 7157},{ 8730, 7125},{ 9091, 7103}, - { 9422, 7086},{ 9753, 7061},{10067, 7036},{10316, 7029} - } - }, - { - /*Cb qi=34 INTRA*/ - { - { 5, 3},{ 91, 369},{ 158, 746},{ 204, 1162}, - { 266, 1561},{ 358, 1903},{ 466, 2189},{ 570, 2439}, - { 665, 2671},{ 765, 2880},{ 864, 3069},{ 970, 3238}, - { 1079, 3392},{ 1174, 3545},{ 1265, 3693},{ 1360, 3841}, - { 1471, 3968},{ 1572, 4083},{ 1675, 4181},{ 1804, 4255}, - { 1939, 4332},{ 2048, 4411},{ 2155, 4484},{ 2339, 4584} - }, - /*Cb qi=34 INTER*/ - { - { 99, 44},{ 92, 345},{ 82, 661},{ 86, 1043}, - { 101, 1436},{ 116, 1821},{ 128, 2191},{ 140, 2549}, - { 154, 2898},{ 168, 3235},{ 185, 3556},{ 203, 3865}, - { 224, 4166},{ 248, 4457},{ 278, 4741},{ 315, 5021}, - { 361, 5289},{ 416, 5546},{ 483, 5792},{ 559, 6025}, - { 651, 6237},{ 752, 6432},{ 849, 6626},{ 967, 6790} - } - }, - { - /*Cr qi=34 INTRA*/ - { - { 11, 7},{ 93, 387},{ 158, 773},{ 212, 1195}, - { 282, 1584},{ 378, 1909},{ 483, 2179},{ 578, 2414}, - { 671, 2633},{ 766, 2837},{ 866, 3038},{ 960, 3223}, - { 1049, 3376},{ 1158, 3520},{ 1285, 3644},{ 1400, 3740}, - { 1505, 3828},{ 1616, 3928},{ 1713, 4030},{ 1820, 4104}, - { 1957, 4185},{ 2063, 4280},{ 2160, 4355},{ 2320, 4341} - }, - /*Cr qi=34 INTER*/ - { - { 78, 11},{ 89, 347},{ 79, 674},{ 90, 1053}, - { 106, 1444},{ 117, 1823},{ 127, 2192},{ 137, 2558}, - { 149, 2912},{ 163, 3249},{ 178, 3574},{ 197, 3888}, - { 222, 4189},{ 252, 4481},{ 293, 4755},{ 341, 5013}, - { 386, 5268},{ 436, 5512},{ 498, 5743},{ 563, 5970}, - { 622, 6200},{ 694, 6415},{ 776, 6622},{ 871, 6818} - } - } - }, - { - { - /*Y' qi=35 INTRA*/ - { - { 116, 51},{ 433, 1312},{ 881, 2221},{ 1406, 2771}, - { 1948, 3156},{ 2511, 3501},{ 3085, 3811},{ 3654, 4066}, - { 4212, 4273},{ 4763, 4444},{ 5298, 4572},{ 5799, 4638}, - { 6285, 4678},{ 6747, 4746},{ 7203, 4838},{ 7673, 4905}, - { 8124, 4950},{ 8552, 5003},{ 8938, 5027},{ 9275, 5026}, - { 9628, 5019},{ 9981, 5024},{10331, 5030},{10795, 5000} - }, - /*Y' qi=35 INTER*/ - { - { 71, -10},{ 108, 1348},{ 203, 2710},{ 325, 3938}, - { 485, 5040},{ 766, 6000},{ 1267, 6706},{ 2048, 7089}, - { 3037, 7191},{ 4032, 7146},{ 4903, 7061},{ 5648, 6977}, - { 6301, 6912},{ 6884, 6857},{ 7413, 6812},{ 7898, 6775}, - { 8342, 6739},{ 8764, 6710},{ 9160, 6688},{ 9519, 6668}, - { 9859, 6646},{10190, 6625},{10492, 6612},{10755, 6595} - } - }, - { - /*Cb qi=35 INTRA*/ - { - { 6, 3},{ 95, 369},{ 164, 746},{ 214, 1156}, - { 287, 1542},{ 390, 1869},{ 504, 2143},{ 611, 2388}, - { 712, 2613},{ 822, 2811},{ 937, 2987},{ 1055, 3147}, - { 1174, 3285},{ 1286, 3420},{ 1386, 3560},{ 1488, 3698}, - { 1604, 3814},{ 1714, 3916},{ 1825, 4008},{ 1958, 4088}, - { 2101, 4159},{ 2224, 4226},{ 2339, 4292},{ 2538, 4383} - }, - /*Cb qi=35 INTER*/ - { - { 98, 41},{ 90, 348},{ 86, 665},{ 92, 1042}, - { 108, 1432},{ 122, 1812},{ 136, 2175},{ 151, 2528}, - { 165, 2872},{ 182, 3202},{ 202, 3516},{ 225, 3819}, - { 251, 4112},{ 281, 4398},{ 320, 4675},{ 367, 4944}, - { 421, 5204},{ 493, 5450},{ 579, 5679},{ 672, 5892}, - { 785, 6082},{ 906, 6258},{ 1026, 6432},{ 1153, 6592} - } - }, - { - /*Cr qi=35 INTRA*/ - { - { 12, 7},{ 98, 388},{ 166, 773},{ 226, 1187}, - { 306, 1563},{ 411, 1874},{ 524, 2134},{ 622, 2365}, - { 721, 2577},{ 826, 2768},{ 947, 2946},{ 1066, 3106}, - { 1163, 3250},{ 1274, 3395},{ 1417, 3508},{ 1539, 3590}, - { 1639, 3671},{ 1754, 3765},{ 1865, 3855},{ 1979, 3921}, - { 2127, 3998},{ 2249, 4085},{ 2346, 4172},{ 2473, 4210} - }, - /*Cr qi=35 INTER*/ - { - { 86, 12},{ 94, 354},{ 85, 677},{ 96, 1052}, - { 113, 1439},{ 125, 1811},{ 135, 2177},{ 147, 2537}, - { 160, 2884},{ 177, 3215},{ 195, 3535},{ 219, 3842}, - { 252, 4133},{ 292, 4413},{ 339, 4680},{ 396, 4928}, - { 455, 5169},{ 514, 5408},{ 588, 5626},{ 672, 5835}, - { 750, 6051},{ 837, 6257},{ 943, 6442},{ 1073, 6595} - } - } - }, - { - { - /*Y' qi=36 INTRA*/ - { - { 116, 52},{ 432, 1312},{ 881, 2215},{ 1407, 2759}, - { 1948, 3140},{ 2511, 3484},{ 3090, 3789},{ 3672, 4036}, - { 4243, 4236},{ 4803, 4397},{ 5346, 4517},{ 5856, 4581}, - { 6350, 4614},{ 6821, 4675},{ 7286, 4763},{ 7754, 4832}, - { 8201, 4875},{ 8631, 4922},{ 9015, 4948},{ 9351, 4945}, - { 9706, 4941},{10061, 4948},{10408, 4949},{10878, 4923} - }, - /*Y' qi=36 INTER*/ - { - { 63, -16},{ 114, 1332},{ 216, 2690},{ 343, 3914}, - { 515, 5009},{ 829, 5939},{ 1399, 6586},{ 2263, 6901}, - { 3290, 6967},{ 4272, 6920},{ 5115, 6847},{ 5839, 6779}, - { 6478, 6726},{ 7051, 6685},{ 7571, 6649},{ 8050, 6614}, - { 8495, 6587},{ 8908, 6567},{ 9298, 6550},{ 9673, 6530}, - {10005, 6512},{10324, 6499},{10640, 6483},{10936, 6487} - } - }, - { - /*Cb qi=36 INTRA*/ - { - { 6, 3},{ 98, 370},{ 170, 746},{ 225, 1150}, - { 306, 1527},{ 416, 1845},{ 534, 2116},{ 642, 2363}, - { 743, 2591},{ 851, 2794},{ 964, 2972},{ 1081, 3133}, - { 1198, 3275},{ 1311, 3410},{ 1411, 3547},{ 1519, 3680}, - { 1642, 3789},{ 1750, 3892},{ 1860, 3982},{ 1998, 4054}, - { 2141, 4129},{ 2256, 4204},{ 2372, 4278},{ 2567, 4356} - }, - /*Cb qi=36 INTER*/ - { - { 107, 30},{ 96, 346},{ 88, 667},{ 100, 1039}, - { 115, 1426},{ 128, 1804},{ 142, 2164},{ 158, 2512}, - { 176, 2851},{ 195, 3178},{ 218, 3491},{ 243, 3791}, - { 270, 4084},{ 307, 4365},{ 348, 4638},{ 397, 4908}, - { 464, 5157},{ 545, 5392},{ 635, 5620},{ 734, 5831}, - { 854, 6015},{ 993, 6170},{ 1124, 6327},{ 1234, 6502} - } - }, - { - /*Cr qi=36 INTRA*/ - { - { 12, 7},{ 102, 388},{ 172, 773},{ 239, 1182}, - { 328, 1546},{ 439, 1848},{ 554, 2106},{ 651, 2341}, - { 747, 2561},{ 850, 2757},{ 972, 2934},{ 1086, 3097}, - { 1182, 3245},{ 1302, 3382},{ 1447, 3491},{ 1572, 3567}, - { 1677, 3641},{ 1793, 3733},{ 1899, 3828},{ 2013, 3894}, - { 2163, 3967},{ 2283, 4059},{ 2387, 4142},{ 2559, 4145} - }, - /*Cr qi=36 INTER*/ - { - { 98, -10},{ 96, 347},{ 89, 676},{ 102, 1048}, - { 118, 1433},{ 130, 1804},{ 141, 2167},{ 154, 2523}, - { 171, 2866},{ 190, 3194},{ 212, 3508},{ 240, 3809}, - { 276, 4099},{ 320, 4377},{ 372, 4638},{ 428, 4887}, - { 492, 5122},{ 560, 5353},{ 638, 5572},{ 725, 5779}, - { 814, 5985},{ 902, 6192},{ 1013, 6377},{ 1155, 6527} - } - } - }, - { - { - /*Y' qi=37 INTRA*/ - { - { 109, 58},{ 445, 1302},{ 927, 2177},{ 1489, 2689}, - { 2053, 3052},{ 2632, 3387},{ 3230, 3683},{ 3830, 3922}, - { 4417, 4114},{ 4992, 4266},{ 5546, 4375},{ 6067, 4430}, - { 6571, 4459},{ 7046, 4516},{ 7513, 4599},{ 7991, 4663}, - { 8445, 4706},{ 8883, 4749},{ 9273, 4771},{ 9612, 4770}, - { 9970, 4765},{10325, 4773},{10672, 4778},{11106, 4758} - }, - /*Y' qi=37 INTER*/ - { - { 56, -14},{ 114, 1333},{ 218, 2683},{ 354, 3894}, - { 550, 4966},{ 916, 5854},{ 1569, 6437},{ 2520, 6685}, - { 3596, 6704},{ 4585, 6635},{ 5424, 6556},{ 6147, 6489}, - { 6787, 6437},{ 7358, 6395},{ 7876, 6358},{ 8361, 6325}, - { 8807, 6294},{ 9229, 6271},{ 9631, 6253},{10002, 6238}, - {10356, 6228},{10678, 6212},{10975, 6197},{11274, 6185} - } - }, - { - /*Cb qi=37 INTRA*/ - { - { 6, 3},{ 99, 370},{ 171, 746},{ 227, 1149}, - { 309, 1522},{ 421, 1836},{ 541, 2104},{ 652, 2347}, - { 757, 2572},{ 871, 2768},{ 989, 2936},{ 1111, 3087}, - { 1238, 3223},{ 1357, 3352},{ 1465, 3486},{ 1576, 3612}, - { 1709, 3705},{ 1828, 3801},{ 1937, 3895},{ 2076, 3967}, - { 2220, 4035},{ 2345, 4104},{ 2466, 4173},{ 2680, 4265} - }, - /*Cb qi=37 INTER*/ - { - { 111, 27},{ 97, 344},{ 87, 667},{ 99, 1038}, - { 115, 1425},{ 128, 1802},{ 143, 2160},{ 159, 2506}, - { 176, 2843},{ 198, 3167},{ 220, 3477},{ 247, 3774}, - { 280, 4061},{ 321, 4338},{ 368, 4608},{ 427, 4867}, - { 501, 5109},{ 595, 5332},{ 701, 5544},{ 818, 5738}, - { 956, 5905},{ 1105, 6066},{ 1248, 6217},{ 1381, 6353} - } - }, - { - /*Cr qi=37 INTRA*/ - { - { 12, 7},{ 102, 388},{ 173, 773},{ 242, 1180}, - { 331, 1541},{ 444, 1839},{ 562, 2095},{ 662, 2326}, - { 763, 2540},{ 871, 2728},{ 1003, 2892},{ 1130, 3045}, - { 1230, 3188},{ 1350, 3321},{ 1503, 3418},{ 1634, 3492}, - { 1737, 3568},{ 1856, 3653},{ 1970, 3744},{ 2091, 3802}, - { 2247, 3871},{ 2371, 3962},{ 2477, 4041},{ 2655, 4052} - }, - /*Cr qi=37 INTER*/ - { - { 89, -9},{ 97, 347},{ 88, 677},{ 102, 1048}, - { 118, 1432},{ 130, 1802},{ 141, 2163},{ 154, 2517}, - { 172, 2857},{ 192, 3181},{ 216, 3494},{ 246, 3793}, - { 286, 4074},{ 337, 4343},{ 395, 4600},{ 464, 4837}, - { 534, 5066},{ 608, 5289},{ 694, 5501},{ 788, 5704}, - { 893, 5901},{ 1010, 6088},{ 1151, 6249},{ 1331, 6374} - } - } - }, - { - { - /*Y' qi=38 INTRA*/ - { - { 107, 65},{ 476, 1286},{ 968, 2148},{ 1548, 2641}, - { 2141, 2979},{ 2757, 3289},{ 3390, 3564},{ 4020, 3784}, - { 4632, 3957},{ 5224, 4097},{ 5794, 4201},{ 6326, 4250}, - { 6828, 4274},{ 7309, 4322},{ 7790, 4401},{ 8271, 4463}, - { 8729, 4498},{ 9165, 4540},{ 9552, 4566},{ 9901, 4560}, - {10266, 4552},{10617, 4563},{10964, 4572},{11393, 4567} - }, - /*Y' qi=38 INTER*/ - { - { 57, -13},{ 118, 1332},{ 233, 2665},{ 386, 3856}, - { 620, 4899},{ 1070, 5722},{ 1849, 6211},{ 2898, 6384}, - { 3989, 6376},{ 4947, 6311},{ 5754, 6249},{ 6454, 6199}, - { 7077, 6161},{ 7640, 6132},{ 8159, 6101},{ 8639, 6076}, - { 9081, 6054},{ 9502, 6037},{ 9900, 6027},{10274, 6012}, - {10621, 5999},{10938, 5991},{11237, 5977},{11557, 5966} - } - }, - { - /*Cb qi=38 INTRA*/ - { - { 8, 3},{ 104, 370},{ 179, 744},{ 243, 1139}, - { 338, 1498},{ 458, 1801},{ 584, 2060},{ 700, 2297}, - { 812, 2514},{ 935, 2699},{ 1061, 2858},{ 1189, 3007}, - { 1321, 3141},{ 1446, 3266},{ 1563, 3388},{ 1684, 3512}, - { 1816, 3614},{ 1942, 3702},{ 2055, 3793},{ 2201, 3857}, - { 2357, 3923},{ 2477, 3994},{ 2593, 4061},{ 2768, 4178} - }, - /*Cb qi=38 INTER*/ - { - { 118, 24},{ 102, 342},{ 91, 663},{ 101, 1040}, - { 116, 1427},{ 131, 1799},{ 147, 2152},{ 168, 2491}, - { 191, 2822},{ 215, 3139},{ 244, 3441},{ 276, 3731}, - { 316, 4013},{ 363, 4286},{ 423, 4546},{ 495, 4795}, - { 584, 5028},{ 691, 5242},{ 814, 5439},{ 959, 5608}, - { 1119, 5759},{ 1277, 5906},{ 1449, 6035},{ 1655, 6144} - } - }, - { - /*Cr qi=38 INTRA*/ - { - { 12, 6},{ 106, 387},{ 182, 771},{ 261, 1168}, - { 364, 1514},{ 483, 1802},{ 603, 2053},{ 707, 2282}, - { 817, 2489},{ 933, 2670},{ 1074, 2825},{ 1210, 2967}, - { 1320, 3104},{ 1444, 3229},{ 1599, 3324},{ 1735, 3396}, - { 1846, 3464},{ 1971, 3547},{ 2086, 3646},{ 2206, 3711}, - { 2366, 3773},{ 2499, 3859},{ 2603, 3945},{ 2766, 3952} - }, - /*Cr qi=38 INTER*/ - { - { 86, -9},{ 91, 352},{ 85, 680},{ 102, 1053}, - { 119, 1435},{ 132, 1799},{ 146, 2153},{ 162, 2501}, - { 183, 2835},{ 209, 3154},{ 240, 3458},{ 278, 3751}, - { 327, 4025},{ 388, 4284},{ 455, 4532},{ 529, 4766}, - { 616, 4980},{ 711, 5188},{ 815, 5386},{ 920, 5583}, - { 1042, 5770},{ 1186, 5936},{ 1348, 6080},{ 1542, 6196} - } - } - }, - { - { - /*Y' qi=39 INTRA*/ - { - { 103, 66},{ 479, 1283},{ 998, 2125},{ 1610, 2591}, - { 2223, 2913},{ 2855, 3214},{ 3501, 3482},{ 4146, 3698}, - { 4772, 3868},{ 5376, 3999},{ 5956, 4095},{ 6496, 4140}, - { 7008, 4162},{ 7499, 4209},{ 7987, 4282},{ 8478, 4338}, - { 8947, 4374},{ 9385, 4417},{ 9783, 4437},{10143, 4433}, - {10504, 4424},{10866, 4435},{11225, 4444},{11665, 4430} - }, - /*Y' qi=39 INTER*/ - { - { 56, 2},{ 118, 1332},{ 235, 2660},{ 395, 3843}, - { 653, 4867},{ 1153, 5652},{ 2003, 6089},{ 3113, 6214}, - { 4228, 6178},{ 5189, 6102},{ 6002, 6031},{ 6707, 5976}, - { 7336, 5936},{ 7901, 5900},{ 8424, 5870},{ 8915, 5844}, - { 9361, 5822},{ 9784, 5807},{10187, 5794},{10571, 5778}, - {10931, 5763},{11264, 5751},{11582, 5742},{11916, 5730} - } - }, - { - /*Cb qi=39 INTRA*/ - { - { 8, 3},{ 104, 370},{ 179, 744},{ 244, 1138}, - { 340, 1496},{ 461, 1796},{ 588, 2053},{ 705, 2288}, - { 820, 2503},{ 945, 2684},{ 1073, 2840},{ 1210, 2981}, - { 1352, 3106},{ 1480, 3225},{ 1603, 3342},{ 1728, 3464}, - { 1865, 3559},{ 1990, 3645},{ 2106, 3734},{ 2258, 3796}, - { 2413, 3856},{ 2540, 3920},{ 2667, 3986},{ 2887, 4060} - }, - /*Cb qi=39 INTER*/ - { - { 119, 19},{ 103, 340},{ 90, 664},{ 100, 1040}, - { 115, 1426},{ 131, 1797},{ 148, 2148},{ 169, 2486}, - { 192, 2816},{ 217, 3131},{ 247, 3432},{ 282, 3721}, - { 324, 3999},{ 374, 4268},{ 435, 4526},{ 520, 4766}, - { 621, 4990},{ 738, 5194},{ 878, 5376},{ 1035, 5543}, - { 1202, 5686},{ 1374, 5819},{ 1545, 5950},{ 1729, 6064} - } - }, - { - /*Cr qi=39 INTRA*/ - { - { 12, 6},{ 106, 387},{ 182, 771},{ 262, 1167}, - { 365, 1512},{ 486, 1798},{ 608, 2047},{ 713, 2274}, - { 824, 2479},{ 945, 2655},{ 1091, 2804},{ 1231, 2941}, - { 1346, 3073},{ 1475, 3194},{ 1633, 3282},{ 1778, 3345}, - { 1891, 3414},{ 2013, 3501},{ 2138, 3584},{ 2266, 3640}, - { 2428, 3701},{ 2568, 3782},{ 2674, 3863},{ 2816, 3894} - }, - /*Cr qi=39 INTER*/ - { - { 88, -7},{ 92, 352},{ 85, 680},{ 102, 1053}, - { 119, 1434},{ 132, 1797},{ 146, 2151},{ 163, 2498}, - { 185, 2830},{ 211, 3147},{ 243, 3451},{ 285, 3735}, - { 337, 4005},{ 401, 4260},{ 477, 4499},{ 565, 4721}, - { 655, 4937},{ 749, 5148},{ 858, 5344},{ 979, 5529}, - { 1110, 5710},{ 1264, 5871},{ 1460, 5990},{ 1677, 6086} - } - } - }, - { - { - /*Y' qi=40 INTRA*/ - { - { 98, 71},{ 491, 1274},{ 1023, 2103},{ 1641, 2559}, - { 2257, 2877},{ 2898, 3171},{ 3566, 3429},{ 4233, 3629}, - { 4881, 3784},{ 5499, 3906},{ 6088, 3997},{ 6631, 4040}, - { 7145, 4060},{ 7640, 4107},{ 8128, 4178},{ 8618, 4233}, - { 9077, 4267},{ 9514, 4304},{ 9919, 4324},{10277, 4317}, - {10635, 4312},{10985, 4324},{11338, 4331},{11792, 4334} - }, - /*Y' qi=40 INTER*/ - { - { 63, -26},{ 125, 1331},{ 256, 2640},{ 439, 3801}, - { 757, 4782},{ 1391, 5474},{ 2399, 5805},{ 3582, 5870}, - { 4678, 5824},{ 5600, 5763},{ 6386, 5710},{ 7076, 5667}, - { 7693, 5637},{ 8252, 5610},{ 8775, 5586},{ 9255, 5571}, - { 9694, 5556},{10115, 5541},{10530, 5530},{10903, 5522}, - {11242, 5515},{11596, 5501},{11904, 5482},{12205, 5475} - } - }, - { - /*Cb qi=40 INTRA*/ - { - { 8, 3},{ 108, 371},{ 189, 743},{ 265, 1128}, - { 371, 1475},{ 499, 1767},{ 628, 2022},{ 746, 2256}, - { 864, 2467},{ 991, 2647},{ 1124, 2801},{ 1270, 2933}, - { 1412, 3054},{ 1547, 3165},{ 1677, 3277},{ 1804, 3393}, - { 1946, 3483},{ 2078, 3569},{ 2201, 3651},{ 2352, 3711}, - { 2513, 3766},{ 2643, 3826},{ 2775, 3880},{ 3025, 3919} - }, - /*Cb qi=40 INTER*/ - { - { 114, 35},{ 104, 349},{ 96, 667},{ 106, 1040}, - { 121, 1423},{ 138, 1789},{ 158, 2132},{ 184, 2464}, - { 212, 2787},{ 242, 3095},{ 279, 3389},{ 321, 3671}, - { 374, 3941},{ 438, 4199},{ 517, 4446},{ 617, 4673}, - { 740, 4881},{ 891, 5064},{ 1058, 5225},{ 1239, 5372}, - { 1441, 5499},{ 1638, 5610},{ 1840, 5719},{ 2076, 5814} - } - }, - { - /*Cr qi=40 INTRA*/ - { - { 14, 7},{ 114, 389},{ 193, 771},{ 283, 1156}, - { 399, 1488},{ 523, 1768},{ 643, 2018},{ 752, 2245}, - { 865, 2450},{ 984, 2626},{ 1139, 2763},{ 1290, 2887}, - { 1413, 3014},{ 1550, 3128},{ 1711, 3211},{ 1865, 3268}, - { 1981, 3334},{ 2103, 3415},{ 2237, 3486},{ 2365, 3543}, - { 2529, 3610},{ 2666, 3700},{ 2775, 3779},{ 2929, 3803} - }, - /*Cr qi=40 INTER*/ - { - { 89, -8},{ 95, 353},{ 90, 681},{ 107, 1053}, - { 124, 1430},{ 139, 1787},{ 156, 2136},{ 177, 2477}, - { 203, 2803},{ 237, 3112},{ 276, 3406},{ 329, 3683}, - { 395, 3942},{ 475, 4182},{ 567, 4407},{ 665, 4624}, - { 767, 4834},{ 879, 5032},{ 1011, 5213},{ 1169, 5375}, - { 1348, 5525},{ 1547, 5654},{ 1785, 5743},{ 2066, 5787} - } - } - }, - { - { - /*Y' qi=41 INTRA*/ - { - { 98, 71},{ 495, 1272},{ 1040, 2090},{ 1675, 2533}, - { 2302, 2842},{ 2953, 3132},{ 3631, 3381},{ 4309, 3574}, - { 4966, 3726},{ 5593, 3846},{ 6189, 3934},{ 6738, 3972}, - { 7256, 3991},{ 7754, 4036},{ 8250, 4099},{ 8747, 4150}, - { 9207, 4185},{ 9650, 4222},{10057, 4242},{10411, 4237}, - {10771, 4230},{11127, 4244},{11486, 4254},{11933, 4252} - }, - /*Y' qi=41 INTER*/ - { - { 65, -25},{ 125, 1331},{ 260, 2633},{ 457, 3782}, - { 807, 4740},{ 1499, 5397},{ 2562, 5693},{ 3766, 5743}, - { 4859, 5695},{ 5776, 5638},{ 6556, 5590},{ 7243, 5554}, - { 7859, 5529},{ 8417, 5506},{ 8935, 5486},{ 9419, 5473}, - { 9869, 5460},{10296, 5446},{10711, 5436},{11089, 5430}, - {11445, 5421},{11802, 5412},{12129, 5404},{12465, 5393} - } - }, - { - /*Cb qi=41 INTRA*/ - { - { 8, 3},{ 108, 371},{ 189, 743},{ 267, 1126}, - { 374, 1471},{ 504, 1760},{ 635, 2011},{ 758, 2241}, - { 881, 2447},{ 1013, 2621},{ 1147, 2773},{ 1293, 2906}, - { 1441, 3023},{ 1580, 3131},{ 1712, 3243},{ 1844, 3360}, - { 1985, 3451},{ 2114, 3532},{ 2240, 3613},{ 2390, 3680}, - { 2550, 3740},{ 2687, 3800},{ 2825, 3862},{ 3052, 3944} - }, - /*Cb qi=41 INTER*/ - { - { 104, 39},{ 100, 350},{ 95, 667},{ 105, 1040}, - { 121, 1422},{ 137, 1787},{ 159, 2129},{ 185, 2459}, - { 216, 2778},{ 249, 3083},{ 287, 3374},{ 335, 3653}, - { 393, 3920},{ 462, 4175},{ 549, 4414},{ 660, 4636}, - { 791, 4839},{ 952, 5014},{ 1135, 5166},{ 1337, 5297}, - { 1552, 5411},{ 1752, 5530},{ 1972, 5634},{ 2224, 5724} - } - }, - { - /*Cr qi=41 INTRA*/ - { - { 15, 7},{ 115, 389},{ 193, 770},{ 284, 1154}, - { 401, 1484},{ 528, 1761},{ 652, 2005},{ 764, 2228}, - { 882, 2427},{ 1008, 2599},{ 1167, 2734},{ 1320, 2859}, - { 1443, 2990},{ 1580, 3103},{ 1743, 3181},{ 1894, 3241}, - { 2012, 3309},{ 2141, 3385},{ 2272, 3459},{ 2398, 3519}, - { 2566, 3584},{ 2707, 3680},{ 2816, 3762},{ 2991, 3770} - }, - /*Cr qi=41 INTER*/ - { - { 92, -9},{ 98, 354},{ 90, 682},{ 107, 1052}, - { 124, 1429},{ 139, 1786},{ 156, 2132},{ 178, 2471}, - { 207, 2794},{ 241, 3100},{ 285, 3391},{ 345, 3662}, - { 417, 3915},{ 503, 4151},{ 600, 4375},{ 703, 4589}, - { 815, 4791},{ 942, 4981},{ 1088, 5155},{ 1250, 5316}, - { 1432, 5462},{ 1653, 5575},{ 1930, 5639},{ 2250, 5655} - } - } - }, - { - { - /*Y' qi=42 INTRA*/ - { - { 109, 75},{ 534, 1257},{ 1114, 2047},{ 1793, 2456}, - { 2461, 2735},{ 3157, 2994},{ 3879, 3221},{ 4595, 3396}, - { 5282, 3531},{ 5931, 3638},{ 6546, 3714},{ 7105, 3749}, - { 7633, 3766},{ 8147, 3803},{ 8652, 3865},{ 9148, 3915}, - { 9613, 3946},{10075, 3976},{10489, 3997},{10835, 3994}, - {11195, 3985},{11553, 3997},{11909, 4004},{12369, 3990} - }, - /*Y' qi=42 INTER*/ - { - { 69, -23},{ 134, 1332},{ 287, 2611},{ 521, 3730}, - { 970, 4624},{ 1827, 5176},{ 3028, 5382},{ 4262, 5389}, - { 5325, 5338},{ 6214, 5291},{ 6976, 5255},{ 7651, 5228}, - { 8260, 5206},{ 8821, 5190},{ 9343, 5177},{ 9823, 5165}, - {10273, 5152},{10709, 5143},{11121, 5136},{11502, 5129}, - {11857, 5125},{12193, 5115},{12520, 5107},{12802, 5097} - } - }, - { - /*Cb qi=42 INTRA*/ - { - { 9, 3},{ 113, 371},{ 199, 743},{ 279, 1123}, - { 390, 1462},{ 525, 1743},{ 662, 1986},{ 789, 2208}, - { 916, 2406},{ 1057, 2571},{ 1204, 2712},{ 1362, 2835}, - { 1524, 2943},{ 1676, 3040},{ 1815, 3145},{ 1959, 3249}, - { 2117, 3325},{ 2249, 3406},{ 2377, 3488},{ 2537, 3547}, - { 2706, 3597},{ 2854, 3646},{ 2999, 3705},{ 3236, 3759} - }, - /*Cb qi=42 INTER*/ - { - { 114, 44},{ 107, 353},{ 101, 670},{ 111, 1041}, - { 129, 1418},{ 148, 1775},{ 174, 2110},{ 208, 2432}, - { 244, 2746},{ 283, 3046},{ 330, 3330},{ 388, 3602}, - { 460, 3858},{ 546, 4101},{ 655, 4326},{ 793, 4530}, - { 966, 4703},{ 1165, 4851},{ 1388, 4980},{ 1630, 5088}, - { 1869, 5189},{ 2122, 5268},{ 2403, 5328},{ 2667, 5417} - } - }, - { - /*Cr qi=42 INTRA*/ - { - { 15, 7},{ 120, 390},{ 202, 771},{ 298, 1150}, - { 421, 1473},{ 553, 1743},{ 681, 1982},{ 796, 2199}, - { 923, 2388},{ 1062, 2547},{ 1225, 2678},{ 1392, 2792}, - { 1531, 2907},{ 1682, 3007},{ 1856, 3074},{ 2009, 3134}, - { 2138, 3192},{ 2274, 3257},{ 2407, 3333},{ 2536, 3393}, - { 2711, 3455},{ 2875, 3531},{ 3000, 3598},{ 3186, 3599} - }, - /*Cr qi=42 INTER*/ - { - { 87, -4},{ 95, 358},{ 97, 683},{ 113, 1052}, - { 131, 1423},{ 148, 1774},{ 170, 2116},{ 198, 2448}, - { 234, 2762},{ 276, 3062},{ 331, 3343},{ 404, 3603}, - { 494, 3844},{ 598, 4067},{ 715, 4276},{ 842, 4471}, - { 977, 4661},{ 1128, 4840},{ 1311, 4991},{ 1516, 5127}, - { 1759, 5233},{ 2050, 5300},{ 2377, 5323},{ 2710, 5304} - } - } - }, - { - { - /*Y' qi=43 INTRA*/ - { - { 99, 79},{ 557, 1244},{ 1175, 2016},{ 1882, 2408}, - { 2570, 2677},{ 3288, 2926},{ 4030, 3141},{ 4760, 3307}, - { 5458, 3435},{ 6115, 3537},{ 6743, 3608},{ 7312, 3636}, - { 7841, 3652},{ 8357, 3687},{ 8870, 3742},{ 9376, 3788}, - { 9850, 3821},{10315, 3853},{10734, 3873},{11084, 3870}, - {11442, 3862},{11800, 3874},{12160, 3879},{12618, 3876} - }, - /*Y' qi=43 INTER*/ - { - { 69, -22},{ 134, 1331},{ 294, 2601},{ 551, 3703}, - { 1056, 4563},{ 2003, 5061},{ 3276, 5215},{ 4534, 5194}, - { 5599, 5133},{ 6488, 5083},{ 7257, 5044},{ 7938, 5014}, - { 8556, 4992},{ 9124, 4975},{ 9648, 4960},{10138, 4948}, - {10594, 4939},{11039, 4926},{11462, 4919},{11847, 4912}, - {12216, 4904},{12570, 4896},{12883, 4889},{13189, 4879} - } - }, - { - /*Cb qi=43 INTRA*/ - { - { 9, 3},{ 114, 371},{ 202, 740},{ 294, 1110}, - { 417, 1440},{ 558, 1716},{ 700, 1956},{ 833, 2172}, - { 966, 2365},{ 1116, 2524},{ 1269, 2661},{ 1431, 2781}, - { 1599, 2885},{ 1756, 2980},{ 1902, 3082},{ 2051, 3185}, - { 2209, 3261},{ 2337, 3342},{ 2464, 3420},{ 2633, 3475}, - { 2809, 3525},{ 2948, 3579},{ 3094, 3633},{ 3347, 3678} - }, - /*Cb qi=43 INTER*/ - { - { 111, 44},{ 106, 353},{ 102, 670},{ 112, 1040}, - { 128, 1416},{ 148, 1771},{ 176, 2104},{ 211, 2424}, - { 250, 2734},{ 293, 3030},{ 347, 3309},{ 411, 3575}, - { 490, 3828},{ 589, 4064},{ 716, 4278},{ 869, 4472}, - { 1050, 4640},{ 1264, 4781},{ 1512, 4895},{ 1775, 4991}, - { 2042, 5069},{ 2310, 5141},{ 2593, 5207},{ 2912, 5239} - } - }, - { - /*Cr qi=43 INTRA*/ - { - { 15, 7},{ 121, 390},{ 208, 767},{ 315, 1135}, - { 449, 1449},{ 586, 1715},{ 718, 1950},{ 843, 2158}, - { 977, 2342},{ 1120, 2501},{ 1290, 2632},{ 1466, 2739}, - { 1613, 2845},{ 1763, 2945},{ 1937, 3015},{ 2093, 3070}, - { 2225, 3126},{ 2366, 3194},{ 2501, 3267},{ 2634, 3324}, - { 2815, 3385},{ 2964, 3466},{ 3087, 3538},{ 3263, 3555} - }, - /*Cr qi=43 INTER*/ - { - { 84, -4},{ 93, 358},{ 95, 683},{ 113, 1052}, - { 131, 1421},{ 148, 1770},{ 171, 2110},{ 201, 2439}, - { 240, 2750},{ 287, 3046},{ 348, 3322},{ 429, 3576}, - { 527, 3811},{ 641, 4029},{ 767, 4230},{ 904, 4422}, - { 1053, 4603},{ 1225, 4765},{ 1433, 4903},{ 1661, 5030}, - { 1928, 5121},{ 2252, 5160},{ 2604, 5164},{ 2979, 5125} - } - } - }, - { - { - /*Y' qi=44 INTRA*/ - { - { 103, 80},{ 560, 1244},{ 1183, 2009},{ 1891, 2391}, - { 2586, 2649},{ 3324, 2884},{ 4093, 3089},{ 4850, 3243}, - { 5575, 3358},{ 6252, 3452},{ 6886, 3518},{ 7459, 3546}, - { 7993, 3562},{ 8515, 3594},{ 9030, 3645},{ 9534, 3691}, - {10004, 3723},{10469, 3750},{10887, 3765},{11236, 3766}, - {11596, 3762},{11960, 3775},{12317, 3784},{12766, 3789} - }, - /*Y' qi=44 INTER*/ - { - { 77, -24},{ 145, 1332},{ 332, 2580},{ 642, 3649}, - { 1270, 4438},{ 2360, 4860},{ 3685, 4982},{ 4910, 4966}, - { 5929, 4928},{ 6785, 4900},{ 7529, 4880},{ 8198, 4863}, - { 8804, 4850},{ 9361, 4842},{ 9882, 4836},{10371, 4830}, - {10827, 4822},{11262, 4816},{11672, 4811},{12052, 4807}, - {12431, 4806},{12780, 4798},{13095, 4792},{13401, 4791} - } - }, - { - /*Cb qi=44 INTRA*/ - { - { 9, 2},{ 122, 371},{ 214, 741},{ 307, 1109}, - { 433, 1432},{ 576, 1704},{ 718, 1939},{ 855, 2152}, - { 991, 2340},{ 1141, 2497},{ 1298, 2632},{ 1463, 2749}, - { 1636, 2851},{ 1796, 2944},{ 1947, 3041},{ 2101, 3140}, - { 2260, 3219},{ 2392, 3297},{ 2527, 3366},{ 2693, 3424}, - { 2872, 3477},{ 3025, 3525},{ 3175, 3584},{ 3451, 3626} - }, - /*Cb qi=44 INTER*/ - { - { 111, 14},{ 110, 339},{ 109, 671},{ 120, 1040}, - { 139, 1410},{ 162, 1758},{ 197, 2084},{ 243, 2397}, - { 291, 2702},{ 342, 2992},{ 405, 3265},{ 484, 3521}, - { 584, 3760},{ 705, 3983},{ 855, 4185},{ 1048, 4356}, - { 1274, 4500},{ 1531, 4617},{ 1816, 4707},{ 2111, 4783}, - { 2409, 4846},{ 2720, 4901},{ 3044, 4957},{ 3391, 4985} - } - }, - { - /*Cr qi=44 INTRA*/ - { - { 17, 7},{ 128, 392},{ 219, 770},{ 329, 1135}, - { 465, 1442},{ 601, 1703},{ 734, 1935},{ 862, 2142}, - { 998, 2325},{ 1147, 2482},{ 1321, 2606},{ 1496, 2710}, - { 1649, 2813},{ 1809, 2908},{ 1984, 2977},{ 2143, 3032}, - { 2279, 3087},{ 2423, 3152},{ 2559, 3225},{ 2684, 3288}, - { 2866, 3351},{ 3025, 3426},{ 3161, 3492},{ 3372, 3500} - }, - /*Cr qi=44 INTER*/ - { - { 89, 0},{ 101, 352},{ 104, 683},{ 121, 1051}, - { 141, 1414},{ 163, 1757},{ 192, 2092},{ 231, 2415}, - { 278, 2720},{ 336, 3007},{ 412, 3273},{ 510, 3516}, - { 633, 3733},{ 769, 3936},{ 914, 4130},{ 1076, 4307}, - { 1256, 4472},{ 1469, 4617},{ 1723, 4732},{ 2012, 4822}, - { 2347, 4871},{ 2716, 4875},{ 3082, 4866},{ 3422, 4826} - } - } - }, - { - { - /*Y' qi=45 INTRA*/ - { - { 119, 78},{ 610, 1226},{ 1271, 1965},{ 2026, 2319}, - { 2768, 2550},{ 3556, 2757},{ 4369, 2938},{ 5157, 3076}, - { 5901, 3182},{ 6598, 3268},{ 7253, 3326},{ 7844, 3343}, - { 8392, 3356},{ 8922, 3386},{ 9453, 3433},{ 9973, 3474}, - {10457, 3503},{10929, 3530},{11351, 3543},{11709, 3541}, - {12068, 3537},{12434, 3547},{12805, 3555},{13268, 3563} - }, - /*Y' qi=45 INTER*/ - { - { 77, -20},{ 146, 1330},{ 342, 2566},{ 699, 3604}, - { 1439, 4332},{ 2669, 4672},{ 4075, 4727},{ 5318, 4679}, - { 6345, 4630},{ 7209, 4595},{ 7963, 4570},{ 8644, 4551}, - { 9262, 4535},{ 9831, 4525},{10370, 4515},{10872, 4506}, - {11334, 4500},{11783, 4492},{12219, 4489},{12617, 4483}, - {12995, 4477},{13350, 4472},{13674, 4466},{13968, 4468} - } - }, - { - /*Cb qi=45 INTRA*/ - { - { 9, 2},{ 122, 370},{ 219, 735},{ 324, 1096}, - { 465, 1414},{ 619, 1679},{ 771, 1905},{ 920, 2103}, - { 1070, 2276},{ 1236, 2419},{ 1410, 2539},{ 1595, 2644}, - { 1784, 2736},{ 1949, 2831},{ 2104, 2931},{ 2275, 3021}, - { 2443, 3092},{ 2586, 3166},{ 2735, 3234},{ 2904, 3288}, - { 3093, 3338},{ 3262, 3382},{ 3419, 3427},{ 3708, 3456} - }, - /*Cb qi=45 INTER*/ - { - { 103, 0},{ 109, 339},{ 109, 670},{ 119, 1039}, - { 137, 1408},{ 162, 1754},{ 199, 2076},{ 248, 2386}, - { 301, 2684},{ 360, 2967},{ 433, 3234},{ 525, 3481}, - { 640, 3713},{ 780, 3924},{ 956, 4110},{ 1176, 4266}, - { 1438, 4390},{ 1736, 4481},{ 2057, 4553},{ 2385, 4613}, - { 2718, 4656},{ 3056, 4698},{ 3416, 4733},{ 3799, 4755} - } - }, - { - /*Cr qi=45 INTRA*/ - { - { 16, 7},{ 128, 391},{ 225, 763},{ 350, 1120}, - { 500, 1420},{ 649, 1673},{ 792, 1893},{ 929, 2089}, - { 1084, 2257},{ 1250, 2401},{ 1440, 2518},{ 1633, 2614}, - { 1799, 2708},{ 1968, 2798},{ 2151, 2863},{ 2314, 2914}, - { 2453, 2968},{ 2611, 3025},{ 2759, 3095},{ 2887, 3160}, - { 3082, 3210},{ 3259, 3278},{ 3403, 3342},{ 3593, 3354} - }, - /*Cr qi=45 INTER*/ - { - { 92, 0},{ 101, 352},{ 103, 682},{ 120, 1049}, - { 140, 1412},{ 163, 1752},{ 193, 2083},{ 234, 2402}, - { 287, 2702},{ 353, 2983},{ 442, 3240},{ 557, 3471}, - { 694, 3680},{ 846, 3873},{ 1014, 4056},{ 1200, 4224}, - { 1414, 4369},{ 1664, 4495},{ 1946, 4595},{ 2278, 4654}, - { 2654, 4673},{ 3047, 4658},{ 3438, 4627},{ 3825, 4585} - } - } - }, - { - { - /*Y' qi=46 INTRA*/ - { - { 119, 78},{ 610, 1227},{ 1277, 1960},{ 2043, 2309}, - { 2805, 2529},{ 3618, 2719},{ 4452, 2887},{ 5257, 3016}, - { 6017, 3115},{ 6727, 3195},{ 7392, 3248},{ 7984, 3267}, - { 8528, 3281},{ 9059, 3310},{ 9593, 3354},{10119, 3395}, - {10599, 3425},{11064, 3450},{11493, 3464},{11850, 3466}, - {12207, 3462},{12578, 3471},{12948, 3480},{13407, 3487} - }, - /*Y' qi=46 INTER*/ - { - { 74, -14},{ 149, 1326},{ 382, 2538},{ 807, 3541}, - { 1670, 4211},{ 3000, 4499},{ 4416, 4533},{ 5628, 4490}, - { 6628, 4453},{ 7479, 4425},{ 8228, 4406},{ 8902, 4393}, - { 9521, 4380},{10090, 4371},{10623, 4364},{11124, 4356}, - {11586, 4351},{12043, 4344},{12476, 4341},{12863, 4340}, - {13244, 4337},{13610, 4329},{13936, 4324},{14246, 4329} - } - }, - { - /*Cb qi=46 INTRA*/ - { - { 11, 2},{ 132, 371},{ 234, 737},{ 340, 1094}, - { 481, 1405},{ 637, 1667},{ 791, 1891},{ 944, 2084}, - { 1099, 2253},{ 1268, 2392},{ 1444, 2507},{ 1633, 2610}, - { 1825, 2700},{ 1990, 2794},{ 2147, 2895},{ 2321, 2984}, - { 2493, 3053},{ 2640, 3126},{ 2787, 3198},{ 2954, 3253}, - { 3146, 3297},{ 3313, 3344},{ 3473, 3393},{ 3757, 3434} - }, - /*Cb qi=46 INTER*/ - { - { 97, 0},{ 109, 339},{ 108, 669},{ 120, 1035}, - { 142, 1398},{ 173, 1737},{ 221, 2052},{ 281, 2353}, - { 345, 2646},{ 415, 2924},{ 504, 3183},{ 616, 3421}, - { 749, 3643},{ 914, 3842},{ 1123, 4012},{ 1379, 4150}, - { 1685, 4250},{ 2014, 4327},{ 2366, 4382},{ 2731, 4426}, - { 3083, 4470},{ 3445, 4490},{ 3805, 4511},{ 4146, 4539} - } - }, - { - /*Cr qi=46 INTRA*/ - { - { 19, 7},{ 137, 393},{ 237, 765},{ 364, 1116}, - { 516, 1411},{ 665, 1662},{ 809, 1880},{ 951, 2072}, - { 1109, 2236},{ 1278, 2378},{ 1474, 2491},{ 1669, 2584}, - { 1835, 2678},{ 2014, 2766},{ 2203, 2828},{ 2366, 2880}, - { 2506, 2933},{ 2661, 2988},{ 2810, 3053},{ 2941, 3116}, - { 3131, 3175},{ 3310, 3243},{ 3461, 3303},{ 3656, 3321} - }, - /*Cr qi=46 INTER*/ - { - { 91, 1},{ 103, 351},{ 104, 681},{ 121, 1046}, - { 144, 1401},{ 173, 1736},{ 213, 2060},{ 265, 2373}, - { 330, 2666},{ 410, 2938},{ 517, 3185},{ 655, 3404}, - { 815, 3601},{ 989, 3784},{ 1183, 3951},{ 1400, 4104}, - { 1649, 4241},{ 1933, 4352},{ 2261, 4427},{ 2646, 4458}, - { 3057, 4446},{ 3453, 4418},{ 3820, 4385},{ 4171, 4352} - } - } - }, - { - { - /*Y' qi=47 INTRA*/ - { - { 117, 83},{ 670, 1205},{ 1408, 1904},{ 2239, 2219}, - { 3049, 2414},{ 3905, 2584},{ 4775, 2734},{ 5610, 2852}, - { 6393, 2944},{ 7121, 3017},{ 7804, 3066},{ 8407, 3081}, - { 8957, 3093},{ 9498, 3119},{10043, 3160},{10582, 3199}, - {11083, 3226},{11561, 3250},{11993, 3263},{12352, 3264}, - {12711, 3259},{13092, 3266},{13463, 3271},{13918, 3275} - }, - /*Y' qi=47 INTER*/ - { - { 74, -11},{ 148, 1325},{ 404, 2518},{ 910, 3478}, - { 1916, 4080},{ 3369, 4298},{ 4823, 4292},{ 6035, 4238}, - { 7037, 4197},{ 7894, 4168},{ 8650, 4146},{ 9337, 4129}, - { 9968, 4116},{10549, 4105},{11096, 4096},{11605, 4089}, - {12081, 4083},{12547, 4076},{12990, 4070},{13399, 4070}, - {13776, 4065},{14133, 4059},{14486, 4057},{14842, 4053} - } - }, - { - /*Cb qi=47 INTRA*/ - { - { 11, 2},{ 133, 370},{ 242, 731},{ 367, 1077}, - { 524, 1378},{ 692, 1630},{ 860, 1844},{ 1028, 2024}, - { 1203, 2178},{ 1393, 2305},{ 1582, 2413},{ 1787, 2507}, - { 1992, 2590},{ 2175, 2676},{ 2351, 2767},{ 2534, 2851}, - { 2707, 2923},{ 2862, 2994},{ 3021, 3060},{ 3193, 3111}, - { 3396, 3147},{ 3573, 3184},{ 3752, 3220},{ 4038, 3255} - }, - /*Cb qi=47 INTER*/ - { - { 101, 0},{ 107, 339},{ 108, 667},{ 120, 1033}, - { 142, 1394},{ 175, 1729},{ 227, 2040},{ 295, 2335}, - { 369, 2619},{ 452, 2888},{ 556, 3138},{ 686, 3368}, - { 850, 3574},{ 1050, 3758},{ 1299, 3910},{ 1605, 4024}, - { 1950, 4104},{ 2317, 4163},{ 2689, 4210},{ 3077, 4239}, - { 3466, 4258},{ 3840, 4278},{ 4205, 4298},{ 4515, 4340} - } - }, - { - /*Cr qi=47 INTRA*/ - { - { 19, 7},{ 138, 392},{ 248, 758},{ 396, 1094}, - { 563, 1378},{ 723, 1621},{ 881, 1829},{ 1037, 2011}, - { 1214, 2165},{ 1410, 2290},{ 1623, 2393},{ 1834, 2480}, - { 2016, 2564},{ 2203, 2647},{ 2405, 2707},{ 2569, 2757}, - { 2709, 2810},{ 2871, 2860},{ 3027, 2924},{ 3178, 2980}, - { 3375, 3034},{ 3563, 3097},{ 3724, 3151},{ 3952, 3153} - }, - /*Cr qi=47 INTER*/ - { - { 91, 1},{ 100, 351},{ 102, 681},{ 120, 1043}, - { 144, 1397},{ 175, 1729},{ 219, 2049},{ 277, 2356}, - { 353, 2640},{ 451, 2902},{ 579, 3136},{ 739, 3342}, - { 926, 3525},{ 1125, 3698},{ 1343, 3859},{ 1595, 3998}, - { 1881, 4113},{ 2208, 4205},{ 2589, 4253},{ 3014, 4250}, - { 3444, 4220},{ 3838, 4183},{ 4196, 4147},{ 4521, 4116} - } - } - }, - { - { - /*Y' qi=48 INTRA*/ - { - { 107, 87},{ 681, 1200},{ 1456, 1883},{ 2306, 2193}, - { 3122, 2386},{ 3984, 2548},{ 4862, 2693},{ 5704, 2808}, - { 6495, 2899},{ 7232, 2970},{ 7915, 3018},{ 8524, 3034}, - { 9085, 3043},{ 9635, 3068},{10192, 3108},{10735, 3145}, - {11237, 3171},{11719, 3194},{12153, 3207},{12516, 3206}, - {12888, 3202},{13266, 3210},{13637, 3218},{14101, 3219} - }, - /*Y' qi=48 INTER*/ - { - { 83, -18},{ 147, 1328},{ 398, 2519},{ 923, 3468}, - { 1979, 4047},{ 3472, 4246},{ 4936, 4232},{ 6148, 4178}, - { 7150, 4139},{ 8007, 4111},{ 8765, 4091},{ 9458, 4076}, - {10090, 4063},{10676, 4054},{11226, 4045},{11742, 4038}, - {12223, 4033},{12686, 4029},{13127, 4022},{13527, 4015}, - {13915, 4012},{14277, 4007},{14619, 4004},{14966, 4001} - } - }, - { - /*Cb qi=48 INTRA*/ - { - { 11, 2},{ 134, 369},{ 245, 730},{ 373, 1075}, - { 531, 1374},{ 698, 1625},{ 865, 1839},{ 1033, 2019}, - { 1207, 2173},{ 1397, 2300},{ 1588, 2408},{ 1795, 2501}, - { 2003, 2581},{ 2187, 2666},{ 2362, 2757},{ 2548, 2841}, - { 2719, 2912},{ 2876, 2983},{ 3034, 3047},{ 3209, 3097}, - { 3409, 3137},{ 3589, 3178},{ 3762, 3216},{ 4004, 3252} - }, - /*Cb qi=48 INTER*/ - { - { 113, 26},{ 112, 344},{ 111, 668},{ 120, 1032}, - { 141, 1392},{ 173, 1727},{ 224, 2036},{ 290, 2330}, - { 363, 2612},{ 447, 2880},{ 551, 3130},{ 685, 3358}, - { 852, 3563},{ 1061, 3742},{ 1332, 3884},{ 1654, 3993}, - { 2011, 4068},{ 2394, 4120},{ 2782, 4160},{ 3172, 4186}, - { 3557, 4209},{ 3932, 4228},{ 4306, 4237},{ 4675, 4236} - } - }, - { - /*Cr qi=48 INTRA*/ - { - { 18, 7},{ 139, 389},{ 252, 755},{ 404, 1090}, - { 573, 1372},{ 732, 1615},{ 889, 1823},{ 1045, 2005}, - { 1222, 2159},{ 1417, 2285},{ 1631, 2387},{ 1843, 2474}, - { 2027, 2558},{ 2212, 2639},{ 2413, 2697},{ 2578, 2746}, - { 2720, 2798},{ 2887, 2852},{ 3040, 2913},{ 3181, 2970}, - { 3381, 3024},{ 3581, 3081},{ 3743, 3130},{ 3948, 3133} - }, - /*Cr qi=48 INTER*/ - { - { 89, 0},{ 106, 352},{ 105, 682},{ 120, 1044}, - { 144, 1395},{ 174, 1724},{ 215, 2044},{ 270, 2350}, - { 343, 2635},{ 441, 2895},{ 571, 3129},{ 735, 3334}, - { 926, 3518},{ 1139, 3684},{ 1371, 3836},{ 1628, 3977}, - { 1933, 4089},{ 2279, 4164},{ 2672, 4204},{ 3105, 4205}, - { 3533, 4176},{ 3931, 4135},{ 4290, 4089},{ 4624, 4057} - } - } - }, - { - { - /*Y' qi=49 INTRA*/ - { - { 120, 85},{ 706, 1194},{ 1485, 1875},{ 2348, 2187}, - { 3190, 2372},{ 4076, 2521},{ 4967, 2658},{ 5819, 2771}, - { 6611, 2861},{ 7345, 2936},{ 8026, 2990},{ 8626, 3013}, - { 9182, 3030},{ 9723, 3059},{10266, 3100},{10802, 3143}, - {11293, 3179},{11768, 3206},{12201, 3221},{12556, 3225}, - {12914, 3226},{13281, 3237},{13639, 3247},{14089, 3257} - }, - /*Y' qi=49 INTER*/ - { - { 72, -11},{ 155, 1320},{ 458, 2485},{ 1090, 3386}, - { 2284, 3907},{ 3835, 4075},{ 5272, 4064},{ 6449, 4026}, - { 7426, 4003},{ 8267, 3987},{ 9017, 3976},{ 9698, 3967}, - {10328, 3962},{10913, 3959},{11452, 3954},{11961, 3950}, - {12442, 3947},{12904, 3946},{13347, 3945},{13749, 3943}, - {14123, 3941},{14490, 3941},{14826, 3939},{15153, 3937} - } - }, - { - /*Cb qi=49 INTRA*/ - { - { 11, 2},{ 145, 369},{ 262, 729},{ 393, 1070}, - { 557, 1363},{ 731, 1607},{ 907, 1811},{ 1085, 1983}, - { 1268, 2130},{ 1465, 2251},{ 1658, 2359},{ 1868, 2454}, - { 2079, 2534},{ 2264, 2621},{ 2440, 2717},{ 2625, 2802}, - { 2792, 2878},{ 2945, 2954},{ 3106, 3021},{ 3277, 3075}, - { 3466, 3119},{ 3638, 3170},{ 3824, 3213},{ 4100, 3243} - }, - /*Cb qi=49 INTER*/ - { - { 98, -6},{ 113, 343},{ 110, 669},{ 122, 1029}, - { 149, 1380},{ 192, 1706},{ 258, 2007},{ 340, 2293}, - { 426, 2569},{ 525, 2831},{ 653, 3071},{ 814, 3287}, - { 1013, 3478},{ 1262, 3637},{ 1575, 3761},{ 1936, 3851}, - { 2328, 3910},{ 2741, 3949},{ 3163, 3970},{ 3559, 3994}, - { 3936, 4025},{ 4300, 4050},{ 4655, 4060},{ 4962, 4062} - } - }, - { - /*Cr qi=49 INTRA*/ - { - { 19, 7},{ 151, 389},{ 270, 753},{ 427, 1084}, - { 602, 1360},{ 767, 1595},{ 933, 1794},{ 1098, 1968}, - { 1285, 2115},{ 1489, 2237},{ 1699, 2342},{ 1912, 2435}, - { 2101, 2519},{ 2288, 2601},{ 2486, 2663},{ 2651, 2715}, - { 2799, 2769},{ 2958, 2825},{ 3106, 2890},{ 3257, 2948}, - { 3452, 3007},{ 3634, 3075},{ 3786, 3136},{ 3959, 3164} - }, - /*Cr qi=49 INTER*/ - { - { 85, 1},{ 103, 352},{ 104, 681},{ 121, 1039}, - { 152, 1382},{ 195, 1702},{ 248, 2015},{ 316, 2316}, - { 403, 2595},{ 520, 2847},{ 676, 3068},{ 870, 3258}, - { 1091, 3429},{ 1329, 3585},{ 1597, 3725},{ 1894, 3849}, - { 2242, 3940},{ 2656, 3984},{ 3098, 3992},{ 3531, 3981}, - { 3936, 3950},{ 4304, 3915},{ 4646, 3879},{ 4915, 3861} - } - } - }, - { - { - /*Y' qi=50 INTRA*/ - { - { 122, 89},{ 798, 1170},{ 1682, 1812},{ 2613, 2096}, - { 3501, 2260},{ 4430, 2388},{ 5352, 2510},{ 6228, 2613}, - { 7043, 2698},{ 7793, 2770},{ 8486, 2823},{ 9092, 2846}, - { 9652, 2865},{10210, 2895},{10773, 2936},{11315, 2979}, - {11817, 3014},{12297, 3041},{12734, 3057},{13097, 3064}, - {13443, 3067},{13813, 3078},{14190, 3088},{14646, 3103} - }, - /*Y' qi=50 INTER*/ - { - { 73, -11},{ 154, 1318},{ 501, 2457},{ 1281, 3291}, - { 2685, 3719},{ 4356, 3810},{ 5811, 3769},{ 6988, 3726}, - { 7976, 3700},{ 8835, 3682},{ 9606, 3669},{10307, 3659}, - {10953, 3652},{11556, 3645},{12115, 3643},{12641, 3640}, - {13138, 3636},{13613, 3634},{14068, 3629},{14488, 3627}, - {14876, 3625},{15237, 3621},{15585, 3623},{15922, 3629} - } - }, - { - /*Cb qi=50 INTRA*/ - { - { 11, 2},{ 148, 368},{ 278, 724},{ 431, 1052}, - { 613, 1334},{ 806, 1567},{ 1004, 1756},{ 1203, 1915}, - { 1405, 2051},{ 1621, 2163},{ 1833, 2262},{ 2059, 2347}, - { 2280, 2424},{ 2476, 2512},{ 2670, 2598},{ 2864, 2679}, - { 3037, 2754},{ 3201, 2826},{ 3376, 2887},{ 3562, 2936}, - { 3756, 2976},{ 3932, 3022},{ 4117, 3065},{ 4385, 3094} - }, - /*Cb qi=50 INTER*/ - { - { 92, -3},{ 112, 343},{ 109, 669},{ 121, 1027}, - { 149, 1375},{ 196, 1697},{ 270, 1992},{ 366, 2267}, - { 471, 2532},{ 594, 2782},{ 747, 3011},{ 942, 3212}, - { 1189, 3384},{ 1497, 3521},{ 1875, 3613},{ 2297, 3673}, - { 2739, 3710},{ 3195, 3725},{ 3644, 3737},{ 4057, 3751}, - { 4445, 3763},{ 4841, 3769},{ 5211, 3779},{ 5568, 3769} - } - }, - { - /*Cr qi=50 INTRA*/ - { - { 19, 7},{ 155, 388},{ 290, 744},{ 474, 1060}, - { 666, 1324},{ 847, 1549},{ 1033, 1737},{ 1219, 1898}, - { 1428, 2034},{ 1653, 2147},{ 1885, 2245},{ 2115, 2329}, - { 2316, 2410},{ 2517, 2486},{ 2730, 2539},{ 2901, 2586}, - { 3042, 2638},{ 3199, 2693},{ 3366, 2755},{ 3534, 2805}, - { 3738, 2858},{ 3934, 2916},{ 4079, 2975},{ 4257, 2992} - }, - /*Cr qi=50 INTER*/ - { - { 87, 1},{ 102, 353},{ 103, 680},{ 121, 1036}, - { 153, 1377},{ 199, 1694},{ 260, 1999},{ 339, 2291}, - { 446, 2559},{ 590, 2797},{ 780, 3003},{ 1010, 3176}, - { 1267, 3331},{ 1547, 3474},{ 1874, 3594},{ 2245, 3688}, - { 2666, 3742},{ 3130, 3758},{ 3594, 3748},{ 4028, 3711}, - { 4415, 3674},{ 4771, 3641},{ 5122, 3605},{ 5482, 3569} - } - } - }, - { - { - /*Y' qi=51 INTRA*/ - { - { 115, 93},{ 819, 1164},{ 1739, 1806},{ 2695, 2101}, - { 3612, 2257},{ 4552, 2374},{ 5479, 2490},{ 6352, 2593}, - { 7158, 2683},{ 7898, 2761},{ 8580, 2823},{ 9177, 2854}, - { 9728, 2880},{10268, 2917},{10816, 2966},{11350, 3016}, - {11834, 3058},{12311, 3089},{12741, 3109},{13092, 3119}, - {13434, 3126},{13791, 3142},{14156, 3155},{14590, 3171} - }, - /*Y' qi=51 INTER*/ - { - { 58, 0},{ 171, 1307},{ 610, 2407},{ 1563, 3175}, - { 3116, 3545},{ 4789, 3624},{ 6185, 3602},{ 7320, 3583}, - { 8282, 3574},{ 9124, 3569},{ 9878, 3567},{10569, 3565}, - {11207, 3563},{11801, 3564},{12359, 3566},{12884, 3567}, - {13373, 3568},{13841, 3567},{14289, 3566},{14699, 3568}, - {15086, 3568},{15446, 3566},{15788, 3564},{16103, 3568} - } - }, - { - /*Cb qi=51 INTRA*/ - { - { 14, 3},{ 161, 369},{ 297, 722},{ 454, 1047}, - { 639, 1325},{ 833, 1554},{ 1033, 1742},{ 1236, 1897}, - { 1440, 2032},{ 1653, 2148},{ 1860, 2253},{ 2077, 2347}, - { 2288, 2432},{ 2476, 2525},{ 2661, 2621},{ 2841, 2714}, - { 3010, 2797},{ 3170, 2876},{ 3333, 2945},{ 3510, 3000}, - { 3696, 3054},{ 3865, 3114},{ 4046, 3164},{ 4317, 3200} - }, - /*Cb qi=51 INTER*/ - { - { 88, -11},{ 109, 341},{ 109, 668},{ 126, 1019}, - { 168, 1358},{ 233, 1670},{ 329, 1955},{ 451, 2219}, - { 584, 2472},{ 736, 2711},{ 931, 2923},{ 1179, 3104}, - { 1480, 3254},{ 1846, 3368},{ 2265, 3448},{ 2714, 3501}, - { 3180, 3524},{ 3638, 3529},{ 4074, 3543},{ 4485, 3560}, - { 4868, 3571},{ 5238, 3581},{ 5597, 3594},{ 5953, 3591} - } - }, - { - /*Cr qi=51 INTRA*/ - { - { 24, 7},{ 168, 388},{ 309, 742},{ 496, 1054}, - { 688, 1316},{ 873, 1538},{ 1063, 1723},{ 1252, 1882}, - { 1460, 2018},{ 1682, 2134},{ 1907, 2238},{ 2125, 2332}, - { 2317, 2422},{ 2507, 2510},{ 2705, 2575},{ 2869, 2630}, - { 3015, 2684},{ 3178, 2744},{ 3329, 2815},{ 3477, 2878}, - { 3667, 2945},{ 3848, 3016},{ 3997, 3082},{ 4174, 3121} - }, - /*Cr qi=51 INTER*/ - { - { 83, -2},{ 102, 351},{ 102, 680},{ 126, 1029}, - { 172, 1359},{ 238, 1665},{ 321, 1962},{ 422, 2246}, - { 552, 2505},{ 733, 2728},{ 970, 2912},{ 1247, 3069}, - { 1552, 3209},{ 1876, 3338},{ 2251, 3440},{ 2692, 3502}, - { 3161, 3529},{ 3637, 3525},{ 4084, 3509},{ 4487, 3479}, - { 4850, 3444},{ 5181, 3419},{ 5507, 3406},{ 5786, 3398} - } - } - }, - { - { - /*Y' qi=52 INTRA*/ - { - { 117, 93},{ 814, 1168},{ 1729, 1822},{ 2706, 2119}, - { 3655, 2262},{ 4604, 2374},{ 5528, 2490},{ 6394, 2596}, - { 7189, 2691},{ 7921, 2777},{ 8596, 2846},{ 9184, 2885}, - { 9728, 2918},{10260, 2961},{10796, 3014},{11316, 3069}, - {11793, 3115},{12267, 3150},{12692, 3172},{13037, 3185}, - {13367, 3196},{13717, 3214},{14087, 3227},{14521, 3249} - }, - /*Y' qi=52 INTER*/ - { - { 52, 0},{ 169, 1308},{ 668, 2382},{ 1735, 3112}, - { 3384, 3451},{ 5077, 3519},{ 6461, 3506},{ 7587, 3496}, - { 8545, 3494},{ 9384, 3494},{10142, 3498},{10838, 3501}, - {11475, 3503},{12078, 3508},{12640, 3511},{13162, 3513}, - {13654, 3517},{14130, 3521},{14576, 3522},{14980, 3523}, - {15369, 3523},{15737, 3522},{16071, 3521},{16382, 3516} - } - }, - { - /*Cb qi=52 INTRA*/ - { - { 14, 3},{ 163, 369},{ 299, 722},{ 457, 1044}, - { 645, 1319},{ 843, 1545},{ 1050, 1728},{ 1261, 1879}, - { 1468, 2013},{ 1678, 2132},{ 1883, 2240},{ 2093, 2338}, - { 2301, 2428},{ 2488, 2523},{ 2667, 2619},{ 2843, 2718}, - { 3010, 2805},{ 3163, 2887},{ 3323, 2963},{ 3490, 3028}, - { 3665, 3087},{ 3841, 3145},{ 4011, 3197},{ 4289, 3230} - }, - /*Cb qi=52 INTER*/ - { - { 98, -7},{ 109, 342},{ 109, 668},{ 126, 1018}, - { 170, 1355},{ 242, 1663},{ 352, 1941},{ 490, 2195}, - { 642, 2439},{ 823, 2666},{ 1052, 2868},{ 1333, 3039}, - { 1670, 3178},{ 2074, 3280},{ 2524, 3348},{ 2996, 3390}, - { 3469, 3410},{ 3923, 3420},{ 4355, 3434},{ 4771, 3451}, - { 5166, 3468},{ 5532, 3483},{ 5885, 3499},{ 6263, 3501} - } - }, - { - /*Cr qi=52 INTRA*/ - { - { 25, 7},{ 170, 388},{ 312, 741},{ 500, 1051}, - { 694, 1310},{ 883, 1529},{ 1082, 1709},{ 1280, 1864}, - { 1491, 1998},{ 1710, 2117},{ 1932, 2225},{ 2143, 2324}, - { 2328, 2418},{ 2516, 2506},{ 2708, 2578},{ 2870, 2637}, - { 3017, 2693},{ 3170, 2758},{ 3312, 2835},{ 3455, 2901}, - { 3644, 2972},{ 3827, 3049},{ 3968, 3121},{ 4115, 3166} - }, - /*Cr qi=52 INTER*/ - { - { 86, -2},{ 101, 352},{ 100, 680},{ 126, 1028}, - { 175, 1356},{ 247, 1657},{ 341, 1948},{ 458, 2224}, - { 615, 2471},{ 828, 2681},{ 1091, 2857},{ 1395, 3008}, - { 1732, 3140},{ 2095, 3257},{ 2502, 3348},{ 2968, 3402}, - { 3457, 3420},{ 3926, 3413},{ 4360, 3388},{ 4759, 3357}, - { 5128, 3329},{ 5449, 3306},{ 5741, 3295},{ 6071, 3296} - } - } - }, - { - { - /*Y' qi=53 INTRA*/ - { - { 138, 93},{ 850, 1161},{ 1773, 1810},{ 2763, 2103}, - { 3722, 2245},{ 4675, 2360},{ 5600, 2483},{ 6464, 2597}, - { 7255, 2700},{ 7982, 2792},{ 8652, 2867},{ 9237, 2913}, - { 9775, 2950},{10302, 2998},{10834, 3058},{11347, 3121}, - {11826, 3169},{12299, 3207},{12713, 3235},{13054, 3250}, - {13387, 3265},{13744, 3286},{14110, 3302},{14515, 3323} - }, - /*Y' qi=53 INTER*/ - { - { 52, 2},{ 169, 1308},{ 680, 2377},{ 1763, 3103}, - { 3410, 3450},{ 5094, 3531},{ 6469, 3526},{ 7590, 3525}, - { 8547, 3530},{ 9385, 3534},{10139, 3540},{10835, 3548}, - {11479, 3553},{12075, 3559},{12634, 3565},{13159, 3570}, - {13650, 3573},{14124, 3576},{14575, 3580},{14993, 3583}, - {15375, 3584},{15744, 3584},{16091, 3583},{16421, 3586} - } - }, - { - /*Cb qi=53 INTRA*/ - { - { 14, 3},{ 167, 367},{ 317, 717},{ 492, 1033}, - { 687, 1306},{ 887, 1531},{ 1095, 1715},{ 1309, 1866}, - { 1517, 2000},{ 1729, 2119},{ 1932, 2227},{ 2146, 2325}, - { 2358, 2414},{ 2544, 2511},{ 2724, 2611},{ 2902, 2711}, - { 3070, 2800},{ 3227, 2878},{ 3381, 2954},{ 3548, 3021}, - { 3724, 3077},{ 3888, 3140},{ 4065, 3196},{ 4359, 3225} - }, - /*Cb qi=53 INTER*/ - { - { 93, -8},{ 110, 342},{ 108, 668},{ 125, 1018}, - { 170, 1355},{ 242, 1663},{ 353, 1939},{ 494, 2192}, - { 651, 2433},{ 838, 2658},{ 1076, 2856},{ 1368, 3022}, - { 1716, 3158},{ 2123, 3260},{ 2575, 3330},{ 3042, 3373}, - { 3507, 3396},{ 3962, 3413},{ 4394, 3430},{ 4797, 3452}, - { 5169, 3476},{ 5547, 3496},{ 5914, 3510},{ 6235, 3525} - } - }, - { - /*Cr qi=53 INTRA*/ - { - { 25, 7},{ 175, 386},{ 335, 734},{ 541, 1037}, - { 737, 1296},{ 926, 1516},{ 1125, 1696},{ 1324, 1851}, - { 1540, 1984},{ 1763, 2102},{ 1989, 2210},{ 2202, 2310}, - { 2386, 2404},{ 2572, 2495},{ 2768, 2569},{ 2929, 2627}, - { 3071, 2684},{ 3231, 2749},{ 3374, 2825},{ 3514, 2894}, - { 3703, 2963},{ 3882, 3040},{ 4024, 3111},{ 4190, 3150} - }, - /*Cr qi=53 INTER*/ - { - { 87, -1},{ 99, 352},{ 100, 680},{ 125, 1027}, - { 175, 1355},{ 249, 1657},{ 343, 1946},{ 462, 2220}, - { 624, 2465},{ 844, 2671},{ 1122, 2841},{ 1435, 2989}, - { 1768, 3125},{ 2134, 3243},{ 2545, 3334},{ 3002, 3393}, - { 3490, 3412},{ 3965, 3405},{ 4401, 3384},{ 4797, 3359}, - { 5156, 3328},{ 5482, 3297},{ 5800, 3292},{ 6135, 3293} - } - } - }, - { - { - /*Y' qi=54 INTRA*/ - { - { 184, 94},{ 902, 1151},{ 1876, 1776},{ 2881, 2057}, - { 3832, 2200},{ 4785, 2315},{ 5709, 2442},{ 6570, 2562}, - { 7362, 2672},{ 8092, 2771},{ 8760, 2852},{ 9337, 2901}, - { 9874, 2943},{10402, 2995},{10928, 3059},{11443, 3126}, - {11926, 3178},{12396, 3220},{12805, 3251},{13139, 3266}, - {13466, 3280},{13822, 3304},{14184, 3322},{14585, 3342} - }, - /*Y' qi=54 INTER*/ - { - { 60, 5},{ 169, 1308},{ 683, 2375},{ 1791, 3090}, - { 3478, 3412},{ 5184, 3470},{ 6568, 3455},{ 7697, 3446}, - { 8659, 3446},{ 9503, 3447},{10266, 3450},{10971, 3454}, - {11619, 3458},{12223, 3462},{12789, 3467},{13315, 3471}, - {13811, 3475},{14291, 3479},{14743, 3479},{15148, 3481}, - {15535, 3483},{15913, 3481},{16252, 3479},{16569, 3472} - } - }, - { - /*Cb qi=54 INTRA*/ - { - { 13, 2},{ 165, 367},{ 318, 715},{ 498, 1030}, - { 698, 1301},{ 906, 1523},{ 1121, 1703},{ 1336, 1853}, - { 1549, 1984},{ 1765, 2100},{ 1974, 2207},{ 2192, 2306}, - { 2402, 2396},{ 2587, 2493},{ 2773, 2591},{ 2953, 2691}, - { 3119, 2778},{ 3277, 2858},{ 3430, 2940},{ 3603, 3004}, - { 3788, 3059},{ 3950, 3121},{ 4128, 3173},{ 4398, 3215} - }, - /*Cb qi=54 INTER*/ - { - { 100, -3},{ 109, 343},{ 107, 668},{ 125, 1018}, - { 169, 1354},{ 241, 1662},{ 353, 1938},{ 496, 2190}, - { 655, 2431},{ 843, 2655},{ 1082, 2851},{ 1381, 3015}, - { 1739, 3146},{ 2154, 3243},{ 2610, 3310},{ 3094, 3344}, - { 3581, 3358},{ 4034, 3371},{ 4457, 3384},{ 4867, 3399}, - { 5255, 3413},{ 5630, 3425},{ 6003, 3440},{ 6346, 3440} - } - }, - { - /*Cr qi=54 INTRA*/ - { - { 23, 7},{ 174, 386},{ 338, 732},{ 549, 1034}, - { 751, 1289},{ 947, 1506},{ 1150, 1685},{ 1353, 1837}, - { 1572, 1969},{ 1800, 2087},{ 2031, 2192},{ 2248, 2291}, - { 2434, 2387},{ 2622, 2477},{ 2815, 2549},{ 2976, 2607}, - { 3126, 2663},{ 3286, 2727},{ 3427, 2807},{ 3569, 2877}, - { 3761, 2941},{ 3942, 3016},{ 4084, 3093},{ 4226, 3131} - }, - /*Cr qi=54 INTER*/ - { - { 88, -2},{ 99, 351},{ 100, 680},{ 125, 1027}, - { 175, 1354},{ 248, 1656},{ 343, 1945},{ 463, 2219}, - { 626, 2463},{ 850, 2668},{ 1128, 2837},{ 1445, 2983}, - { 1791, 3111},{ 2168, 3224},{ 2597, 3309},{ 3075, 3351}, - { 3560, 3364},{ 4029, 3356},{ 4464, 3335},{ 4858, 3307}, - { 5218, 3275},{ 5547, 3256},{ 5850, 3247},{ 6171, 3214} - } - } - }, - { - { - /*Y' qi=55 INTRA*/ - { - { 178, 95},{ 968, 1137},{ 2000, 1747},{ 3013, 2027}, - { 3966, 2173},{ 4920, 2294},{ 5842, 2427},{ 6702, 2553}, - { 7489, 2668},{ 8213, 2773},{ 8875, 2858},{ 9452, 2913}, - { 9986, 2959},{10504, 3016},{11023, 3085},{11530, 3157}, - {12011, 3213},{12480, 3257},{12882, 3291},{13214, 3310}, - {13542, 3325},{13890, 3350},{14248, 3371},{14671, 3398} - }, - /*Y' qi=55 INTER*/ - { - { 59, 5},{ 170, 1307},{ 725, 2358},{ 1886, 3058}, - { 3589, 3385},{ 5284, 3459},{ 6654, 3458},{ 7771, 3461}, - { 8727, 3470},{ 9564, 3478},{10322, 3488},{11019, 3497}, - {11658, 3505},{12258, 3513},{12819, 3520},{13344, 3527}, - {13840, 3533},{14314, 3537},{14755, 3541},{15161, 3544}, - {15552, 3548},{15916, 3548},{16257, 3548},{16576, 3540} - } - }, - { - /*Cb qi=55 INTRA*/ - { - { 13, 2},{ 167, 366},{ 322, 714},{ 508, 1026}, - { 716, 1292},{ 930, 1511},{ 1148, 1690},{ 1366, 1839}, - { 1578, 1972},{ 1793, 2090},{ 2001, 2199},{ 2217, 2300}, - { 2427, 2393},{ 2609, 2495},{ 2784, 2600},{ 2961, 2704}, - { 3121, 2797},{ 3268, 2884},{ 3423, 2965},{ 3590, 3032}, - { 3764, 3096},{ 3926, 3165},{ 4101, 3223},{ 4405, 3258} - }, - /*Cb qi=55 INTER*/ - { - { 90, -4},{ 109, 344},{ 107, 668},{ 126, 1017}, - { 172, 1351},{ 249, 1657},{ 370, 1928},{ 527, 2174}, - { 702, 2407},{ 909, 2624},{ 1170, 2814},{ 1493, 2970}, - { 1869, 3097},{ 2292, 3192},{ 2752, 3258},{ 3232, 3295}, - { 3709, 3314},{ 4156, 3335},{ 4592, 3355},{ 5004, 3373}, - { 5377, 3389},{ 5737, 3411},{ 6092, 3432},{ 6473, 3423} - } - }, - { - /*Cr qi=55 INTRA*/ - { - { 23, 7},{ 175, 385},{ 342, 730},{ 561, 1028}, - { 771, 1279},{ 973, 1493},{ 1181, 1669},{ 1384, 1822}, - { 1602, 1956},{ 1830, 2076},{ 2057, 2184},{ 2270, 2288}, - { 2452, 2389},{ 2637, 2484},{ 2823, 2559},{ 2983, 2621}, - { 3129, 2682},{ 3280, 2753},{ 3417, 2833},{ 3554, 2904}, - { 3743, 2977},{ 3921, 3060},{ 4055, 3137},{ 4185, 3186} - }, - /*Cr qi=55 INTER*/ - { - { 85, 0},{ 99, 352},{ 100, 679},{ 126, 1025}, - { 178, 1351},{ 256, 1650},{ 359, 1935},{ 493, 2202}, - { 675, 2439},{ 921, 2636},{ 1220, 2799},{ 1552, 2941}, - { 1910, 3068},{ 2303, 3177},{ 2735, 3262},{ 3206, 3311}, - { 3689, 3333},{ 4152, 3327},{ 4588, 3299},{ 4978, 3272}, - { 5325, 3243},{ 5651, 3221},{ 5969, 3210},{ 6218, 3185} - } - } - }, - { - { - /*Y' qi=56 INTRA*/ - { - { 137, 104},{ 1048, 1128},{ 2147, 1760},{ 3261, 2029}, - { 4319, 2131},{ 5310, 2234},{ 6245, 2351},{ 7101, 2464}, - { 7886, 2572},{ 8610, 2675},{ 9270, 2762},{ 9840, 2818}, - {10365, 2869},{10875, 2928},{11393, 2997},{11900, 3071}, - {12371, 3128},{12834, 3172},{13233, 3208},{13562, 3228}, - {13878, 3245},{14221, 3271},{14584, 3292},{15008, 3320} - }, - /*Y' qi=56 INTER*/ - { - { 19, 21},{ 207, 1292},{ 1031, 2252},{ 2553, 2846}, - { 4463, 3085},{ 6137, 3131},{ 7441, 3151},{ 8526, 3172}, - { 9468, 3193},{10301, 3209},{11059, 3224},{11760, 3237}, - {12405, 3249},{13008, 3261},{13570, 3270},{14100, 3278}, - {14597, 3284},{15074, 3289},{15524, 3297},{15929, 3302}, - {16314, 3306},{16675, 3307},{17004, 3305},{17288, 3301} - } - }, - { - /*Cb qi=56 INTRA*/ - { - { 16, 3},{ 188, 367},{ 353, 712},{ 546, 1017}, - { 765, 1275},{ 989, 1484},{ 1221, 1653},{ 1459, 1791}, - { 1681, 1920},{ 1893, 2046},{ 2102, 2160},{ 2323, 2257}, - { 2534, 2347},{ 2720, 2447},{ 2902, 2549},{ 3075, 2654}, - { 3239, 2749},{ 3392, 2835},{ 3544, 2920},{ 3712, 2988}, - { 3882, 3052},{ 4052, 3123},{ 4227, 3181},{ 4483, 3213} - }, - /*Cb qi=56 INTER*/ - { - { 92, -1},{ 111, 343},{ 114, 665},{ 148, 1003}, - { 224, 1321},{ 345, 1609},{ 526, 1858},{ 754, 2077}, - { 1009, 2281},{ 1319, 2464},{ 1702, 2614},{ 2145, 2732}, - { 2625, 2824},{ 3123, 2890},{ 3634, 2933},{ 4137, 2954}, - { 4614, 2965},{ 5052, 2988},{ 5468, 3015},{ 5852, 3035}, - { 6213, 3060},{ 6557, 3081},{ 6906, 3094},{ 7243, 3112} - } - }, - { - /*Cr qi=56 INTRA*/ - { - { 28, 8},{ 195, 385},{ 373, 727},{ 598, 1019}, - { 816, 1263},{ 1033, 1465},{ 1260, 1630},{ 1482, 1773}, - { 1717, 1900},{ 1949, 2018},{ 2178, 2128},{ 2393, 2233}, - { 2570, 2338},{ 2749, 2435},{ 2937, 2514},{ 3097, 2577}, - { 3240, 2638},{ 3398, 2709},{ 3540, 2791},{ 3673, 2865}, - { 3869, 2938},{ 4049, 3019},{ 4179, 3095},{ 4330, 3137} - }, - /*Cr qi=56 INTER*/ - { - { 83, 0},{ 99, 353},{ 103, 676},{ 146, 1010}, - { 232, 1320},{ 355, 1601},{ 512, 1866},{ 713, 2109}, - { 988, 2312},{ 1344, 2471},{ 1750, 2602},{ 2180, 2719}, - { 2642, 2819},{ 3141, 2892},{ 3653, 2939},{ 4159, 2961}, - { 4636, 2961},{ 5072, 2945},{ 5464, 2917},{ 5813, 2895}, - { 6134, 2890},{ 6458, 2883},{ 6735, 2881},{ 6953, 2902} - } - } - }, - { - { - /*Y' qi=57 INTRA*/ - { - { 170, 106},{ 1106, 1120},{ 2246, 1740},{ 3399, 1993}, - { 4482, 2077},{ 5492, 2167},{ 6446, 2273},{ 7324, 2379}, - { 8130, 2482},{ 8866, 2578},{ 9537, 2661},{10119, 2715}, - {10646, 2762},{11161, 2820},{11694, 2886},{12214, 2957}, - {12693, 3013},{13166, 3053},{13569, 3087},{13897, 3106}, - {14224, 3122},{14568, 3148},{14931, 3167},{15390, 3192} - }, - /*Y' qi=57 INTER*/ - { - { 19, 20},{ 205, 1292},{ 1096, 2229},{ 2775, 2766}, - { 4811, 2943},{ 6512, 2964},{ 7832, 2976},{ 8940, 2990}, - { 9903, 3004},{10755, 3017},{11532, 3029},{12243, 3039}, - {12891, 3047},{13502, 3058},{14073, 3065},{14603, 3071}, - {15097, 3078},{15581, 3083},{16036, 3086},{16452, 3090}, - {16855, 3093},{17222, 3094},{17552, 3092},{17851, 3098} - } - }, - { - /*Cb qi=57 INTRA*/ - { - { 16, 3},{ 197, 365},{ 384, 704},{ 603, 1001}, - { 837, 1252},{ 1077, 1455},{ 1326, 1618},{ 1581, 1748}, - { 1819, 1871},{ 2042, 1993},{ 2264, 2104},{ 2500, 2196}, - { 2722, 2280},{ 2916, 2375},{ 3103, 2473},{ 3290, 2575}, - { 3456, 2667},{ 3612, 2748},{ 3775, 2829},{ 3958, 2896}, - { 4145, 2947},{ 4307, 3012},{ 4476, 3070},{ 4733, 3110} - }, - /*Cb qi=57 INTER*/ - { - { 94, -1},{ 111, 344},{ 112, 665},{ 147, 1002}, - { 227, 1319},{ 353, 1604},{ 543, 1849},{ 785, 2062}, - { 1066, 2257},{ 1408, 2430},{ 1827, 2568},{ 2320, 2670}, - { 2848, 2743},{ 3386, 2791},{ 3934, 2812},{ 4453, 2820}, - { 4929, 2830},{ 5368, 2842},{ 5787, 2856},{ 6190, 2875}, - { 6554, 2896},{ 6895, 2913},{ 7229, 2927},{ 7572, 2932} - } - }, - { - /*Cr qi=57 INTRA*/ - { - { 28, 8},{ 207, 383},{ 413, 716},{ 661, 999}, - { 889, 1237},{ 1123, 1433},{ 1365, 1592},{ 1603, 1731}, - { 1853, 1852},{ 2103, 1965},{ 2345, 2072},{ 2571, 2173}, - { 2763, 2271},{ 2949, 2364},{ 3146, 2438},{ 3315, 2497}, - { 3459, 2552},{ 3618, 2616},{ 3767, 2697},{ 3906, 2773}, - { 4099, 2841},{ 4281, 2916},{ 4429, 2987},{ 4569, 3030} - }, - /*Cr qi=57 INTER*/ - { - { 85, 0},{ 99, 352},{ 102, 675},{ 147, 1008}, - { 235, 1317},{ 363, 1597},{ 529, 1858},{ 748, 2094}, - { 1050, 2287},{ 1439, 2436},{ 1877, 2557},{ 2352, 2660}, - { 2869, 2740},{ 3413, 2791},{ 3962, 2815},{ 4485, 2819}, - { 4955, 2816},{ 5382, 2800},{ 5769, 2772},{ 6107, 2748}, - { 6443, 2740},{ 6754, 2739},{ 7029, 2737},{ 7284, 2745} - } - } - }, - { - { - /*Y' qi=58 INTRA*/ - { - { 164, 109},{ 1198, 1111},{ 2396, 1737},{ 3606, 1978}, - { 4727, 2048},{ 5749, 2138},{ 6708, 2243},{ 7584, 2347}, - { 8388, 2449},{ 9122, 2549},{ 9784, 2635},{10354, 2691}, - {10876, 2740},{11385, 2800},{11912, 2869},{12429, 2941}, - {12902, 2997},{13375, 3040},{13779, 3075},{14103, 3096}, - {14435, 3112},{14783, 3140},{15141, 3160},{15599, 3186} - }, - /*Y' qi=58 INTER*/ - { - { 14, 23},{ 210, 1290},{ 1277, 2178},{ 3118, 2677}, - { 5207, 2834},{ 6902, 2857},{ 8218, 2878},{ 9323, 2900}, - {10285, 2919},{11132, 2934},{11899, 2949},{12599, 2961}, - {13235, 2971},{13835, 2982},{14394, 2991},{14917, 2997}, - {15412, 3005},{15882, 3009},{16325, 3013},{16735, 3016}, - {17131, 3018},{17501, 3021},{17824, 3021},{18125, 3016} - } - }, - { - /*Cb qi=58 INTRA*/ - { - { 17, 3},{ 200, 365},{ 389, 703},{ 613, 996}, - { 853, 1243},{ 1095, 1445},{ 1349, 1604},{ 1613, 1731}, - { 1853, 1853},{ 2074, 1978},{ 2292, 2091},{ 2526, 2184}, - { 2750, 2266},{ 2945, 2360},{ 3134, 2458},{ 3320, 2561}, - { 3482, 2654},{ 3641, 2737},{ 3804, 2818},{ 3985, 2881}, - { 4168, 2935},{ 4331, 3003},{ 4499, 3060},{ 4751, 3100} - }, - /*Cb qi=58 INTER*/ - { - { 94, -1},{ 112, 345},{ 112, 665},{ 152, 998}, - { 247, 1307},{ 406, 1580},{ 644, 1810},{ 938, 2007}, - { 1271, 2189},{ 1668, 2348},{ 2151, 2470},{ 2691, 2558}, - { 3249, 2619},{ 3798, 2659},{ 4334, 2682},{ 4849, 2692}, - { 5314, 2700},{ 5747, 2721},{ 6167, 2742},{ 6547, 2765}, - { 6902, 2790},{ 7251, 2804},{ 7583, 2819},{ 7924, 2833} - } - }, - { - /*Cr qi=58 INTRA*/ - { - { 29, 8},{ 210, 382},{ 419, 714},{ 671, 993}, - { 903, 1229},{ 1141, 1422},{ 1390, 1578},{ 1635, 1713}, - { 1889, 1833},{ 2140, 1946},{ 2379, 2055},{ 2604, 2157}, - { 2794, 2256},{ 2977, 2349},{ 3174, 2422},{ 3339, 2482}, - { 3483, 2537},{ 3643, 2604},{ 3790, 2684},{ 3927, 2757}, - { 4112, 2826},{ 4294, 2900},{ 4451, 2975},{ 4600, 3011} - }, - /*Cr qi=58 INTER*/ - { - { 86, 0},{ 99, 352},{ 103, 675},{ 151, 1004}, - { 256, 1306},{ 417, 1573},{ 628, 1819},{ 901, 2040}, - { 1262, 2217},{ 1705, 2353},{ 2191, 2466},{ 2713, 2556}, - { 3268, 2622},{ 3831, 2664},{ 4374, 2682},{ 4881, 2686}, - { 5339, 2685},{ 5747, 2668},{ 6123, 2646},{ 6465, 2630}, - { 6783, 2618},{ 7082, 2623},{ 7366, 2632},{ 7673, 2654} - } - } - }, - { - { - /*Y' qi=59 INTRA*/ - { - { 142, 112},{ 1259, 1100},{ 2552, 1711},{ 3815, 1933}, - { 4955, 1987},{ 5983, 2068},{ 6949, 2165},{ 7832, 2263}, - { 8645, 2359},{ 9392, 2454},{10066, 2536},{10643, 2589}, - {11174, 2636},{11696, 2693},{12230, 2758},{12752, 2826}, - {13239, 2883},{13721, 2926},{14139, 2959},{14479, 2978}, - {14811, 2993},{15166, 3020},{15532, 3039},{16000, 3062} - }, - /*Y' qi=59 INTER*/ - { - { 8, 25},{ 211, 1289},{ 1394, 2144},{ 3421, 2580}, - { 5611, 2689},{ 7316, 2701},{ 8643, 2717},{ 9762, 2734}, - {10735, 2750},{11587, 2763},{12353, 2775},{13056, 2785}, - {13693, 2793},{14288, 2805},{14843, 2814},{15361, 2821}, - {15857, 2827},{16328, 2831},{16763, 2834},{17171, 2838}, - {17568, 2840},{17941, 2842},{18285, 2843},{18586, 2839} - } - }, - { - /*Cb qi=59 INTRA*/ - { - { 17, 3},{ 224, 363},{ 441, 696},{ 689, 982}, - { 945, 1222},{ 1204, 1416},{ 1474, 1571},{ 1751, 1695}, - { 2001, 1816},{ 2228, 1941},{ 2453, 2055},{ 2693, 2147}, - { 2924, 2227},{ 3125, 2321},{ 3321, 2416},{ 3510, 2520}, - { 3676, 2616},{ 3839, 2699},{ 4008, 2778},{ 4193, 2842}, - { 4371, 2898},{ 4535, 2965},{ 4710, 3023},{ 4921, 3068} - }, - /*Cb qi=59 INTER*/ - { - { 95, -5},{ 111, 343},{ 112, 664},{ 157, 995}, - { 258, 1302},{ 429, 1569},{ 691, 1790},{ 1017, 1977}, - { 1387, 2148},{ 1832, 2294},{ 2368, 2401},{ 2961, 2472}, - { 3553, 2518},{ 4133, 2545},{ 4688, 2557},{ 5198, 2563}, - { 5663, 2574},{ 6100, 2590},{ 6511, 2608},{ 6898, 2621}, - { 7274, 2634},{ 7631, 2655},{ 7984, 2669},{ 8361, 2669} - } - }, - { - /*Cr qi=59 INTRA*/ - { - { 31, 8},{ 240, 379},{ 480, 706},{ 748, 978}, - { 993, 1208},{ 1250, 1394},{ 1519, 1543},{ 1779, 1674}, - { 2047, 1792},{ 2307, 1904},{ 2552, 2013},{ 2780, 2116}, - { 2973, 2216},{ 3165, 2309},{ 3362, 2383},{ 3528, 2444}, - { 3677, 2499},{ 3841, 2566},{ 3995, 2646},{ 4139, 2720}, - { 4324, 2793},{ 4504, 2867},{ 4658, 2939},{ 4806, 2975} - }, - /*Cr qi=59 INTER*/ - { - { 89, -3},{ 98, 352},{ 103, 674},{ 156, 1002}, - { 268, 1300},{ 441, 1562},{ 673, 1801},{ 980, 2010}, - { 1385, 2175},{ 1868, 2301},{ 2401, 2402},{ 2984, 2474}, - { 3591, 2520},{ 4179, 2545},{ 4729, 2555},{ 5232, 2553}, - { 5679, 2545},{ 6081, 2530},{ 6447, 2510},{ 6791, 2496}, - { 7101, 2487},{ 7393, 2489},{ 7684, 2499},{ 7950, 2501} - } - } - }, - { - { - /*Y' qi=60 INTRA*/ - { - { 92, 116},{ 1361, 1085},{ 2746, 1686},{ 4050, 1895}, - { 5209, 1939},{ 6244, 2012},{ 7213, 2103},{ 8105, 2197}, - { 8928, 2290},{ 9685, 2381},{10371, 2460},{10952, 2511}, - {11487, 2556},{12026, 2611},{12574, 2674},{13102, 2739}, - {13597, 2793},{14092, 2831},{14523, 2862},{14862, 2881}, - {15198, 2897},{15568, 2923},{15949, 2941},{16416, 2964} - }, - /*Y' qi=60 INTER*/ - { - { 4, 30},{ 215, 1287},{ 1547, 2104},{ 3729, 2491}, - { 5973, 2568},{ 7672, 2577},{ 9001, 2591},{10123, 2606}, - {11094, 2620},{11943, 2632},{12709, 2643},{13409, 2652}, - {14044, 2660},{14641, 2669},{15193, 2677},{15709, 2684}, - {16201, 2689},{16675, 2693},{17118, 2696},{17522, 2701}, - {17920, 2704},{18293, 2706},{18620, 2702},{18923, 2700} - } - }, - { - /*Cb qi=60 INTRA*/ - { - { 18, 3},{ 227, 362},{ 447, 694},{ 708, 974}, - { 981, 1207},{ 1252, 1397},{ 1532, 1547},{ 1822, 1663}, - { 2082, 1780},{ 2316, 1903},{ 2548, 2013},{ 2794, 2101}, - { 3029, 2178},{ 3242, 2266},{ 3445, 2360},{ 3638, 2459}, - { 3816, 2547},{ 3980, 2628},{ 4146, 2708},{ 4344, 2766}, - { 4546, 2812},{ 4725, 2872},{ 4880, 2930},{ 5054, 2966} - }, - /*Cb qi=60 INTER*/ - { - { 97, -4},{ 112, 343},{ 114, 664},{ 162, 993}, - { 273, 1294},{ 472, 1553},{ 774, 1762},{ 1138, 1939}, - { 1543, 2102},{ 2034, 2236},{ 2620, 2329},{ 3244, 2389}, - { 3860, 2423},{ 4443, 2440},{ 4997, 2449},{ 5502, 2455}, - { 5962, 2458},{ 6413, 2466},{ 6836, 2485},{ 7217, 2506}, - { 7592, 2518},{ 7957, 2533},{ 8291, 2543},{ 8574, 2545} - } - }, - { - /*Cr qi=60 INTRA*/ - { - { 32, 8},{ 243, 379},{ 488, 702},{ 771, 968}, - { 1030, 1192},{ 1300, 1373},{ 1581, 1517},{ 1854, 1643}, - { 2127, 1757},{ 2393, 1864},{ 2645, 1968},{ 2879, 2068}, - { 3078, 2166},{ 3277, 2256},{ 3484, 2325},{ 3660, 2381}, - { 3808, 2433},{ 3970, 2496},{ 4138, 2571},{ 4288, 2643}, - { 4475, 2710},{ 4655, 2778},{ 4810, 2843},{ 4959, 2879} - }, - /*Cr qi=60 INTER*/ - { - { 86, -2},{ 99, 352},{ 103, 673},{ 160, 998}, - { 284, 1292},{ 484, 1546},{ 753, 1774},{ 1100, 1973}, - { 1546, 2129},{ 2072, 2246},{ 2652, 2334},{ 3279, 2392}, - { 3911, 2425},{ 4504, 2440},{ 5044, 2443},{ 5536, 2440}, - { 5979, 2430},{ 6381, 2413},{ 6735, 2397},{ 7062, 2382}, - { 7383, 2376},{ 7680, 2375},{ 7962, 2373},{ 8203, 2379} - } - } - }, - { - { - /*Y' qi=61 INTRA*/ - { - { 54, 121},{ 1477, 1069},{ 3061, 1638},{ 4465, 1808}, - { 5649, 1827},{ 6710, 1884},{ 7716, 1958},{ 8648, 2037}, - { 9514, 2116},{10311, 2192},{11033, 2261},{11641, 2305}, - {12202, 2342},{12771, 2387},{13356, 2440},{13924, 2493}, - {14444, 2541},{14951, 2576},{15409, 2600},{15779, 2615}, - {16131, 2626},{16521, 2648},{16921, 2663},{17409, 2694} - }, - /*Y' qi=61 INTER*/ - { - { -1, 32},{ 216, 1286},{ 1806, 2036},{ 4279, 2327}, - { 6629, 2352},{ 8347, 2352},{ 9707, 2357},{10860, 2364}, - {11857, 2372},{12726, 2377},{13508, 2382},{14225, 2387}, - {14877, 2392},{15484, 2398},{16048, 2401},{16581, 2405}, - {17092, 2409},{17573, 2409},{18016, 2410},{18427, 2413}, - {18829, 2415},{19221, 2415},{19578, 2415},{19980, 2413} - } - }, - { - /*Cb qi=61 INTRA*/ - { - { 19, 3},{ 231, 362},{ 456, 693},{ 733, 965}, - { 1032, 1188},{ 1330, 1369},{ 1637, 1508},{ 1956, 1612}, - { 2241, 1718},{ 2496, 1832},{ 2750, 1932},{ 3019, 2007}, - { 3274, 2074},{ 3505, 2154},{ 3725, 2236},{ 3943, 2323}, - { 4138, 2403},{ 4323, 2476},{ 4505, 2543},{ 4706, 2592}, - { 4909, 2630},{ 5109, 2675},{ 5292, 2724},{ 5495, 2768} - }, - /*Cb qi=61 INTER*/ - { - { 91, -2},{ 111, 344},{ 114, 663},{ 166, 989}, - { 291, 1285},{ 522, 1534},{ 875, 1729},{ 1302, 1889}, - { 1786, 2031},{ 2368, 2141},{ 3042, 2207},{ 3734, 2243}, - { 4388, 2259},{ 4982, 2264},{ 5533, 2265},{ 6043, 2262}, - { 6524, 2264},{ 6982, 2274},{ 7422, 2283},{ 7831, 2295}, - { 8198, 2308},{ 8593, 2319},{ 8965, 2329},{ 9258, 2340} - } - }, - { - /*Cr qi=61 INTRA*/ - { - { 33, 9},{ 245, 378},{ 497, 699},{ 801, 958}, - { 1087, 1171},{ 1384, 1342},{ 1692, 1474},{ 1992, 1589}, - { 2290, 1692},{ 2576, 1789},{ 2852, 1884},{ 3109, 1973}, - { 3324, 2061},{ 3544, 2142},{ 3763, 2199},{ 3945, 2244}, - { 4103, 2292},{ 4283, 2349},{ 4469, 2413},{ 4635, 2476}, - { 4836, 2534},{ 5038, 2592},{ 5210, 2649},{ 5358, 2682} - }, - /*Cr qi=61 INTER*/ - { - { 82, 0},{ 97, 353},{ 104, 672},{ 165, 995}, - { 303, 1284},{ 532, 1529},{ 852, 1742},{ 1273, 1921}, - { 1798, 2057},{ 2409, 2154},{ 3090, 2212},{ 3794, 2240}, - { 4460, 2251},{ 5057, 2249},{ 5596, 2249},{ 6085, 2245}, - { 6519, 2234},{ 6908, 2220},{ 7269, 2203},{ 7618, 2196}, - { 7949, 2198},{ 8269, 2195},{ 8554, 2196},{ 8928, 2217} - } - } - }, - { - { - /*Y' qi=62 INTRA*/ - { - { 29, 124},{ 1527, 1067},{ 3221, 1618},{ 4703, 1751}, - { 5909, 1744},{ 7001, 1779},{ 8057, 1829},{ 9049, 1885}, - { 9968, 1943},{10813, 1999},{11572, 2050},{12206, 2082}, - {12801, 2107},{13402, 2140},{14020, 2180},{14625, 2223}, - {15179, 2260},{15718, 2288},{16196, 2305},{16581, 2313}, - {16963, 2324},{17382, 2341},{17800, 2351},{18318, 2376} - }, - /*Y' qi=62 INTER*/ - { - { -8, 36},{ 218, 1284},{ 2073, 1965},{ 4814, 2159}, - { 7237, 2138},{ 8979, 2124},{10378, 2115},{11570, 2109}, - {12601, 2106},{13503, 2103},{14320, 2103},{15064, 2103}, - {15746, 2103},{16384, 2104},{16975, 2105},{17534, 2105}, - {18062, 2106},{18564, 2107},{19035, 2106},{19471, 2107}, - {19890, 2107},{20288, 2107},{20651, 2107},{21012, 2108} - } - }, - { - /*Cb qi=62 INTRA*/ - { - { 21, 3},{ 283, 360},{ 565, 683},{ 907, 938}, - { 1269, 1143},{ 1611, 1311},{ 1949, 1441},{ 2290, 1535}, - { 2596, 1632},{ 2877, 1738},{ 3162, 1828},{ 3458, 1893}, - { 3745, 1948},{ 4011, 2016},{ 4253, 2089},{ 4506, 2164}, - { 4734, 2233},{ 4943, 2294},{ 5162, 2353},{ 5381, 2393}, - { 5593, 2420},{ 5807, 2454},{ 6003, 2496},{ 6210, 2543} - }, - /*Cb qi=62 INTER*/ - { - { 91, -1},{ 110, 344},{ 113, 663},{ 169, 987}, - { 306, 1279},{ 562, 1519},{ 961, 1701},{ 1450, 1845}, - { 2013, 1967},{ 2686, 2053},{ 3437, 2095},{ 4171, 2109}, - { 4841, 2109},{ 5441, 2105},{ 6002, 2097},{ 6542, 2089}, - { 7028, 2087},{ 7491, 2088},{ 7949, 2090},{ 8377, 2089}, - { 8789, 2095},{ 9195, 2103},{ 9569, 2104},{ 9937, 2102} - } - }, - { - /*Cr qi=62 INTRA*/ - { - { 38, 8},{ 308, 374},{ 619, 685},{ 984, 925}, - { 1326, 1126},{ 1662, 1285},{ 1999, 1407},{ 2328, 1512}, - { 2659, 1604},{ 2976, 1691},{ 3285, 1774},{ 3570, 1853}, - { 3815, 1931},{ 4068, 1998},{ 4304, 2044},{ 4491, 2082}, - { 4666, 2124},{ 4870, 2174},{ 5078, 2231},{ 5262, 2285}, - { 5480, 2335},{ 5703, 2378},{ 5905, 2423},{ 6075, 2454} - }, - /*Cr qi=62 INTER*/ - { - { 79, 1},{ 95, 353},{ 102, 671},{ 169, 992}, - { 318, 1277},{ 569, 1515},{ 936, 1716},{ 1428, 1876}, - { 2034, 1993},{ 2738, 2067},{ 3511, 2095},{ 4268, 2094}, - { 4943, 2087},{ 5543, 2079},{ 6074, 2074},{ 6552, 2069}, - { 6985, 2057},{ 7366, 2043},{ 7728, 2030},{ 8086, 2021}, - { 8423, 2017},{ 8752, 2016},{ 9057, 2014},{ 9376, 2008} - } - } - }, - { - { - /*Y' qi=63 INTRA*/ - { - { -59, 134},{ 1734, 1036},{ 3743, 1521},{ 5309, 1618}, - { 6520, 1597},{ 7664, 1609},{ 8809, 1630},{ 9894, 1657}, - {10907, 1687},{11838, 1717},{12673, 1744},{13379, 1758}, - {14038, 1767},{14698, 1784},{15379, 1806},{16062, 1831}, - {16694, 1852},{17300, 1867},{17827, 1878},{18250, 1881}, - {18702, 1884},{19199, 1892},{19665, 1896},{20273, 1908} - }, - /*Y' qi=63 INTER*/ - { - { -7, 33},{ 209, 1285},{ 2309, 1904},{ 5274, 2025}, - { 7801, 1966},{ 9637, 1924},{11126, 1892},{12403, 1868}, - {13515, 1849},{14491, 1834},{15380, 1822},{16197, 1814}, - {16944, 1806},{17645, 1799},{18303, 1794},{18916, 1789}, - {19494, 1785},{20056, 1782},{20568, 1779},{21047, 1776}, - {21508, 1775},{21925, 1772},{22327, 1770},{22678, 1771} - } - }, - { - /*Cb qi=63 INTRA*/ - { - { 20, 3},{ 294, 357},{ 608, 673},{ 1047, 908}, - { 1501, 1090},{ 1898, 1240},{ 2275, 1353},{ 2654, 1427}, - { 3014, 1502},{ 3366, 1579},{ 3726, 1637},{ 4084, 1674}, - { 4425, 1703},{ 4752, 1743},{ 5058, 1791},{ 5377, 1838}, - { 5676, 1877},{ 5946, 1912},{ 6213, 1945},{ 6458, 1969}, - { 6704, 1982},{ 6969, 1997},{ 7210, 2017},{ 7439, 2037} - }, - /*Cb qi=63 INTER*/ - { - { 86, 1},{ 108, 345},{ 111, 663},{ 168, 985}, - { 307, 1276},{ 577, 1513},{ 1007, 1688},{ 1550, 1819}, - { 2189, 1921},{ 2938, 1981},{ 3744, 2002},{ 4512, 2002}, - { 5199, 1996},{ 5824, 1986},{ 6419, 1971},{ 6978, 1954}, - { 7507, 1940},{ 8015, 1932},{ 8502, 1928},{ 8978, 1920}, - { 9410, 1915},{ 9842, 1910},{10262, 1901},{10634, 1896} - } - }, - { - /*Cr qi=63 INTRA*/ - { - { 38, 7},{ 324, 367},{ 677, 670},{ 1136, 892}, - { 1562, 1070},{ 1951, 1209},{ 2326, 1313},{ 2694, 1399}, - { 3074, 1471},{ 3460, 1531},{ 3850, 1575},{ 4214, 1622}, - { 4522, 1679},{ 4819, 1723},{ 5089, 1749},{ 5315, 1769}, - { 5530, 1792},{ 5756, 1825},{ 6006, 1860},{ 6244, 1889}, - { 6514, 1924},{ 6792, 1946},{ 7026, 1962},{ 7191, 1971} - }, - /*Cr qi=63 INTER*/ - { - { 80, 2},{ 95, 354},{ 101, 671},{ 167, 990}, - { 321, 1274},{ 585, 1509},{ 984, 1702},{ 1534, 1849}, - { 2217, 1947},{ 3005, 1995},{ 3839, 1999},{ 4619, 1986}, - { 5310, 1973},{ 5933, 1961},{ 6486, 1952},{ 6988, 1942}, - { 7435, 1927},{ 7817, 1911},{ 8198, 1900},{ 8552, 1895}, - { 8881, 1890},{ 9253, 1883},{ 9598, 1876},{ 9923, 1859} - } - } - } -}; - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/ocintrin.h b/src/add-ons/media/plugins/theora/libtheora/ocintrin.h deleted file mode 100644 index d49ebb2159..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/ocintrin.h +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: ocintrin.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -/*Some common macros for potential platform-specific optimization.*/ -#include -#if !defined(_ocintrin_H) -# define _ocintrin_H (1) - -/*Some specific platforms may have optimized intrinsic or inline assembly - versions of these functions which can substantially improve performance. - We define macros for them to allow easy incorporation of these non-ANSI - features.*/ - -/*Note that we do not provide a macro for abs(), because it is provided as a - library function, which we assume is translated into an intrinsic to avoid - the function call overhead and then implemented in the smartest way for the - target platform. - With modern gcc (4.x), this is true: it uses cmov instructions if the - architecture supports it and branchless bit-twiddling if it does not (the - speed difference between the two approaches is not measurable). - Interestingly, the bit-twiddling method was patented in 2000 (US 6,073,150) - by Sun Microsystems, despite prior art dating back to at least 1996: - http://web.archive.org/web/19961201174141/www.x86.org/ftp/articles/pentopt/PENTOPT.TXT - On gcc 3.x, however, our assumption is not true, as abs() is translated to a - conditional jump, which is horrible on deeply piplined architectures (e.g., - all consumer architectures for the past decade or more). - Also be warned that -C*abs(x) where C is a constant is mis-optimized as - abs(C*x) on every gcc release before 4.2.3. - See bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34130 */ - -/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if - given an appropriate architecture, but the branchless bit-twiddling versions - are just as fast, and do not require any special target architecture. - Earlier gcc versions (3.x) compiled both code to the same assembly - instructions, because of the way they represented ((_b)>(_a)) internally.*/ -#define OC_MAXI(_a,_b) ((_a)-((_a)-(_b)&-((_b)>(_a)))) -#define OC_MINI(_a,_b) ((_a)+((_b)-(_a)&-((_b)<(_a)))) -/*Clamps an integer into the given range. - If _a>_c, then the lower bound _a is respected over the upper bound _c (this - behavior is required to meet our documented API behavior). - _a: The lower bound. - _b: The value to clamp. - _c: The upper boud.*/ -#define OC_CLAMPI(_a,_b,_c) (OC_MAXI(_a,OC_MINI(_b,_c))) -#define OC_CLAMP255(_x) ((unsigned char)((((_x)<0)-1)&((_x)|-((_x)>255)))) -/*This has a chance of compiling branchless, and is just as fast as the - bit-twiddling method, which is slightly less portable, since it relies on a - sign-extended rightshift, which is not guaranteed by ANSI (but present on - every relevant platform).*/ -#define OC_SIGNI(_a) (((_a)>0)-((_a)<0)) -/*Slightly more portable than relying on a sign-extended right-shift (which is - not guaranteed by ANSI), and just as fast, since gcc (3.x and 4.x both) - compile it into the right-shift anyway.*/ -#define OC_SIGNMASK(_a) (-((_a)<0)) -/*Divides an integer by a power of two, truncating towards 0. - _dividend: The integer to divide. - _shift: The non-negative power of two to divide by. - _rmask: (1<<_shift)-1*/ -#define OC_DIV_POW2(_dividend,_shift,_rmask)\ - ((_dividend)+(OC_SIGNMASK(_dividend)&(_rmask))>>(_shift)) -/*Divides _x by 65536, truncating towards 0.*/ -#define OC_DIV2_16(_x) OC_DIV_POW2(_x,16,0xFFFF) -/*Divides _x by 2, truncating towards 0.*/ -#define OC_DIV2(_x) OC_DIV_POW2(_x,1,0x1) -/*Divides _x by 8, truncating towards 0.*/ -#define OC_DIV8(_x) OC_DIV_POW2(_x,3,0x7) -/*Divides _x by 16, truncating towards 0.*/ -#define OC_DIV16(_x) OC_DIV_POW2(_x,4,0xF) -/*Right shifts _dividend by _shift, adding _rval, and subtracting one for - negative dividends first. - When _rval is (1<<_shift-1), this is equivalent to division with rounding - ties away from zero.*/ -#define OC_DIV_ROUND_POW2(_dividend,_shift,_rval)\ - ((_dividend)+OC_SIGNMASK(_dividend)+(_rval)>>(_shift)) -/*Divides a _x by 2, rounding towards even numbers.*/ -#define OC_DIV2_RE(_x) ((_x)+((_x)>>1&1)>>1) -/*Divides a _x by (1<<(_shift)), rounding towards even numbers.*/ -#define OC_DIV_POW2_RE(_x,_shift) \ - ((_x)+((_x)>>(_shift)&1)+((1<<(_shift))-1>>1)>>(_shift)) -/*Swaps two integers _a and _b if _a>_b.*/ -#define OC_SORT2I(_a,_b) \ - do{ \ - int t__; \ - t__=((_a)^(_b))&-((_b)<(_a)); \ - (_a)^=t__; \ - (_b)^=t__; \ - } \ - while(0) - -/*Accesses one of four (signed) bytes given an index. - This can be used to avoid small lookup tables.*/ -#define OC_BYTE_TABLE32(_a,_b,_c,_d,_i) \ - ((signed char) \ - (((_a)&0xFF|((_b)&0xFF)<<8|((_c)&0xFF)<<16|((_d)&0xFF)<<24)>>(_i)*8)) -/*Accesses one of eight (unsigned) nibbles given an index. - This can be used to avoid small lookup tables.*/ -#define OC_UNIBBLE_TABLE32(_a,_b,_c,_d,_e,_f,_g,_h,_i) \ - ((((_a)&0xF|((_b)&0xF)<<4|((_c)&0xF)<<8|((_d)&0xF)<<12| \ - ((_e)&0xF)<<16|((_f)&0xF)<<20|((_g)&0xF)<<24|((_h)&0xF)<<28)>>(_i)*4)&0xF) - - - -/*All of these macros should expect floats as arguments.*/ -#define OC_MAXF(_a,_b) ((_a)<(_b)?(_b):(_a)) -#define OC_MINF(_a,_b) ((_a)>(_b)?(_b):(_a)) -#define OC_CLAMPF(_a,_b,_c) (OC_MINF(_a,OC_MAXF(_b,_c))) -#define OC_FABSF(_f) ((float)fabs(_f)) -#define OC_SQRTF(_f) ((float)sqrt(_f)) -#define OC_POWF(_b,_e) ((float)pow(_b,_e)) -#define OC_LOGF(_f) ((float)log(_f)) -#define OC_IFLOORF(_f) ((int)floor(_f)) -#define OC_ICEILF(_f) ((int)ceil(_f)) - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/quant.c b/src/add-ons/media/plugins/theora/libtheora/quant.c deleted file mode 100644 index 7fe79f4cdc..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/quant.c +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: quant.c 33343 2009-09-29 00:37:35Z phoudoin $ - - ********************************************************************/ - -#include -#include -#include -#include "quant.h" -#include "decint.h" - -static const unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2}; -static const unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2}; - -/*Initializes the dequantization tables from a set of quantizer info. - Currently the dequantizer (and elsewhere enquantizer) tables are expected to - be initialized as pointing to the storage reserved for them in the - oc_theora_state (resp. oc_enc_ctx) structure. - If some tables are duplicates of others, the pointers will be adjusted to - point to a single copy of the tables, but the storage for them will not be - freed. - If you're concerned about the memory footprint, the obvious thing to do is - to move the storage out of its fixed place in the structures and allocate - it on demand. - However, a much, much better option is to only store the quantization - matrices being used for the current frame, and to recalculate these as the - qi values change between frames (this is what VP3 did).*/ -void oc_dequant_tables_init(ogg_uint16_t *_dequant[64][3][2], - int _pp_dc_scale[64],const th_quant_info *_qinfo){ - /*Coding mode: intra or inter.*/ - int qti; - /*Y', C_b, C_r*/ - int pli; - for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){ - /*Quality index.*/ - int qi; - /*Range iterator.*/ - int qri; - for(qi=0,qri=0;qri<=_qinfo->qi_ranges[qti][pli].nranges;qri++){ - th_quant_base base; - ogg_uint32_t q; - int qi_start; - int qi_end; - memcpy(base,_qinfo->qi_ranges[qti][pli].base_matrices[qri], - sizeof(base)); - qi_start=qi; - if(qri==_qinfo->qi_ranges[qti][pli].nranges)qi_end=qi+1; - else qi_end=qi+_qinfo->qi_ranges[qti][pli].sizes[qri]; - /*Iterate over quality indicies in this range.*/ - for(;;){ - ogg_uint32_t qfac; - int zzi; - int ci; - /*In the original VP3.2 code, the rounding offset and the size of the - dead zone around 0 were controlled by a "sharpness" parameter. - The size of our dead zone is now controlled by the per-coefficient - quality thresholds returned by our HVS module. - We round down from a more accurate value when the quality of the - reconstruction does not fall below our threshold and it saves bits. - Hence, all of that VP3.2 code is gone from here, and the remaining - floating point code has been implemented as equivalent integer code - with exact precision.*/ - qfac=(ogg_uint32_t)_qinfo->dc_scale[qi]*base[0]; - /*For postprocessing, not dequantization.*/ - if(_pp_dc_scale!=NULL)_pp_dc_scale[qi]=(int)(qfac/160); - /*Scale DC the coefficient from the proper table.*/ - q=(qfac/100)<<2; - q=OC_CLAMPI(OC_DC_QUANT_MIN[qti],q,OC_QUANT_MAX); - _dequant[qi][pli][qti][0]=(ogg_uint16_t)q; - /*Now scale AC coefficients from the proper table.*/ - for(zzi=1;zzi<64;zzi++){ - q=((ogg_uint32_t)_qinfo->ac_scale[qi]*base[OC_FZIG_ZAG[zzi]]/100)<<2; - q=OC_CLAMPI(OC_AC_QUANT_MIN[qti],q,OC_QUANT_MAX); - _dequant[qi][pli][qti][zzi]=(ogg_uint16_t)q; - } - /*If this is a duplicate of a previous matrix, use that instead. - This simple check helps us improve cache coherency later.*/ - { - int dupe; - int qtj; - int plj; - dupe=0; - for(qtj=0;qtj<=qti;qtj++){ - for(plj=0;plj<(qtj=qi_end)break; - /*Interpolate the next base matrix.*/ - for(ci=0;ci<64;ci++){ - base[ci]=(unsigned char)( - (2*((qi_end-qi)*_qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+ - (qi-qi_start)*_qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci]) - +_qinfo->qi_ranges[qti][pli].sizes[qri])/ - (2*_qinfo->qi_ranges[qti][pli].sizes[qri])); - } - } - } - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/quant.h b/src/add-ons/media/plugins/theora/libtheora/quant.h deleted file mode 100644 index 49ce13a65c..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/quant.h +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: quant.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#if !defined(_quant_H) -# define _quant_H (1) -# include "theora/codec.h" -# include "ocintrin.h" - -typedef ogg_uint16_t oc_quant_table[64]; - - -/*Maximum scaled quantizer value.*/ -#define OC_QUANT_MAX (1024<<2) - - -void oc_dequant_tables_init(ogg_uint16_t *_dequant[64][3][2], - int _pp_dc_scale[64],const th_quant_info *_qinfo); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/rate.c b/src/add-ons/media/plugins/theora/libtheora/rate.c deleted file mode 100644 index 4f43bb2e5f..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/rate.c +++ /dev/null @@ -1,1137 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: rate.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include -#include -#include "encint.h" - -/*A rough lookup table for tan(x), 0<=x>24; - if(i>=17)i=16; - t0=OC_ROUGH_TAN_LOOKUP[i]; - t1=OC_ROUGH_TAN_LOOKUP[i+1]; - d=_alpha*36-(i<<24); - return (int)(((ogg_int64_t)t0<<32)+(t1-t0<<8)*(ogg_int64_t)d>>32); -} - -/*Re-initialize the Bessel filter coefficients with the specified delay. - This does not alter the x/y state, but changes the reaction time of the - filter. - Altering the time constant of a reactive filter without alterning internal - state is something that has to be done carefuly, but our design operates at - high enough delays and with small enough time constant changes to make it - safe.*/ -static void oc_iir_filter_reinit(oc_iir_filter *_f,int _delay){ - int alpha; - ogg_int64_t one48; - ogg_int64_t warp; - ogg_int64_t k1; - ogg_int64_t k2; - ogg_int64_t d; - ogg_int64_t a; - ogg_int64_t ik2; - ogg_int64_t b1; - ogg_int64_t b2; - /*This borrows some code from an unreleased version of Postfish. - See the recipe at http://unicorn.us.com/alex/2polefilters.html for details - on deriving the filter coefficients.*/ - /*alpha is Q24*/ - alpha=(1<<24)/_delay; - one48=(ogg_int64_t)1<<48; - /*warp is 7.12*/ - warp=OC_MAXI(oc_warp_alpha(alpha),1); - /*k1 is 9.12*/ - k1=3*warp; - /*k2 is 16.24.*/ - k2=k1*warp; - /*d is 16.15.*/ - d=((1<<12)+k1<<12)+k2+256>>9; - /*a is 0.32, since d is larger than both 1.0 and k2.*/ - a=(k2<<23)/d; - /*ik2 is 25.24.*/ - ik2=one48/k2; - /*b1 is Q56; in practice, the integer ranges between -2 and 2.*/ - b1=2*a*(ik2-(1<<24)); - /*b2 is Q56; in practice, the integer ranges between -2 and 2.*/ - b2=(one48<<8)-(4*a<<24)-b1; - /*All of the filter parameters are Q24.*/ - _f->c[0]=(ogg_int32_t)(b1+((ogg_int64_t)1<<31)>>32); - _f->c[1]=(ogg_int32_t)(b2+((ogg_int64_t)1<<31)>>32); - _f->g=(ogg_int32_t)(a+128>>8); -} - -/*Initialize a 2nd order low-pass Bessel filter with the corresponding delay - and initial value. - _value is Q24.*/ -static void oc_iir_filter_init(oc_iir_filter *_f,int _delay,ogg_int32_t _value){ - oc_iir_filter_reinit(_f,_delay); - _f->y[1]=_f->y[0]=_f->x[1]=_f->x[0]=_value; -} - -static ogg_int64_t oc_iir_filter_update(oc_iir_filter *_f,ogg_int32_t _x){ - ogg_int64_t c0; - ogg_int64_t c1; - ogg_int64_t g; - ogg_int64_t x0; - ogg_int64_t x1; - ogg_int64_t y0; - ogg_int64_t y1; - ogg_int64_t ya; - c0=_f->c[0]; - c1=_f->c[1]; - g=_f->g; - x0=_f->x[0]; - x1=_f->x[1]; - y0=_f->y[0]; - y1=_f->y[1]; - ya=(_x+x0*2+x1)*g+y0*c0+y1*c1+(1<<23)>>24; - _f->x[1]=(ogg_int32_t)x0; - _f->x[0]=_x; - _f->y[1]=(ogg_int32_t)y0; - _f->y[0]=(ogg_int32_t)ya; - return ya; -} - - - -/*Search for the quantizer that matches the target most closely. - We don't assume a linear ordering, but when there are ties we pick the - quantizer closest to the old one.*/ -static int oc_enc_find_qi_for_target(oc_enc_ctx *_enc,int _qti,int _qi_old, - int _qi_min,ogg_int64_t _log_qtarget){ - ogg_int64_t best_qdiff; - int best_qi; - int qi; - best_qi=_qi_min; - best_qdiff=_enc->log_qavg[_qti][best_qi]-_log_qtarget; - best_qdiff=best_qdiff+OC_SIGNMASK(best_qdiff)^OC_SIGNMASK(best_qdiff); - for(qi=_qi_min+1;qi<64;qi++){ - ogg_int64_t qdiff; - qdiff=_enc->log_qavg[_qti][qi]-_log_qtarget; - qdiff=qdiff+OC_SIGNMASK(qdiff)^OC_SIGNMASK(qdiff); - if(qdiffstate.qis[0]; - /*If rate control is active, use the lambda for the _target_ quantizer. - This allows us to scale to rates slightly lower than we'd normally be able - to reach, and give the rate control a semblance of "fractional qi" - precision. - TODO: Add API for changing QI, and allow extra precision.*/ - if(_enc->state.info.target_bitrate>0)lq=_enc->rc.log_qtarget; - else lq=_enc->log_qavg[_qti][qi]; - /*The resulting lambda value is less than 0x500000.*/ - _enc->lambda=(int)oc_bexp64(2*lq-0x4780BD468D6B62BLL); - /*Select additional quantizers. - The R-D optimal block AC quantizer statistics suggest that the distribution - is roughly Gaussian-like with a slight positive skew. - K-means clustering on log_qavg to select 3 quantizers produces cluster - centers of {log_qavg-0.6,log_qavg,log_qavg+0.7}. - Experiments confirm these are relatively good choices. - - Although we do greedy R-D optimization of the qii flags to avoid switching - too frequently, this becomes ineffective at low rates, either because we - do a poor job of predicting the actual R-D cost, or the greedy - optimization is not sufficient. - Therefore adaptive quantization is disabled above an (experimentally - suggested) threshold of log_qavg=7.00 (e.g., below INTRA qi=12 or - INTER qi=20 with current matrices). - This may need to be revised if the R-D cost estimation or qii flag - optimization strategies change.*/ - nqis=1; - if(lq<(OC_Q57(56)>>3)&&!_enc->vp3_compatible){ - qi1=oc_enc_find_qi_for_target(_enc,_qti,OC_MAXI(qi-1,0),0, - lq+(OC_Q57(7)+5)/10); - if(qi1!=qi)_enc->state.qis[nqis++]=qi1; - qi1=oc_enc_find_qi_for_target(_enc,_qti,OC_MINI(qi+1,63),0, - lq-(OC_Q57(6)+5)/10); - if(qi1!=qi&&qi1!=_enc->state.qis[nqis-1])_enc->state.qis[nqis++]=qi1; - } - _enc->state.nqis=nqis; -} - -/*Binary exponential of _log_scale with 24-bit fractional precision and - saturation. - _log_scale: A binary logarithm in Q24 format. - Return: The binary exponential in Q24 format, saturated to 2**47-1 if - _log_scale was too large.*/ -static ogg_int64_t oc_bexp_q24(ogg_int32_t _log_scale){ - if(_log_scale<(ogg_int32_t)23<<24){ - ogg_int64_t ret; - ret=oc_bexp64(((ogg_int64_t)_log_scale<<33)+OC_Q57(24)); - return ret<0x7FFFFFFFFFFFLL?ret:0x7FFFFFFFFFFFLL; - } - return 0x7FFFFFFFFFFFLL; -} - -/*Convenience function converts Q57 value to a clamped 32-bit Q24 value - _in: input in Q57 format. - Return: same number in Q24 */ -static ogg_int32_t oc_q57_to_q24(ogg_int64_t _in){ - ogg_int64_t ret; - ret=_in+((ogg_int64_t)1<<32)>>33; - /*0x80000000 is automatically converted to unsigned on 32-bit systems. - -0x7FFFFFFF-1 is needed to avoid "promoting" the whole expression to - unsigned.*/ - return (ogg_int32_t)OC_CLAMPI(-0x7FFFFFFF-1,ret,0x7FFFFFFF); -} - -/*Binary exponential of _log_scale with 24-bit fractional precision and - saturation. - _log_scale: A binary logarithm in Q57 format. - Return: The binary exponential in Q24 format, saturated to 2**31-1 if - _log_scale was too large.*/ -static ogg_int32_t oc_bexp64_q24(ogg_int64_t _log_scale){ - if(_log_scalerc.bits_per_frame=(_enc->state.info.target_bitrate* - (ogg_int64_t)_enc->state.info.fps_denominator)/ - _enc->state.info.fps_numerator; - /*Insane framerates or frame sizes mean insane bitrates. - Let's not get carried away.*/ - if(_enc->rc.bits_per_frame>0x400000000000LL){ - _enc->rc.bits_per_frame=(ogg_int64_t)0x400000000000LL; - } - else if(_enc->rc.bits_per_frame<32)_enc->rc.bits_per_frame=32; - _enc->rc.buf_delay=OC_MAXI(_enc->rc.buf_delay,12); - _enc->rc.max=_enc->rc.bits_per_frame*_enc->rc.buf_delay; - /*Start with a buffer fullness of 50% plus 25% of the amount we plan to spend - on a single keyframe interval. - We can require fully half the bits in an interval for a keyframe, so this - initial level gives us maximum flexibility for over/under-shooting in - subsequent frames.*/ - _enc->rc.target=(_enc->rc.max+1>>1)+(_enc->rc.bits_per_frame+2>>2)* - OC_MINI(_enc->keyframe_frequency_force,_enc->rc.buf_delay); - _enc->rc.fullness=_enc->rc.target; - /*Pick exponents and initial scales for quantizer selection.*/ - npixels=_enc->state.info.frame_width* - (ogg_int64_t)_enc->state.info.frame_height; - _enc->rc.log_npixels=oc_blog64(npixels); - ibpp=npixels/_enc->rc.bits_per_frame; - if(ibpp<1){ - _enc->rc.exp[0]=59; - _enc->rc.log_scale[0]=oc_blog64(1997)-OC_Q57(8); - } - else if(ibpp<2){ - _enc->rc.exp[0]=55; - _enc->rc.log_scale[0]=oc_blog64(1604)-OC_Q57(8); - } - else{ - _enc->rc.exp[0]=48; - _enc->rc.log_scale[0]=oc_blog64(834)-OC_Q57(8); - } - if(ibpp<4){ - _enc->rc.exp[1]=100; - _enc->rc.log_scale[1]=oc_blog64(2249)-OC_Q57(8); - } - else if(ibpp<8){ - _enc->rc.exp[1]=95; - _enc->rc.log_scale[1]=oc_blog64(1751)-OC_Q57(8); - } - else{ - _enc->rc.exp[1]=73; - _enc->rc.log_scale[1]=oc_blog64(1260)-OC_Q57(8); - } - _enc->rc.prev_drop_count=0; - _enc->rc.log_drop_scale=OC_Q57(0); - /*Set up second order followers, initialized according to corresponding - time constants.*/ - oc_iir_filter_init(&_enc->rc.scalefilter[0],4, - oc_q57_to_q24(_enc->rc.log_scale[0])); - inter_delay=(_enc->rc.twopass? - OC_MAXI(_enc->keyframe_frequency_force,12):_enc->rc.buf_delay)>>1; - _enc->rc.inter_count=0; - /*We clamp the actual inter_delay to a minimum of 10 to work within the range - of values where later incrementing the delay works as designed. - 10 is not an exact choice, but rather a good working trade-off.*/ - _enc->rc.inter_delay=10; - _enc->rc.inter_delay_target=inter_delay; - oc_iir_filter_init(&_enc->rc.scalefilter[1],_enc->rc.inter_delay, - oc_q57_to_q24(_enc->rc.log_scale[1])); - oc_iir_filter_init(&_enc->rc.vfrfilter,4, - oc_bexp64_q24(_enc->rc.log_drop_scale)); -} - -void oc_rc_state_init(oc_rc_state *_rc,oc_enc_ctx *_enc){ - _rc->twopass=0; - _rc->twopass_buffer_bytes=0; - _rc->twopass_force_kf=0; - _rc->frame_metrics=NULL; - _rc->rate_bias=0; - if(_enc->state.info.target_bitrate>0){ - /*The buffer size is set equal to the keyframe interval, clamped to the - range [12,256] frames. - The 12 frame minimum gives us some chance to distribute bit estimation - errors. - The 256 frame maximum means we'll require 8-10 seconds of pre-buffering - at 24-30 fps, which is not unreasonable.*/ - _rc->buf_delay=_enc->keyframe_frequency_force>256? - 256:_enc->keyframe_frequency_force; - /*By default, enforce all buffer constraints.*/ - _rc->drop_frames=1; - _rc->cap_overflow=1; - _rc->cap_underflow=0; - oc_enc_rc_reset(_enc); - } -} - -void oc_rc_state_clear(oc_rc_state *_rc){ - _ogg_free(_rc->frame_metrics); -} - -void oc_enc_rc_resize(oc_enc_ctx *_enc){ - /*If encoding has not yet begun, reset the buffer state.*/ - if(_enc->state.curframe_num<0)oc_enc_rc_reset(_enc); - else{ - int idt; - /*Otherwise, update the bounds on the buffer, but not the current - fullness.*/ - _enc->rc.bits_per_frame=(_enc->state.info.target_bitrate* - (ogg_int64_t)_enc->state.info.fps_denominator)/ - _enc->state.info.fps_numerator; - /*Insane framerates or frame sizes mean insane bitrates. - Let's not get carried away.*/ - if(_enc->rc.bits_per_frame>0x400000000000LL){ - _enc->rc.bits_per_frame=(ogg_int64_t)0x400000000000LL; - } - else if(_enc->rc.bits_per_frame<32)_enc->rc.bits_per_frame=32; - _enc->rc.buf_delay=OC_MAXI(_enc->rc.buf_delay,12); - _enc->rc.max=_enc->rc.bits_per_frame*_enc->rc.buf_delay; - _enc->rc.target=(_enc->rc.max+1>>1)+(_enc->rc.bits_per_frame+2>>2)* - OC_MINI(_enc->keyframe_frequency_force,_enc->rc.buf_delay); - /*Update the INTER-frame scale filter delay. - We jump to it immediately if we've already seen enough frames; otherwise - it is simply set as the new target.*/ - _enc->rc.inter_delay_target=idt=OC_MAXI(_enc->rc.buf_delay>>1,10); - if(idtrc.inter_delay,_enc->rc.inter_count)){ - oc_iir_filter_init(&_enc->rc.scalefilter[1],idt, - _enc->rc.scalefilter[1].y[0]); - _enc->rc.inter_delay=idt; - } - } - /*If we're in pass-2 mode, make sure the frame metrics array is big enough - to hold frame statistics for the full buffer.*/ - if(_enc->rc.twopass==2){ - int cfm; - int buf_delay; - int reset_window; - buf_delay=_enc->rc.buf_delay; - reset_window=_enc->rc.frame_metrics==NULL&&(_enc->rc.frames_total[0]==0|| - buf_delay<_enc->rc.frames_total[0]+_enc->rc.frames_total[1] - +_enc->rc.frames_total[2]); - cfm=_enc->rc.cframe_metrics; - /*Only try to resize the frame metrics buffer if a) it's too small and - b) we were using a finite buffer, or are about to start.*/ - if(cfmrc.frame_metrics!=NULL||reset_window)){ - oc_frame_metrics *fm; - int nfm; - int fmh; - fm=(oc_frame_metrics *)_ogg_realloc(_enc->rc.frame_metrics, - buf_delay*sizeof(*_enc->rc.frame_metrics)); - if(fm==NULL){ - /*We failed to allocate a finite buffer.*/ - /*If we don't have a valid 2-pass header yet, just return; we'll reset - the buffer size when we read the header.*/ - if(_enc->rc.frames_total[0]==0)return; - /*Otherwise revert to the largest finite buffer previously set, or to - whole-file buffering if we were still using that.*/ - _enc->rc.buf_delay=_enc->rc.frame_metrics!=NULL? - cfm:_enc->rc.frames_total[0]+_enc->rc.frames_total[1] - +_enc->rc.frames_total[2]; - oc_enc_rc_resize(_enc); - return; - } - _enc->rc.frame_metrics=fm; - _enc->rc.cframe_metrics=buf_delay; - /*Re-organize the circular buffer.*/ - fmh=_enc->rc.frame_metrics_head; - nfm=_enc->rc.nframe_metrics; - if(fmh+nfm>cfm){ - int shift; - shift=OC_MINI(fmh+nfm-cfm,buf_delay-cfm); - memcpy(fm+cfm,fm,OC_MINI(fmh+nfm-cfm,buf_delay-cfm)*sizeof(*fm)); - if(fmh+nfm>buf_delay)memmove(fm,fm+shift,fmh+nfm-buf_delay); - } - } - /*We were using whole-file buffering; now we're not.*/ - if(reset_window){ - _enc->rc.nframes[0]=_enc->rc.nframes[1]=_enc->rc.nframes[2]=0; - _enc->rc.scale_sum[0]=_enc->rc.scale_sum[1]=0; - _enc->rc.scale_window_end=_enc->rc.scale_window0= - _enc->state.curframe_num+_enc->prev_dup_count+1; - if(_enc->rc.twopass_buffer_bytes){ - int qti; - /*We already read the metrics for the first frame in the window.*/ - *(_enc->rc.frame_metrics)=*&_enc->rc.cur_metrics; - _enc->rc.nframe_metrics++; - qti=_enc->rc.cur_metrics.frame_type; - _enc->rc.nframes[qti]++; - _enc->rc.nframes[2]+=_enc->rc.cur_metrics.dup_count; - _enc->rc.scale_sum[qti]+=oc_bexp_q24(_enc->rc.cur_metrics.log_scale); - _enc->rc.scale_window_end+=_enc->rc.cur_metrics.dup_count+1; - if(_enc->rc.scale_window_end-_enc->rc.scale_window0rc.twopass_buffer_bytes=0; - } - } - } - /*Otherwise, we could shrink the size of the current window, if necessary, - but leaving it like it is lets us adapt to the new buffer size more - gracefully.*/ - } -} - -/*Scale the number of frames by the number of expected drops/duplicates.*/ -static int oc_rc_scale_drop(oc_rc_state *_rc,int _nframes){ - if(_rc->prev_drop_count>0||_rc->log_drop_scale>OC_Q57(0)){ - ogg_int64_t dup_scale; - dup_scale=oc_bexp64((_rc->log_drop_scale - +oc_blog64(_rc->prev_drop_count+1)>>1)+OC_Q57(8)); - if(dup_scale<_nframes<<8){ - int dup_scalei; - dup_scalei=(int)dup_scale; - if(dup_scalei>0)_nframes=((_nframes<<8)+dup_scalei-1)/dup_scalei; - } - else _nframes=!!_nframes; - } - return _nframes; -} - -int oc_enc_select_qi(oc_enc_ctx *_enc,int _qti,int _clamp){ - ogg_int64_t rate_total; - ogg_int64_t rate_bias; - int nframes[2]; - int buf_delay; - int buf_pad; - ogg_int64_t log_qtarget; - ogg_int64_t log_scale0; - ogg_int64_t log_cur_scale; - ogg_int64_t log_qexp; - int exp0; - int old_qi; - int qi; - /*Figure out how to re-distribute bits so that we hit our fullness target - before the last keyframe in our current buffer window (after the current - frame), or the end of the buffer window, whichever comes first.*/ - log_cur_scale=(ogg_int64_t)_enc->rc.scalefilter[_qti].y[0]<<33; - buf_pad=0; - switch(_enc->rc.twopass){ - default:{ - ogg_uint32_t next_key_frame; - /*Single pass mode: assume only forced keyframes and attempt to estimate - the drop count for VFR content.*/ - next_key_frame=_qti?_enc->keyframe_frequency_force - -(_enc->state.curframe_num-_enc->state.keyframe_num):0; - nframes[0]=(_enc->rc.buf_delay-OC_MINI(next_key_frame,_enc->rc.buf_delay) - +_enc->keyframe_frequency_force-1)/_enc->keyframe_frequency_force; - if(nframes[0]+_qti>1){ - nframes[0]--; - buf_delay=next_key_frame+nframes[0]*_enc->keyframe_frequency_force; - } - else buf_delay=_enc->rc.buf_delay; - nframes[1]=buf_delay-nframes[0]; - /*Downgrade the delta frame rate to correspond to the recent drop count - history.*/ - nframes[1]=oc_rc_scale_drop(&_enc->rc,nframes[1]); - }break; - case 1:{ - /*Pass 1 mode: use a fixed qi value.*/ - qi=_enc->state.qis[0]; - _enc->rc.log_qtarget=_enc->log_qavg[_qti][qi]; - return qi; - }break; - case 2:{ - ogg_int64_t scale_sum[2]; - int qti; - /*Pass 2 mode: we know exactly how much of each frame type there is in - the current buffer window, and have estimates for the scales.*/ - nframes[0]=_enc->rc.nframes[0]; - nframes[1]=_enc->rc.nframes[1]; - scale_sum[0]=_enc->rc.scale_sum[0]; - scale_sum[1]=_enc->rc.scale_sum[1]; - /*The window size can be slightly larger than the buffer window for VFR - content; clamp it down, if appropriate (the excess will all be dup - frames).*/ - buf_delay=OC_MINI(_enc->rc.scale_window_end-_enc->rc.scale_window0, - _enc->rc.buf_delay); - /*If we're approaching the end of the file, add some slack to keep us - from slamming into a rail. - Our rate accuracy goes down, but it keeps the result sensible. - We position the target where the first forced keyframe beyond the end - of the file would be (for consistency with 1-pass mode).*/ - buf_pad=OC_MINI(_enc->rc.buf_delay,_enc->state.keyframe_num - +_enc->keyframe_frequency_force-_enc->rc.scale_window0); - if(buf_delayrc.frame_metrics!=NULL){ - int fmi; - int fm_tail; - fm_tail=_enc->rc.frame_metrics_head+_enc->rc.nframe_metrics; - if(fm_tail>=_enc->rc.cframe_metrics)fm_tail-=_enc->rc.cframe_metrics; - for(fmi=fm_tail;;){ - oc_frame_metrics *m; - fmi--; - if(fmi<0)fmi+=_enc->rc.cframe_metrics; - /*Stop before we remove the first frame.*/ - if(fmi==_enc->rc.frame_metrics_head)break; - m=_enc->rc.frame_metrics+fmi; - /*If we find a keyframe, remove it and everything past it.*/ - if(m->frame_type==OC_INTRA_FRAME){ - do{ - qti=m->frame_type; - nframes[qti]--; - scale_sum[qti]-=oc_bexp_q24(m->log_scale); - buf_delay-=m->dup_count+1; - fmi++; - if(fmi>=_enc->rc.cframe_metrics)fmi=0; - m=_enc->rc.frame_metrics+fmi; - } - while(fmi!=fm_tail); - /*And stop scanning backwards.*/ - break; - } - } - } - } - /*If we're not using the same frame type as in pass 1 (because someone - changed the keyframe interval), remove that scale estimate. - We'll add in a replacement for the correct frame type below.*/ - qti=_enc->rc.cur_metrics.frame_type; - if(qti!=_qti){ - nframes[qti]--; - scale_sum[qti]-=oc_bexp_q24(_enc->rc.cur_metrics.log_scale); - } - /*Compute log_scale estimates for each frame type from the pass-1 scales - we measured in the current window.*/ - for(qti=0;qti<2;qti++){ - _enc->rc.log_scale[qti]=nframes[qti]>0? - oc_blog64(scale_sum[qti])-oc_blog64(nframes[qti])-OC_Q57(24): - -_enc->rc.log_npixels; - } - /*If we're not using the same frame type as in pass 1, add a scale - estimate for the corresponding frame using the current low-pass - filter value. - This is mostly to ensure we have a valid estimate even when pass 1 had - no frames of this type in the buffer window. - TODO: We could also plan ahead and figure out how many keyframes we'll - be forced to add in the current buffer window.*/ - qti=_enc->rc.cur_metrics.frame_type; - if(qti!=_qti){ - ogg_int64_t scale; - scale=_enc->rc.log_scale[_qti]rc.log_scale[_qti]+OC_Q57(24)):0x7FFFFFFFFFFFLL; - scale*=nframes[_qti]; - nframes[_qti]++; - scale+=oc_bexp_q24(log_cur_scale>>33); - _enc->rc.log_scale[_qti]=oc_blog64(scale) - -oc_blog64(nframes[qti])-OC_Q57(24); - } - else log_cur_scale=(ogg_int64_t)_enc->rc.cur_metrics.log_scale<<33; - /*Add the padding from above. - This basically reverts to 1-pass estimations in the last keyframe - interval.*/ - if(buf_pad>0){ - ogg_int64_t scale; - int nextra_frames; - /*Extend the buffer.*/ - buf_delay+=buf_pad; - /*Add virtual delta frames according to the estimated drop count.*/ - nextra_frames=oc_rc_scale_drop(&_enc->rc,buf_pad); - /*And blend in the low-pass filtered scale according to how many frames - we added.*/ - scale= - oc_bexp64(_enc->rc.log_scale[1]+OC_Q57(24))*(ogg_int64_t)nframes[1] - +oc_bexp_q24(_enc->rc.scalefilter[1].y[0])*(ogg_int64_t)nextra_frames; - nframes[1]+=nextra_frames; - _enc->rc.log_scale[1]=oc_blog64(scale)-oc_blog64(nframes[1])-OC_Q57(24); - } - }break; - } - /*If we've been missing our target, add a penalty term.*/ - rate_bias=(_enc->rc.rate_bias/(_enc->state.curframe_num+1000))* - (buf_delay-buf_pad); - /*rate_total is the total bits available over the next buf_delay frames.*/ - rate_total=_enc->rc.fullness-_enc->rc.target+rate_bias - +buf_delay*_enc->rc.bits_per_frame; - log_scale0=_enc->rc.log_scale[_qti]+_enc->rc.log_npixels; - /*If there aren't enough bits to achieve our desired fullness level, use the - minimum quality permitted.*/ - if(rate_total<=buf_delay)log_qtarget=OC_QUANT_MAX_LOG; - else{ - static const ogg_int64_t LOG_KEY_RATIO=0x0137222BB70747BALL; - ogg_int64_t log_scale1; - ogg_int64_t rlo; - ogg_int64_t rhi; - log_scale1=_enc->rc.log_scale[1-_qti]+_enc->rc.log_npixels; - rlo=0; - rhi=(rate_total+nframes[_qti]-1)/nframes[_qti]; - while(rlo>1; - log_rpow=oc_blog64(curr)-log_scale0; - log_rpow=(log_rpow+(_enc->rc.exp[_qti]>>1))/_enc->rc.exp[_qti]; - if(_qti)log_rpow+=LOG_KEY_RATIO>>6; - else log_rpow-=LOG_KEY_RATIO>>6; - log_rpow*=_enc->rc.exp[1-_qti]; - rscale=nframes[1-_qti]*oc_bexp64(log_scale1+log_rpow); - rdiff=nframes[_qti]*curr+rscale-rate_total; - if(rdiff<0)rlo=curr+1; - else if(rdiff>0)rhi=curr-1; - else break; - } - log_qtarget=OC_Q57(2)-((oc_blog64(rlo)-log_scale0+(_enc->rc.exp[_qti]>>1))/ - _enc->rc.exp[_qti]<<6); - log_qtarget=OC_MINI(log_qtarget,OC_QUANT_MAX_LOG); - } - /*The above allocation looks only at the total rate we'll accumulate in the - next buf_delay frames. - However, we could overflow the buffer on the very next frame, so check for - that here, if we're not using a soft target.*/ - exp0=_enc->rc.exp[_qti]; - if(_enc->rc.cap_overflow){ - ogg_int64_t margin; - ogg_int64_t soft_limit; - ogg_int64_t log_soft_limit; - /*Allow 3% of the buffer for prediction error. - This should be plenty, and we don't mind if we go a bit over; we only - want to keep these bits from being completely wasted.*/ - margin=_enc->rc.max+31>>5; - /*We want to use at least this many bits next frame.*/ - soft_limit=_enc->rc.fullness+_enc->rc.bits_per_frame-(_enc->rc.max-margin); - log_soft_limit=oc_blog64(soft_limit); - /*If we're predicting we won't use that many...*/ - log_qexp=(log_qtarget-OC_Q57(2)>>6)*exp0; - if(log_scale0-log_qexp>32)* - ((OC_MINI(margin,soft_limit)<<32)/margin); - log_qtarget=((log_qexp+(exp0>>1))/exp0<<6)+OC_Q57(2); - } - } - /*If this was not one of the initial frames, limit the change in quality.*/ - old_qi=_enc->state.qis[0]; - if(_clamp){ - ogg_int64_t log_qmin; - ogg_int64_t log_qmax; - /*Clamp the target quantizer to within [0.8*Q,1.2*Q], where Q is the - current quantizer. - TODO: With user-specified quant matrices, we need to enlarge these limits - if they don't actually let us change qi values.*/ - log_qmin=_enc->log_qavg[_qti][old_qi]-0x00A4D3C25E68DC58LL; - log_qmax=_enc->log_qavg[_qti][old_qi]+0x00A4D3C25E68DC58LL; - log_qtarget=OC_CLAMPI(log_qmin,log_qtarget,log_qmax); - } - /*The above allocation looks only at the total rate we'll accumulate in the - next buf_delay frames. - However, we could bust the budget on the very next frame, so check for that - here, if we're not using a soft target.*/ - /* Disabled when our minimum qi > 0; if we saturate log_qtarget to - to the maximum possible size when we have a minimum qi, the - resulting lambda will interact very strangely with SKIP. The - resulting artifacts look like waterfalls. */ - if(_enc->state.info.quality==0){ - ogg_int64_t log_hard_limit; - /*Compute the maximum number of bits we can use in the next frame. - Allow 50% of the rate for a single frame for prediction error. - This may not be enough for keyframes or sudden changes in complexity.*/ - log_hard_limit=oc_blog64(_enc->rc.fullness+(_enc->rc.bits_per_frame>>1)); - /*If we're predicting we'll use more than this...*/ - log_qexp=(log_qtarget-OC_Q57(2)>>6)*exp0; - if(log_scale0-log_qexp>log_hard_limit){ - /*Force the target to hit our limit exactly.*/ - log_qexp=log_scale0-log_hard_limit; - log_qtarget=((log_qexp+(exp0>>1))/exp0<<6)+OC_Q57(2); - /*If that target is unreasonable, oh well; we'll have to drop.*/ - log_qtarget=OC_MINI(log_qtarget,OC_QUANT_MAX_LOG); - } - } - /*Compute a final estimate of the number of bits we plan to use.*/ - log_qexp=(log_qtarget-OC_Q57(2)>>6)*_enc->rc.exp[_qti]; - _enc->rc.rate_bias+=oc_bexp64(log_cur_scale+_enc->rc.log_npixels-log_qexp); - qi=oc_enc_find_qi_for_target(_enc,_qti,old_qi, - _enc->state.info.quality,log_qtarget); - /*Save the quantizer target for lambda calculations.*/ - _enc->rc.log_qtarget=log_qtarget; - return qi; -} - -int oc_enc_update_rc_state(oc_enc_ctx *_enc, - long _bits,int _qti,int _qi,int _trial,int _droppable){ - ogg_int64_t buf_delta; - ogg_int64_t log_scale; - int dropped; - dropped=0; - /* Drop frames also disabled for now in the case of infinite-buffer - two-pass mode */ - if(!_enc->rc.drop_frames||_enc->rc.twopass&&_enc->rc.frame_metrics==NULL){ - _droppable=0; - } - buf_delta=_enc->rc.bits_per_frame*(1+_enc->dup_count); - if(_bits<=0){ - /*We didn't code any blocks in this frame.*/ - log_scale=OC_Q57(-64); - _bits=0; - } - else{ - ogg_int64_t log_bits; - ogg_int64_t log_qexp; - /*Compute the estimated scale factor for this frame type.*/ - log_bits=oc_blog64(_bits); - log_qexp=_enc->rc.log_qtarget-OC_Q57(2); - log_qexp=(log_qexp>>6)*(_enc->rc.exp[_qti]); - log_scale=OC_MINI(log_bits-_enc->rc.log_npixels+log_qexp,OC_Q57(16)); - } - /*Special two-pass processing.*/ - switch(_enc->rc.twopass){ - case 1:{ - /*Pass 1 mode: save the metrics for this frame.*/ - _enc->rc.cur_metrics.log_scale=oc_q57_to_q24(log_scale); - _enc->rc.cur_metrics.dup_count=_enc->dup_count; - _enc->rc.cur_metrics.frame_type=_enc->state.frame_type; - _enc->rc.twopass_buffer_bytes=0; - }break; - case 2:{ - /*Pass 2 mode:*/ - if(!_trial){ - ogg_int64_t next_frame_num; - int qti; - /*Move the current metrics back one frame.*/ - *&_enc->rc.prev_metrics=*&_enc->rc.cur_metrics; - next_frame_num=_enc->state.curframe_num+_enc->dup_count+1; - /*Back out the last frame's statistics from the sliding window.*/ - qti=_enc->rc.prev_metrics.frame_type; - _enc->rc.frames_left[qti]--; - _enc->rc.frames_left[2]-=_enc->rc.prev_metrics.dup_count; - _enc->rc.nframes[qti]--; - _enc->rc.nframes[2]-=_enc->rc.prev_metrics.dup_count; - _enc->rc.scale_sum[qti]-=oc_bexp_q24(_enc->rc.prev_metrics.log_scale); - _enc->rc.scale_window0=(int)next_frame_num; - /*Free the corresponding entry in the circular buffer.*/ - if(_enc->rc.frame_metrics!=NULL){ - _enc->rc.nframe_metrics--; - _enc->rc.frame_metrics_head++; - if(_enc->rc.frame_metrics_head>=_enc->rc.cframe_metrics){ - _enc->rc.frame_metrics_head=0; - } - } - /*Mark us ready for the next 2-pass packet.*/ - _enc->rc.twopass_buffer_bytes=0; - /*Update state, so the user doesn't have to keep calling 2pass_in after - they've fed in all the data when we're using a finite buffer.*/ - _enc->prev_dup_count=_enc->dup_count; - oc_enc_rc_2pass_in(_enc,NULL,0); - } - }break; - } - /*Common to all passes:*/ - if(_bits>0){ - if(_trial){ - oc_iir_filter *f; - /*Use the estimated scale factor directly if this was a trial.*/ - f=_enc->rc.scalefilter+_qti; - f->y[1]=f->y[0]=f->x[1]=f->x[0]=oc_q57_to_q24(log_scale); - _enc->rc.log_scale[_qti]=log_scale; - } - else{ - /*Lengthen the time constant for the INTER filter as we collect more - frame statistics, until we reach our target.*/ - if(_enc->rc.inter_delay<_enc->rc.inter_delay_target&& - _enc->rc.inter_count>=_enc->rc.inter_delay&&_qti==OC_INTER_FRAME){ - oc_iir_filter_reinit(&_enc->rc.scalefilter[1],++_enc->rc.inter_delay); - } - /*Otherwise update the low-pass scale filter for this frame type, - regardless of whether or not we dropped this frame.*/ - _enc->rc.log_scale[_qti]=oc_iir_filter_update( - _enc->rc.scalefilter+_qti,oc_q57_to_q24(log_scale))<<33; - /*If this frame busts our budget, it must be dropped.*/ - if(_droppable&&_enc->rc.fullness+buf_delta<_bits){ - _enc->rc.prev_drop_count+=1+_enc->dup_count; - _bits=0; - dropped=1; - } - else{ - ogg_uint32_t drop_count; - /*Update a low-pass filter to estimate the "real" frame rate taking - drops and duplicates into account. - This is only done if the frame is coded, as it needs the final - count of dropped frames.*/ - drop_count=_enc->rc.prev_drop_count+1; - if(drop_count>0x7F)drop_count=0x7FFFFFFF; - else drop_count<<=24; - _enc->rc.log_drop_scale=oc_blog64(oc_iir_filter_update( - &_enc->rc.vfrfilter,drop_count))-OC_Q57(24); - /*Initialize the drop count for this frame to the user-requested dup - count. - It will be increased if we drop more frames.*/ - _enc->rc.prev_drop_count=_enc->dup_count; - } - } - /*Increment the INTER frame count, for filter adaptation purposes.*/ - if(_enc->rc.inter_countrc.inter_count+=_qti; - } - /*Increase the drop count.*/ - else _enc->rc.prev_drop_count+=1+_enc->dup_count; - /*And update the buffer fullness level.*/ - if(!_trial){ - _enc->rc.fullness+=buf_delta-_bits; - /*If we're too quick filling the buffer and overflow is capped, - that rate is lost forever.*/ - if(_enc->rc.cap_overflow&&_enc->rc.fullness>_enc->rc.max){ - _enc->rc.fullness=_enc->rc.max; - } - /*If we're too quick draining the buffer and underflow is capped, - don't try to make up that rate later.*/ - if(_enc->rc.cap_underflow&&_enc->rc.fullness<0){ - _enc->rc.fullness=0; - } - /*Adjust the bias for the real bits we've used.*/ - _enc->rc.rate_bias-=_bits; - } - return dropped; -} - -#define OC_RC_2PASS_VERSION (1) -#define OC_RC_2PASS_HDR_SZ (38) -#define OC_RC_2PASS_PACKET_SZ (8) - -static void oc_rc_buffer_val(oc_rc_state *_rc,ogg_int64_t _val,int _bytes){ - while(_bytes-->0){ - _rc->twopass_buffer[_rc->twopass_buffer_bytes++]=(unsigned char)(_val&0xFF); - _val>>=8; - } -} - -int oc_enc_rc_2pass_out(oc_enc_ctx *_enc,unsigned char **_buf){ - if(_enc->rc.twopass_buffer_bytes==0){ - if(_enc->rc.twopass==0){ - int qi; - /*Pick first-pass qi for scale calculations.*/ - qi=oc_enc_select_qi(_enc,0,0); - _enc->state.nqis=1; - _enc->state.qis[0]=qi; - _enc->rc.twopass=1; - _enc->rc.frames_total[0]=_enc->rc.frames_total[1]= - _enc->rc.frames_total[2]=0; - _enc->rc.scale_sum[0]=_enc->rc.scale_sum[1]=0; - /*Fill in dummy summary values.*/ - oc_rc_buffer_val(&_enc->rc,0x5032544F,4); - oc_rc_buffer_val(&_enc->rc,OC_RC_2PASS_VERSION,4); - oc_rc_buffer_val(&_enc->rc,0,OC_RC_2PASS_HDR_SZ-8); - } - else{ - int qti; - qti=_enc->rc.cur_metrics.frame_type; - _enc->rc.scale_sum[qti]+=oc_bexp_q24(_enc->rc.cur_metrics.log_scale); - _enc->rc.frames_total[qti]++; - _enc->rc.frames_total[2]+=_enc->rc.cur_metrics.dup_count; - oc_rc_buffer_val(&_enc->rc, - _enc->rc.cur_metrics.dup_count|_enc->rc.cur_metrics.frame_type<<31,4); - oc_rc_buffer_val(&_enc->rc,_enc->rc.cur_metrics.log_scale,4); - } - } - else if(_enc->packet_state==OC_PACKET_DONE&& - _enc->rc.twopass_buffer_bytes!=OC_RC_2PASS_HDR_SZ){ - _enc->rc.twopass_buffer_bytes=0; - oc_rc_buffer_val(&_enc->rc,0x5032544F,4); - oc_rc_buffer_val(&_enc->rc,OC_RC_2PASS_VERSION,4); - oc_rc_buffer_val(&_enc->rc,_enc->rc.frames_total[0],4); - oc_rc_buffer_val(&_enc->rc,_enc->rc.frames_total[1],4); - oc_rc_buffer_val(&_enc->rc,_enc->rc.frames_total[2],4); - oc_rc_buffer_val(&_enc->rc,_enc->rc.exp[0],1); - oc_rc_buffer_val(&_enc->rc,_enc->rc.exp[1],1); - oc_rc_buffer_val(&_enc->rc,_enc->rc.scale_sum[0],8); - oc_rc_buffer_val(&_enc->rc,_enc->rc.scale_sum[1],8); - } - else{ - /*The data for this frame has already been retrieved.*/ - *_buf=NULL; - return 0; - } - *_buf=_enc->rc.twopass_buffer; - return _enc->rc.twopass_buffer_bytes; -} - -static size_t oc_rc_buffer_fill(oc_rc_state *_rc, - unsigned char *_buf,size_t _bytes,size_t _consumed,size_t _goal){ - while(_rc->twopass_buffer_fill<_goal&&_consumed<_bytes){ - _rc->twopass_buffer[_rc->twopass_buffer_fill++]=_buf[_consumed++]; - } - return _consumed; -} - -static ogg_int64_t oc_rc_unbuffer_val(oc_rc_state *_rc,int _bytes){ - ogg_int64_t ret; - int shift; - ret=0; - shift=0; - while(_bytes-->0){ - ret|=((ogg_int64_t)_rc->twopass_buffer[_rc->twopass_buffer_bytes++])<rc.twopass==0){ - _enc->rc.twopass=2; - _enc->rc.twopass_buffer_fill=0; - _enc->rc.frames_total[0]=0; - _enc->rc.nframe_metrics=0; - _enc->rc.cframe_metrics=0; - _enc->rc.frame_metrics_head=0; - _enc->rc.scale_window0=0; - _enc->rc.scale_window_end=0; - } - /*If we haven't got a valid summary header yet, try to parse one.*/ - if(_enc->rc.frames_total[0]==0){ - if(!_buf){ - int frames_needed; - /*If we're using a whole-file buffer, we just need the first frame. - Otherwise, we may need as many as one per buffer slot.*/ - frames_needed=_enc->rc.frame_metrics==NULL?1:_enc->rc.buf_delay; - return OC_RC_2PASS_HDR_SZ+frames_needed*OC_RC_2PASS_PACKET_SZ - -_enc->rc.twopass_buffer_fill; - } - consumed=oc_rc_buffer_fill(&_enc->rc, - _buf,_bytes,consumed,OC_RC_2PASS_HDR_SZ); - if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_HDR_SZ){ - ogg_int64_t scale_sum[2]; - int exp[2]; - int buf_delay; - /*Read the summary header data.*/ - /*Check the magic value and version number.*/ - if(oc_rc_unbuffer_val(&_enc->rc,4)!=0x5032544F|| - oc_rc_unbuffer_val(&_enc->rc,4)!=OC_RC_2PASS_VERSION){ - _enc->rc.twopass_buffer_bytes=0; - return TH_ENOTFORMAT; - } - _enc->rc.frames_total[0]=(ogg_uint32_t)oc_rc_unbuffer_val(&_enc->rc,4); - _enc->rc.frames_total[1]=(ogg_uint32_t)oc_rc_unbuffer_val(&_enc->rc,4); - _enc->rc.frames_total[2]=(ogg_uint32_t)oc_rc_unbuffer_val(&_enc->rc,4); - exp[0]=(int)oc_rc_unbuffer_val(&_enc->rc,1); - exp[1]=(int)oc_rc_unbuffer_val(&_enc->rc,1); - scale_sum[0]=oc_rc_unbuffer_val(&_enc->rc,8); - scale_sum[1]=oc_rc_unbuffer_val(&_enc->rc,8); - /*Make sure the file claims to have at least one frame. - Otherwise we probably got the placeholder data from an aborted pass 1. - Also make sure the total frame count doesn't overflow an integer.*/ - buf_delay=_enc->rc.frames_total[0]+_enc->rc.frames_total[1] - +_enc->rc.frames_total[2]; - if(_enc->rc.frames_total[0]==0||buf_delay<0|| - (ogg_uint32_t)buf_delay<_enc->rc.frames_total[0]|| - (ogg_uint32_t)buf_delay<_enc->rc.frames_total[1]){ - _enc->rc.frames_total[0]=0; - _enc->rc.twopass_buffer_bytes=0; - return TH_EBADHEADER; - } - /*Got a valid header; set up pass 2.*/ - _enc->rc.frames_left[0]=_enc->rc.frames_total[0]; - _enc->rc.frames_left[1]=_enc->rc.frames_total[1]; - _enc->rc.frames_left[2]=_enc->rc.frames_total[2]; - /*If the user hasn't specified a buffer size, use the whole file.*/ - if(_enc->rc.frame_metrics==NULL){ - _enc->rc.buf_delay=buf_delay; - _enc->rc.nframes[0]=_enc->rc.frames_total[0]; - _enc->rc.nframes[1]=_enc->rc.frames_total[1]; - _enc->rc.nframes[2]=_enc->rc.frames_total[2]; - _enc->rc.scale_sum[0]=scale_sum[0]; - _enc->rc.scale_sum[1]=scale_sum[1]; - _enc->rc.scale_window_end=buf_delay; - oc_enc_rc_reset(_enc); - } - _enc->rc.exp[0]=exp[0]; - _enc->rc.exp[1]=exp[1]; - /*Clear the header data from the buffer to make room for packet data.*/ - _enc->rc.twopass_buffer_fill=0; - _enc->rc.twopass_buffer_bytes=0; - } - } - if(_enc->rc.frames_total[0]!=0){ - ogg_int64_t curframe_num; - int nframes_total; - curframe_num=_enc->state.curframe_num; - if(curframe_num>=0){ - /*We just encoded a frame; make sure things matched.*/ - if(_enc->rc.prev_metrics.dup_count!=_enc->prev_dup_count){ - _enc->rc.twopass_buffer_bytes=0; - return TH_EINVAL; - } - } - curframe_num+=_enc->prev_dup_count+1; - nframes_total=_enc->rc.frames_total[0]+_enc->rc.frames_total[1] - +_enc->rc.frames_total[2]; - if(curframe_num>=nframes_total){ - /*We don't want any more data after the last frame, and we don't want to - allow any more frames to be encoded.*/ - _enc->rc.twopass_buffer_bytes=0; - } - else if(_enc->rc.twopass_buffer_bytes==0){ - if(_enc->rc.frame_metrics==NULL){ - /*We're using a whole-file buffer:*/ - if(!_buf)return OC_RC_2PASS_PACKET_SZ-_enc->rc.twopass_buffer_fill; - consumed=oc_rc_buffer_fill(&_enc->rc, - _buf,_bytes,consumed,OC_RC_2PASS_PACKET_SZ); - if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_PACKET_SZ){ - ogg_uint32_t dup_count; - ogg_int32_t log_scale; - int qti; - int arg; - /*Read the metrics for the next frame.*/ - dup_count=oc_rc_unbuffer_val(&_enc->rc,4); - log_scale=oc_rc_unbuffer_val(&_enc->rc,4); - _enc->rc.cur_metrics.log_scale=log_scale; - qti=(dup_count&0x80000000)>>31; - _enc->rc.cur_metrics.dup_count=dup_count&0x7FFFFFFF; - _enc->rc.cur_metrics.frame_type=qti; - _enc->rc.twopass_force_kf=qti==OC_INTRA_FRAME; - /*"Helpfully" set the dup count back to what it was in pass 1.*/ - arg=_enc->rc.cur_metrics.dup_count; - th_encode_ctl(_enc,TH_ENCCTL_SET_DUP_COUNT,&arg,sizeof(arg)); - /*Clear the buffer for the next frame.*/ - _enc->rc.twopass_buffer_fill=0; - } - } - else{ - int frames_needed; - /*We're using a finite buffer:*/ - frames_needed=OC_CLAMPI(0,_enc->rc.buf_delay - -(_enc->rc.scale_window_end-_enc->rc.scale_window0), - _enc->rc.frames_left[0]+_enc->rc.frames_left[1] - -_enc->rc.nframes[0]-_enc->rc.nframes[1]); - while(frames_needed>0){ - if(!_buf){ - return OC_RC_2PASS_PACKET_SZ*frames_needed - -_enc->rc.twopass_buffer_fill; - } - consumed=oc_rc_buffer_fill(&_enc->rc, - _buf,_bytes,consumed,OC_RC_2PASS_PACKET_SZ); - if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_PACKET_SZ){ - oc_frame_metrics *m; - int fmi; - ogg_uint32_t dup_count; - ogg_int32_t log_scale; - int qti; - /*Read the metrics for the next frame.*/ - dup_count=oc_rc_unbuffer_val(&_enc->rc,4); - log_scale=oc_rc_unbuffer_val(&_enc->rc,4); - /*Add the to the circular buffer.*/ - fmi=_enc->rc.frame_metrics_head+_enc->rc.nframe_metrics++; - if(fmi>=_enc->rc.cframe_metrics)fmi-=_enc->rc.cframe_metrics; - m=_enc->rc.frame_metrics+fmi; - m->log_scale=log_scale; - qti=(dup_count&0x80000000)>>31; - m->dup_count=dup_count&0x7FFFFFFF; - m->frame_type=qti; - /*And accumulate the statistics over the window.*/ - _enc->rc.nframes[qti]++; - _enc->rc.nframes[2]+=m->dup_count; - _enc->rc.scale_sum[qti]+=oc_bexp_q24(m->log_scale); - _enc->rc.scale_window_end+=m->dup_count+1; - /*Compute an upper bound on the number of remaining packets needed - for the current window.*/ - frames_needed=OC_CLAMPI(0,_enc->rc.buf_delay - -(_enc->rc.scale_window_end-_enc->rc.scale_window0), - _enc->rc.frames_left[0]+_enc->rc.frames_left[1] - -_enc->rc.nframes[0]-_enc->rc.nframes[1]); - /*Clear the buffer for the next frame.*/ - _enc->rc.twopass_buffer_fill=0; - _enc->rc.twopass_buffer_bytes=0; - } - /*Go back for more data.*/ - else break; - } - /*If we've got all the frames we need, fill in the current metrics. - We're ready to go.*/ - if(frames_needed<=0){ - int arg; - *&_enc->rc.cur_metrics= - *(_enc->rc.frame_metrics+_enc->rc.frame_metrics_head); - _enc->rc.twopass_force_kf= - _enc->rc.cur_metrics.frame_type==OC_INTRA_FRAME; - /*"Helpfully" set the dup count back to what it was in pass 1.*/ - arg=_enc->rc.cur_metrics.dup_count; - th_encode_ctl(_enc,TH_ENCCTL_SET_DUP_COUNT,&arg,sizeof(arg)); - /*Mark us ready for the next frame.*/ - _enc->rc.twopass_buffer_bytes=1; - } - } - } - } - return (int)consumed; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/state.c b/src/add-ons/media/plugins/theora/libtheora/state.c deleted file mode 100644 index 42ed33a9a3..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/state.c +++ /dev/null @@ -1,1227 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: state.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include -#include -#include "internal.h" -#if defined(OC_X86_ASM) -#if defined(_MSC_VER) -# include "x86_vc/x86int.h" -#else -# include "x86/x86int.h" -#endif -#endif -#if defined(OC_DUMP_IMAGES) -# include -# include "png.h" -#endif - -/*Returns the fragment index of the top-left block in a macro block. - This can be used to test whether or not the whole macro block is valid. - _sb_map: The super block map. - _quadi: The quadrant number. - Return: The index of the fragment of the upper left block in the macro - block, or -1 if the block lies outside the coded frame.*/ -static ptrdiff_t oc_sb_quad_top_left_frag(oc_sb_map_quad _sb_map[4],int _quadi){ - /*It so happens that under the Hilbert curve ordering described below, the - upper-left block in each macro block is at index 0, except in macro block - 3, where it is at index 2.*/ - return _sb_map[_quadi][_quadi&_quadi<<1]; -} - -/*Fills in the mapping from block positions to fragment numbers for a single - color plane. - This function also fills in the "valid" flag of each quadrant in the super - block flags. - _sb_maps: The array of super block maps for the color plane. - _sb_flags: The array of super block flags for the color plane. - _frag0: The index of the first fragment in the plane. - _hfrags: The number of horizontal fragments in a coded frame. - _vfrags: The number of vertical fragments in a coded frame.*/ -static void oc_sb_create_plane_mapping(oc_sb_map _sb_maps[], - oc_sb_flags _sb_flags[],ptrdiff_t _frag0,int _hfrags,int _vfrags){ - /*Contains the (macro_block,block) indices for a 4x4 grid of - fragments. - The pattern is a 4x4 Hilbert space-filling curve. - A Hilbert curve has the nice property that as the curve grows larger, its - fractal dimension approaches 2. - The intuition is that nearby blocks in the curve are also close spatially, - with the previous element always an immediate neighbor, so that runs of - blocks should be well correlated.*/ - static const int SB_MAP[4][4][2]={ - {{0,0},{0,1},{3,2},{3,3}}, - {{0,3},{0,2},{3,1},{3,0}}, - {{1,0},{1,3},{2,0},{2,3}}, - {{1,1},{1,2},{2,1},{2,2}} - }; - ptrdiff_t yfrag; - unsigned sbi; - int y; - sbi=0; - yfrag=_frag0; - for(y=0;;y+=4){ - int imax; - int x; - /*Figure out how many columns of blocks in this super block lie within the - image.*/ - imax=_vfrags-y; - if(imax>4)imax=4; - else if(imax<=0)break; - for(x=0;;x+=4,sbi++){ - ptrdiff_t xfrag; - int jmax; - int quadi; - int i; - /*Figure out how many rows of blocks in this super block lie within the - image.*/ - jmax=_hfrags-x; - if(jmax>4)jmax=4; - else if(jmax<=0)break; - /*By default, set all fragment indices to -1.*/ - memset(_sb_maps[sbi][0],0xFF,sizeof(_sb_maps[sbi])); - /*Fill in the fragment map for this super block.*/ - xfrag=yfrag+x; - for(i=0;i=0)<nhfrags+_xfrag0+j; - } -} - -/*Fills in the chroma plane fragment maps for a macro block. - This version is for use with chroma decimated in the X and Y directions - (4:2:0). - _mb_map: The macro block map to fill. - _fplanes: The descriptions of the fragment planes. - _xfrag0: The X location of the upper-left hand fragment in the luma plane. - _yfrag0: The Y location of the upper-left hand fragment in the luma plane.*/ -static void oc_mb_fill_cmapping00(oc_mb_map_plane _mb_map[3], - const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0){ - ptrdiff_t fragi; - _xfrag0>>=1; - _yfrag0>>=1; - fragi=_yfrag0*(ptrdiff_t)_fplanes[1].nhfrags+_xfrag0; - _mb_map[1][0]=fragi+_fplanes[1].froffset; - _mb_map[2][0]=fragi+_fplanes[2].froffset; -} - -/*Fills in the chroma plane fragment maps for a macro block. - This version is for use with chroma decimated in the Y direction. - _mb_map: The macro block map to fill. - _fplanes: The descriptions of the fragment planes. - _xfrag0: The X location of the upper-left hand fragment in the luma plane. - _yfrag0: The Y location of the upper-left hand fragment in the luma plane.*/ -static void oc_mb_fill_cmapping01(oc_mb_map_plane _mb_map[3], - const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0){ - ptrdiff_t fragi; - int j; - _yfrag0>>=1; - fragi=_yfrag0*(ptrdiff_t)_fplanes[1].nhfrags+_xfrag0; - for(j=0;j<2;j++){ - _mb_map[1][j]=fragi+_fplanes[1].froffset; - _mb_map[2][j]=fragi+_fplanes[2].froffset; - fragi++; - } -} - -/*Fills in the chroma plane fragment maps for a macro block. - This version is for use with chroma decimated in the X direction (4:2:2). - _mb_map: The macro block map to fill. - _fplanes: The descriptions of the fragment planes. - _xfrag0: The X location of the upper-left hand fragment in the luma plane. - _yfrag0: The Y location of the upper-left hand fragment in the luma plane.*/ -static void oc_mb_fill_cmapping10(oc_mb_map_plane _mb_map[3], - const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0){ - ptrdiff_t fragi; - int i; - _xfrag0>>=1; - fragi=_yfrag0*(ptrdiff_t)_fplanes[1].nhfrags+_xfrag0; - for(i=0;i<2;i++){ - _mb_map[1][i<<1]=fragi+_fplanes[1].froffset; - _mb_map[2][i<<1]=fragi+_fplanes[2].froffset; - fragi+=_fplanes[1].nhfrags; - } -} - -/*Fills in the chroma plane fragment maps for a macro block. - This version is for use with no chroma decimation (4:4:4). - This uses the already filled-in luma plane values. - _mb_map: The macro block map to fill. - _fplanes: The descriptions of the fragment planes.*/ -static void oc_mb_fill_cmapping11(oc_mb_map_plane _mb_map[3], - const oc_fragment_plane _fplanes[3]){ - int k; - for(k=0;k<4;k++){ - _mb_map[1][k]=_mb_map[0][k]+_fplanes[1].froffset; - _mb_map[2][k]=_mb_map[0][k]+_fplanes[2].froffset; - } -} - -/*The function type used to fill in the chroma plane fragment maps for a - macro block. - _mb_map: The macro block map to fill. - _fplanes: The descriptions of the fragment planes. - _xfrag0: The X location of the upper-left hand fragment in the luma plane. - _yfrag0: The Y location of the upper-left hand fragment in the luma plane.*/ -typedef void (*oc_mb_fill_cmapping_func)(oc_mb_map_plane _mb_map[3], - const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0); - -/*A table of functions used to fill in the chroma plane fragment maps for a - macro block for each type of chrominance decimation.*/ -static const oc_mb_fill_cmapping_func OC_MB_FILL_CMAPPING_TABLE[4]={ - oc_mb_fill_cmapping00, - oc_mb_fill_cmapping01, - oc_mb_fill_cmapping10, - (oc_mb_fill_cmapping_func)oc_mb_fill_cmapping11 -}; - -/*Fills in the mapping from macro blocks to their corresponding fragment - numbers in each plane. - _mb_maps: The list of macro block maps. - _mb_modes: The list of macro block modes; macro blocks completely outside - the coded region are marked invalid. - _fplanes: The descriptions of the fragment planes. - _pixel_fmt: The chroma decimation type.*/ -static void oc_mb_create_mapping(oc_mb_map _mb_maps[], - signed char _mb_modes[],const oc_fragment_plane _fplanes[3],int _pixel_fmt){ - oc_mb_fill_cmapping_func mb_fill_cmapping; - unsigned sbi; - int y; - mb_fill_cmapping=OC_MB_FILL_CMAPPING_TABLE[_pixel_fmt]; - /*Loop through the luma plane super blocks.*/ - for(sbi=y=0;y<_fplanes[0].nvfrags;y+=4){ - int x; - for(x=0;x<_fplanes[0].nhfrags;x+=4,sbi++){ - int ymb; - /*Loop through the macro blocks in each super block in display order.*/ - for(ymb=0;ymb<2;ymb++){ - int xmb; - for(xmb=0;xmb<2;xmb++){ - unsigned mbi; - int mbx; - int mby; - mbi=sbi<<2|OC_MB_MAP[ymb][xmb]; - mbx=x|xmb<<1; - mby=y|ymb<<1; - /*Initialize fragment indices to -1.*/ - memset(_mb_maps[mbi],0xFF,sizeof(_mb_maps[mbi])); - /*Make sure this macro block is within the encoded region.*/ - if(mbx>=_fplanes[0].nhfrags||mby>=_fplanes[0].nvfrags){ - _mb_modes[mbi]=OC_MODE_INVALID; - continue; - } - /*Fill in the fragment indices for the luma plane.*/ - oc_mb_fill_ymapping(_mb_maps[mbi],_fplanes,mbx,mby); - /*Fill in the fragment indices for the chroma planes.*/ - (*mb_fill_cmapping)(_mb_maps[mbi],_fplanes,mbx,mby); - } - } - } - } -} - -/*Marks the fragments which fall all or partially outside the displayable - region of the frame. - _state: The Theora state containing the fragments to be marked.*/ -static void oc_state_border_init(oc_theora_state *_state){ - oc_fragment *frag; - oc_fragment *yfrag_end; - oc_fragment *xfrag_end; - oc_fragment_plane *fplane; - int crop_x0; - int crop_y0; - int crop_xf; - int crop_yf; - int pli; - int y; - int x; - /*The method we use here is slow, but the code is dead simple and handles - all the special cases easily. - We only ever need to do it once.*/ - /*Loop through the fragments, marking those completely outside the - displayable region and constructing a border mask for those that straddle - the border.*/ - _state->nborders=0; - yfrag_end=frag=_state->frags; - for(pli=0;pli<3;pli++){ - fplane=_state->fplanes+pli; - /*Set up the cropping rectangle for this plane.*/ - crop_x0=_state->info.pic_x; - crop_xf=_state->info.pic_x+_state->info.pic_width; - crop_y0=_state->info.pic_y; - crop_yf=_state->info.pic_y+_state->info.pic_height; - if(pli>0){ - if(!(_state->info.pixel_fmt&1)){ - crop_x0=crop_x0>>1; - crop_xf=crop_xf+1>>1; - } - if(!(_state->info.pixel_fmt&2)){ - crop_y0=crop_y0>>1; - crop_yf=crop_yf+1>>1; - } - } - y=0; - for(yfrag_end+=fplane->nfrags;fragnhfrags;frag=crop_xf||crop_y0>=crop_yf){ - frag->invalid=1; - } - /*Otherwise, check to see if it straddles the border.*/ - else if(x=crop_x0&&x+j=crop_y0&&y+i=_state->nborders){ - _state->nborders++; - _state->borders[i].mask=mask; - _state->borders[i].npixels=npixels; - } - else if(_state->borders[i].mask!=mask)continue; - frag->borderi=i; - break; - } - } - else frag->borderi=-1; - } - } - } -} - -static int oc_state_frarray_init(oc_theora_state *_state){ - int yhfrags; - int yvfrags; - int chfrags; - int cvfrags; - ptrdiff_t yfrags; - ptrdiff_t cfrags; - ptrdiff_t nfrags; - unsigned yhsbs; - unsigned yvsbs; - unsigned chsbs; - unsigned cvsbs; - unsigned ysbs; - unsigned csbs; - unsigned nsbs; - size_t nmbs; - int hdec; - int vdec; - int pli; - /*Figure out the number of fragments in each plane.*/ - /*These parameters have already been validated to be multiples of 16.*/ - yhfrags=_state->info.frame_width>>3; - yvfrags=_state->info.frame_height>>3; - hdec=!(_state->info.pixel_fmt&1); - vdec=!(_state->info.pixel_fmt&2); - chfrags=yhfrags+hdec>>hdec; - cvfrags=yvfrags+vdec>>vdec; - yfrags=yhfrags*(ptrdiff_t)yvfrags; - cfrags=chfrags*(ptrdiff_t)cvfrags; - nfrags=yfrags+2*cfrags; - /*Figure out the number of super blocks in each plane.*/ - yhsbs=yhfrags+3>>2; - yvsbs=yvfrags+3>>2; - chsbs=chfrags+3>>2; - cvsbs=cvfrags+3>>2; - ysbs=yhsbs*yvsbs; - csbs=chsbs*cvsbs; - nsbs=ysbs+2*csbs; - nmbs=(size_t)ysbs<<2; - /*Check for overflow. - We support the ridiculous upper limits of the specification (1048560 by - 1048560, or 3 TB frames) if the target architecture has 64-bit pointers, - but for those with 32-bit pointers (or smaller!) we have to check. - If the caller wants to prevent denial-of-service by imposing a more - reasonable upper limit on the size of attempted allocations, they must do - so themselves; we have no platform independent way to determine how much - system memory there is nor an application-independent way to decide what a - "reasonable" allocation is.*/ - if(yfrags/yhfrags!=yvfrags||2*cfrags>2!=ysbs){ - return TH_EIMPL; - } - /*Initialize the fragment array.*/ - _state->fplanes[0].nhfrags=yhfrags; - _state->fplanes[0].nvfrags=yvfrags; - _state->fplanes[0].froffset=0; - _state->fplanes[0].nfrags=yfrags; - _state->fplanes[0].nhsbs=yhsbs; - _state->fplanes[0].nvsbs=yvsbs; - _state->fplanes[0].sboffset=0; - _state->fplanes[0].nsbs=ysbs; - _state->fplanes[1].nhfrags=_state->fplanes[2].nhfrags=chfrags; - _state->fplanes[1].nvfrags=_state->fplanes[2].nvfrags=cvfrags; - _state->fplanes[1].froffset=yfrags; - _state->fplanes[2].froffset=yfrags+cfrags; - _state->fplanes[1].nfrags=_state->fplanes[2].nfrags=cfrags; - _state->fplanes[1].nhsbs=_state->fplanes[2].nhsbs=chsbs; - _state->fplanes[1].nvsbs=_state->fplanes[2].nvsbs=cvsbs; - _state->fplanes[1].sboffset=ysbs; - _state->fplanes[2].sboffset=ysbs+csbs; - _state->fplanes[1].nsbs=_state->fplanes[2].nsbs=csbs; - _state->nfrags=nfrags; - _state->frags=_ogg_calloc(nfrags,sizeof(*_state->frags)); - _state->frag_mvs=_ogg_malloc(nfrags*sizeof(*_state->frag_mvs)); - _state->nsbs=nsbs; - _state->sb_maps=_ogg_malloc(nsbs*sizeof(*_state->sb_maps)); - _state->sb_flags=_ogg_calloc(nsbs,sizeof(*_state->sb_flags)); - _state->nhmbs=yhsbs<<1; - _state->nvmbs=yvsbs<<1; - _state->nmbs=nmbs; - _state->mb_maps=_ogg_calloc(nmbs,sizeof(*_state->mb_maps)); - _state->mb_modes=_ogg_calloc(nmbs,sizeof(*_state->mb_modes)); - _state->coded_fragis=_ogg_malloc(nfrags*sizeof(*_state->coded_fragis)); - if(_state->frags==NULL||_state->frag_mvs==NULL||_state->sb_maps==NULL|| - _state->sb_flags==NULL||_state->mb_maps==NULL||_state->mb_modes==NULL|| - _state->coded_fragis==NULL){ - return TH_EFAULT; - } - /*Create the mapping from super blocks to fragments.*/ - for(pli=0;pli<3;pli++){ - oc_fragment_plane *fplane; - fplane=_state->fplanes+pli; - oc_sb_create_plane_mapping(_state->sb_maps+fplane->sboffset, - _state->sb_flags+fplane->sboffset,fplane->froffset, - fplane->nhfrags,fplane->nvfrags); - } - /*Create the mapping from macro blocks to fragments.*/ - oc_mb_create_mapping(_state->mb_maps,_state->mb_modes, - _state->fplanes,_state->info.pixel_fmt); - /*Initialize the invalid and borderi fields of each fragment.*/ - oc_state_border_init(_state); - return 0; -} - -static void oc_state_frarray_clear(oc_theora_state *_state){ - _ogg_free(_state->coded_fragis); - _ogg_free(_state->mb_modes); - _ogg_free(_state->mb_maps); - _ogg_free(_state->sb_flags); - _ogg_free(_state->sb_maps); - _ogg_free(_state->frag_mvs); - _ogg_free(_state->frags); -} - - -/*Initializes the buffers used for reconstructed frames. - These buffers are padded with 16 extra pixels on each side, to allow - unrestricted motion vectors without special casing the boundary. - If chroma is decimated in either direction, the padding is reduced by a - factor of 2 on the appropriate sides. - _nrefs: The number of reference buffers to init; must be 3 or 4.*/ -static int oc_state_ref_bufs_init(oc_theora_state *_state,int _nrefs){ - th_info *info; - unsigned char *ref_frame_data; - size_t ref_frame_data_sz; - size_t ref_frame_sz; - size_t yplane_sz; - size_t cplane_sz; - int yhstride; - int yheight; - int chstride; - int cheight; - ptrdiff_t yoffset; - ptrdiff_t coffset; - ptrdiff_t *frag_buf_offs; - ptrdiff_t fragi; - int hdec; - int vdec; - int rfi; - int pli; - if(_nrefs<3||_nrefs>4)return TH_EINVAL; - info=&_state->info; - /*Compute the image buffer parameters for each plane.*/ - hdec=!(info->pixel_fmt&1); - vdec=!(info->pixel_fmt&2); - yhstride=info->frame_width+2*OC_UMV_PADDING; - yheight=info->frame_height+2*OC_UMV_PADDING; - chstride=yhstride>>hdec; - cheight=yheight>>vdec; - yplane_sz=yhstride*(size_t)yheight; - cplane_sz=chstride*(size_t)cheight; - yoffset=OC_UMV_PADDING+OC_UMV_PADDING*(ptrdiff_t)yhstride; - coffset=(OC_UMV_PADDING>>hdec)+(OC_UMV_PADDING>>vdec)*(ptrdiff_t)chstride; - ref_frame_sz=yplane_sz+2*cplane_sz; - ref_frame_data_sz=_nrefs*ref_frame_sz; - /*Check for overflow. - The same caveats apply as for oc_state_frarray_init().*/ - if(yplane_sz/yhstride!=yheight||2*cplane_szfrag_buf_offs= - _ogg_malloc(_state->nfrags*sizeof(*frag_buf_offs)); - if(ref_frame_data==NULL||frag_buf_offs==NULL){ - _ogg_free(frag_buf_offs); - _ogg_free(ref_frame_data); - return TH_EFAULT; - } - /*Set up the width, height and stride for the image buffers.*/ - _state->ref_frame_bufs[0][0].width=info->frame_width; - _state->ref_frame_bufs[0][0].height=info->frame_height; - _state->ref_frame_bufs[0][0].stride=yhstride; - _state->ref_frame_bufs[0][1].width=_state->ref_frame_bufs[0][2].width= - info->frame_width>>hdec; - _state->ref_frame_bufs[0][1].height=_state->ref_frame_bufs[0][2].height= - info->frame_height>>vdec; - _state->ref_frame_bufs[0][1].stride=_state->ref_frame_bufs[0][2].stride= - chstride; - for(rfi=1;rfi<_nrefs;rfi++){ - memcpy(_state->ref_frame_bufs[rfi],_state->ref_frame_bufs[0], - sizeof(_state->ref_frame_bufs[0])); - } - /*Set up the data pointers for the image buffers.*/ - for(rfi=0;rfi<_nrefs;rfi++){ - _state->ref_frame_data[rfi]=ref_frame_data; - _state->ref_frame_bufs[rfi][0].data=ref_frame_data+yoffset; - ref_frame_data+=yplane_sz; - _state->ref_frame_bufs[rfi][1].data=ref_frame_data+coffset; - ref_frame_data+=cplane_sz; - _state->ref_frame_bufs[rfi][2].data=ref_frame_data+coffset; - ref_frame_data+=cplane_sz; - /*Flip the buffer upside down. - This allows us to decode Theora's bottom-up frames in their natural - order, yet return a top-down buffer with a positive stride to the user.*/ - oc_ycbcr_buffer_flip(_state->ref_frame_bufs[rfi], - _state->ref_frame_bufs[rfi]); - } - _state->ref_ystride[0]=-yhstride; - _state->ref_ystride[1]=_state->ref_ystride[2]=-chstride; - /*Initialize the fragment buffer offsets.*/ - ref_frame_data=_state->ref_frame_data[0]; - fragi=0; - for(pli=0;pli<3;pli++){ - th_img_plane *iplane; - oc_fragment_plane *fplane; - unsigned char *vpix; - ptrdiff_t stride; - ptrdiff_t vfragi_end; - int nhfrags; - iplane=_state->ref_frame_bufs[0]+pli; - fplane=_state->fplanes+pli; - vpix=iplane->data; - vfragi_end=fplane->froffset+fplane->nfrags; - nhfrags=fplane->nhfrags; - stride=iplane->stride; - while(fragiref_frame_idx[OC_FRAME_GOLD]= - _state->ref_frame_idx[OC_FRAME_PREV]= - _state->ref_frame_idx[OC_FRAME_SELF]=-1; - _state->ref_frame_idx[OC_FRAME_IO]=_nrefs>3?3:-1; - return 0; -} - -static void oc_state_ref_bufs_clear(oc_theora_state *_state){ - _ogg_free(_state->frag_buf_offs); - _ogg_free(_state->ref_frame_data[0]); -} - - -void oc_state_vtable_init_c(oc_theora_state *_state){ - _state->opt_vtable.frag_copy=oc_frag_copy_c; - _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c; - _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c; - _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_c; - _state->opt_vtable.idct8x8=oc_idct8x8_c; - _state->opt_vtable.state_frag_recon=oc_state_frag_recon_c; - _state->opt_vtable.state_frag_copy_list=oc_state_frag_copy_list_c; - _state->opt_vtable.state_loop_filter_frag_rows= - oc_state_loop_filter_frag_rows_c; - _state->opt_vtable.restore_fpu=oc_restore_fpu_c; - _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG; -} - -/*Initialize the accelerated function pointers.*/ -void oc_state_vtable_init(oc_theora_state *_state){ -#if defined(OC_X86_ASM) - oc_state_vtable_init_x86(_state); -#else - oc_state_vtable_init_c(_state); -#endif -} - - -int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs){ - int ret; - /*First validate the parameters.*/ - if(_info==NULL)return TH_EFAULT; - /*The width and height of the encoded frame must be multiples of 16. - They must also, when divided by 16, fit into a 16-bit unsigned integer. - The displayable frame offset coordinates must fit into an 8-bit unsigned - integer. - Note that the offset Y in the API is specified on the opposite side from - how it is specified in the bitstream, because the Y axis is flipped in - the bitstream. - The displayable frame must fit inside the encoded frame. - The color space must be one known by the encoder.*/ - if((_info->frame_width&0xF)||(_info->frame_height&0xF)|| - _info->frame_width<=0||_info->frame_width>=0x100000|| - _info->frame_height<=0||_info->frame_height>=0x100000|| - _info->pic_x+_info->pic_width>_info->frame_width|| - _info->pic_y+_info->pic_height>_info->frame_height|| - _info->pic_x>255||_info->frame_height-_info->pic_height-_info->pic_y>255|| - /*Note: the following <0 comparisons may generate spurious warnings on - platforms where enums are unsigned. - We could cast them to unsigned and just use the following >= comparison, - but there are a number of compilers which will mis-optimize this. - It's better to live with the spurious warnings.*/ - _info->colorspace<0||_info->colorspace>=TH_CS_NSPACES|| - _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS){ - return TH_EINVAL; - } - memset(_state,0,sizeof(*_state)); - memcpy(&_state->info,_info,sizeof(*_info)); - /*Invert the sense of pic_y to match Theora's right-handed coordinate - system.*/ - _state->info.pic_y=_info->frame_height-_info->pic_height-_info->pic_y; - _state->frame_type=OC_UNKWN_FRAME; - oc_state_vtable_init(_state); - ret=oc_state_frarray_init(_state); - if(ret>=0)ret=oc_state_ref_bufs_init(_state,_nrefs); - if(ret<0){ - oc_state_frarray_clear(_state); - return ret; - } - /*If the keyframe_granule_shift is out of range, use the maximum allowable - value.*/ - if(_info->keyframe_granule_shift<0||_info->keyframe_granule_shift>31){ - _state->info.keyframe_granule_shift=31; - } - _state->keyframe_num=0; - _state->curframe_num=-1; - /*3.2.0 streams mark the frame index instead of the frame count. - This was changed with stream version 3.2.1 to conform to other Ogg - codecs. - We add an extra bias when computing granule positions for new streams.*/ - _state->granpos_bias=TH_VERSION_CHECK(_info,3,2,1); - return 0; -} - -void oc_state_clear(oc_theora_state *_state){ - oc_state_ref_bufs_clear(_state); - oc_state_frarray_clear(_state); -} - - -/*Duplicates the pixels on the border of the image plane out into the - surrounding padding for use by unrestricted motion vectors. - This function only adds the left and right borders, and only for the fragment - rows specified. - _refi: The index of the reference buffer to pad. - _pli: The color plane. - _y0: The Y coordinate of the first row to pad. - _yend: The Y coordinate of the row to stop padding at.*/ -void oc_state_borders_fill_rows(oc_theora_state *_state,int _refi,int _pli, - int _y0,int _yend){ - th_img_plane *iplane; - unsigned char *apix; - unsigned char *bpix; - unsigned char *epix; - int stride; - int hpadding; - hpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&1)); - iplane=_state->ref_frame_bufs[_refi]+_pli; - stride=iplane->stride; - apix=iplane->data+_y0*(ptrdiff_t)stride; - bpix=apix+iplane->width-1; - epix=iplane->data+_yend*(ptrdiff_t)stride; - /*Note the use of != instead of <, which allows the stride to be negative.*/ - while(apix!=epix){ - memset(apix-hpadding,apix[0],hpadding); - memset(bpix+1,bpix[0],hpadding); - apix+=stride; - bpix+=stride; - } -} - -/*Duplicates the pixels on the border of the image plane out into the - surrounding padding for use by unrestricted motion vectors. - This function only adds the top and bottom borders, and must be called after - the left and right borders are added. - _refi: The index of the reference buffer to pad. - _pli: The color plane.*/ -void oc_state_borders_fill_caps(oc_theora_state *_state,int _refi,int _pli){ - th_img_plane *iplane; - unsigned char *apix; - unsigned char *bpix; - unsigned char *epix; - int stride; - int hpadding; - int vpadding; - int fullw; - hpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&1)); - vpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&2)); - iplane=_state->ref_frame_bufs[_refi]+_pli; - stride=iplane->stride; - fullw=iplane->width+(hpadding<<1); - apix=iplane->data-hpadding; - bpix=iplane->data+(iplane->height-1)*(ptrdiff_t)stride-hpadding; - epix=apix-stride*(ptrdiff_t)vpadding; - while(apix!=epix){ - memcpy(apix-stride,apix,fullw); - memcpy(bpix+stride,bpix,fullw); - apix-=stride; - bpix+=stride; - } -} - -/*Duplicates the pixels on the border of the given reference image out into - the surrounding padding for use by unrestricted motion vectors. - _state: The context containing the reference buffers. - _refi: The index of the reference buffer to pad.*/ -void oc_state_borders_fill(oc_theora_state *_state,int _refi){ - int pli; - for(pli=0;pli<3;pli++){ - oc_state_borders_fill_rows(_state,_refi,pli,0, - _state->ref_frame_bufs[_refi][pli].height); - oc_state_borders_fill_caps(_state,_refi,pli); - } -} - -/*Determines the offsets in an image buffer to use for motion compensation. - _state: The Theora state the offsets are to be computed with. - _offsets: Returns the offset for the buffer(s). - _offsets[0] is always set. - _offsets[1] is set if the motion vector has non-zero fractional - components. - _pli: The color plane index. - _dx: The X component of the motion vector. - _dy: The Y component of the motion vector. - Return: The number of offsets returned: 1 or 2.*/ -int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2], - int _pli,int _dx,int _dy){ - /*Here is a brief description of how Theora handles motion vectors: - Motion vector components are specified to half-pixel accuracy in - undecimated directions of each plane, and quarter-pixel accuracy in - decimated directions. - Integer parts are extracted by dividing (not shifting) by the - appropriate amount, with truncation towards zero. - These integer values are used to calculate the first offset. - - If either of the fractional parts are non-zero, then a second offset is - computed. - No third or fourth offsets are computed, even if both components have - non-zero fractional parts. - The second offset is computed by dividing (not shifting) by the - appropriate amount, always truncating _away_ from zero.*/ -#if 0 - /*This version of the code doesn't use any tables, but is slower.*/ - int ystride; - int xprec; - int yprec; - int xfrac; - int yfrac; - int offs; - ystride=_state->ref_ystride[_pli]; - /*These two variables decide whether we are in half- or quarter-pixel - precision in each component.*/ - xprec=1+(_pli!=0&&!(_state->info.pixel_fmt&1)); - yprec=1+(_pli!=0&&!(_state->info.pixel_fmt&2)); - /*These two variables are either 0 if all the fractional bits are zero or -1 - if any of them are non-zero.*/ - xfrac=OC_SIGNMASK(-(_dx&(xprec|1))); - yfrac=OC_SIGNMASK(-(_dy&(yprec|1))); - offs=(_dx>>xprec)+(_dy>>yprec)*ystride; - if(xfrac||yfrac){ - int xmask; - int ymask; - xmask=OC_SIGNMASK(_dx); - ymask=OC_SIGNMASK(_dy); - yfrac&=ystride; - _offsets[0]=offs-(xfrac&xmask)+(yfrac&ymask); - _offsets[1]=offs-(xfrac&~xmask)+(yfrac&~ymask); - return 2; - } - else{ - _offsets[0]=offs; - return 1; - } -#else - /*Using tables simplifies the code, and there's enough arithmetic to hide the - latencies of the memory references.*/ - static const signed char OC_MVMAP[2][64]={ - { - -15,-15,-14,-14,-13,-13,-12,-12,-11,-11,-10,-10, -9, -9, -8, - -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 - }, - { - -7, -7, -7, -7, -6, -6, -6, -6, -5, -5, -5, -5, -4, -4, -4, - -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7 - } - }; - static const signed char OC_MVMAP2[2][64]={ - { - -1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, - 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 - }, - { - -1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, - 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 - } - }; - int ystride; - int qpx; - int qpy; - int mx; - int my; - int mx2; - int my2; - int offs; - ystride=_state->ref_ystride[_pli]; - qpy=_pli!=0&&!(_state->info.pixel_fmt&2); - my=OC_MVMAP[qpy][_dy+31]; - my2=OC_MVMAP2[qpy][_dy+31]; - qpx=_pli!=0&&!(_state->info.pixel_fmt&1); - mx=OC_MVMAP[qpx][_dx+31]; - mx2=OC_MVMAP2[qpx][_dx+31]; - offs=my*ystride+mx; - if(mx2||my2){ - _offsets[1]=offs+my2*ystride+mx2; - _offsets[0]=offs; - return 2; - } - _offsets[0]=offs; - return 1; -#endif -} - -void oc_state_frag_recon(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ - _state->opt_vtable.state_frag_recon(_state,_fragi,_pli,_dct_coeffs, - _last_zzi,_dc_quant); -} - -void oc_state_frag_recon_c(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ - unsigned char *dst; - ptrdiff_t frag_buf_off; - int ystride; - int mb_mode; - /*Apply the inverse transform.*/ - /*Special case only having a DC component.*/ - if(_last_zzi<2){ - ogg_int16_t p; - int ci; - /*We round this dequant product (and not any of the others) because there's - no iDCT rounding.*/ - p=(ogg_int16_t)(_dct_coeffs[0]*(ogg_int32_t)_dc_quant+15>>5); - /*LOOP VECTORIZES.*/ - for(ci=0;ci<64;ci++)_dct_coeffs[ci]=p; - } - else{ - /*First, dequantize the DC coefficient.*/ - _dct_coeffs[0]=(ogg_int16_t)(_dct_coeffs[0]*(int)_dc_quant); - oc_idct8x8(_state,_dct_coeffs,_last_zzi); - } - /*Fill in the target buffer.*/ - frag_buf_off=_state->frag_buf_offs[_fragi]; - mb_mode=_state->frags[_fragi].mb_mode; - ystride=_state->ref_ystride[_pli]; - dst=_state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_SELF]]+frag_buf_off; - if(mb_mode==OC_MODE_INTRA)oc_frag_recon_intra(_state,dst,ystride,_dct_coeffs); - else{ - const unsigned char *ref; - int mvoffsets[2]; - ref= - _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]] - +frag_buf_off; - if(oc_state_get_mv_offsets(_state,mvoffsets,_pli, - _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){ - oc_frag_recon_inter2(_state, - dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride,_dct_coeffs); - } - else oc_frag_recon_inter(_state,dst,ref+mvoffsets[0],ystride,_dct_coeffs); - } -} - -/*Copies the fragments specified by the lists of fragment indices from one - frame to another. - _fragis: A pointer to a list of fragment indices. - _nfragis: The number of fragment indices to copy. - _dst_frame: The reference frame to copy to. - _src_frame: The reference frame to copy from. - _pli: The color plane the fragments lie in.*/ -void oc_state_frag_copy_list(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - _state->opt_vtable.state_frag_copy_list(_state,_fragis,_nfragis,_dst_frame, - _src_frame,_pli); -} - -void oc_state_frag_copy_list_c(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - const ptrdiff_t *frag_buf_offs; - const unsigned char *src_frame_data; - unsigned char *dst_frame_data; - ptrdiff_t fragii; - int ystride; - dst_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_dst_frame]]; - src_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_src_frame]]; - ystride=_state->ref_ystride[_pli]; - frag_buf_offs=_state->frag_buf_offs; - for(fragii=0;fragii<_nfragis;fragii++){ - ptrdiff_t frag_buf_off; - frag_buf_off=frag_buf_offs[_fragis[fragii]]; - oc_frag_copy(_state,dst_frame_data+frag_buf_off, - src_frame_data+frag_buf_off,ystride); - } -} - -static void loop_filter_h(unsigned char *_pix,int _ystride,int *_bv){ - int y; - _pix-=2; - for(y=0;y<8;y++){ - int f; - f=_pix[0]-_pix[3]+3*(_pix[2]-_pix[1]); - /*The _bv array is used to compute the function - f=OC_CLAMPI(OC_MINI(-_2flimit-f,0),f,OC_MAXI(_2flimit-f,0)); - where _2flimit=_state->loop_filter_limits[_state->qis[0]]<<1;*/ - f=*(_bv+(f+4>>3)); - _pix[1]=OC_CLAMP255(_pix[1]+f); - _pix[2]=OC_CLAMP255(_pix[2]-f); - _pix+=_ystride; - } -} - -static void loop_filter_v(unsigned char *_pix,int _ystride,int *_bv){ - int x; - _pix-=_ystride*2; - for(x=0;x<8;x++){ - int f; - f=_pix[x]-_pix[_ystride*3+x]+3*(_pix[_ystride*2+x]-_pix[_ystride+x]); - /*The _bv array is used to compute the function - f=OC_CLAMPI(OC_MINI(-_2flimit-f,0),f,OC_MAXI(_2flimit-f,0)); - where _2flimit=_state->loop_filter_limits[_state->qis[0]]<<1;*/ - f=*(_bv+(f+4>>3)); - _pix[_ystride+x]=OC_CLAMP255(_pix[_ystride+x]+f); - _pix[_ystride*2+x]=OC_CLAMP255(_pix[_ystride*2+x]-f); - } -} - -/*Initialize the bounding values array used by the loop filter. - _bv: Storage for the array. - Return: 0 on success, or a non-zero value if no filtering need be applied.*/ -int oc_state_loop_filter_init(oc_theora_state *_state,int _bv[256]){ - int flimit; - int i; - flimit=_state->loop_filter_limits[_state->qis[0]]; - if(flimit==0)return 1; - memset(_bv,0,sizeof(_bv[0])*256); - for(i=0;i=0)_bv[127-i-flimit]=i-flimit; - _bv[127-i]=-i; - _bv[127+i]=i; - if(127+i+flimit<256)_bv[127+i+flimit]=flimit-i; - } - return 0; -} - -/*Apply the loop filter to a given set of fragment rows in the given plane. - The filter may be run on the bottom edge, affecting pixels in the next row of - fragments, so this row also needs to be available. - _bv: The bounding values array. - _refi: The index of the frame buffer to filter. - _pli: The color plane to filter. - _fragy0: The Y coordinate of the first fragment row to filter. - _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/ -void oc_state_loop_filter_frag_rows(const oc_theora_state *_state,int _bv[256], - int _refi,int _pli,int _fragy0,int _fragy_end){ - _state->opt_vtable.state_loop_filter_frag_rows(_state,_bv,_refi,_pli, - _fragy0,_fragy_end); -} - -void oc_state_loop_filter_frag_rows_c(const oc_theora_state *_state,int *_bv, - int _refi,int _pli,int _fragy0,int _fragy_end){ - const oc_fragment_plane *fplane; - const oc_fragment *frags; - const ptrdiff_t *frag_buf_offs; - unsigned char *ref_frame_data; - ptrdiff_t fragi_top; - ptrdiff_t fragi_bot; - ptrdiff_t fragi0; - ptrdiff_t fragi0_end; - int ystride; - int nhfrags; - _bv+=127; - fplane=_state->fplanes+_pli; - nhfrags=fplane->nhfrags; - fragi_top=fplane->froffset; - fragi_bot=fragi_top+fplane->nfrags; - fragi0=fragi_top+_fragy0*(ptrdiff_t)nhfrags; - fragi0_end=fragi0+(_fragy_end-_fragy0)*(ptrdiff_t)nhfrags; - ystride=_state->ref_ystride[_pli]; - frags=_state->frags; - frag_buf_offs=_state->frag_buf_offs; - ref_frame_data=_state->ref_frame_data[_refi]; - /*The following loops are constructed somewhat non-intuitively on purpose. - The main idea is: if a block boundary has at least one coded fragment on - it, the filter is applied to it. - However, the order that the filters are applied in matters, and VP3 chose - the somewhat strange ordering used below.*/ - while(fragi0fragi0)loop_filter_h(ref,ystride,_bv); - if(fragi0>fragi_top)loop_filter_v(ref,ystride,_bv); - if(fragi+1info.frame_width; - height=_state->info.frame_height; - iframe=_state->granpos>>_state->info.keyframe_granule_shift; - pframe=_state->granpos-(iframe<<_state->info.keyframe_granule_shift); - sprintf(fname,"%08i%s.png",(int)(iframe+pframe),_suf); - fp=fopen(fname,"wb"); - if(fp==NULL)return TH_EFAULT; - image=(png_bytep *)oc_malloc_2d(height,6*width,sizeof(**image)); - if(image==NULL){ - fclose(fp); - return TH_EFAULT; - } - png=png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); - if(png==NULL){ - oc_free_2d(image); - fclose(fp); - return TH_EFAULT; - } - info=png_create_info_struct(png); - if(info==NULL){ - png_destroy_write_struct(&png,NULL); - oc_free_2d(image); - fclose(fp); - return TH_EFAULT; - } - if(setjmp(png_jmpbuf(png))){ - png_destroy_write_struct(&png,&info); - oc_free_2d(image); - fclose(fp); - return TH_EFAULT; - } - framei=_state->ref_frame_idx[_frame]; - y_row=_state->ref_frame_bufs[framei][0].data; - u_row=_state->ref_frame_bufs[framei][1].data; - v_row=_state->ref_frame_bufs[framei][2].data; - y_stride=_state->ref_frame_bufs[framei][0].stride; - u_stride=_state->ref_frame_bufs[framei][1].stride; - v_stride=_state->ref_frame_bufs[framei][2].stride; - /*Chroma up-sampling is just done with a box filter. - This is very likely what will actually be used in practice on a real - display, and also removes one more layer to search in for the source of - artifacts. - As an added bonus, it's dead simple.*/ - for(imgi=height;imgi-->0;){ - int dc; - y=y_row; - u=u_row; - v=v_row; - for(imgj=0;imgj<6*width;){ - float yval; - float uval; - float vval; - unsigned rval; - unsigned gval; - unsigned bval; - /*This is intentionally slow and very accurate.*/ - yval=(*y-16)*(1.0F/219); - uval=(*u-128)*(2*(1-0.114F)/224); - vval=(*v-128)*(2*(1-0.299F)/224); - rval=OC_CLAMPI(0,(int)(65535*(yval+vval)+0.5F),65535); - gval=OC_CLAMPI(0,(int)(65535*( - yval-uval*(0.114F/0.587F)-vval*(0.299F/0.587F))+0.5F),65535); - bval=OC_CLAMPI(0,(int)(65535*(yval+uval)+0.5F),65535); - image[imgi][imgj++]=(unsigned char)(rval>>8); - image[imgi][imgj++]=(unsigned char)(rval&0xFF); - image[imgi][imgj++]=(unsigned char)(gval>>8); - image[imgi][imgj++]=(unsigned char)(gval&0xFF); - image[imgi][imgj++]=(unsigned char)(bval>>8); - image[imgi][imgj++]=(unsigned char)(bval&0xFF); - dc=(y-y_row&1)|(_state->info.pixel_fmt&1); - y++; - u+=dc; - v+=dc; - } - dc=-((height-1-imgi&1)|_state->info.pixel_fmt>>1); - y_row+=y_stride; - u_row+=dc&u_stride; - v_row+=dc&v_stride; - } - png_init_io(png,fp); - png_set_compression_level(png,Z_BEST_COMPRESSION); - png_set_IHDR(png,info,width,height,16,PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT); - switch(_state->info.colorspace){ - case TH_CS_ITU_REC_470M:{ - png_set_gAMA(png,info,2.2); - png_set_cHRM_fixed(png,info,31006,31616, - 67000,32000,21000,71000,14000,8000); - }break; - case TH_CS_ITU_REC_470BG:{ - png_set_gAMA(png,info,2.67); - png_set_cHRM_fixed(png,info,31271,32902, - 64000,33000,29000,60000,15000,6000); - }break; - default:break; - } - png_set_pHYs(png,info,_state->info.aspect_numerator, - _state->info.aspect_denominator,0); - png_set_rows(png,info,image); - png_write_png(png,info,PNG_TRANSFORM_IDENTITY,NULL); - png_write_end(png,info); - png_destroy_write_struct(&png,&info); - oc_free_2d(image); - fclose(fp); - return 0; -} -#endif - - - -ogg_int64_t th_granule_frame(void *_encdec,ogg_int64_t _granpos){ - oc_theora_state *state; - state=(oc_theora_state *)_encdec; - if(_granpos>=0){ - ogg_int64_t iframe; - ogg_int64_t pframe; - iframe=_granpos>>state->info.keyframe_granule_shift; - pframe=_granpos-(iframe<info.keyframe_granule_shift); - /*3.2.0 streams store the frame index in the granule position. - 3.2.1 and later store the frame count. - We return the index, so adjust the value if we have a 3.2.1 or later - stream.*/ - return iframe+pframe-TH_VERSION_CHECK(&state->info,3,2,1); - } - return -1; -} - -double th_granule_time(void *_encdec,ogg_int64_t _granpos){ - oc_theora_state *state; - state=(oc_theora_state *)_encdec; - if(_granpos>=0){ - return (th_granule_frame(_encdec, _granpos)+1)*( - (double)state->info.fps_denominator/state->info.fps_numerator); - } - return -1; -} diff --git a/src/add-ons/media/plugins/theora/libtheora/theora/codec.h b/src/add-ons/media/plugins/theora/libtheora/theora/codec.h deleted file mode 100644 index 5c2669630c..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/theora/codec.h +++ /dev/null @@ -1,591 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $ - - ********************************************************************/ - -/**\mainpage - * - * \section intro Introduction - * - * This is the documentation for libtheora C API. - * The current reference - * implementation for Theora, a free, - * patent-unencumbered video codec. - * Theora is derived from On2's VP3 codec with additional features and - * integration with Ogg multimedia formats by - * the Xiph.Org Foundation. - * Complete documentation of the format itself is available in - * the Theora - * specification. - * - * \subsection Organization - * - * The functions documented here are actually subdivided into three - * separate libraries: - * - libtheoraenc contains the encoder interface, - * described in \ref encfuncs. - * - libtheoradec contains the decoder interface and - * routines shared with the encoder. - * You must also link to this if you link to libtheoraenc. - * The routines in this library are described in \ref decfuncs and - * \ref basefuncs. - * - libtheora contains the \ref oldfuncs. - * - * New code should link to libtheoradec and, if using encoder - * features, libtheoraenc. Together these two export both - * the standard and the legacy API, so this is all that is needed by - * any code. The older libtheora library is provided just for - * compatibility with older build configurations. - * - * In general the recommended 1.x API symbols can be distinguished - * by their th_ or TH_ namespace prefix. - * The older, legacy API uses theora_ or OC_ - * prefixes instead. - */ - -/**\file - * The shared libtheoradec and libtheoraenc C API. - * You don't need to include this directly.*/ - -#if !defined(_O_THEORA_CODEC_H_) -# define _O_THEORA_CODEC_H_ (1) -# include - -#if defined(__cplusplus) -extern "C" { -#endif - - - -/**\name Return codes*/ -/*@{*/ -/**An invalid pointer was provided.*/ -#define TH_EFAULT (-1) -/**An invalid argument was provided.*/ -#define TH_EINVAL (-10) -/**The contents of the header were incomplete, invalid, or unexpected.*/ -#define TH_EBADHEADER (-20) -/**The header does not belong to a Theora stream.*/ -#define TH_ENOTFORMAT (-21) -/**The bitstream version is too high.*/ -#define TH_EVERSION (-22) -/**The specified function is not implemented.*/ -#define TH_EIMPL (-23) -/**There were errors in the video data packet.*/ -#define TH_EBADPACKET (-24) -/**The decoded packet represented a dropped frame. - The player can continue to display the current frame, as the contents of the - decoded frame buffer have not changed.*/ -#define TH_DUPFRAME (1) -/*@}*/ - -/**The currently defined color space tags. - * See the Theora - * specification, Chapter 4, for exact details on the meaning - * of each of these color spaces.*/ -typedef enum{ - /**The color space was not specified at the encoder. - It may be conveyed by an external means.*/ - TH_CS_UNSPECIFIED, - /**A color space designed for NTSC content.*/ - TH_CS_ITU_REC_470M, - /**A color space designed for PAL/SECAM content.*/ - TH_CS_ITU_REC_470BG, - /**The total number of currently defined color spaces.*/ - TH_CS_NSPACES -}th_colorspace; - -/**The currently defined pixel format tags. - * See the Theora - * specification, Section 4.4, for details on the precise sample - * locations.*/ -typedef enum{ - /**Chroma decimation by 2 in both the X and Y directions (4:2:0). - The Cb and Cr chroma planes are half the width and half the - height of the luma plane.*/ - TH_PF_420, - /**Currently reserved.*/ - TH_PF_RSVD, - /**Chroma decimation by 2 in the X direction (4:2:2). - The Cb and Cr chroma planes are half the width of the luma plane, but full - height.*/ - TH_PF_422, - /**No chroma decimation (4:4:4). - The Cb and Cr chroma planes are full width and full height.*/ - TH_PF_444, - /**The total number of currently defined pixel formats.*/ - TH_PF_NFORMATS -}th_pixel_fmt; - - - -/**A buffer for a single color plane in an uncompressed image. - * This contains the image data in a left-to-right, top-down format. - * Each row of pixels is stored contiguously in memory, but successive - * rows need not be. - * Use \a stride to compute the offset of the next row. - * The encoder accepts both positive \a stride values (top-down in memory) - * and negative (bottom-up in memory). - * The decoder currently always generates images with positive strides.*/ -typedef struct{ - /**The width of this plane.*/ - int width; - /**The height of this plane.*/ - int height; - /**The offset in bytes between successive rows.*/ - int stride; - /**A pointer to the beginning of the first row.*/ - unsigned char *data; -}th_img_plane; - -/**A complete image buffer for an uncompressed frame. - * The chroma planes may be decimated by a factor of two in either - * direction, as indicated by th_info#pixel_fmt. - * The width and height of the Y' plane must be multiples of 16. - * They may need to be cropped for display, using the rectangle - * specified by th_info#pic_x, th_info#pic_y, th_info#pic_width, - * and th_info#pic_height. - * All samples are 8 bits. - * \note The term YUV often used to describe a colorspace is ambiguous. - * The exact parameters of the RGB to YUV conversion process aside, in - * many contexts the U and V channels actually have opposite meanings. - * To avoid this confusion, we are explicit: the name of the color - * channels are Y'CbCr, and they appear in that order, always. - * The prime symbol denotes that the Y channel is non-linear. - * Cb and Cr stand for "Chroma blue" and "Chroma red", respectively.*/ -typedef th_img_plane th_ycbcr_buffer[3]; - -/**Theora bitstream information. - * This contains the basic playback parameters for a stream, and corresponds to - * the initial 'info' header packet. - * To initialize an encoder, the application fills in this structure and - * passes it to th_encode_alloc(). - * A default encoding mode is chosen based on the values of the #quality and - * #target_bitrate fields. - * On decode, it is filled in by th_decode_headerin(), and then passed to - * th_decode_alloc(). - * - * Encoded Theora frames must be a multiple of 16 in size; - * this is what the #frame_width and #frame_height members represent. - * To handle arbitrary picture sizes, a crop rectangle is specified in the - * #pic_x, #pic_y, #pic_width and #pic_height members. - * - * All frame buffers contain pointers to the full, padded frame. - * However, the current encoder will not reference pixels outside of - * the cropped picture region, and the application does not need to fill them - * in. - * The decoder will allocate storage for a full frame, but the - * application should not rely on the padding containing sensible - * data. - * - * It is also generally recommended that the offsets and sizes should still be - * multiples of 2 to avoid chroma sampling shifts when chroma is sub-sampled. - * See the Theora - * specification, Section 4.4, for more details. - * - * Frame rate, in frames per second, is stored as a rational fraction, as is - * the pixel aspect ratio. - * Note that this refers to the aspect ratio of the individual pixels, not of - * the overall frame itself. - * The frame aspect ratio can be computed from pixel aspect ratio using the - * image dimensions.*/ -typedef struct{ - /**\name Theora version - * Bitstream version information.*/ - /*@{*/ - unsigned char version_major; - unsigned char version_minor; - unsigned char version_subminor; - /*@}*/ - /**The encoded frame width. - * This must be a multiple of 16, and less than 1048576.*/ - ogg_uint32_t frame_width; - /**The encoded frame height. - * This must be a multiple of 16, and less than 1048576.*/ - ogg_uint32_t frame_height; - /**The displayed picture width. - * This must be no larger than width.*/ - ogg_uint32_t pic_width; - /**The displayed picture height. - * This must be no larger than height.*/ - ogg_uint32_t pic_height; - /**The X offset of the displayed picture. - * This must be no larger than #frame_width-#pic_width or 255, whichever is - * smaller.*/ - ogg_uint32_t pic_x; - /**The Y offset of the displayed picture. - * This must be no larger than #frame_height-#pic_height, and - * #frame_height-#pic_height-#pic_y must be no larger than 255. - * This slightly funny restriction is due to the fact that the offset is - * specified from the top of the image for consistency with the standard - * graphics left-handed coordinate system used throughout this API, while - * it is stored in the encoded stream as an offset from the bottom.*/ - ogg_uint32_t pic_y; - /**\name Frame rate - * The frame rate, as a fraction. - * If either is 0, the frame rate is undefined.*/ - /*@{*/ - ogg_uint32_t fps_numerator; - ogg_uint32_t fps_denominator; - /*@}*/ - /**\name Aspect ratio - * The aspect ratio of the pixels. - * If either value is zero, the aspect ratio is undefined. - * If not specified by any external means, 1:1 should be assumed. - * The aspect ratio of the full picture can be computed as - * \code - * aspect_numerator*pic_width/(aspect_denominator*pic_height). - * \endcode */ - /*@{*/ - ogg_uint32_t aspect_numerator; - ogg_uint32_t aspect_denominator; - /*@}*/ - /**The color space.*/ - th_colorspace colorspace; - /**The pixel format.*/ - th_pixel_fmt pixel_fmt; - /**The target bit-rate in bits per second. - If initializing an encoder with this struct, set this field to a non-zero - value to activate CBR encoding by default.*/ - int target_bitrate; - /**The target quality level. - Valid values range from 0 to 63, inclusive, with higher values giving - higher quality. - If initializing an encoder with this struct, and #target_bitrate is set - to zero, VBR encoding at this quality will be activated by default.*/ - /*Currently this is set so that a qi of 0 corresponds to distortions of 24 - times the JND, and each increase by 16 halves that value. - This gives us fine discrimination at low qualities, yet effective rate - control at high qualities. - The qi value 63 is special, however. - For this, the highest quality, we use one half of a JND for our threshold. - Due to the lower bounds placed on allowable quantizers in Theora, we will - not actually be able to achieve quality this good, but this should - provide as close to visually lossless quality as Theora is capable of. - We could lift the quantizer restrictions without breaking VP3.1 - compatibility, but this would result in quantized coefficients that are - too large for the current bitstream to be able to store. - We'd have to redesign the token syntax to store these large coefficients, - which would make transcoding complex.*/ - int quality; - /**The amount to shift to extract the last keyframe number from the granule - * position. - * This can be at most 31. - * th_info_init() will set this to a default value (currently 6, - * which is good for streaming applications), but you can set it to 0 to - * make every frame a keyframe. - * The maximum distance between key frames is - * 1<<#keyframe_granule_shift. - * The keyframe frequency can be more finely controlled with - * #TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, which can also be adjusted - * during encoding (for example, to force the next frame to be a keyframe), - * but it cannot be set larger than the amount permitted by this field after - * the headers have been output.*/ - int keyframe_granule_shift; -}th_info; - -/**The comment information. - * - * This structure holds the in-stream metadata corresponding to - * the 'comment' header packet. - * The comment header is meant to be used much like someone jotting a quick - * note on the label of a video. - * It should be a short, to the point text note that can be more than a couple - * words, but not more than a short paragraph. - * - * The metadata is stored as a series of (tag, value) pairs, in - * length-encoded string vectors. - * The first occurrence of the '=' character delimits the tag and value. - * A particular tag may occur more than once, and order is significant. - * The character set encoding for the strings is always UTF-8, but the tag - * names are limited to ASCII, and treated as case-insensitive. - * See the Theora - * specification, Section 6.3.3 for details. - * - * In filling in this structure, th_decode_headerin() will null-terminate - * the user_comment strings for safety. - * However, the bitstream format itself treats them as 8-bit clean vectors, - * possibly containing null characters, and so the length array should be - * treated as their authoritative length. - */ -typedef struct th_comment{ - /**The array of comment string vectors.*/ - char **user_comments; - /**An array of the corresponding length of each vector, in bytes.*/ - int *comment_lengths; - /**The total number of comment strings.*/ - int comments; - /**The null-terminated vendor string. - This identifies the software used to encode the stream.*/ - char *vendor; -}th_comment; - - - -/**A single base matrix.*/ -typedef unsigned char th_quant_base[64]; - -/**A set of \a qi ranges.*/ -typedef struct{ - /**The number of ranges in the set.*/ - int nranges; - /**The size of each of the #nranges ranges. - These must sum to 63.*/ - const int *sizes; - /**#nranges +1 base matrices. - Matrices \a i and i+1 form the endpoints of range \a i.*/ - const th_quant_base *base_matrices; -}th_quant_ranges; - -/**A complete set of quantization parameters. - The quantizer for each coefficient is calculated as: - \code - Q=MAX(MIN(qmin[qti][ci!=0],scale[ci!=0][qi]*base[qti][pli][qi][ci]/100), - 1024). - \endcode - - \a qti is the quantization type index: 0 for intra, 1 for inter. - ci!=0 is 0 for the DC coefficient and 1 for AC coefficients. - \a qi is the quality index, ranging between 0 (low quality) and 63 (high - quality). - \a pli is the color plane index: 0 for Y', 1 for Cb, 2 for Cr. - \a ci is the DCT coefficient index. - Coefficient indices correspond to the normal 2D DCT block - ordering--row-major with low frequencies first--\em not zig-zag order. - - Minimum quantizers are constant, and are given by: - \code - qmin[2][2]={{4,2},{8,4}}. - \endcode - - Parameters that can be stored in the bitstream are as follows: - - The two scale matrices ac_scale and dc_scale. - \code - scale[2][64]={dc_scale,ac_scale}. - \endcode - - The base matrices for each \a qi, \a qti and \a pli (up to 384 in all). - In order to avoid storing a full 384 base matrices, only a sparse set of - matrices are stored, and the rest are linearly interpolated. - This is done as follows. - For each \a qti and \a pli, a series of \a n \a qi ranges is defined. - The size of each \a qi range can vary arbitrarily, but they must sum to - 63. - Then, n+1 matrices are specified, one for each endpoint of the - ranges. - For interpolation purposes, each range's endpoints are the first \a qi - value it contains and one past the last \a qi value it contains. - Fractional values are rounded to the nearest integer, with ties rounded - away from zero. - - Base matrices are stored by reference, so if the same matrices are used - multiple times, they will only appear once in the bitstream. - The bitstream is also capable of omitting an entire set of ranges and - its associated matrices if they are the same as either the previous - set (indexed in row-major order) or if the inter set is the same as the - intra set. - - - Loop filter limit values. - The same limits are used for the loop filter in all color planes, despite - potentially differing levels of quantization in each. - - For the current encoder, scale[ci!=0][qi] must be no greater - than scale[ci!=0][qi-1] and base[qti][pli][qi][ci] must - be no greater than base[qti][pli][qi-1][ci]. - These two conditions ensure that the actual quantizer for a given \a qti, - \a pli, and \a ci does not increase as \a qi increases. - This is not required by the decoder.*/ -typedef struct{ - /**The DC scaling factors.*/ - ogg_uint16_t dc_scale[64]; - /**The AC scaling factors.*/ - ogg_uint16_t ac_scale[64]; - /**The loop filter limit values.*/ - unsigned char loop_filter_limits[64]; - /**The \a qi ranges for each \a ci and \a pli.*/ - th_quant_ranges qi_ranges[2][3]; -}th_quant_info; - - - -/**The number of Huffman tables used by Theora.*/ -#define TH_NHUFFMAN_TABLES (80) -/**The number of DCT token values in each table.*/ -#define TH_NDCT_TOKENS (32) - -/**A Huffman code for a Theora DCT token. - * Each set of Huffman codes in a given table must form a complete, prefix-free - * code. - * There is no requirement that all the tokens in a table have a valid code, - * but the current encoder is not optimized to take advantage of this. - * If each of the five grouops of 16 tables does not contain at least one table - * with a code for every token, then the encoder may fail to encode certain - * frames. - * The complete table in the first group of 16 does not have to be in the same - * place as the complete table in the other groups, but the complete tables in - * the remaining four groups must all be in the same place.*/ -typedef struct{ - /**The bit pattern for the code, with the LSbit of the pattern aligned in - * the LSbit of the word.*/ - ogg_uint32_t pattern; - /**The number of bits in the code. - * This must be between 0 and 32, inclusive.*/ - int nbits; -}th_huff_code; - - - -/**\defgroup basefuncs Functions Shared by Encode and Decode*/ -/*@{*/ -/**\name Basic shared functions*/ -/*@{*/ -/**Retrieves a human-readable string to identify the library vendor and - * version. - * \return the version string.*/ -extern const char *th_version_string(void); -/**Retrieves the library version number. - * This is the highest bitstream version that the encoder library will produce, - * or that the decoder library can decode. - * This number is composed of a 16-bit major version, 8-bit minor version - * and 8 bit sub-version, composed as follows: - * \code - * (VERSION_MAJOR<<16)+(VERSION_MINOR<<8)+(VERSION_SUBMINOR) - * \endcode - * \return the version number.*/ -extern ogg_uint32_t th_version_number(void); -/**Converts a granule position to an absolute frame index, starting at - * 0. - * The granule position is interpreted in the context of a given - * #th_enc_ctx or #th_dec_ctx handle (either will suffice). - * \param _encdec A previously allocated #th_enc_ctx or #th_dec_ctx - * handle. - * \param _granpos The granule position to convert. - * \returns The absolute frame index corresponding to \a _granpos. - * \retval -1 The given granule position was invalid (i.e. negative).*/ -extern ogg_int64_t th_granule_frame(void *_encdec,ogg_int64_t _granpos); -/**Converts a granule position to an absolute time in seconds. - * The granule position is interpreted in the context of a given - * #th_enc_ctx or #th_dec_ctx handle (either will suffice). - * \param _encdec A previously allocated #th_enc_ctx or #th_dec_ctx - * handle. - * \param _granpos The granule position to convert. - * \return The absolute time in seconds corresponding to \a _granpos. - * This is the "end time" for the frame, or the latest time it should - * be displayed. - * It is not the presentation time. - * \retval -1 The given granule position was invalid (i.e. negative).*/ -extern double th_granule_time(void *_encdec,ogg_int64_t _granpos); -/**Determines whether a Theora packet is a header or not. - * This function does no verification beyond checking the packet type bit, so - * it should not be used for bitstream identification; use - * th_decode_headerin() for that. - * As per the Theora specification, an empty (0-byte) packet is treated as a - * data packet (a delta frame with no coded blocks). - * \param _op An ogg_packet containing encoded Theora data. - * \retval 1 The packet is a header packet - * \retval 0 The packet is a video data packet.*/ -extern int th_packet_isheader(ogg_packet *_op); -/**Determines whether a theora packet is a key frame or not. - * This function does no verification beyond checking the packet type and - * key frame bits, so it should not be used for bitstream identification; use - * th_decode_headerin() for that. - * As per the Theora specification, an empty (0-byte) packet is treated as a - * delta frame (with no coded blocks). - * \param _op An ogg_packet containing encoded Theora data. - * \retval 1 The packet contains a key frame. - * \retval 0 The packet contains a delta frame. - * \retval -1 The packet is not a video data packet.*/ -extern int th_packet_iskeyframe(ogg_packet *_op); -/*@}*/ - - -/**\name Functions for manipulating header data*/ -/*@{*/ -/**Initializes a th_info structure. - * This should be called on a freshly allocated #th_info structure before - * attempting to use it. - * \param _info The #th_info struct to initialize.*/ -extern void th_info_init(th_info *_info); -/**Clears a #th_info structure. - * This should be called on a #th_info structure after it is no longer - * needed. - * \param _info The #th_info struct to clear.*/ -extern void th_info_clear(th_info *_info); - -/**Initialize a #th_comment structure. - * This should be called on a freshly allocated #th_comment structure - * before attempting to use it. - * \param _tc The #th_comment struct to initialize.*/ -extern void th_comment_init(th_comment *_tc); -/**Add a comment to an initialized #th_comment structure. - * \note Neither th_comment_add() nor th_comment_add_tag() support - * comments containing null values, although the bitstream format does - * support them. - * To add such comments you will need to manipulate the #th_comment - * structure directly. - * \param _tc The #th_comment struct to add the comment to. - * \param _comment Must be a null-terminated UTF-8 string containing the - * comment in "TAG=the value" form.*/ -extern void th_comment_add(th_comment *_tc, char *_comment); -/**Add a comment to an initialized #th_comment structure. - * \note Neither th_comment_add() nor th_comment_add_tag() support - * comments containing null values, although the bitstream format does - * support them. - * To add such comments you will need to manipulate the #th_comment - * structure directly. - * \param _tc The #th_comment struct to add the comment to. - * \param _tag A null-terminated string containing the tag associated with - * the comment. - * \param _val The corresponding value as a null-terminated string.*/ -extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val); -/**Look up a comment value by its tag. - * \param _tc An initialized #th_comment structure. - * \param _tag The tag to look up. - * \param _count The instance of the tag. - * The same tag can appear multiple times, each with a distinct - * value, so an index is required to retrieve them all. - * The order in which these values appear is significant and - * should be preserved. - * Use th_comment_query_count() to get the legal range for - * the \a _count parameter. - * \return A pointer to the queried tag's value. - * This points directly to data in the #th_comment structure. - * It should not be modified or freed by the application, and - * modifications to the structure may invalidate the pointer. - * \retval NULL If no matching tag is found.*/ -extern char *th_comment_query(th_comment *_tc,char *_tag,int _count); -/**Look up the number of instances of a tag. - * Call this first when querying for a specific tag and then iterate over the - * number of instances with separate calls to th_comment_query() to - * retrieve all the values for that tag in order. - * \param _tc An initialized #th_comment structure. - * \param _tag The tag to look up. - * \return The number on instances of this particular tag.*/ -extern int th_comment_query_count(th_comment *_tc,char *_tag); -/**Clears a #th_comment structure. - * This should be called on a #th_comment structure after it is no longer - * needed. - * It will free all memory used by the structure members. - * \param _tc The #th_comment struct to clear.*/ -extern void th_comment_clear(th_comment *_tc); -/*@}*/ -/*@}*/ - - - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/theora/theora.h b/src/add-ons/media/plugins/theora/libtheora/theora/theora.h deleted file mode 100644 index 0a1979041a..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/theora/theora.h +++ /dev/null @@ -1,784 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: theora.h 33343 2009-09-29 00:37:35Z phoudoin $ - - ********************************************************************/ - -#ifndef _O_THEORA_H_ -#define _O_THEORA_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#include /* for size_t */ - -#include - -/** \file - * The libtheora pre-1.0 legacy C API. - * - * \ingroup oldfuncs - * - * \section intro Introduction - * - * This is the documentation for the libtheora legacy C API, declared in - * the theora.h header, which describes the old interface used before - * the 1.0 release. This API was widely deployed for several years and - * remains supported, but for new code we recommend the cleaner API - * declared in theoradec.h and theoraenc.h. - * - * libtheora is the reference implementation for - * Theora, a free video codec. - * Theora is derived from On2's VP3 codec with improved integration with - * Ogg multimedia formats by Xiph.Org. - * - * \section overview Overview - * - * This library will both decode and encode theora packets to/from raw YUV - * frames. In either case, the packets will most likely either come from or - * need to be embedded in an Ogg stream. Use - * libogg or - * liboggz - * to extract/package these packets. - * - * \section decoding Decoding Process - * - * Decoding can be separated into the following steps: - * -# initialise theora_info and theora_comment structures using - * theora_info_init() and theora_comment_init(): - \verbatim - theora_info info; - theora_comment comment; - - theora_info_init(&info); - theora_comment_init(&comment); - \endverbatim - * -# retrieve header packets from Ogg stream (there should be 3) and decode - * into theora_info and theora_comment structures using - * theora_decode_header(). See \ref identification for more information on - * identifying which packets are theora packets. - \verbatim - int i; - for (i = 0; i < 3; i++) - { - (get a theora packet "op" from the Ogg stream) - theora_decode_header(&info, &comment, op); - } - \endverbatim - * -# initialise the decoder based on the information retrieved into the - * theora_info struct by theora_decode_header(). You will need a - * theora_state struct. - \verbatim - theora_state state; - - theora_decode_init(&state, &info); - \endverbatim - * -# pass in packets and retrieve decoded frames! See the yuv_buffer - * documentation for information on how to retrieve raw YUV data. - \verbatim - yuf_buffer buffer; - while (last packet was not e_o_s) { - (get a theora packet "op" from the Ogg stream) - theora_decode_packetin(&state, op); - theora_decode_YUVout(&state, &buffer); - } - \endverbatim - * - * - * \subsection identification Identifying Theora Packets - * - * All streams inside an Ogg file have a unique serial_no attached to the - * stream. Typically, you will want to - * - retrieve the serial_no for each b_o_s (beginning of stream) page - * encountered within the Ogg file; - * - test the first (only) packet on that page to determine if it is a theora - * packet; - * - once you have found a theora b_o_s page then use the retrieved serial_no - * to identify future packets belonging to the same theora stream. - * - * Note that you \e cannot use theora_packet_isheader() to determine if a - * packet is a theora packet or not, as this function does not perform any - * checking beyond whether a header bit is present. Instead, use the - * theora_decode_header() function and check the return value; or examine the - * header bytes at the beginning of the Ogg page. - */ - - -/** \defgroup oldfuncs Legacy pre-1.0 C API */ -/* @{ */ - -/** - * A YUV buffer for passing uncompressed frames to and from the codec. - * This holds a Y'CbCr frame in planar format. The CbCr planes can be - * subsampled and have their own separate dimensions and row stride - * offsets. Note that the strides may be negative in some - * configurations. For theora the width and height of the largest plane - * must be a multiple of 16. The actual meaningful picture size and - * offset are stored in the theora_info structure; frames returned by - * the decoder may need to be cropped for display. - * - * All samples are 8 bits. Within each plane samples are ordered by - * row from the top of the frame to the bottom. Within each row samples - * are ordered from left to right. - * - * During decode, the yuv_buffer struct is allocated by the user, but all - * fields (including luma and chroma pointers) are filled by the library. - * These pointers address library-internal memory and their contents should - * not be modified. - * - * Conversely, during encode the user allocates the struct and fills out all - * fields. The user also manages the data addressed by the luma and chroma - * pointers. See the encoder_example.c and dump_video.c example files in - * theora/examples/ for more information. - */ -typedef struct { - int y_width; /**< Width of the Y' luminance plane */ - int y_height; /**< Height of the luminance plane */ - int y_stride; /**< Offset in bytes between successive rows */ - - int uv_width; /**< Width of the Cb and Cr chroma planes */ - int uv_height; /**< Height of the chroma planes */ - int uv_stride; /**< Offset between successive chroma rows */ - unsigned char *y; /**< Pointer to start of luminance data */ - unsigned char *u; /**< Pointer to start of Cb data */ - unsigned char *v; /**< Pointer to start of Cr data */ - -} yuv_buffer; - -/** - * A Colorspace. - */ -typedef enum { - OC_CS_UNSPECIFIED, /**< The colorspace is unknown or unspecified */ - OC_CS_ITU_REC_470M, /**< This is the best option for 'NTSC' content */ - OC_CS_ITU_REC_470BG, /**< This is the best option for 'PAL' content */ - OC_CS_NSPACES /**< This marks the end of the defined colorspaces */ -} theora_colorspace; - -/** - * A Chroma subsampling - * - * These enumerate the available chroma subsampling options supported - * by the theora format. See Section 4.4 of the specification for - * exact definitions. - */ -typedef enum { - OC_PF_420, /**< Chroma subsampling by 2 in each direction (4:2:0) */ - OC_PF_RSVD, /**< Reserved value */ - OC_PF_422, /**< Horizonatal chroma subsampling by 2 (4:2:2) */ - OC_PF_444, /**< No chroma subsampling at all (4:4:4) */ -} theora_pixelformat; - -/** - * Theora bitstream info. - * Contains the basic playback parameters for a stream, - * corresponding to the initial 'info' header packet. - * - * Encoded theora frames must be a multiple of 16 in width and height. - * To handle other frame sizes, a crop rectangle is specified in - * frame_height and frame_width, offset_x and * offset_y. The offset - * and size should still be a multiple of 2 to avoid chroma sampling - * shifts. Offset values in this structure are measured from the - * upper left of the image. - * - * Frame rate, in frames per second, is stored as a rational - * fraction. Aspect ratio is also stored as a rational fraction, and - * refers to the aspect ratio of the frame pixels, not of the - * overall frame itself. - * - * See - * examples/encoder_example.c for usage examples of the - * other paramters and good default settings for the encoder parameters. - */ -typedef struct { - ogg_uint32_t width; /**< encoded frame width */ - ogg_uint32_t height; /**< encoded frame height */ - ogg_uint32_t frame_width; /**< display frame width */ - ogg_uint32_t frame_height; /**< display frame height */ - ogg_uint32_t offset_x; /**< horizontal offset of the displayed frame */ - ogg_uint32_t offset_y; /**< vertical offset of the displayed frame */ - ogg_uint32_t fps_numerator; /**< frame rate numerator **/ - ogg_uint32_t fps_denominator; /**< frame rate denominator **/ - ogg_uint32_t aspect_numerator; /**< pixel aspect ratio numerator */ - ogg_uint32_t aspect_denominator; /**< pixel aspect ratio denominator */ - theora_colorspace colorspace; /**< colorspace */ - int target_bitrate; /**< nominal bitrate in bits per second */ - int quality; /**< Nominal quality setting, 0-63 */ - int quick_p; /**< Quick encode/decode */ - - /* decode only */ - unsigned char version_major; - unsigned char version_minor; - unsigned char version_subminor; - - void *codec_setup; - - /* encode only */ - int dropframes_p; - int keyframe_auto_p; - ogg_uint32_t keyframe_frequency; - ogg_uint32_t keyframe_frequency_force; /* also used for decode init to - get granpos shift correct */ - ogg_uint32_t keyframe_data_target_bitrate; - ogg_int32_t keyframe_auto_threshold; - ogg_uint32_t keyframe_mindistance; - ogg_int32_t noise_sensitivity; - ogg_int32_t sharpness; - - theora_pixelformat pixelformat; /**< chroma subsampling mode to expect */ - -} theora_info; - -/** Codec internal state and context. - */ -typedef struct{ - theora_info *i; - ogg_int64_t granulepos; - - void *internal_encode; - void *internal_decode; - -} theora_state; - -/** - * Comment header metadata. - * - * This structure holds the in-stream metadata corresponding to - * the 'comment' header packet. - * - * Meta data is stored as a series of (tag, value) pairs, in - * length-encoded string vectors. The first occurence of the - * '=' character delimits the tag and value. A particular tag - * may occur more than once. The character set encoding for - * the strings is always UTF-8, but the tag names are limited - * to case-insensitive ASCII. See the spec for details. - * - * In filling in this structure, theora_decode_header() will - * null-terminate the user_comment strings for safety. However, - * the bitstream format itself treats them as 8-bit clean, - * and so the length array should be treated as authoritative - * for their length. - */ -typedef struct theora_comment{ - char **user_comments; /**< An array of comment string vectors */ - int *comment_lengths; /**< An array of corresponding string vector lengths in bytes */ - int comments; /**< The total number of comment string vectors */ - char *vendor; /**< The vendor string identifying the encoder, null terminated */ - -} theora_comment; - - -/**\name theora_control() codes */ -/* \anchor decctlcodes_old - * These are the available request codes for theora_control() - * when called with a decoder instance. - * By convention decoder control codes are odd, to distinguish - * them from \ref encctlcodes_old "encoder control codes" which - * are even. - * - * Note that since the 1.0 release, both the legacy and the final - * implementation accept all the same control codes, but only the - * final API declares the newer codes. - * - * Keep any experimental or vendor-specific values above \c 0x8000.*/ - -/*@{*/ - -/**Get the maximum post-processing level. - * The decoder supports a post-processing filter that can improve - * the appearance of the decoded images. This returns the highest - * level setting for this post-processor, corresponding to maximum - * improvement and computational expense. - */ -#define TH_DECCTL_GET_PPLEVEL_MAX (1) - -/**Set the post-processing level. - * Sets the level of post-processing to use when decoding the - * compressed stream. This must be a value between zero (off) - * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX. - */ -#define TH_DECCTL_SET_PPLEVEL (3) - -/**Sets the maximum distance between key frames. - * This can be changed during an encode, but will be bounded by - * 1<. - * If it is set before encoding begins, th_info#keyframe_granule_shift will - * be enlarged appropriately. - * - * \param[in] buf ogg_uint32_t: The maximum distance between key - * frames. - * \param[out] buf ogg_uint32_t: The actual maximum distance set. - * \retval OC_FAULT \a theora_state or \a buf is NULL. - * \retval OC_EINVAL \a buf_sz is not sizeof(ogg_uint32_t). - * \retval OC_IMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4) - -/**Set the granule position. - * Call this after a seek, to update the internal granulepos - * in the decoder, to insure that subsequent frames are marked - * properly. If you track timestamps yourself and do not use - * the granule postion returned by the decoder, then you do - * not need to use this control. - */ -#define TH_DECCTL_SET_GRANPOS (5) - -/**\anchor encctlcodes_old */ - -/**Sets the quantization parameters to use. - * The parameters are copied, not stored by reference, so they can be freed - * after this call. - * NULL may be specified to revert to the default parameters. - * - * \param[in] buf #th_quant_info - * \retval OC_FAULT \a theora_state is NULL. - * \retval OC_EINVAL Encoding has already begun, the quantization parameters - * are not acceptable to this version of the encoder, - * \a buf is NULL and \a buf_sz is not zero, - * or \a buf is non-NULL and \a buf_sz is - * not sizeof(#th_quant_info). - * \retval OC_IMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_QUANT_PARAMS (2) - -/**Disables any encoder features that would prevent lossless transcoding back - * to VP3. - * This primarily means disabling block-level QI values and not using 4MV mode - * when any of the luma blocks in a macro block are not coded. - * It also includes using the VP3 quantization tables and Huffman codes; if you - * set them explicitly after calling this function, the resulting stream will - * not be VP3-compatible. - * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source - * material, or when using a picture region smaller than the full frame (e.g. - * a non-multiple-of-16 width or height), then non-VP3 bitstream features will - * still be disabled, but the stream will still not be VP3-compatible, as VP3 - * was not capable of encoding such formats. - * If you call this after encoding has already begun, then the quantization - * tables and codebooks cannot be changed, but the frame-level features will - * be enabled or disabled as requested. - * - * \param[in] buf int: a non-zero value to enable VP3 compatibility, - * or 0 to disable it (the default). - * \param[out] buf int: 1 if all bitstream features required for - * VP3-compatibility could be set, and 0 otherwise. - * The latter will be returned if the pixel format is not - * 4:2:0, the picture region is smaller than the full frame, - * or if encoding has begun, preventing the quantization - * tables and codebooks from being set. - * \retval OC_FAULT \a theora_state or \a buf is NULL. - * \retval OC_EINVAL \a buf_sz is not sizeof(int). - * \retval OC_IMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_VP3_COMPATIBLE (10) - -/**Gets the maximum speed level. - * Higher speed levels favor quicker encoding over better quality per bit. - * Depending on the encoding mode, and the internal algorithms used, quality - * may actually improve, but in this case bitrate will also likely increase. - * In any case, overall rate/distortion performance will probably decrease. - * The maximum value, and the meaning of each value, may change depending on - * the current encoding mode (VBR vs. CQI, etc.). - * - * \param[out] buf int: The maximum encoding speed level. - * \retval OC_FAULT \a theora_state or \a buf is NULL. - * \retval OC_EINVAL \a buf_sz is not sizeof(int). - * \retval OC_IMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_GET_SPLEVEL_MAX (12) - -/**Sets the speed level. - * By default a speed value of 1 is used. - * - * \param[in] buf int: The new encoding speed level. - * 0 is slowest, larger values use less CPU. - * \retval OC_FAULT \a theora_state or \a buf is NULL. - * \retval OC_EINVAL \a buf_sz is not sizeof(int), or the - * encoding speed level is out of bounds. - * The maximum encoding speed level may be - * implementation- and encoding mode-specific, and can be - * obtained via #TH_ENCCTL_GET_SPLEVEL_MAX. - * \retval OC_IMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_SET_SPLEVEL (14) - -/*@}*/ - -#define OC_FAULT -1 /**< General failure */ -#define OC_EINVAL -10 /**< Library encountered invalid internal data */ -#define OC_DISABLED -11 /**< Requested action is disabled */ -#define OC_BADHEADER -20 /**< Header packet was corrupt/invalid */ -#define OC_NOTFORMAT -21 /**< Packet is not a theora packet */ -#define OC_VERSION -22 /**< Bitstream version is not handled */ -#define OC_IMPL -23 /**< Feature or action not implemented */ -#define OC_BADPACKET -24 /**< Packet is corrupt */ -#define OC_NEWPACKET -25 /**< Packet is an (ignorable) unhandled extension */ -#define OC_DUPFRAME 1 /**< Packet is a dropped frame */ - -/** - * Retrieve a human-readable string to identify the encoder vendor and version. - * \returns A version string. - */ -extern const char *theora_version_string(void); - -/** - * Retrieve a 32-bit version number. - * This number is composed of a 16-bit major version, 8-bit minor version - * and 8 bit sub-version, composed as follows: -
-   (VERSION_MAJOR<<16) + (VERSION_MINOR<<8) + (VERSION_SUB)
-
-* \returns The version number. -*/ -extern ogg_uint32_t theora_version_number(void); - -/** - * Initialize the theora encoder. - * \param th The theora_state handle to initialize for encoding. - * \param ti A theora_info struct filled with the desired encoding parameters. - * \retval 0 Success - */ -extern int theora_encode_init(theora_state *th, theora_info *ti); - -/** - * Submit a YUV buffer to the theora encoder. - * \param t A theora_state handle previously initialized for encoding. - * \param yuv A buffer of YUV data to encode. Note that both the yuv_buffer - * struct and the luma/chroma buffers within should be allocated by - * the user. - * \retval OC_EINVAL Encoder is not ready, or is finished. - * \retval -1 The size of the given frame differs from those previously input - * \retval 0 Success - */ -extern int theora_encode_YUVin(theora_state *t, yuv_buffer *yuv); - -/** - * Request the next packet of encoded video. - * The encoded data is placed in a user-provided ogg_packet structure. - * \param t A theora_state handle previously initialized for encoding. - * \param last_p whether this is the last packet the encoder should produce. - * \param op An ogg_packet structure to fill. libtheora will set all - * elements of this structure, including a pointer to encoded - * data. The memory for the encoded data is owned by libtheora. - * \retval 0 No internal storage exists OR no packet is ready - * \retval -1 The encoding process has completed - * \retval 1 Success - */ -extern int theora_encode_packetout( theora_state *t, int last_p, - ogg_packet *op); - -/** - * Request a packet containing the initial header. - * A pointer to the header data is placed in a user-provided ogg_packet - * structure. - * \param t A theora_state handle previously initialized for encoding. - * \param op An ogg_packet structure to fill. libtheora will set all - * elements of this structure, including a pointer to the header - * data. The memory for the header data is owned by libtheora. - * \retval 0 Success - */ -extern int theora_encode_header(theora_state *t, ogg_packet *op); - -/** - * Request a comment header packet from provided metadata. - * A pointer to the comment data is placed in a user-provided ogg_packet - * structure. - * \param tc A theora_comment structure filled with the desired metadata - * \param op An ogg_packet structure to fill. libtheora will set all - * elements of this structure, including a pointer to the encoded - * comment data. The memory for the comment data is owned by - * libtheora. - * \retval 0 Success - */ -extern int theora_encode_comment(theora_comment *tc, ogg_packet *op); - -/** - * Request a packet containing the codebook tables for the stream. - * A pointer to the codebook data is placed in a user-provided ogg_packet - * structure. - * \param t A theora_state handle previously initialized for encoding. - * \param op An ogg_packet structure to fill. libtheora will set all - * elements of this structure, including a pointer to the codebook - * data. The memory for the header data is owned by libtheora. - * \retval 0 Success - */ -extern int theora_encode_tables(theora_state *t, ogg_packet *op); - -/** - * Decode an Ogg packet, with the expectation that the packet contains - * an initial header, comment data or codebook tables. - * - * \param ci A theora_info structure to fill. This must have been previously - * initialized with theora_info_init(). If \a op contains an initial - * header, theora_decode_header() will fill \a ci with the - * parsed header values. If \a op contains codebook tables, - * theora_decode_header() will parse these and attach an internal - * representation to \a ci->codec_setup. - * \param cc A theora_comment structure to fill. If \a op contains comment - * data, theora_decode_header() will fill \a cc with the parsed - * comments. - * \param op An ogg_packet structure which you expect contains an initial - * header, comment data or codebook tables. - * - * \retval OC_BADHEADER \a op is NULL; OR the first byte of \a op->packet - * has the signature of an initial packet, but op is - * not a b_o_s packet; OR this packet has the signature - * of an initial header packet, but an initial header - * packet has already been seen; OR this packet has the - * signature of a comment packet, but the initial header - * has not yet been seen; OR this packet has the signature - * of a comment packet, but contains invalid data; OR - * this packet has the signature of codebook tables, - * but the initial header or comments have not yet - * been seen; OR this packet has the signature of codebook - * tables, but contains invalid data; - * OR the stream being decoded has a compatible version - * but this packet does not have the signature of a - * theora initial header, comments, or codebook packet - * \retval OC_VERSION The packet data of \a op is an initial header with - * a version which is incompatible with this version of - * libtheora. - * \retval OC_NEWPACKET the stream being decoded has an incompatible (future) - * version and contains an unknown signature. - * \retval 0 Success - * - * \note The normal usage is that theora_decode_header() be called on the - * first three packets of a theora logical bitstream in succession. - */ -extern int theora_decode_header(theora_info *ci, theora_comment *cc, - ogg_packet *op); - -/** - * Initialize a theora_state handle for decoding. - * \param th The theora_state handle to initialize. - * \param c A theora_info struct filled with the desired decoding parameters. - * This is of course usually obtained from a previous call to - * theora_decode_header(). - * \retval 0 Success - */ -extern int theora_decode_init(theora_state *th, theora_info *c); - -/** - * Input a packet containing encoded data into the theora decoder. - * \param th A theora_state handle previously initialized for decoding. - * \param op An ogg_packet containing encoded theora data. - * \retval 0 Success - * \retval OC_BADPACKET \a op does not contain encoded video data - */ -extern int theora_decode_packetin(theora_state *th,ogg_packet *op); - -/** - * Output the next available frame of decoded YUV data. - * \param th A theora_state handle previously initialized for decoding. - * \param yuv A yuv_buffer in which libtheora should place the decoded data. - * Note that the buffer struct itself is allocated by the user, but - * that the luma and chroma pointers will be filled in by the - * library. Also note that these luma and chroma regions should be - * considered read-only by the user. - * \retval 0 Success - */ -extern int theora_decode_YUVout(theora_state *th,yuv_buffer *yuv); - -/** - * Report whether a theora packet is a header or not - * This function does no verification beyond checking the header - * flag bit so it should not be used for bitstream identification; - * use theora_decode_header() for that. - * - * \param op An ogg_packet containing encoded theora data. - * \retval 1 The packet is a header packet - * \retval 0 The packet is not a header packet (and so contains frame data) - * - * Thus function was added in the 1.0alpha4 release. - */ -extern int theora_packet_isheader(ogg_packet *op); - -/** - * Report whether a theora packet is a keyframe or not - * - * \param op An ogg_packet containing encoded theora data. - * \retval 1 The packet contains a keyframe image - * \retval 0 The packet is contains an interframe delta - * \retval -1 The packet is not an image data packet at all - * - * Thus function was added in the 1.0alpha4 release. - */ -extern int theora_packet_iskeyframe(ogg_packet *op); - -/** - * Report the granulepos shift radix - * - * When embedded in Ogg, Theora uses a two-part granulepos, - * splitting the 64-bit field into two pieces. The more-significant - * section represents the frame count at the last keyframe, - * and the less-significant section represents the count of - * frames since the last keyframe. In this way the overall - * field is still non-decreasing with time, but usefully encodes - * a pointer to the last keyframe, which is necessary for - * correctly restarting decode after a seek. - * - * This function reports the number of bits used to represent - * the distance to the last keyframe, and thus how the granulepos - * field must be shifted or masked to obtain the two parts. - * - * Since libtheora returns compressed data in an ogg_packet - * structure, this may be generally useful even if the Theora - * packets are not being used in an Ogg container. - * - * \param ti A previously initialized theora_info struct - * \returns The bit shift dividing the two granulepos fields - * - * This function was added in the 1.0alpha5 release. - */ -int theora_granule_shift(theora_info *ti); - -/** - * Convert a granulepos to an absolute frame index, starting at 0. - * The granulepos is interpreted in the context of a given theora_state handle. - * - * Note that while the granulepos encodes the frame count (i.e. starting - * from 1) this call returns the frame index, starting from zero. Thus - * One can calculate the presentation time by multiplying the index by - * the rate. - * - * \param th A previously initialized theora_state handle (encode or decode) - * \param granulepos The granulepos to convert. - * \returns The frame index corresponding to \a granulepos. - * \retval -1 The given granulepos is undefined (i.e. negative) - * - * Thus function was added in the 1.0alpha4 release. - */ -extern ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos); - -/** - * Convert a granulepos to absolute time in seconds. The granulepos is - * interpreted in the context of a given theora_state handle, and gives - * the end time of a frame's presentation as used in Ogg mux ordering. - * - * \param th A previously initialized theora_state handle (encode or decode) - * \param granulepos The granulepos to convert. - * \returns The absolute time in seconds corresponding to \a granulepos. - * This is the "end time" for the frame, or the latest time it should - * be displayed. - * It is not the presentation time. - * \retval -1. The given granulepos is undefined (i.e. negative), or - * \retval -1. The function has been disabled because floating - * point support is not available. - */ -extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos); - -/** - * Initialize a theora_info structure. All values within the given theora_info - * structure are initialized, and space is allocated within libtheora for - * internal codec setup data. - * \param c A theora_info struct to initialize. - */ -extern void theora_info_init(theora_info *c); - -/** - * Clear a theora_info structure. All values within the given theora_info - * structure are cleared, and associated internal codec setup data is freed. - * \param c A theora_info struct to initialize. - */ -extern void theora_info_clear(theora_info *c); - -/** - * Free all internal data associated with a theora_state handle. - * \param t A theora_state handle. - */ -extern void theora_clear(theora_state *t); - -/** - * Initialize an allocated theora_comment structure - * \param tc An allocated theora_comment structure - **/ -extern void theora_comment_init(theora_comment *tc); - -/** - * Add a comment to an initialized theora_comment structure - * \param tc A previously initialized theora comment structure - * \param comment A null-terminated string encoding the comment in the form - * "TAG=the value" - * - * Neither theora_comment_add() nor theora_comment_add_tag() support - * comments containing null values, although the bitstream format - * supports this. To add such comments you will need to manipulate - * the theora_comment structure directly. - **/ - -extern void theora_comment_add(theora_comment *tc, char *comment); - -/** - * Add a comment to an initialized theora_comment structure. - * \param tc A previously initialized theora comment structure - * \param tag A null-terminated string containing the tag - * associated with the comment. - * \param value The corresponding value as a null-terminated string - * - * Neither theora_comment_add() nor theora_comment_add_tag() support - * comments containing null values, although the bitstream format - * supports this. To add such comments you will need to manipulate - * the theora_comment structure directly. - **/ -extern void theora_comment_add_tag(theora_comment *tc, - char *tag, char *value); - -/** - * Look up a comment value by tag. - * \param tc Tn initialized theora_comment structure - * \param tag The tag to look up - * \param count The instance of the tag. The same tag can appear multiple - * times, each with a distinct and ordered value, so an index - * is required to retrieve them all. - * \returns A pointer to the queried tag's value - * \retval NULL No matching tag is found - * - * \note Use theora_comment_query_count() to get the legal range for the - * count parameter. - **/ - -extern char *theora_comment_query(theora_comment *tc, char *tag, int count); - -/** Look up the number of instances of a tag. - * \param tc An initialized theora_comment structure - * \param tag The tag to look up - * \returns The number on instances of a particular tag. - * - * Call this first when querying for a specific tag and then interate - * over the number of instances with separate calls to - * theora_comment_query() to retrieve all instances in order. - **/ -extern int theora_comment_query_count(theora_comment *tc, char *tag); - -/** - * Clear an allocated theora_comment struct so that it can be freed. - * \param tc An allocated theora_comment structure. - **/ -extern void theora_comment_clear(theora_comment *tc); - -/**Encoder control function. - * This is used to provide advanced control the encoding process. - * \param th A #theora_state handle. - * \param req The control code to process. - * See \ref encctlcodes_old "the list of available - * control codes" for details. - * \param buf The parameters for this control code. - * \param buf_sz The size of the parameter buffer.*/ -extern int theora_control(theora_state *th,int req,void *buf,size_t buf_sz); - -/* @} */ /* end oldfuncs doxygen group */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _O_THEORA_H_ */ diff --git a/src/add-ons/media/plugins/theora/libtheora/theora/theoradec.h b/src/add-ons/media/plugins/theora/libtheora/theora/theoradec.h deleted file mode 100644 index b20f0e3a64..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/theora/theoradec.h +++ /dev/null @@ -1,325 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $ - - ********************************************************************/ - -/**\file - * The libtheoradec C decoding API.*/ - -#if !defined(_O_THEORA_THEORADEC_H_) -# define _O_THEORA_THEORADEC_H_ (1) -# include -# include -# include "codec.h" - -#if defined(__cplusplus) -extern "C" { -#endif - - - -/**\name th_decode_ctl() codes - * \anchor decctlcodes - * These are the available request codes for th_decode_ctl(). - * By convention, these are odd, to distinguish them from the - * \ref encctlcodes "encoder control codes". - * Keep any experimental or vendor-specific values above \c 0x8000.*/ -/*@{*/ -/**Gets the maximum post-processing level. - * The decoder supports a post-processing filter that can improve - * the appearance of the decoded images. This returns the highest - * level setting for this post-processor, corresponding to maximum - * improvement and computational expense. - * - * \param[out] _buf int: The maximum post-processing level. - * \retval TH_EFAULT \a _dec_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int). - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_DECCTL_GET_PPLEVEL_MAX (1) -/**Sets the post-processing level. - * By default, post-processing is disabled. - * - * Sets the level of post-processing to use when decoding the - * compressed stream. This must be a value between zero (off) - * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX. - * - * \param[in] _buf int: The new post-processing level. - * 0 to disable; larger values use more CPU. - * \retval TH_EFAULT \a _dec_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int), or the - * post-processing level is out of bounds. - * The maximum post-processing level may be - * implementation-specific, and can be obtained via - * #TH_DECCTL_GET_PPLEVEL_MAX. - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_DECCTL_SET_PPLEVEL (3) -/**Sets the granule position. - * Call this after a seek, before decoding the first frame, to ensure that the - * proper granule position is returned for all subsequent frames. - * If you track timestamps yourself and do not use the granule position - * returned by the decoder, then you need not call this function. - * - * \param[in] _buf ogg_int64_t: The granule position of the next - * frame. - * \retval TH_EFAULT \a _dec_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(ogg_int64_t), or the - * granule position is negative.*/ -#define TH_DECCTL_SET_GRANPOS (5) -/**Sets the striped decode callback function. - * If set, this function will be called as each piece of a frame is fully - * decoded in th_decode_packetin(). - * You can pass in a #th_stripe_callback with - * th_stripe_callback#stripe_decoded set to NULL to disable the - * callbacks at any point. - * Enabling striped decode does not prevent you from calling - * th_decode_ycbcr_out() after the frame is fully decoded. - * - * \param[in] _buf #th_stripe_callback: The callback parameters. - * \retval TH_EFAULT \a _dec_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not - * sizeof(th_stripe_callback).*/ -#define TH_DECCTL_SET_STRIPE_CB (7) - -/**Enables telemetry and sets the macroblock display mode */ -#define TH_DECCTL_SET_TELEMETRY_MBMODE (9) -/**Enables telemetry and sets the motion vector display mode */ -#define TH_DECCTL_SET_TELEMETRY_MV (11) -/**Enables telemetry and sets the adaptive quantization display mode */ -#define TH_DECCTL_SET_TELEMETRY_QI (13) -/**Enables telemetry and sets the bitstream breakdown visualization mode */ -#define TH_DECCTL_SET_TELEMETRY_BITS (15) -/*@}*/ - - - -/**A callback function for striped decode. - * This is a function pointer to an application-provided function that will be - * called each time a section of the image is fully decoded in - * th_decode_packetin(). - * This allows the application to process the section immediately, while it is - * still in cache. - * Note that the frame is decoded bottom to top, so \a _yfrag0 will steadily - * decrease with each call until it reaches 0, at which point the full frame - * is decoded. - * The number of fragment rows made available in each call depends on the pixel - * format and the number of post-processing filters enabled, and may not even - * be constant for the entire frame. - * If a non-NULL \a _granpos pointer is passed to - * th_decode_packetin(), the granule position for the frame will be stored - * in it before the first callback is made. - * If an entire frame is dropped (a 0-byte packet), then no callbacks will be - * made at all for that frame. - * \param _ctx An application-provided context pointer. - * \param _buf The image buffer for the decoded frame. - * \param _yfrag0 The Y coordinate of the first row of 8x8 fragments - * decoded. - * Multiply this by 8 to obtain the pixel row number in the - * luma plane. - * If the chroma planes are subsampled in the Y direction, - * this will always be divisible by two. - * \param _yfrag_end The Y coordinate of the first row of 8x8 fragments past - * the newly decoded section. - * If the chroma planes are subsampled in the Y direction, - * this will always be divisible by two. - * I.e., this section contains fragment rows - * \a _yfrag0 ...\a _yfrag_end -1.*/ -typedef void (*th_stripe_decoded_func)(void *_ctx,th_ycbcr_buffer _buf, - int _yfrag0,int _yfrag_end); - -/**The striped decode callback data to pass to #TH_DECCTL_SET_STRIPE_CB.*/ -typedef struct{ - /**An application-provided context pointer. - * This will be passed back verbatim to the application.*/ - void *ctx; - /**The callback function pointer.*/ - th_stripe_decoded_func stripe_decoded; -}th_stripe_callback; - - - -/**\name Decoder state - The following data structures are opaque, and their contents are not - publicly defined by this API. - Referring to their internals directly is unsupported, and may break without - warning.*/ -/*@{*/ -/**The decoder context.*/ -typedef struct th_dec_ctx th_dec_ctx; -/**Setup information. - This contains auxiliary information (Huffman tables and quantization - parameters) decoded from the setup header by th_decode_headerin() to be - passed to th_decode_alloc(). - It can be re-used to initialize any number of decoders, and can be freed - via th_setup_free() at any time.*/ -typedef struct th_setup_info th_setup_info; -/*@}*/ - - - -/**\defgroup decfuncs Functions for Decoding*/ -/*@{*/ -/**\name Functions for decoding - * You must link to libtheoradec if you use any of the - * functions in this section. - * - * The functions are listed in the order they are used in a typical decode. - * The basic steps are: - * - Parse the header packets by repeatedly calling th_decode_headerin(). - * - Allocate a #th_dec_ctx handle with th_decode_alloc(). - * - Call th_setup_free() to free any memory used for codec setup - * information. - * - Perform any additional decoder configuration with th_decode_ctl(). - * - For each video data packet: - * - Submit the packet to the decoder via th_decode_packetin(). - * - Retrieve the uncompressed video data via th_decode_ycbcr_out(). - * - Call th_decode_free() to release all decoder memory.*/ -/*@{*/ -/**Decodes the header packets of a Theora stream. - * This should be called on the initial packets of the stream, in succession, - * until it returns 0, indicating that all headers have been - * processed, or an error is encountered. - * At least three header packets are required, and additional optional header - * packets may follow. - * This can be used on the first packet of any logical stream to determine if - * that stream is a Theora stream. - * \param _info A #th_info structure to fill in. - * This must have been previously initialized with - * th_info_init(). - * The application may immediately begin using the contents of - * this structure after the first header is decoded, though it - * must continue to be passed in on all subsequent calls. - * \param _tc A #th_comment structure to fill in. - * The application may immediately begin using the contents of - * this structure after the second header is decoded, though it - * must continue to be passed in on all subsequent calls. - * \param _setup Returns a pointer to additional, private setup information - * needed by the decoder. - * The contents of this pointer must be initialized to - * NULL on the first call, and the returned value must - * continue to be passed in on all subsequent calls. - * \param _op An ogg_packet structure which contains one of the - * initial packets of an Ogg logical stream. - * \return A positive value indicates that a Theora header was successfully - * processed. - * \retval 0 The first video data packet was encountered after all - * required header packets were parsed. - * The packet just passed in on this call should be saved - * and fed to th_decode_packetin() to begin decoding - * video data. - * \retval TH_EFAULT One of \a _info, \a _tc, or \a _setup was - * NULL. - * \retval TH_EBADHEADER \a _op was NULL, the packet was not the next - * header packet in the expected sequence, or the format - * of the header data was invalid. - * \retval TH_EVERSION The packet data was a Theora info header, but for a - * bitstream version not decodable with this version of - * libtheoradec. - * \retval TH_ENOTFORMAT The packet was not a Theora header. - */ -extern int th_decode_headerin(th_info *_info,th_comment *_tc, - th_setup_info **_setup,ogg_packet *_op); -/**Allocates a decoder instance. - * - * Security Warning: The Theora format supports very large frame sizes, - * potentially even larger than the address space of a 32-bit machine, and - * creating a decoder context allocates the space for several frames of data. - * If the allocation fails here, your program will crash, possibly at some - * future point because the OS kernel returned a valid memory range and will - * only fail when it tries to map the pages in it the first time they are - * used. - * Even if it succeeds, you may experience a denial of service if the frame - * size is large enough to cause excessive paging. - * If you are integrating libtheora in a larger application where such things - * are undesirable, it is highly recommended that you check the frame size in - * \a _info before calling this function and refuse to decode streams where it - * is larger than some reasonable maximum. - * libtheora will not check this for you, because there may be machines that - * can handle such streams and applications that wish to. - * \param _info A #th_info struct filled via th_decode_headerin(). - * \param _setup A #th_setup_info handle returned via - * th_decode_headerin(). - * \return The initialized #th_dec_ctx handle. - * \retval NULL If the decoding parameters were invalid.*/ -extern th_dec_ctx *th_decode_alloc(const th_info *_info, - const th_setup_info *_setup); -/**Releases all storage used for the decoder setup information. - * This should be called after you no longer want to create any decoders for - * a stream whose headers you have parsed with th_decode_headerin(). - * \param _setup The setup information to free. - * This can safely be NULL.*/ -extern void th_setup_free(th_setup_info *_setup); -/**Decoder control function. - * This is used to provide advanced control of the decoding process. - * \param _dec A #th_dec_ctx handle. - * \param _req The control code to process. - * See \ref decctlcodes "the list of available control codes" - * for details. - * \param _buf The parameters for this control code. - * \param _buf_sz The size of the parameter buffer.*/ -extern int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, - size_t _buf_sz); -/**Submits a packet containing encoded video data to the decoder. - * \param _dec A #th_dec_ctx handle. - * \param _op An ogg_packet containing encoded video data. - * \param _granpos Returns the granule position of the decoded packet. - * If non-NULL, the granule position for this specific - * packet is stored in this location. - * This is computed incrementally from previously decoded - * packets. - * After a seek, the correct granule position must be set via - * #TH_DECCTL_SET_GRANPOS for this to work properly. - * \retval 0 Success. - * A new decoded frame can be retrieved by calling - * th_decode_ycbcr_out(). - * \retval TH_DUPFRAME The packet represented a dropped (0-byte) frame. - * The player can skip the call to th_decode_ycbcr_out(), - * as the contents of the decoded frame buffer have not - * changed. - * \retval TH_EFAULT \a _dec or \a _op was NULL. - * \retval TH_EBADPACKET \a _op does not contain encoded video data. - * \retval TH_EIMPL The video data uses bitstream features which this - * library does not support.*/ -extern int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, - ogg_int64_t *_granpos); -/**Outputs the next available frame of decoded Y'CbCr data. - * If a striped decode callback has been set with #TH_DECCTL_SET_STRIPE_CB, - * then the application does not need to call this function. - * \param _dec A #th_dec_ctx handle. - * \param _ycbcr A video buffer structure to fill in. - * libtheoradec will fill in all the members of this - * structure, including the pointers to the uncompressed video - * data. - * The memory for this video data is owned by - * libtheoradec. - * It may be freed or overwritten without notification when - * subsequent frames are decoded. - * \retval 0 Success - * \retval TH_EFAULT \a _dec or \a _ycbcr was NULL. - */ -extern int th_decode_ycbcr_out(th_dec_ctx *_dec, - th_ycbcr_buffer _ycbcr); -/**Frees an allocated decoder instance. - * \param _dec A #th_dec_ctx handle.*/ -extern void th_decode_free(th_dec_ctx *_dec); -/*@}*/ -/*@}*/ - - - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/theora/theoraenc.h b/src/add-ons/media/plugins/theora/libtheora/theora/theoraenc.h deleted file mode 100644 index fdf2ab21e2..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/theora/theoraenc.h +++ /dev/null @@ -1,486 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $ - - ********************************************************************/ - -/**\file - * The libtheoraenc C encoding API.*/ - -#if !defined(_O_THEORA_THEORAENC_H_) -# define _O_THEORA_THEORAENC_H_ (1) -# include -# include -# include "codec.h" - -#if defined(__cplusplus) -extern "C" { -#endif - - - -/**\name th_encode_ctl() codes - * \anchor encctlcodes - * These are the available request codes for th_encode_ctl(). - * By convention, these are even, to distinguish them from the - * \ref decctlcodes "decoder control codes". - * Keep any experimental or vendor-specific values above \c 0x8000.*/ -/*@{*/ -/**Sets the Huffman tables to use. - * The tables are copied, not stored by reference, so they can be freed after - * this call. - * NULL may be specified to revert to the default tables. - * - * \param[in] _buf #th_huff_code[#TH_NHUFFMAN_TABLES][#TH_NDCT_TOKENS] - * \retval TH_EFAULT \a _enc_ctx is NULL. - * \retval TH_EINVAL Encoding has already begun or one or more of the given - * tables is not full or prefix-free, \a _buf is - * NULL and \a _buf_sz is not zero, or \a _buf is - * non-NULL and \a _buf_sz is not - * sizeof(#th_huff_code)*#TH_NHUFFMAN_TABLES*#TH_NDCT_TOKENS. - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_HUFFMAN_CODES (0) -/**Sets the quantization parameters to use. - * The parameters are copied, not stored by reference, so they can be freed - * after this call. - * NULL may be specified to revert to the default parameters. - * - * \param[in] _buf #th_quant_info - * \retval TH_EFAULT \a _enc_ctx is NULL. - * \retval TH_EINVAL Encoding has already begun, \a _buf is - * NULL and \a _buf_sz is not zero, - * or \a _buf is non-NULL and - * \a _buf_sz is not sizeof(#th_quant_info). - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_QUANT_PARAMS (2) -/**Sets the maximum distance between key frames. - * This can be changed during an encode, but will be bounded by - * 1<. - * If it is set before encoding begins, th_info#keyframe_granule_shift will - * be enlarged appropriately. - * - * \param[in] _buf ogg_uint32_t: The maximum distance between key - * frames. - * \param[out] _buf ogg_uint32_t: The actual maximum distance set. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(ogg_uint32_t). - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4) -/**Disables any encoder features that would prevent lossless transcoding back - * to VP3. - * This primarily means disabling block-adaptive quantization and always coding - * all four luma blocks in a macro block when 4MV is used. - * It also includes using the VP3 quantization tables and Huffman codes; if you - * set them explicitly after calling this function, the resulting stream will - * not be VP3-compatible. - * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source - * material, or when using a picture region smaller than the full frame (e.g. - * a non-multiple-of-16 width or height), then non-VP3 bitstream features will - * still be disabled, but the stream will still not be VP3-compatible, as VP3 - * was not capable of encoding such formats. - * If you call this after encoding has already begun, then the quantization - * tables and codebooks cannot be changed, but the frame-level features will - * be enabled or disabled as requested. - * - * \param[in] _buf int: a non-zero value to enable VP3 compatibility, - * or 0 to disable it (the default). - * \param[out] _buf int: 1 if all bitstream features required for - * VP3-compatibility could be set, and 0 otherwise. - * The latter will be returned if the pixel format is not - * 4:2:0, the picture region is smaller than the full frame, - * or if encoding has begun, preventing the quantization - * tables and codebooks from being set. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int). - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_VP3_COMPATIBLE (10) -/**Gets the maximum speed level. - * Higher speed levels favor quicker encoding over better quality per bit. - * Depending on the encoding mode, and the internal algorithms used, quality - * may actually improve, but in this case bitrate will also likely increase. - * In any case, overall rate/distortion performance will probably decrease. - * The maximum value, and the meaning of each value, may change depending on - * the current encoding mode (VBR vs. constant quality, etc.). - * - * \param[out] _buf int: The maximum encoding speed level. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int). - * \retval TH_EIMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_GET_SPLEVEL_MAX (12) -/**Sets the speed level. - * The current speed level may be retrieved using #TH_ENCCTL_GET_SPLEVEL. - * - * \param[in] _buf int: The new encoding speed level. - * 0 is slowest, larger values use less CPU. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int), or the - * encoding speed level is out of bounds. - * The maximum encoding speed level may be - * implementation- and encoding mode-specific, and can be - * obtained via #TH_ENCCTL_GET_SPLEVEL_MAX. - * \retval TH_EIMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_SET_SPLEVEL (14) -/**Gets the current speed level. - * The default speed level may vary according to encoder implementation, but if - * this control code is not supported (it returns #TH_EIMPL), the default may - * be assumed to be the slowest available speed (0). - * The maximum encoding speed level may be implementation- and encoding - * mode-specific, and can be obtained via #TH_ENCCTL_GET_SPLEVEL_MAX. - * - * \param[out] _buf int: The current encoding speed level. - * 0 is slowest, larger values use less CPU. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int). - * \retval TH_EIMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_GET_SPLEVEL (16) -/**Sets the number of duplicates of the next frame to produce. - * Although libtheora can encode duplicate frames very cheaply, it costs some - * amount of CPU to detect them, and a run of duplicates cannot span a - * keyframe boundary. - * This control code tells the encoder to produce the specified number of extra - * duplicates of the next frame. - * This allows the encoder to make smarter keyframe placement decisions and - * rate control decisions, and reduces CPU usage as well, when compared to - * just submitting the same frame for encoding multiple times. - * This setting only applies to the next frame submitted for encoding. - * You MUST call th_encode_packetout() repeatedly until it returns 0, or the - * extra duplicate frames will be lost. - * - * \param[in] _buf int: The number of duplicates to produce. - * If this is negative or zero, no duplicates will be produced. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int), or the - * number of duplicates is greater than or equal to the - * maximum keyframe interval. - * In the latter case, NO duplicate frames will be produced. - * You must ensure that the maximum keyframe interval is set - * larger than the maximum number of duplicates you will - * ever wish to insert prior to encoding. - * \retval TH_EIMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_SET_DUP_COUNT (18) -/**Modifies the default bitrate management behavior. - * Use to allow or disallow frame dropping, and to enable or disable capping - * bit reservoir overflows and underflows. - * See \ref encctlcodes "the list of available flags". - * The flags are set by default to - * #TH_RATECTL_DROP_FRAMES|#TH_RATECTL_CAP_OVERFLOW. - * - * \param[in] _buf int: Any combination of - * \ref ratectlflags "the available flags": - * - #TH_RATECTL_DROP_FRAMES: Enable frame dropping. - * - #TH_RATECTL_CAP_OVERFLOW: Don't bank excess bits for later - * use. - * - #TH_RATECTL_CAP_UNDERFLOW: Don't try to make up shortfalls - * later. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int) or rate control - * is not enabled. - * \retval TH_EIMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_SET_RATE_FLAGS (20) -/**Sets the size of the bitrate management bit reservoir as a function - * of number of frames. - * The reservoir size affects how quickly bitrate management reacts to - * instantaneous changes in the video complexity. - * Larger reservoirs react more slowly, and provide better overall quality, but - * require more buffering by a client, adding more latency to live streams. - * By default, libtheora sets the reservoir to the maximum distance between - * keyframes, subject to a minimum and maximum limit. - * This call may be used to increase or decrease the reservoir, increasing or - * decreasing the allowed temporary variance in bitrate. - * An implementation may impose some limits on the size of a reservoir it can - * handle, in which case the actual reservoir size may not be exactly what was - * requested. - * The actual value set will be returned. - * - * \param[in] _buf int: Requested size of the reservoir measured in - * frames. - * \param[out] _buf int: The actual size of the reservoir set. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(int), or rate control - * is not enabled. The buffer has an implementation - * defined minimum and maximum size and the value in _buf - * will be adjusted to match the actual value set. - * \retval TH_EIMPL Not supported by this implementation in the current - * encoding mode.*/ -#define TH_ENCCTL_SET_RATE_BUFFER (22) -/**Enable pass 1 of two-pass encoding mode and retrieve the first pass metrics. - * Pass 1 mode must be enabled before the first frame is encoded, and a target - * bitrate must have already been specified to the encoder. - * Although this does not have to be the exact rate that will be used in the - * second pass, closer values may produce better results. - * The first call returns the size of the two-pass header data, along with some - * placeholder content, and sets the encoder into pass 1 mode implicitly. - * This call sets the encoder to pass 1 mode implicitly. - * Then, a subsequent call must be made after each call to - * th_encode_ycbcr_in() to retrieve the metrics for that frame. - * An additional, final call must be made to retrieve the summary data, - * containing such information as the total number of frames, etc. - * This must be stored in place of the placeholder data that was returned - * in the first call, before the frame metrics data. - * All of this data must be presented back to the encoder during pass 2 using - * #TH_ENCCTL_2PASS_IN. - * - * \param[out] char *_buf: Returns a pointer to internal storage - * containing the two pass metrics data. - * This storage is only valid until the next call, or until the - * encoder context is freed, and must be copied by the - * application. - * \retval >=0 The number of bytes of metric data available in the - * returned buffer. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL \a _buf_sz is not sizeof(char *), no target - * bitrate has been set, or the first call was made after - * the first frame was submitted for encoding. - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_2PASS_OUT (24) -/**Submits two-pass encoding metric data collected the first encoding pass to - * the second pass. - * The first call must be made before the first frame is encoded, and a target - * bitrate must have already been specified to the encoder. - * It sets the encoder to pass 2 mode implicitly; this cannot be disabled. - * The encoder may require reading data from some or all of the frames in - * advance, depending on, e.g., the reservoir size used in the second pass. - * You must call this function repeatedly before each frame to provide data - * until either a) it fails to consume all of the data presented or b) all of - * the pass 1 data has been consumed. - * In the first case, you must save the remaining data to be presented after - * the next frame. - * You can call this function with a NULL argument to get an upper bound on - * the number of bytes that will be required before the next frame. - * - * When pass 2 is first enabled, the default bit reservoir is set to the entire - * file; this gives maximum flexibility but can lead to very high peak rates. - * You can subsequently set it to another value with #TH_ENCCTL_SET_RATE_BUFFER - * (e.g., to set it to the keyframe interval for non-live streaming), however, - * you may then need to provide more data before the next frame. - * - * \param[in] _buf char[]: A buffer containing the data returned by - * #TH_ENCCTL_2PASS_OUT in pass 1. - * You may pass NULL for \a _buf to return an upper - * bound on the number of additional bytes needed before the - * next frame. - * The summary data returned at the end of pass 1 must be at - * the head of the buffer on the first call with a - * non-NULL \a _buf, and the placeholder data - * returned at the start of pass 1 should be omitted. - * After each call you should advance this buffer by the number - * of bytes consumed. - * \retval >0 The number of bytes of metric data required/consumed. - * \retval 0 No more data is required before the next frame. - * \retval TH_EFAULT \a _enc_ctx is NULL. - * \retval TH_EINVAL No target bitrate has been set, or the first call was - * made after the first frame was submitted for - * encoding. - * \retval TH_ENOTFORMAT The data did not appear to be pass 1 from a compatible - * implementation of this library. - * \retval TH_EBADHEADER The data was invalid; this may be returned when - * attempting to read an aborted pass 1 file that still - * has the placeholder data in place of the summary - * data. - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_2PASS_IN (26) -/**Sets the current encoding quality. - * This is only valid so long as no bitrate has been specified, either through - * the #th_info struct used to initialize the encoder or through - * #TH_ENCCTL_SET_BITRATE (this restriction may be relaxed in a future - * version). - * If it is set before the headers are emitted, the target quality encoded in - * them will be updated. - * - * \param[in] _buf int: The new target quality, in the range 0...63, - * inclusive. - * \retval 0 Success. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL A target bitrate has already been specified, or the - * quality index was not in the range 0...63. - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_QUALITY (28) -/**Sets the current encoding bitrate. - * Once a bitrate is set, the encoder must use a rate-controlled mode for all - * future frames (this restriction may be relaxed in a future version). - * If it is set before the headers are emitted, the target bitrate encoded in - * them will be updated. - * Due to the buffer delay, the exact bitrate of each section of the encode is - * not guaranteed. - * The encoder may have already used more bits than allowed for the frames it - * has encoded, expecting to make them up in future frames, or it may have - * used fewer, holding the excess in reserve. - * The exact transition between the two bitrates is not well-defined by this - * API, but may be affected by flags set with #TH_ENCCTL_SET_RATE_FLAGS. - * After a number of frames equal to the buffer delay, one may expect further - * output to average at the target bitrate. - * - * \param[in] _buf long: The new target bitrate, in bits per second. - * \retval 0 Success. - * \retval TH_EFAULT \a _enc_ctx or \a _buf is NULL. - * \retval TH_EINVAL The target bitrate was not positive. - * \retval TH_EIMPL Not supported by this implementation.*/ -#define TH_ENCCTL_SET_BITRATE (30) - -/*@}*/ - - -/**\name TH_ENCCTL_SET_RATE_FLAGS flags - * \anchor ratectlflags - * These are the flags available for use with #TH_ENCCTL_SET_RATE_FLAGS.*/ -/*@{*/ -/**Drop frames to keep within bitrate buffer constraints. - * This can have a severe impact on quality, but is the only way to ensure that - * bitrate targets are met at low rates during sudden bursts of activity.*/ -#define TH_RATECTL_DROP_FRAMES (0x1) -/**Ignore bitrate buffer overflows. - * If the encoder uses so few bits that the reservoir of available bits - * overflows, ignore the excess. - * The encoder will not try to use these extra bits in future frames. - * At high rates this may cause the result to be undersized, but allows a - * client to play the stream using a finite buffer; it should normally be - * enabled.*/ -#define TH_RATECTL_CAP_OVERFLOW (0x2) -/**Ignore bitrate buffer underflows. - * If the encoder uses so many bits that the reservoir of available bits - * underflows, ignore the deficit. - * The encoder will not try to make up these extra bits in future frames. - * At low rates this may cause the result to be oversized; it should normally - * be disabled.*/ -#define TH_RATECTL_CAP_UNDERFLOW (0x4) -/*@}*/ - - - -/**The quantization parameters used by VP3.*/ -extern const th_quant_info TH_VP31_QUANT_INFO; - -/**The Huffman tables used by VP3.*/ -extern const th_huff_code - TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]; - - - -/**\name Encoder state - The following data structure is opaque, and its contents are not publicly - defined by this API. - Referring to its internals directly is unsupported, and may break without - warning.*/ -/*@{*/ -/**The encoder context.*/ -typedef struct th_enc_ctx th_enc_ctx; -/*@}*/ - - - -/**\defgroup encfuncs Functions for Encoding*/ -/*@{*/ -/**\name Functions for encoding - * You must link to libtheoraenc and libtheoradec - * if you use any of the functions in this section. - * - * The functions are listed in the order they are used in a typical encode. - * The basic steps are: - * - Fill in a #th_info structure with details on the format of the video you - * wish to encode. - * - Allocate a #th_enc_ctx handle with th_encode_alloc(). - * - Perform any additional encoder configuration required with - * th_encode_ctl(). - * - Repeatedly call th_encode_flushheader() to retrieve all the header - * packets. - * - For each uncompressed frame: - * - Submit the uncompressed frame via th_encode_ycbcr_in() - * - Repeatedly call th_encode_packetout() to retrieve any video data packets - * that are ready. - * - Call th_encode_free() to release all encoder memory.*/ -/*@{*/ -/**Allocates an encoder instance. - * \param _info A #th_info struct filled with the desired encoding parameters. - * \return The initialized #th_enc_ctx handle. - * \retval NULL If the encoding parameters were invalid.*/ -extern th_enc_ctx *th_encode_alloc(const th_info *_info); -/**Encoder control function. - * This is used to provide advanced control the encoding process. - * \param _enc A #th_enc_ctx handle. - * \param _req The control code to process. - * See \ref encctlcodes "the list of available control codes" - * for details. - * \param _buf The parameters for this control code. - * \param _buf_sz The size of the parameter buffer.*/ -extern int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz); -/**Outputs the next header packet. - * This should be called repeatedly after encoder initialization until it - * returns 0 in order to get all of the header packets, in order, before - * encoding actual video data. - * \param _enc A #th_enc_ctx handle. - * \param _comments The metadata to place in the comment header, when it is - * encoded. - * \param _op An ogg_packet structure to fill. - * All of the elements of this structure will be set, - * including a pointer to the header data. - * The memory for the header data is owned by - * libtheoraenc, and may be invalidated when the - * next encoder function is called. - * \return A positive value indicates that a header packet was successfully - * produced. - * \retval 0 No packet was produced, and no more header packets remain. - * \retval TH_EFAULT \a _enc, \a _comments, or \a _op was NULL.*/ -extern int th_encode_flushheader(th_enc_ctx *_enc, - th_comment *_comments,ogg_packet *_op); -/**Submits an uncompressed frame to the encoder. - * \param _enc A #th_enc_ctx handle. - * \param _ycbcr A buffer of Y'CbCr data to encode. - * \retval 0 Success. - * \retval TH_EFAULT \a _enc or \a _ycbcr is NULL. - * \retval TH_EINVAL The buffer size does not match the frame size the encoder - * was initialized with, or encoding has already - * completed.*/ -extern int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _ycbcr); -/**Retrieves encoded video data packets. - * This should be called repeatedly after each frame is submitted to flush any - * encoded packets, until it returns 0. - * The encoder will not buffer these packets as subsequent frames are - * compressed, so a failure to do so will result in lost video data. - * \note Currently the encoder operates in a one-frame-in, one-packet-out - * manner. - * However, this may be changed in the future. - * \param _enc A #th_enc_ctx handle. - * \param _last Set this flag to a non-zero value if no more uncompressed - * frames will be submitted. - * This ensures that a proper EOS flag is set on the last packet. - * \param _op An ogg_packet structure to fill. - * All of the elements of this structure will be set, including a - * pointer to the video data. - * The memory for the video data is owned by - * libtheoraenc, and may be invalidated when the next - * encoder function is called. - * \return A positive value indicates that a video data packet was successfully - * produced. - * \retval 0 No packet was produced, and no more encoded video data - * remains. - * \retval TH_EFAULT \a _enc or \a _op was NULL.*/ -extern int th_encode_packetout(th_enc_ctx *_enc,int _last,ogg_packet *_op); -/**Frees an allocated encoder instance. - * \param _enc A #th_enc_ctx handle.*/ -extern void th_encode_free(th_enc_ctx *_enc); -/*@}*/ -/*@}*/ - - - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/tokenize.c b/src/add-ons/media/plugins/theora/libtheora/tokenize.c deleted file mode 100644 index 60574c3594..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/tokenize.c +++ /dev/null @@ -1,1072 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: tokenize.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ -#include -#include -#include "encint.h" - - - -static int oc_make_eob_token(int _run_count){ - if(_run_count<4)return OC_DCT_EOB1_TOKEN+_run_count-1; - else{ - int cat; - cat=OC_ILOGNZ_32(_run_count)-3; - cat=OC_MINI(cat,3); - return OC_DCT_REPEAT_RUN0_TOKEN+cat; - } -} - -static int oc_make_eob_token_full(int _run_count,int *_eb){ - if(_run_count<4){ - *_eb=0; - return OC_DCT_EOB1_TOKEN+_run_count-1; - } - else{ - int cat; - cat=OC_ILOGNZ_32(_run_count)-3; - cat=OC_MINI(cat,3); - *_eb=_run_count-OC_BYTE_TABLE32(4,8,16,0,cat); - return OC_DCT_REPEAT_RUN0_TOKEN+cat; - } -} - -/*Returns the number of blocks ended by an EOB token.*/ -static int oc_decode_eob_token(int _token,int _eb){ - return (0x20820C41U>>_token*5&0x1F)+_eb; -} - -/*TODO: This is now only used during DCT tokenization, and never for runs; it - should be simplified.*/ -static int oc_make_dct_token_full(int _zzi,int _zzj,int _val,int *_eb){ - int neg; - int zero_run; - int token; - int eb; - neg=_val<0; - _val=abs(_val); - zero_run=_zzj-_zzi; - if(zero_run>0){ - int adj; - /*Implement a minor restriction on stack 1 so that we know during DC fixups - that extending a dctrun token from stack 1 will never overflow.*/ - adj=_zzi!=1; - if(_val<2&&zero_run<17+adj){ - if(zero_run<6){ - token=OC_DCT_RUN_CAT1A+zero_run-1; - eb=neg; - } - else if(zero_run<10){ - token=OC_DCT_RUN_CAT1B; - eb=zero_run-6+(neg<<2); - } - else{ - token=OC_DCT_RUN_CAT1C; - eb=zero_run-10+(neg<<3); - } - } - else if(_val<4&&zero_run<3+adj){ - if(zero_run<2){ - token=OC_DCT_RUN_CAT2A; - eb=_val-2+(neg<<1); - } - else{ - token=OC_DCT_RUN_CAT2B; - eb=zero_run-2+(_val-2<<1)+(neg<<2); - } - } - else{ - if(zero_run<9)token=OC_DCT_SHORT_ZRL_TOKEN; - else token=OC_DCT_ZRL_TOKEN; - eb=zero_run-1; - } - } - else if(_val<3){ - token=OC_ONE_TOKEN+(_val-1<<1)+neg; - eb=0; - } - else if(_val<7){ - token=OC_DCT_VAL_CAT2+_val-3; - eb=neg; - } - else if(_val<9){ - token=OC_DCT_VAL_CAT3; - eb=_val-7+(neg<<1); - } - else if(_val<13){ - token=OC_DCT_VAL_CAT4; - eb=_val-9+(neg<<2); - } - else if(_val<21){ - token=OC_DCT_VAL_CAT5; - eb=_val-13+(neg<<3); - } - else if(_val<37){ - token=OC_DCT_VAL_CAT6; - eb=_val-21+(neg<<4); - } - else if(_val<69){ - token=OC_DCT_VAL_CAT7; - eb=_val-37+(neg<<5); - } - else{ - token=OC_DCT_VAL_CAT8; - eb=_val-69+(neg<<9); - } - *_eb=eb; - return token; -} - -/*Token logging to allow a few fragments of efficient rollback. - Late SKIP analysis is tied up in the tokenization process, so we need to be - able to undo a fragment's tokens on a whim.*/ - -static const unsigned char OC_ZZI_HUFF_OFFSET[64]={ - 0,16,16,16,16,16,32,32, - 32,32,32,32,32,32,32,48, - 48,48,48,48,48,48,48,48, - 48,48,48,48,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64 -}; - -static int oc_token_bits(oc_enc_ctx *_enc,int _huffi,int _zzi,int _token){ - return _enc->huff_codes[_huffi+OC_ZZI_HUFF_OFFSET[_zzi]][_token].nbits - +OC_DCT_TOKEN_EXTRA_BITS[_token]; -} - -static void oc_enc_tokenlog_checkpoint(oc_enc_ctx *_enc, - oc_token_checkpoint *_cp,int _pli,int _zzi){ - _cp->pli=_pli; - _cp->zzi=_zzi; - _cp->eob_run=_enc->eob_run[_pli][_zzi]; - _cp->ndct_tokens=_enc->ndct_tokens[_pli][_zzi]; -} - -void oc_enc_tokenlog_rollback(oc_enc_ctx *_enc, - const oc_token_checkpoint *_stack,int _n){ - int i; - for(i=_n;i-->0;){ - int pli; - int zzi; - pli=_stack[i].pli; - zzi=_stack[i].zzi; - _enc->eob_run[pli][zzi]=_stack[i].eob_run; - _enc->ndct_tokens[pli][zzi]=_stack[i].ndct_tokens; - } -} - -static void oc_enc_token_log(oc_enc_ctx *_enc, - int _pli,int _zzi,int _token,int _eb){ - ptrdiff_t ti; - ti=_enc->ndct_tokens[_pli][_zzi]++; - _enc->dct_tokens[_pli][_zzi][ti]=(unsigned char)_token; - _enc->extra_bits[_pli][_zzi][ti]=(ogg_uint16_t)_eb; -} - -static void oc_enc_eob_log(oc_enc_ctx *_enc, - int _pli,int _zzi,int _run_count){ - int token; - int eb; - token=oc_make_eob_token_full(_run_count,&eb); - oc_enc_token_log(_enc,_pli,_zzi,token,eb); -} - - -void oc_enc_tokenize_start(oc_enc_ctx *_enc){ - memset(_enc->ndct_tokens,0,sizeof(_enc->ndct_tokens)); - memset(_enc->eob_run,0,sizeof(_enc->eob_run)); - memset(_enc->dct_token_offs,0,sizeof(_enc->dct_token_offs)); - memset(_enc->dc_pred_last,0,sizeof(_enc->dc_pred_last)); -} - -typedef struct oc_quant_token oc_quant_token; - -/*A single node in the Viterbi trellis. - We maintain up to 2 of these per coefficient: - - A token to code if the value is zero (EOB, zero run, or combo token). - - A token to code if the value is not zero (DCT value token).*/ -struct oc_quant_token{ - unsigned char next; - signed char token; - ogg_int16_t eb; - ogg_uint32_t cost; - int bits; - int qc; -}; - -/*Tokenizes the AC coefficients, possibly adjusting the quantization, and then - dequantizes and de-zig-zags the result. - The DC coefficient is not preserved; it should be restored by the caller.*/ -int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, - ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, - int _zzi,oc_token_checkpoint **_stack,int _acmin){ - oc_token_checkpoint *stack; - ogg_int64_t zflags; - ogg_int64_t nzflags; - ogg_int64_t best_flags; - ogg_uint32_t d2_accum[64]; - oc_quant_token tokens[64][2]; - ogg_uint16_t *eob_run; - const unsigned char *dct_fzig_zag; - ogg_uint32_t cost; - int bits; - int eob; - int token; - int eb; - int next; - int huffi; - int zzi; - int ti; - int zzj; - int qc; - huffi=_enc->huff_idxs[_enc->state.frame_type][1][_pli+1>>1]; - eob_run=_enc->eob_run[_pli]; - memset(tokens[0],0,sizeof(tokens[0])); - best_flags=nzflags=0; - zflags=1; - d2_accum[0]=0; - zzj=64; - for(zzi=OC_MINI(_zzi,63);zzi>0;zzi--){ - ogg_int32_t lambda; - ogg_uint32_t best_cost; - int best_bits=best_bits; - int best_next=best_next; - int best_token=best_token; - int best_eb=best_eb; - int best_qc=best_qc; - int flush_bits; - ogg_uint32_t d2; - int dq; - int e; - int c; - int s; - int tj; - lambda=_enc->lambda; - qc=_qdct[zzi]; - s=-(qc<0); - qc=qc+s^s; - c=_dct[OC_FZIG_ZAG[zzi]]; - if(qc<=1){ - ogg_uint32_t sum_d2; - int nzeros; - int dc_reserve; - /*The hard case: try a zero run.*/ - if(!qc){ - /*Skip runs that are already quantized to zeros. - If we considered each zero coefficient in turn, we might - theoretically find a better way to partition long zero runs (e.g., - a run of > 17 zeros followed by a 1 might be better coded as a short - zero run followed by a combo token, rather than the longer zero - token followed by a 1 value token), but zeros are so common that - this becomes very computationally expensive (quadratic instead of - linear in the number of coefficients), for a marginal gain.*/ - while(zzi>1&&!_qdct[zzi-1])zzi--; - /*The distortion of coefficients originally quantized to zero is - treated as zero (since we'll never quantize them to anything else).*/ - d2=0; - } - else{ - c=c+s^s; - d2=c*(ogg_int32_t)c; - } - eob=eob_run[zzi]; - nzeros=zzj-zzi; - zzj&=63; - sum_d2=d2+d2_accum[zzj]; - d2_accum[zzi]=sum_d2; - flush_bits=eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0; - /*We reserve 1 spot for combo run tokens that start in the 1st AC stack - to ensure they can be extended to include the DC coefficient if - necessary; this greatly simplifies stack-rewriting later on.*/ - dc_reserve=zzi+62>>6; - best_cost=0xFFFFFFFF; - for(;;){ - if(nzflags>>zzj&1){ - int cat; - int val; - int val_s; - int zzk; - int tk; - next=tokens[zzj][1].next; - tk=next&1; - zzk=next>>1; - /*Try a pure zero run to this point.*/ - cat=nzeros+55>>6; - token=OC_DCT_SHORT_ZRL_TOKEN+cat; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - d2=sum_d2-d2_accum[zzj]; - cost=d2+lambda*bits+tokens[zzj][1].cost; - if(cost<=best_cost){ - best_next=(zzj<<1)+1; - best_token=token; - best_eb=nzeros-1; - best_cost=cost; - best_bits=bits+tokens[zzj][1].bits; - best_qc=0; - } - if(nzeros<16+dc_reserve){ - val=_qdct[zzj]; - val_s=-(val<0); - val=val+val_s^val_s; - if(val<=2){ - /*Try a +/- 1 combo token.*/ - if(nzeros<6){ - token=OC_DCT_RUN_CAT1A+nzeros-1; - eb=-val_s; - } - else{ - cat=nzeros+54>>6; - token=OC_DCT_RUN_CAT1B+cat; - eb=(-val_s<>1; - token=OC_DCT_RUN_CAT2A+cat; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - val=2+((val+val_s^val_s)>2); - e=(_dct[OC_FZIG_ZAG[zzj]]+val_s^val_s)-_dequant[zzj]*val; - d2=e*(ogg_int32_t)e+sum_d2-d2_accum[zzj]; - cost=d2+lambda*bits+tokens[zzk][tk].cost; - if(cost<=best_cost){ - best_cost=cost; - best_bits=bits+tokens[zzk][tk].bits; - best_next=next; - best_token=token; - best_eb=(-val_s<<1+cat)+(val-2<>1); - best_qc=val+val_s^val_s; - } - } - } - /*zzj can't be coded as a zero, so stop trying to extend the run.*/ - if(!(zflags>>zzj&1))break; - } - /*We could try to consider _all_ potentially non-zero coefficients, but - if we already found a bunch of them not worth coding, it's fairly - unlikely they would now be worth coding from this position; skipping - them saves a lot of work.*/ - zzj=(tokens[zzj][0].next>>1)-(tokens[zzj][0].qc!=0)&63; - if(zzj==0){ - /*We made it all the way to the end of the block; try an EOB token.*/ - if(eob<4095){ - bits=oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob+1)) - -flush_bits; - } - else bits=oc_token_bits(_enc,huffi,zzi,OC_DCT_EOB1_TOKEN); - cost=sum_d2+bits*lambda; - /*If the best route so far is still a pure zero run to the end of the - block, force coding it as an EOB. - Even if it's not optimal for this block, it has a good chance of - getting combined with an EOB token from subsequent blocks, saving - bits overall.*/ - if(cost<=best_cost||best_token<=OC_DCT_ZRL_TOKEN&&zzi+best_eb==63){ - best_next=0; - /*This token is just a marker; in reality we may not emit any - tokens, but update eob_run[] instead.*/ - best_token=OC_DCT_EOB1_TOKEN; - best_eb=0; - best_cost=cost; - best_bits=bits; - best_qc=0; - } - break; - } - nzeros=zzj-zzi; - } - tokens[zzi][0].next=(unsigned char)best_next; - tokens[zzi][0].token=(signed char)best_token; - tokens[zzi][0].eb=(ogg_int16_t)best_eb; - tokens[zzi][0].cost=best_cost; - tokens[zzi][0].bits=best_bits; - tokens[zzi][0].qc=best_qc; - zflags|=(ogg_int64_t)1<>zzj&1; - next=(zzj<<1)+tj; - tokens[zzi][1].next=(unsigned char)next; - tokens[zzi][1].token=(signed char)token; - tokens[zzi][1].eb=0; - tokens[zzi][1].cost=d2+lambda*bits+tokens[zzj][tj].cost; - tokens[zzi][1].bits=bits+tokens[zzj][tj].bits; - tokens[zzi][1].qc=1+s^s; - nzflags|=(ogg_int64_t)1<0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0; - if(qc<=2){ - e=2*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_TWO_TOKEN-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=OC_ONE_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_bits=bits; - best_cost=cost; - qc--; - } - best_eb=0; - } - else if(qc<=3){ - e=3*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT2; - best_eb=-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=OC_TWO_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=0; - best_bits=bits; - best_cost=cost; - qc--; - } - } - else if(qc<=6){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT2+qc-3; - best_eb=-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_bits=bits; - best_cost=cost; - qc--; - } - } - else if(qc<=8){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT3; - best_eb=(-s<<1)+qc-7; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=6*dq-c; - d2=e*(ogg_int32_t)e; - token=OC_DCT_VAL_CAT2+3; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=-s; - best_bits=bits; - best_cost=cost; - qc=6; - } - } - else if(qc<=12){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT4; - best_eb=(-s<<2)+qc-9; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=8*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<1)+1; - best_bits=bits; - best_cost=cost; - qc=8; - } - } - else if(qc<=20){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT5; - best_eb=(-s<<3)+qc-13; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=12*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<2)+3; - best_bits=bits; - best_cost=cost; - qc=12; - } - } - else if(qc<=36){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT6; - best_eb=(-s<<4)+qc-21; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=20*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<3)+7; - best_bits=bits; - best_cost=cost; - qc=20; - } - } - else if(qc<=68){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT7; - best_eb=(-s<<5)+qc-37; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=36*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost>zzj&1; - next=(zzj<<1)+tj; - tokens[zzi][1].next=(unsigned char)next; - tokens[zzi][1].token=(signed char)best_token; - tokens[zzi][1].eb=best_eb; - tokens[zzi][1].cost=best_cost+tokens[zzj][tj].cost; - tokens[zzi][1].bits=best_bits+tokens[zzj][tj].bits; - tokens[zzi][1].qc=qc+s^s; - nzflags|=(ogg_int64_t)1<state.opt_data.dct_fzig_zag; - zzi=1; - ti=best_flags>>1&1; - bits=tokens[zzi][ti].bits; - do{ - oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); - eob=eob_run[zzi]; - if(tokens[zzi][ti].token=4095){ - oc_enc_eob_log(_enc,_pli,zzi,eob); - eob=0; - } - eob_run[zzi]=eob; - /*We don't include the actual EOB cost for this block in the return value. - It will be paid for by the fragment that terminates the EOB run.*/ - bits-=tokens[zzi][ti].bits; - zzi=_zzi; - break; - } - /*Emit pending EOB run if any.*/ - if(eob>0){ - oc_enc_eob_log(_enc,_pli,zzi,eob); - eob_run[zzi]=0; - } - oc_enc_token_log(_enc,_pli,zzi,tokens[zzi][ti].token,tokens[zzi][ti].eb); - next=tokens[zzi][ti].next; - qc=tokens[zzi][ti].qc; - zzj=(next>>1)-1&63; - /*TODO: It may be worth saving the dequantized coefficient in the trellis - above; we had to compute it to measure the error anyway.*/ - _qdct[dct_fzig_zag[zzj]]=(ogg_int16_t)(qc*(int)_dequant[zzj]); - zzi=next>>1; - ti=next&1; - } - while(zzi); - *_stack=stack; - return bits; -} - -void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, - int _pli,int _fragy0,int _frag_yend){ - const oc_fragment_plane *fplane; - const oc_fragment *frags; - ogg_int16_t *frag_dc; - ptrdiff_t fragi; - int *pred_last; - int nhfrags; - int fragx; - int fragy; - fplane=_enc->state.fplanes+_pli; - frags=_enc->state.frags; - frag_dc=_enc->frag_dc; - pred_last=_enc->dc_pred_last[_pli]; - nhfrags=fplane->nhfrags; - fragi=fplane->froffset+_fragy0*nhfrags; - for(fragy=_fragy0;fragy<_frag_yend;fragy++){ - if(fragy==0){ - /*For the first row, all of the cases reduce to just using the previous - predictor for the same reference frame.*/ - for(fragx=0;fragx=nhfrags)ur_ref=-1; - else{ - ur_ref=u_frags[fragi+1].coded? - OC_FRAME_FOR_MODE(u_frags[fragi+1].mb_mode):-1; - } - if(frags[fragi].coded){ - int pred; - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); - /*We break out a separate case based on which of our neighbors use - the same reference frames. - This is somewhat faster than trying to make a generic case which - handles all of them, since it reduces lots of poorly predicted - jumps to one switch statement, and also lets a number of the - multiplications be optimized out by strength reduction.*/ - switch((l_ref==ref)|(ul_ref==ref)<<1| - (u_ref==ref)<<2|(ur_ref==ref)<<3){ - default:pred=pred_last[ref];break; - case 1: - case 3:pred=frags[fragi-1].dc;break; - case 2:pred=u_frags[fragi-1].dc;break; - case 4: - case 6: - case 12:pred=u_frags[fragi].dc;break; - case 5:pred=(frags[fragi-1].dc+u_frags[fragi].dc)/2;break; - case 8:pred=u_frags[fragi+1].dc;break; - case 9: - case 11: - case 13:{ - pred=(75*frags[fragi-1].dc+53*u_frags[fragi+1].dc)/128; - }break; - case 10:pred=(u_frags[fragi-1].dc+u_frags[fragi+1].dc)/2;break; - case 14:{ - pred=(3*(u_frags[fragi-1].dc+u_frags[fragi+1].dc) - +10*u_frags[fragi].dc)/16; - }break; - case 7: - case 15:{ - int p0; - int p1; - int p2; - p0=frags[fragi-1].dc; - p1=u_frags[fragi-1].dc; - p2=u_frags[fragi].dc; - pred=(29*(p0+p2)-26*p1)/32; - if(abs(pred-p2)>128)pred=p2; - else if(abs(pred-p0)>128)pred=p0; - else if(abs(pred-p1)>128)pred=p1; - }break; - } - frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred); - pred_last[ref]=frags[fragi].dc; - l_ref=ref; - } - else l_ref=-1; - ul_ref=u_ref; - u_ref=ur_ref; - } - } - } -} - -void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, - const ptrdiff_t *_coded_fragis,ptrdiff_t _ncoded_fragis, - int _prev_ndct_tokens1,int _prev_eob_run1){ - const ogg_int16_t *frag_dc; - ptrdiff_t fragii; - unsigned char *dct_tokens0; - unsigned char *dct_tokens1; - ogg_uint16_t *extra_bits0; - ogg_uint16_t *extra_bits1; - ptrdiff_t ti0; - ptrdiff_t ti1r; - ptrdiff_t ti1w; - int eob_run0; - int eob_run1; - int neobs1; - int token; - int eb; - int token1=token1; - int eb1=eb1; - /*Return immediately if there are no coded fragments; otherwise we'd flush - any trailing EOB run into the AC 1 list and never read it back out.*/ - if(_ncoded_fragis<=0)return; - frag_dc=_enc->frag_dc; - dct_tokens0=_enc->dct_tokens[_pli][0]; - dct_tokens1=_enc->dct_tokens[_pli][1]; - extra_bits0=_enc->extra_bits[_pli][0]; - extra_bits1=_enc->extra_bits[_pli][1]; - ti0=_enc->ndct_tokens[_pli][0]; - ti1w=ti1r=_prev_ndct_tokens1; - eob_run0=_enc->eob_run[_pli][0]; - /*Flush any trailing EOB run for the 1st AC coefficient. - This is needed to allow us to track tokens to the end of the list.*/ - eob_run1=_enc->eob_run[_pli][1]; - if(eob_run1>0)oc_enc_eob_log(_enc,_pli,1,eob_run1); - /*If there was an active EOB run at the start of the 1st AC stack, read it - in and decode it.*/ - if(_prev_eob_run1>0){ - token1=dct_tokens1[ti1r]; - eb1=extra_bits1[ti1r]; - ti1r++; - eob_run1=oc_decode_eob_token(token1,eb1); - /*Consume the portion of the run that came before these fragments.*/ - neobs1=eob_run1-_prev_eob_run1; - } - else eob_run1=neobs1=0; - for(fragii=0;fragii<_ncoded_fragis;fragii++){ - int val; - /*All tokens in the 1st AC coefficient stack are regenerated as the DC - coefficients are produced. - This can be done in-place; stack 1 cannot get larger.*/ - if(!neobs1){ - /*There's no active EOB run in stack 1; read the next token.*/ - token1=dct_tokens1[ti1r]; - eb1=extra_bits1[ti1r]; - ti1r++; - if(token10){ - token=oc_make_eob_token_full(eob_run0,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; - ti0++; - eob_run0=0; - } - token=oc_make_dct_token_full(0,0,val,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; - ti0++; - } - else{ - /*Zero DC value; that means the entry in stack 1 might need to be coded - from stack 0. - This requires a stack 1 fixup.*/ - if(neobs1>0){ - /*We're in the middle of an active EOB run in stack 1. - Move it to stack 0.*/ - if(++eob_run0>=4095){ - token=oc_make_eob_token_full(eob_run0,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; - ti0++; - eob_run0=0; - } - eob_run1--; - } - else{ - /*No active EOB run in stack 1, so we can't extend one in stack 0. - Flush it if we've got it.*/ - if(eob_run0>0){ - token=oc_make_eob_token_full(eob_run0,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; - ti0++; - eob_run0=0; - } - /*Stack 1 token is one of: a pure zero run token, a single - coefficient token, or a zero run/coefficient combo token. - A zero run token is expanded and moved to token stack 0, and the - stack 1 entry dropped. - A single coefficient value may be transformed into combo token that - is moved to stack 0, or if it cannot be combined, it is left alone - and a single length-1 zero run is emitted in stack 0. - A combo token is extended and moved to stack 0. - During AC coding, we restrict the run lengths on combo tokens for - stack 1 to guarantee we can extend them.*/ - switch(token1){ - case OC_DCT_SHORT_ZRL_TOKEN:{ - if(eb1<7){ - dct_tokens0[ti0]=OC_DCT_SHORT_ZRL_TOKEN; - extra_bits0[ti0]=(ogg_uint16_t)(eb1+1); - ti0++; - /*Don't write the AC coefficient back out.*/ - continue; - } - /*Fall through.*/ - } - case OC_DCT_ZRL_TOKEN:{ - dct_tokens0[ti0]=OC_DCT_ZRL_TOKEN; - extra_bits0[ti0]=(ogg_uint16_t)(eb1+1); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_ONE_TOKEN: - case OC_MINUS_ONE_TOKEN:{ - dct_tokens0[ti0]=OC_DCT_RUN_CAT1A; - extra_bits0[ti0]=(ogg_uint16_t)(token1-OC_ONE_TOKEN); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_TWO_TOKEN: - case OC_MINUS_TWO_TOKEN:{ - dct_tokens0[ti0]=OC_DCT_RUN_CAT2A; - extra_bits0[ti0]=(ogg_uint16_t)(token1-OC_TWO_TOKEN<<1); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_DCT_VAL_CAT2:{ - dct_tokens0[ti0]=OC_DCT_RUN_CAT2A; - extra_bits0[ti0]=(ogg_uint16_t)((eb1<<1)+1); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_DCT_RUN_CAT1A: - case OC_DCT_RUN_CAT1A+1: - case OC_DCT_RUN_CAT1A+2: - case OC_DCT_RUN_CAT1A+3:{ - dct_tokens0[ti0]=(unsigned char)(token1+1); - extra_bits0[ti0]=(ogg_uint16_t)eb1; - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_DCT_RUN_CAT1A+4:{ - dct_tokens0[ti0]=OC_DCT_RUN_CAT1B; - extra_bits0[ti0]=(ogg_uint16_t)(eb1<<2); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_DCT_RUN_CAT1B:{ - if((eb1&3)<3){ - dct_tokens0[ti0]=OC_DCT_RUN_CAT1B; - extra_bits0[ti0]=(ogg_uint16_t)(eb1+1); - ti0++; - /*Don't write the AC coefficient back out.*/ - continue; - } - eb1=((eb1&4)<<1)-1; - /*Fall through.*/ - } - case OC_DCT_RUN_CAT1C:{ - dct_tokens0[ti0]=OC_DCT_RUN_CAT1C; - extra_bits0[ti0]=(ogg_uint16_t)(eb1+1); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - case OC_DCT_RUN_CAT2A:{ - eb1=(eb1<<1)-1; - /*Fall through.*/ - } - case OC_DCT_RUN_CAT2B:{ - dct_tokens0[ti0]=OC_DCT_RUN_CAT2B; - extra_bits0[ti0]=(ogg_uint16_t)(eb1+1); - ti0++; - /*Don't write the AC coefficient back out.*/ - }continue; - } - /*We can't merge tokens, write a short zero run and keep going.*/ - dct_tokens0[ti0]=OC_DCT_SHORT_ZRL_TOKEN; - extra_bits0[ti0]=0; - ti0++; - } - } - if(!neobs1){ - /*Flush any (inactive) EOB run.*/ - if(eob_run1>0){ - token=oc_make_eob_token_full(eob_run1,&eb); - dct_tokens1[ti1w]=(unsigned char)token; - extra_bits1[ti1w]=(ogg_uint16_t)eb; - ti1w++; - eob_run1=0; - } - /*There's no active EOB run, so log the current token.*/ - dct_tokens1[ti1w]=(unsigned char)token1; - extra_bits1[ti1w]=(ogg_uint16_t)eb1; - ti1w++; - } - else{ - /*Otherwise consume one EOB from the current run.*/ - neobs1--; - /*If we have more than 4095 EOBs outstanding in stack1, flush the run.*/ - if(eob_run1-neobs1>=4095){ - token=oc_make_eob_token_full(4095,&eb); - dct_tokens1[ti1w]=(unsigned char)token; - extra_bits1[ti1w]=(ogg_uint16_t)eb; - ti1w++; - eob_run1-=4095; - } - } - } - /*Save the current state.*/ - _enc->ndct_tokens[_pli][0]=ti0; - _enc->ndct_tokens[_pli][1]=ti1w; - _enc->eob_run[_pli][0]=eob_run0; - _enc->eob_run[_pli][1]=eob_run1; -} - -/*Final EOB run welding.*/ -void oc_enc_tokenize_finish(oc_enc_ctx *_enc){ - int pli; - int zzi; - /*Emit final EOB runs.*/ - for(pli=0;pli<3;pli++)for(zzi=0;zzi<64;zzi++){ - int eob_run; - eob_run=_enc->eob_run[pli][zzi]; - if(eob_run>0)oc_enc_eob_log(_enc,pli,zzi,eob_run); - } - /*Merge the final EOB run of one token list with the start of the next, if - possible.*/ - for(zzi=0;zzi<64;zzi++)for(pli=0;pli<3;pli++){ - int old_tok1; - int old_tok2; - int old_eb1; - int old_eb2; - int new_tok; - int new_eb; - int zzj; - int plj; - ptrdiff_t ti=ti; - int run_count; - /*Make sure this coefficient has tokens at all.*/ - if(_enc->ndct_tokens[pli][zzi]<=0)continue; - /*Ensure the first token is an EOB run.*/ - old_tok2=_enc->dct_tokens[pli][zzi][0]; - if(old_tok2>=OC_NDCT_EOB_TOKEN_MAX)continue; - /*Search for a previous coefficient that has any tokens at all.*/ - old_tok1=OC_NDCT_EOB_TOKEN_MAX; - for(zzj=zzi,plj=pli;zzj>=0;zzj--){ - while(plj-->0){ - ti=_enc->ndct_tokens[plj][zzj]-1; - if(ti>=_enc->dct_token_offs[plj][zzj]){ - old_tok1=_enc->dct_tokens[plj][zzj][ti]; - break; - } - } - if(plj>=0)break; - plj=3; - } - /*Ensure its last token was an EOB run.*/ - if(old_tok1>=OC_NDCT_EOB_TOKEN_MAX)continue; - /*Pull off the associated extra bits, if any, and decode the runs.*/ - old_eb1=_enc->extra_bits[plj][zzj][ti]; - old_eb2=_enc->extra_bits[pli][zzi][0]; - run_count=oc_decode_eob_token(old_tok1,old_eb1) - +oc_decode_eob_token(old_tok2,old_eb2); - /*We can't possibly combine these into one run. - It might be possible to split them more optimally, but we'll just leave - them as-is.*/ - if(run_count>=4096)continue; - /*We CAN combine them into one run.*/ - new_tok=oc_make_eob_token_full(run_count,&new_eb); - _enc->dct_tokens[plj][zzj][ti]=(unsigned char)new_tok; - _enc->extra_bits[plj][zzj][ti]=(ogg_uint16_t)new_eb; - _enc->dct_token_offs[pli][zzi]++; - } -} diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxencfrag.c b/src/add-ons/media/plugins/theora/libtheora/x86/mmxencfrag.c deleted file mode 100644 index c79ff01fcc..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxencfrag.c +++ /dev/null @@ -1,900 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: dsp_mmx.c 14579 2008-03-12 06:42:40Z xiphmont $ - - ********************************************************************/ -#include -#include "x86enc.h" - -#if defined(OC_X86_ASM) - -unsigned oc_enc_frag_sad_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride){ - ptrdiff_t ystride3; - ptrdiff_t ret; - __asm__ __volatile__( - /*Load the first 4 rows of each block.*/ - "movq (%[src]),%%mm0\n\t" - "movq (%[ref]),%%mm1\n\t" - "movq (%[src],%[ystride]),%%mm2\n\t" - "movq (%[ref],%[ystride]),%%mm3\n\t" - "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" - "movq (%[src],%[ystride],2),%%mm4\n\t" - "movq (%[ref],%[ystride],2),%%mm5\n\t" - "movq (%[src],%[ystride3]),%%mm6\n\t" - "movq (%[ref],%[ystride3]),%%mm7\n\t" - /*Compute their SADs and add them in %%mm0*/ - "psadbw %%mm1,%%mm0\n\t" - "psadbw %%mm3,%%mm2\n\t" - "lea (%[src],%[ystride],4),%[src]\n\t" - "paddw %%mm2,%%mm0\n\t" - "lea (%[ref],%[ystride],4),%[ref]\n\t" - /*Load the next 3 rows as registers become available.*/ - "movq (%[src]),%%mm2\n\t" - "movq (%[ref]),%%mm3\n\t" - "psadbw %%mm5,%%mm4\n\t" - "psadbw %%mm7,%%mm6\n\t" - "paddw %%mm4,%%mm0\n\t" - "movq (%[ref],%[ystride]),%%mm5\n\t" - "movq (%[src],%[ystride]),%%mm4\n\t" - "paddw %%mm6,%%mm0\n\t" - "movq (%[ref],%[ystride],2),%%mm7\n\t" - "movq (%[src],%[ystride],2),%%mm6\n\t" - /*Start adding their SADs to %%mm0*/ - "psadbw %%mm3,%%mm2\n\t" - "psadbw %%mm5,%%mm4\n\t" - "paddw %%mm2,%%mm0\n\t" - "psadbw %%mm7,%%mm6\n\t" - /*Load last row as registers become available.*/ - "movq (%[src],%[ystride3]),%%mm2\n\t" - "movq (%[ref],%[ystride3]),%%mm3\n\t" - /*And finish adding up their SADs.*/ - "paddw %%mm4,%%mm0\n\t" - "psadbw %%mm3,%%mm2\n\t" - "paddw %%mm6,%%mm0\n\t" - "paddw %%mm2,%%mm0\n\t" - "movd %%mm0,%[ret]\n\t" - :[ret]"=a"(ret),[src]"+%r"(_src),[ref]"+r"(_ref),[ystride3]"=&r"(ystride3) - :[ystride]"r"((ptrdiff_t)_ystride) - ); - return (unsigned)ret; -} - -unsigned oc_enc_frag_sad_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ - /*Early termination is for suckers.*/ - return oc_enc_frag_sad_mmxext(_src,_ref,_ystride); -} - -/*Assumes the first two rows of %[ref1] and %[ref2] are in %%mm0...%%mm3, the - first two rows of %[src] are in %%mm4,%%mm5, and {1}x8 is in %%mm7. - We pre-load the next two rows of data as registers become available.*/ -#define OC_SAD2_LOOP \ - "#OC_SAD2_LOOP\n\t" \ - /*We want to compute (%%mm0+%%mm1>>1) on unsigned bytes without overflow, but \ - pavgb computes (%%mm0+%%mm1+1>>1). \ - The latter is exactly 1 too large when the low bit of two corresponding \ - bytes is only set in one of them. \ - Therefore we pxor the operands, pand to mask out the low bits, and psubb to \ - correct the output of pavgb.*/ \ - "movq %%mm0,%%mm6\n\t" \ - "lea (%[ref1],%[ystride],2),%[ref1]\n\t" \ - "pxor %%mm1,%%mm0\n\t" \ - "pavgb %%mm1,%%mm6\n\t" \ - "lea (%[ref2],%[ystride],2),%[ref2]\n\t" \ - "movq %%mm2,%%mm1\n\t" \ - "pand %%mm7,%%mm0\n\t" \ - "pavgb %%mm3,%%mm2\n\t" \ - "pxor %%mm3,%%mm1\n\t" \ - "movq (%[ref2],%[ystride]),%%mm3\n\t" \ - "psubb %%mm0,%%mm6\n\t" \ - "movq (%[ref1]),%%mm0\n\t" \ - "pand %%mm7,%%mm1\n\t" \ - "psadbw %%mm6,%%mm4\n\t" \ - "movd %[ret],%%mm6\n\t" \ - "psubb %%mm1,%%mm2\n\t" \ - "movq (%[ref2]),%%mm1\n\t" \ - "lea (%[src],%[ystride],2),%[src]\n\t" \ - "psadbw %%mm2,%%mm5\n\t" \ - "movq (%[ref1],%[ystride]),%%mm2\n\t" \ - "paddw %%mm4,%%mm5\n\t" \ - "movq (%[src]),%%mm4\n\t" \ - "paddw %%mm5,%%mm6\n\t" \ - "movq (%[src],%[ystride]),%%mm5\n\t" \ - "movd %%mm6,%[ret]\n\t" \ - -/*Same as above, but does not pre-load the next two rows.*/ -#define OC_SAD2_TAIL \ - "#OC_SAD2_TAIL\n\t" \ - "movq %%mm0,%%mm6\n\t" \ - "pavgb %%mm1,%%mm0\n\t" \ - "pxor %%mm1,%%mm6\n\t" \ - "movq %%mm2,%%mm1\n\t" \ - "pand %%mm7,%%mm6\n\t" \ - "pavgb %%mm3,%%mm2\n\t" \ - "pxor %%mm3,%%mm1\n\t" \ - "psubb %%mm6,%%mm0\n\t" \ - "pand %%mm7,%%mm1\n\t" \ - "psadbw %%mm0,%%mm4\n\t" \ - "psubb %%mm1,%%mm2\n\t" \ - "movd %[ret],%%mm6\n\t" \ - "psadbw %%mm2,%%mm5\n\t" \ - "paddw %%mm4,%%mm5\n\t" \ - "paddw %%mm5,%%mm6\n\t" \ - "movd %%mm6,%[ret]\n\t" \ - -unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ - ptrdiff_t ret; - __asm__ __volatile__( - "movq (%[ref1]),%%mm0\n\t" - "movq (%[ref2]),%%mm1\n\t" - "movq (%[ref1],%[ystride]),%%mm2\n\t" - "movq (%[ref2],%[ystride]),%%mm3\n\t" - "xor %[ret],%[ret]\n\t" - "movq (%[src]),%%mm4\n\t" - "pxor %%mm7,%%mm7\n\t" - "pcmpeqb %%mm6,%%mm6\n\t" - "movq (%[src],%[ystride]),%%mm5\n\t" - "psubb %%mm6,%%mm7\n\t" - OC_SAD2_LOOP - OC_SAD2_LOOP - OC_SAD2_LOOP - OC_SAD2_TAIL - :[ret]"=&a"(ret),[src]"+r"(_src),[ref1]"+%r"(_ref1),[ref2]"+r"(_ref2) - :[ystride]"r"((ptrdiff_t)_ystride) - ); - return (unsigned)ret; -} - -/*Load an 8x4 array of pixel values from %[src] and %[ref] and compute their - 16-bit difference in %%mm0...%%mm7.*/ -#define OC_LOAD_SUB_8x4(_off) \ - "#OC_LOAD_SUB_8x4\n\t" \ - "movd "_off"(%[src]),%%mm0\n\t" \ - "movd "_off"(%[ref]),%%mm4\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm1\n\t" \ - "lea (%[src],%[src_ystride],2),%[src]\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm5\n\t" \ - "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ - "movd "_off"(%[src]),%%mm2\n\t" \ - "movd "_off"(%[ref]),%%mm7\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm3\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm6\n\t" \ - "punpcklbw %%mm4,%%mm0\n\t" \ - "lea (%[src],%[src_ystride],2),%[src]\n\t" \ - "punpcklbw %%mm4,%%mm4\n\t" \ - "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ - "psubw %%mm4,%%mm0\n\t" \ - "movd "_off"(%[src]),%%mm4\n\t" \ - "movq %%mm0,"_off"*2(%[buf])\n\t" \ - "movd "_off"(%[ref]),%%mm0\n\t" \ - "punpcklbw %%mm5,%%mm1\n\t" \ - "punpcklbw %%mm5,%%mm5\n\t" \ - "psubw %%mm5,%%mm1\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm5\n\t" \ - "punpcklbw %%mm7,%%mm2\n\t" \ - "punpcklbw %%mm7,%%mm7\n\t" \ - "psubw %%mm7,%%mm2\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm7\n\t" \ - "punpcklbw %%mm6,%%mm3\n\t" \ - "lea (%[src],%[src_ystride],2),%[src]\n\t" \ - "punpcklbw %%mm6,%%mm6\n\t" \ - "psubw %%mm6,%%mm3\n\t" \ - "movd "_off"(%[src]),%%mm6\n\t" \ - "punpcklbw %%mm0,%%mm4\n\t" \ - "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ - "punpcklbw %%mm0,%%mm0\n\t" \ - "lea (%[src],%[src_ystride],2),%[src]\n\t" \ - "psubw %%mm0,%%mm4\n\t" \ - "movd "_off"(%[ref]),%%mm0\n\t" \ - "punpcklbw %%mm7,%%mm5\n\t" \ - "neg %[src_ystride]\n\t" \ - "punpcklbw %%mm7,%%mm7\n\t" \ - "psubw %%mm7,%%mm5\n\t" \ - "movd "_off"(%[src],%[src_ystride]),%%mm7\n\t" \ - "punpcklbw %%mm0,%%mm6\n\t" \ - "lea (%[ref],%[ref_ystride],2),%[ref]\n\t" \ - "punpcklbw %%mm0,%%mm0\n\t" \ - "neg %[ref_ystride]\n\t" \ - "psubw %%mm0,%%mm6\n\t" \ - "movd "_off"(%[ref],%[ref_ystride]),%%mm0\n\t" \ - "lea (%[src],%[src_ystride],8),%[src]\n\t" \ - "punpcklbw %%mm0,%%mm7\n\t" \ - "neg %[src_ystride]\n\t" \ - "punpcklbw %%mm0,%%mm0\n\t" \ - "lea (%[ref],%[ref_ystride],8),%[ref]\n\t" \ - "psubw %%mm0,%%mm7\n\t" \ - "neg %[ref_ystride]\n\t" \ - "movq "_off"*2(%[buf]),%%mm0\n\t" \ - -/*Load an 8x4 array of pixel values from %[src] into %%mm0...%%mm7.*/ -#define OC_LOAD_8x4(_off) \ - "#OC_LOAD_8x4\n\t" \ - "movd "_off"(%[src]),%%mm0\n\t" \ - "movd "_off"(%[src],%[ystride]),%%mm1\n\t" \ - "movd "_off"(%[src],%[ystride],2),%%mm2\n\t" \ - "pxor %%mm7,%%mm7\n\t" \ - "movd "_off"(%[src],%[ystride3]),%%mm3\n\t" \ - "punpcklbw %%mm7,%%mm0\n\t" \ - "movd "_off"(%[src4]),%%mm4\n\t" \ - "punpcklbw %%mm7,%%mm1\n\t" \ - "movd "_off"(%[src4],%[ystride]),%%mm5\n\t" \ - "punpcklbw %%mm7,%%mm2\n\t" \ - "movd "_off"(%[src4],%[ystride],2),%%mm6\n\t" \ - "punpcklbw %%mm7,%%mm3\n\t" \ - "movd "_off"(%[src4],%[ystride3]),%%mm7\n\t" \ - "punpcklbw %%mm4,%%mm4\n\t" \ - "punpcklbw %%mm5,%%mm5\n\t" \ - "psrlw $8,%%mm4\n\t" \ - "psrlw $8,%%mm5\n\t" \ - "punpcklbw %%mm6,%%mm6\n\t" \ - "punpcklbw %%mm7,%%mm7\n\t" \ - "psrlw $8,%%mm6\n\t" \ - "psrlw $8,%%mm7\n\t" \ - -/*Performs the first two stages of an 8-point 1-D Hadamard transform. - The transform is performed in place, except that outputs 0-3 are swapped with - outputs 4-7. - Outputs 2, 3, 6 and 7 from the second stage are negated (which allows us to - perform this stage in place with no temporary registers).*/ -#define OC_HADAMARD_AB_8x4 \ - "#OC_HADAMARD_AB_8x4\n\t" \ - /*Stage A: \ - Outputs 0-3 are swapped with 4-7 here.*/ \ - "paddw %%mm1,%%mm5\n\t" \ - "paddw %%mm2,%%mm6\n\t" \ - "paddw %%mm1,%%mm1\n\t" \ - "paddw %%mm2,%%mm2\n\t" \ - "psubw %%mm5,%%mm1\n\t" \ - "psubw %%mm6,%%mm2\n\t" \ - "paddw %%mm3,%%mm7\n\t" \ - "paddw %%mm0,%%mm4\n\t" \ - "paddw %%mm3,%%mm3\n\t" \ - "paddw %%mm0,%%mm0\n\t" \ - "psubw %%mm7,%%mm3\n\t" \ - "psubw %%mm4,%%mm0\n\t" \ - /*Stage B:*/ \ - "paddw %%mm2,%%mm0\n\t" \ - "paddw %%mm3,%%mm1\n\t" \ - "paddw %%mm6,%%mm4\n\t" \ - "paddw %%mm7,%%mm5\n\t" \ - "paddw %%mm2,%%mm2\n\t" \ - "paddw %%mm3,%%mm3\n\t" \ - "paddw %%mm6,%%mm6\n\t" \ - "paddw %%mm7,%%mm7\n\t" \ - "psubw %%mm0,%%mm2\n\t" \ - "psubw %%mm1,%%mm3\n\t" \ - "psubw %%mm4,%%mm6\n\t" \ - "psubw %%mm5,%%mm7\n\t" \ - -/*Performs the last stage of an 8-point 1-D Hadamard transform in place. - Ouputs 1, 3, 5, and 7 are negated (which allows us to perform this stage in - place with no temporary registers).*/ -#define OC_HADAMARD_C_8x4 \ - "#OC_HADAMARD_C_8x4\n\t" \ - /*Stage C:*/ \ - "paddw %%mm1,%%mm0\n\t" \ - "paddw %%mm3,%%mm2\n\t" \ - "paddw %%mm5,%%mm4\n\t" \ - "paddw %%mm7,%%mm6\n\t" \ - "paddw %%mm1,%%mm1\n\t" \ - "paddw %%mm3,%%mm3\n\t" \ - "paddw %%mm5,%%mm5\n\t" \ - "paddw %%mm7,%%mm7\n\t" \ - "psubw %%mm0,%%mm1\n\t" \ - "psubw %%mm2,%%mm3\n\t" \ - "psubw %%mm4,%%mm5\n\t" \ - "psubw %%mm6,%%mm7\n\t" \ - -/*Performs an 8-point 1-D Hadamard transform. - The transform is performed in place, except that outputs 0-3 are swapped with - outputs 4-7. - Outputs 1, 2, 5 and 6 are negated (which allows us to perform the transform - in place with no temporary registers).*/ -#define OC_HADAMARD_8x4 \ - OC_HADAMARD_AB_8x4 \ - OC_HADAMARD_C_8x4 \ - -/*Performs the first part of the final stage of the Hadamard transform and - summing of absolute values. - At the end of this part, %%mm1 will contain the DC coefficient of the - transform.*/ -#define OC_HADAMARD_C_ABS_ACCUM_A_8x4(_r6,_r7) \ - /*We use the fact that \ - (abs(a+b)+abs(a-b))/2=max(abs(a),abs(b)) \ - to merge the final butterfly with the abs and the first stage of \ - accumulation. \ - Thus we can avoid using pabsw, which is not available until SSSE3. \ - Emulating pabsw takes 3 instructions, so the straightforward MMXEXT \ - implementation would be (3+3)*8+7=55 instructions (+4 for spilling \ - registers). \ - Even with pabsw, it would be (3+1)*8+7=39 instructions (with no spills). \ - This implementation is only 26 (+4 for spilling registers).*/ \ - "#OC_HADAMARD_C_ABS_ACCUM_A_8x4\n\t" \ - "movq %%mm7,"_r7"(%[buf])\n\t" \ - "movq %%mm6,"_r6"(%[buf])\n\t" \ - /*mm7={0x7FFF}x4 \ - mm0=max(abs(mm0),abs(mm1))-0x7FFF*/ \ - "pcmpeqb %%mm7,%%mm7\n\t" \ - "movq %%mm0,%%mm6\n\t" \ - "psrlw $1,%%mm7\n\t" \ - "paddw %%mm1,%%mm6\n\t" \ - "pmaxsw %%mm1,%%mm0\n\t" \ - "paddsw %%mm7,%%mm6\n\t" \ - "psubw %%mm6,%%mm0\n\t" \ - /*mm2=max(abs(mm2),abs(mm3))-0x7FFF \ - mm4=max(abs(mm4),abs(mm5))-0x7FFF*/ \ - "movq %%mm2,%%mm6\n\t" \ - "movq %%mm4,%%mm1\n\t" \ - "pmaxsw %%mm3,%%mm2\n\t" \ - "pmaxsw %%mm5,%%mm4\n\t" \ - "paddw %%mm3,%%mm6\n\t" \ - "paddw %%mm5,%%mm1\n\t" \ - "movq "_r7"(%[buf]),%%mm3\n\t" \ - -/*Performs the second part of the final stage of the Hadamard transform and - summing of absolute values.*/ -#define OC_HADAMARD_C_ABS_ACCUM_B_8x4(_r6,_r7) \ - "#OC_HADAMARD_C_ABS_ACCUM_B_8x4\n\t" \ - "paddsw %%mm7,%%mm6\n\t" \ - "movq "_r6"(%[buf]),%%mm5\n\t" \ - "paddsw %%mm7,%%mm1\n\t" \ - "psubw %%mm6,%%mm2\n\t" \ - "psubw %%mm1,%%mm4\n\t" \ - /*mm7={1}x4 (needed for the horizontal add that follows) \ - mm0+=mm2+mm4+max(abs(mm3),abs(mm5))-0x7FFF*/ \ - "movq %%mm3,%%mm6\n\t" \ - "pmaxsw %%mm5,%%mm3\n\t" \ - "paddw %%mm2,%%mm0\n\t" \ - "paddw %%mm5,%%mm6\n\t" \ - "paddw %%mm4,%%mm0\n\t" \ - "paddsw %%mm7,%%mm6\n\t" \ - "paddw %%mm3,%%mm0\n\t" \ - "psrlw $14,%%mm7\n\t" \ - "psubw %%mm6,%%mm0\n\t" \ - -/*Performs the last stage of an 8-point 1-D Hadamard transform, takes the - absolute value of each component, and accumulates everything into mm0. - This is the only portion of SATD which requires MMXEXT (we could use plain - MMX, but it takes 4 instructions and an extra register to work around the - lack of a pmaxsw, which is a pretty serious penalty).*/ -#define OC_HADAMARD_C_ABS_ACCUM_8x4(_r6,_r7) \ - OC_HADAMARD_C_ABS_ACCUM_A_8x4(_r6,_r7) \ - OC_HADAMARD_C_ABS_ACCUM_B_8x4(_r6,_r7) \ - -/*Performs an 8-point 1-D Hadamard transform, takes the absolute value of each - component, and accumulates everything into mm0. - Note that mm0 will have an extra 4 added to each column, and that after - removing this value, the remainder will be half the conventional value.*/ -#define OC_HADAMARD_ABS_ACCUM_8x4(_r6,_r7) \ - OC_HADAMARD_AB_8x4 \ - OC_HADAMARD_C_ABS_ACCUM_8x4(_r6,_r7) - -/*Performs two 4x4 transposes (mostly) in place. - On input, {mm0,mm1,mm2,mm3} contains rows {e,f,g,h}, and {mm4,mm5,mm6,mm7} - contains rows {a,b,c,d}. - On output, {0x40,0x50,0x60,0x70}+_off(%[buf]) contains {e,f,g,h}^T, and - {mm4,mm5,mm6,mm7} contains the transposed rows {a,b,c,d}^T.*/ -#define OC_TRANSPOSE_4x4x2(_off) \ - "#OC_TRANSPOSE_4x4x2\n\t" \ - /*First 4x4 transpose:*/ \ - "movq %%mm5,0x10+"_off"(%[buf])\n\t" \ - /*mm0 = e3 e2 e1 e0 \ - mm1 = f3 f2 f1 f0 \ - mm2 = g3 g2 g1 g0 \ - mm3 = h3 h2 h1 h0*/ \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklwd %%mm3,%%mm2\n\t" \ - "punpckhwd %%mm3,%%mm5\n\t" \ - "movq %%mm0,%%mm3\n\t" \ - "punpcklwd %%mm1,%%mm0\n\t" \ - "punpckhwd %%mm1,%%mm3\n\t" \ - /*mm0 = f1 e1 f0 e0 \ - mm3 = f3 e3 f2 e2 \ - mm2 = h1 g1 h0 g0 \ - mm5 = h3 g3 h2 g2*/ \ - "movq %%mm0,%%mm1\n\t" \ - "punpckldq %%mm2,%%mm0\n\t" \ - "punpckhdq %%mm2,%%mm1\n\t" \ - "movq %%mm3,%%mm2\n\t" \ - "punpckhdq %%mm5,%%mm3\n\t" \ - "movq %%mm0,0x40+"_off"(%[buf])\n\t" \ - "punpckldq %%mm5,%%mm2\n\t" \ - /*mm0 = h0 g0 f0 e0 \ - mm1 = h1 g1 f1 e1 \ - mm2 = h2 g2 f2 e2 \ - mm3 = h3 g3 f3 e3*/ \ - "movq 0x10+"_off"(%[buf]),%%mm5\n\t" \ - /*Second 4x4 transpose:*/ \ - /*mm4 = a3 a2 a1 a0 \ - mm5 = b3 b2 b1 b0 \ - mm6 = c3 c2 c1 c0 \ - mm7 = d3 d2 d1 d0*/ \ - "movq %%mm6,%%mm0\n\t" \ - "punpcklwd %%mm7,%%mm6\n\t" \ - "movq %%mm1,0x50+"_off"(%[buf])\n\t" \ - "punpckhwd %%mm7,%%mm0\n\t" \ - "movq %%mm4,%%mm7\n\t" \ - "punpcklwd %%mm5,%%mm4\n\t" \ - "movq %%mm2,0x60+"_off"(%[buf])\n\t" \ - "punpckhwd %%mm5,%%mm7\n\t" \ - /*mm4 = b1 a1 b0 a0 \ - mm7 = b3 a3 b2 a2 \ - mm6 = d1 c1 d0 c0 \ - mm0 = d3 c3 d2 c2*/ \ - "movq %%mm4,%%mm5\n\t" \ - "punpckldq %%mm6,%%mm4\n\t" \ - "movq %%mm3,0x70+"_off"(%[buf])\n\t" \ - "punpckhdq %%mm6,%%mm5\n\t" \ - "movq %%mm7,%%mm6\n\t" \ - "punpckhdq %%mm0,%%mm7\n\t" \ - "punpckldq %%mm0,%%mm6\n\t" \ - /*mm4 = d0 c0 b0 a0 \ - mm5 = d1 c1 b1 a1 \ - mm6 = d2 c2 b2 a2 \ - mm7 = d3 c3 b3 a3*/ \ - -static unsigned oc_int_frag_satd_thresh_mmxext(const unsigned char *_src, - int _src_ystride,const unsigned char *_ref,int _ref_ystride,unsigned _thresh){ - OC_ALIGN8(ogg_int16_t buf[64]); - ogg_int16_t *bufp; - unsigned ret; - unsigned ret2; - bufp=buf; - __asm__ __volatile__( - OC_LOAD_SUB_8x4("0x00") - OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x00") - /*Finish swapping out this 8x4 block to make room for the next one. - mm0...mm3 have been swapped out already.*/ - "movq %%mm4,0x00(%[buf])\n\t" - "movq %%mm5,0x10(%[buf])\n\t" - "movq %%mm6,0x20(%[buf])\n\t" - "movq %%mm7,0x30(%[buf])\n\t" - OC_LOAD_SUB_8x4("0x04") - OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x08") - /*Here the first 4x4 block of output from the last transpose is the second - 4x4 block of input for the next transform. - We have cleverly arranged that it already be in the appropriate place, so - we only have to do half the loads.*/ - "movq 0x10(%[buf]),%%mm1\n\t" - "movq 0x20(%[buf]),%%mm2\n\t" - "movq 0x30(%[buf]),%%mm3\n\t" - "movq 0x00(%[buf]),%%mm0\n\t" - OC_HADAMARD_ABS_ACCUM_8x4("0x28","0x38") - /*Up to this point, everything fit in 16 bits (8 input + 1 for the - difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 - for the factor of two we dropped + 3 for the vertical accumulation). - Now we finally have to promote things to dwords. - We break this part out of OC_HADAMARD_ABS_ACCUM_8x4 to hide the long - latency of pmaddwd by starting the next series of loads now.*/ - "mov %[thresh],%[ret2]\n\t" - "pmaddwd %%mm7,%%mm0\n\t" - "movq 0x50(%[buf]),%%mm1\n\t" - "movq 0x58(%[buf]),%%mm5\n\t" - "movq %%mm0,%%mm4\n\t" - "movq 0x60(%[buf]),%%mm2\n\t" - "punpckhdq %%mm0,%%mm0\n\t" - "movq 0x68(%[buf]),%%mm6\n\t" - "paddd %%mm0,%%mm4\n\t" - "movq 0x70(%[buf]),%%mm3\n\t" - "movd %%mm4,%[ret]\n\t" - "movq 0x78(%[buf]),%%mm7\n\t" - /*The sums produced by OC_HADAMARD_ABS_ACCUM_8x4 each have an extra 4 - added to them, and a factor of two removed; correct the final sum here.*/ - "lea -32(%[ret],%[ret]),%[ret]\n\t" - "movq 0x40(%[buf]),%%mm0\n\t" - "cmp %[ret2],%[ret]\n\t" - "movq 0x48(%[buf]),%%mm4\n\t" - "jae 1f\n\t" - OC_HADAMARD_ABS_ACCUM_8x4("0x68","0x78") - "pmaddwd %%mm7,%%mm0\n\t" - /*There isn't much to stick in here to hide the latency this time, but the - alternative to pmaddwd is movq->punpcklwd->punpckhwd->paddd, whose - latency is even worse.*/ - "sub $32,%[ret]\n\t" - "movq %%mm0,%%mm4\n\t" - "punpckhdq %%mm0,%%mm0\n\t" - "paddd %%mm0,%%mm4\n\t" - "movd %%mm4,%[ret2]\n\t" - "lea (%[ret],%[ret2],2),%[ret]\n\t" - ".p2align 4,,15\n\t" - "1:\n\t" - /*Although it looks like we're using 7 registers here, gcc can alias %[ret] - and %[ret2] with some of the inputs, since for once we don't write to - them until after we're done using everything but %[buf] (which is also - listed as an output to ensure gcc _doesn't_ alias them against it).*/ - /*Note that _src_ystride and _ref_ystride must be given non-overlapping - constraints, otherewise if gcc can prove they're equal it will allocate - them to the same register (which is bad); _src and _ref face a similar - problem, though those are never actually the same.*/ - :[ret]"=a"(ret),[ret2]"=r"(ret2),[buf]"+r"(bufp) - :[src]"r"(_src),[src_ystride]"c"((ptrdiff_t)_src_ystride), - [ref]"r"(_ref),[ref_ystride]"d"((ptrdiff_t)_ref_ystride), - [thresh]"m"(_thresh) - /*We have to use neg, so we actually clobber the condition codes for once - (not to mention cmp, sub, and add).*/ - :"cc" - ); - return ret; -} - -unsigned oc_enc_frag_satd_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh){ - return oc_int_frag_satd_thresh_mmxext(_src,_ystride,_ref,_ystride,_thresh); -} - -/*Our internal implementation of frag_copy2 takes an extra stride parameter so - we can share code with oc_enc_frag_satd2_thresh_mmxext().*/ -static void oc_int_frag_copy2_mmxext(unsigned char *_dst,int _dst_ystride, - const unsigned char *_src1,const unsigned char *_src2,int _src_ystride){ - __asm__ __volatile__( - /*Load the first 3 rows.*/ - "movq (%[src1]),%%mm0\n\t" - "movq (%[src2]),%%mm1\n\t" - "movq (%[src1],%[src_ystride]),%%mm2\n\t" - "lea (%[src1],%[src_ystride],2),%[src1]\n\t" - "movq (%[src2],%[src_ystride]),%%mm3\n\t" - "lea (%[src2],%[src_ystride],2),%[src2]\n\t" - "pxor %%mm7,%%mm7\n\t" - "movq (%[src1]),%%mm4\n\t" - "pcmpeqb %%mm6,%%mm6\n\t" - "movq (%[src2]),%%mm5\n\t" - /*mm7={1}x8.*/ - "psubb %%mm6,%%mm7\n\t" - /*Start averaging %%mm0 and %%mm1 into %%mm6.*/ - "movq %%mm0,%%mm6\n\t" - "pxor %%mm1,%%mm0\n\t" - "pavgb %%mm1,%%mm6\n\t" - /*%%mm1 is free, start averaging %%mm3 into %%mm2 using %%mm1.*/ - "movq %%mm2,%%mm1\n\t" - "pand %%mm7,%%mm0\n\t" - "pavgb %%mm3,%%mm2\n\t" - "pxor %%mm3,%%mm1\n\t" - /*%%mm3 is free.*/ - "psubb %%mm0,%%mm6\n\t" - /*%%mm0 is free, start loading the next row.*/ - "movq (%[src1],%[src_ystride]),%%mm0\n\t" - /*Start averaging %%mm5 and %%mm4 using %%mm3.*/ - "movq %%mm4,%%mm3\n\t" - /*%%mm6 (row 0) is done; write it out.*/ - "movq %%mm6,(%[dst])\n\t" - "pand %%mm7,%%mm1\n\t" - "pavgb %%mm5,%%mm4\n\t" - "psubb %%mm1,%%mm2\n\t" - /*%%mm1 is free, continue loading the next row.*/ - "movq (%[src2],%[src_ystride]),%%mm1\n\t" - "pxor %%mm5,%%mm3\n\t" - "lea (%[src1],%[src_ystride],2),%[src1]\n\t" - /*%%mm2 (row 1) is done; write it out.*/ - "movq %%mm2,(%[dst],%[dst_ystride])\n\t" - "pand %%mm7,%%mm3\n\t" - /*Start loading the next row.*/ - "movq (%[src1]),%%mm2\n\t" - "lea (%[dst],%[dst_ystride],2),%[dst]\n\t" - "psubb %%mm3,%%mm4\n\t" - "lea (%[src2],%[src_ystride],2),%[src2]\n\t" - /*%%mm4 (row 2) is done; write it out.*/ - "movq %%mm4,(%[dst])\n\t" - /*Continue loading the next row.*/ - "movq (%[src2]),%%mm3\n\t" - /*Start averaging %%mm0 and %%mm1 into %%mm6.*/ - "movq %%mm0,%%mm6\n\t" - "pxor %%mm1,%%mm0\n\t" - /*Start loading the next row.*/ - "movq (%[src1],%[src_ystride]),%%mm4\n\t" - "pavgb %%mm1,%%mm6\n\t" - /*%%mm1 is free; start averaging %%mm3 into %%mm2 using %%mm1.*/ - "movq %%mm2,%%mm1\n\t" - "pand %%mm7,%%mm0\n\t" - /*Continue loading the next row.*/ - "movq (%[src2],%[src_ystride]),%%mm5\n\t" - "pavgb %%mm3,%%mm2\n\t" - "lea (%[src1],%[src_ystride],2),%[src1]\n\t" - "pxor %%mm3,%%mm1\n\t" - /*%%mm3 is free.*/ - "psubb %%mm0,%%mm6\n\t" - /*%%mm0 is free, start loading the next row.*/ - "movq (%[src1]),%%mm0\n\t" - /*Start averaging %%mm5 into %%mm4 using %%mm3.*/ - "movq %%mm4,%%mm3\n\t" - /*%%mm6 (row 3) is done; write it out.*/ - "movq %%mm6,(%[dst],%[dst_ystride])\n\t" - "pand %%mm7,%%mm1\n\t" - "lea (%[src2],%[src_ystride],2),%[src2]\n\t" - "pavgb %%mm5,%%mm4\n\t" - "lea (%[dst],%[dst_ystride],2),%[dst]\n\t" - "psubb %%mm1,%%mm2\n\t" - /*%%mm1 is free; continue loading the next row.*/ - "movq (%[src2]),%%mm1\n\t" - "pxor %%mm5,%%mm3\n\t" - /*%%mm2 (row 4) is done; write it out.*/ - "movq %%mm2,(%[dst])\n\t" - "pand %%mm7,%%mm3\n\t" - /*Start loading the next row.*/ - "movq (%[src1],%[src_ystride]),%%mm2\n\t" - "psubb %%mm3,%%mm4\n\t" - /*Start averaging %%mm0 and %%mm1 into %%mm6.*/ - "movq %%mm0,%%mm6\n\t" - /*Continue loading the next row.*/ - "movq (%[src2],%[src_ystride]),%%mm3\n\t" - /*%%mm4 (row 5) is done; write it out.*/ - "movq %%mm4,(%[dst],%[dst_ystride])\n\t" - "pxor %%mm1,%%mm0\n\t" - "pavgb %%mm1,%%mm6\n\t" - /*%%mm4 is free; start averaging %%mm3 into %%mm2 using %%mm4.*/ - "movq %%mm2,%%mm4\n\t" - "pand %%mm7,%%mm0\n\t" - "pavgb %%mm3,%%mm2\n\t" - "pxor %%mm3,%%mm4\n\t" - "lea (%[dst],%[dst_ystride],2),%[dst]\n\t" - "psubb %%mm0,%%mm6\n\t" - "pand %%mm7,%%mm4\n\t" - /*%%mm6 (row 6) is done, write it out.*/ - "movq %%mm6,(%[dst])\n\t" - "psubb %%mm4,%%mm2\n\t" - /*%%mm2 (row 7) is done, write it out.*/ - "movq %%mm2,(%[dst],%[dst_ystride])\n\t" - :[dst]"+r"(_dst),[src1]"+%r"(_src1),[src2]"+r"(_src2) - :[dst_ystride]"r"((ptrdiff_t)_dst_ystride), - [src_ystride]"r"((ptrdiff_t)_src_ystride) - :"memory" - ); -} - -unsigned oc_enc_frag_satd2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh){ - OC_ALIGN8(unsigned char ref[64]); - oc_int_frag_copy2_mmxext(ref,8,_ref1,_ref2,_ystride); - return oc_int_frag_satd_thresh_mmxext(_src,_ystride,ref,8,_thresh); -} - -unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src, - int _ystride){ - OC_ALIGN8(ogg_int16_t buf[64]); - ogg_int16_t *bufp; - unsigned ret; - unsigned ret2; - bufp=buf; - __asm__ __volatile__( - OC_LOAD_8x4("0x00") - OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x00") - /*Finish swapping out this 8x4 block to make room for the next one. - mm0...mm3 have been swapped out already.*/ - "movq %%mm4,0x00(%[buf])\n\t" - "movq %%mm5,0x10(%[buf])\n\t" - "movq %%mm6,0x20(%[buf])\n\t" - "movq %%mm7,0x30(%[buf])\n\t" - OC_LOAD_8x4("0x04") - OC_HADAMARD_8x4 - OC_TRANSPOSE_4x4x2("0x08") - /*Here the first 4x4 block of output from the last transpose is the second - 4x4 block of input for the next transform. - We have cleverly arranged that it already be in the appropriate place, so - we only have to do half the loads.*/ - "movq 0x10(%[buf]),%%mm1\n\t" - "movq 0x20(%[buf]),%%mm2\n\t" - "movq 0x30(%[buf]),%%mm3\n\t" - "movq 0x00(%[buf]),%%mm0\n\t" - /*We split out the stages here so we can save the DC coefficient in the - middle.*/ - OC_HADAMARD_AB_8x4 - OC_HADAMARD_C_ABS_ACCUM_A_8x4("0x28","0x38") - "movd %%mm1,%[ret]\n\t" - OC_HADAMARD_C_ABS_ACCUM_B_8x4("0x28","0x38") - /*Up to this point, everything fit in 16 bits (8 input + 1 for the - difference + 2*3 for the two 8-point 1-D Hadamards - 1 for the abs - 1 - for the factor of two we dropped + 3 for the vertical accumulation). - Now we finally have to promote things to dwords. - We break this part out of OC_HADAMARD_ABS_ACCUM_8x4 to hide the long - latency of pmaddwd by starting the next series of loads now.*/ - "pmaddwd %%mm7,%%mm0\n\t" - "movq 0x50(%[buf]),%%mm1\n\t" - "movq 0x58(%[buf]),%%mm5\n\t" - "movq 0x60(%[buf]),%%mm2\n\t" - "movq %%mm0,%%mm4\n\t" - "movq 0x68(%[buf]),%%mm6\n\t" - "punpckhdq %%mm0,%%mm0\n\t" - "movq 0x70(%[buf]),%%mm3\n\t" - "paddd %%mm0,%%mm4\n\t" - "movq 0x78(%[buf]),%%mm7\n\t" - "movd %%mm4,%[ret2]\n\t" - "movq 0x40(%[buf]),%%mm0\n\t" - "movq 0x48(%[buf]),%%mm4\n\t" - OC_HADAMARD_ABS_ACCUM_8x4("0x68","0x78") - "pmaddwd %%mm7,%%mm0\n\t" - /*We assume that the DC coefficient is always positive (which is true, - because the input to the INTRA transform was not a difference).*/ - "movzx %w[ret],%[ret]\n\t" - "add %[ret2],%[ret2]\n\t" - "sub %[ret],%[ret2]\n\t" - "movq %%mm0,%%mm4\n\t" - "punpckhdq %%mm0,%%mm0\n\t" - "paddd %%mm0,%%mm4\n\t" - "movd %%mm4,%[ret]\n\t" - "lea -64(%[ret2],%[ret],2),%[ret]\n\t" - /*Although it looks like we're using 7 registers here, gcc can alias %[ret] - and %[ret2] with some of the inputs, since for once we don't write to - them until after we're done using everything but %[buf] (which is also - listed as an output to ensure gcc _doesn't_ alias them against it).*/ - :[ret]"=a"(ret),[ret2]"=r"(ret2),[buf]"+r"(bufp) - :[src]"r"(_src),[src4]"r"(_src+4*_ystride), - [ystride]"r"((ptrdiff_t)_ystride),[ystride3]"r"((ptrdiff_t)3*_ystride) - /*We have to use sub, so we actually clobber the condition codes for once - (not to mention add).*/ - :"cc" - ); - return ret; -} - -void oc_enc_frag_sub_mmx(ogg_int16_t _residue[64], - const unsigned char *_src,const unsigned char *_ref,int _ystride){ - int i; - __asm__ __volatile__("pxor %%mm7,%%mm7\n\t"::); - for(i=4;i-->0;){ - __asm__ __volatile__( - /*mm0=[src]*/ - "movq (%[src]),%%mm0\n\t" - /*mm1=[ref]*/ - "movq (%[ref]),%%mm1\n\t" - /*mm4=[src+ystride]*/ - "movq (%[src],%[ystride]),%%mm4\n\t" - /*mm5=[ref+ystride]*/ - "movq (%[ref],%[ystride]),%%mm5\n\t" - /*Compute [src]-[ref].*/ - "movq %%mm0,%%mm2\n\t" - "punpcklbw %%mm7,%%mm0\n\t" - "movq %%mm1,%%mm3\n\t" - "punpckhbw %%mm7,%%mm2\n\t" - "punpcklbw %%mm7,%%mm1\n\t" - "punpckhbw %%mm7,%%mm3\n\t" - "psubw %%mm1,%%mm0\n\t" - "psubw %%mm3,%%mm2\n\t" - /*Compute [src+ystride]-[ref+ystride].*/ - "movq %%mm4,%%mm1\n\t" - "punpcklbw %%mm7,%%mm4\n\t" - "movq %%mm5,%%mm3\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "lea (%[src],%[ystride],2),%[src]\n\t" - "punpcklbw %%mm7,%%mm5\n\t" - "lea (%[ref],%[ystride],2),%[ref]\n\t" - "punpckhbw %%mm7,%%mm3\n\t" - "psubw %%mm5,%%mm4\n\t" - "psubw %%mm3,%%mm1\n\t" - /*Write the answer out.*/ - "movq %%mm0,0x00(%[residue])\n\t" - "movq %%mm2,0x08(%[residue])\n\t" - "movq %%mm4,0x10(%[residue])\n\t" - "movq %%mm1,0x18(%[residue])\n\t" - "lea 0x20(%[residue]),%[residue]\n\t" - :[residue]"+r"(_residue),[src]"+r"(_src),[ref]"+r"(_ref) - :[ystride]"r"((ptrdiff_t)_ystride) - :"memory" - ); - } -} - -void oc_enc_frag_sub_128_mmx(ogg_int16_t _residue[64], - const unsigned char *_src,int _ystride){ - ptrdiff_t ystride3; - __asm__ __volatile__( - /*mm0=[src]*/ - "movq (%[src]),%%mm0\n\t" - /*mm1=[src+ystride]*/ - "movq (%[src],%[ystride]),%%mm1\n\t" - /*mm6={-1}x4*/ - "pcmpeqw %%mm6,%%mm6\n\t" - /*mm2=[src+2*ystride]*/ - "movq (%[src],%[ystride],2),%%mm2\n\t" - /*[ystride3]=3*[ystride]*/ - "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" - /*mm6={1}x4*/ - "psllw $15,%%mm6\n\t" - /*mm3=[src+3*ystride]*/ - "movq (%[src],%[ystride3]),%%mm3\n\t" - /*mm6={128}x4*/ - "psrlw $8,%%mm6\n\t" - /*mm7=0*/ - "pxor %%mm7,%%mm7\n\t" - /*[src]=[src]+4*[ystride]*/ - "lea (%[src],%[ystride],4),%[src]\n\t" - /*Compute [src]-128 and [src+ystride]-128*/ - "movq %%mm0,%%mm4\n\t" - "punpcklbw %%mm7,%%mm0\n\t" - "movq %%mm1,%%mm5\n\t" - "punpckhbw %%mm7,%%mm4\n\t" - "psubw %%mm6,%%mm0\n\t" - "punpcklbw %%mm7,%%mm1\n\t" - "psubw %%mm6,%%mm4\n\t" - "punpckhbw %%mm7,%%mm5\n\t" - "psubw %%mm6,%%mm1\n\t" - "psubw %%mm6,%%mm5\n\t" - /*Write the answer out.*/ - "movq %%mm0,0x00(%[residue])\n\t" - "movq %%mm4,0x08(%[residue])\n\t" - "movq %%mm1,0x10(%[residue])\n\t" - "movq %%mm5,0x18(%[residue])\n\t" - /*mm0=[src+4*ystride]*/ - "movq (%[src]),%%mm0\n\t" - /*mm1=[src+5*ystride]*/ - "movq (%[src],%[ystride]),%%mm1\n\t" - /*Compute [src+2*ystride]-128 and [src+3*ystride]-128*/ - "movq %%mm2,%%mm4\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "movq %%mm3,%%mm5\n\t" - "punpckhbw %%mm7,%%mm4\n\t" - "psubw %%mm6,%%mm2\n\t" - "punpcklbw %%mm7,%%mm3\n\t" - "psubw %%mm6,%%mm4\n\t" - "punpckhbw %%mm7,%%mm5\n\t" - "psubw %%mm6,%%mm3\n\t" - "psubw %%mm6,%%mm5\n\t" - /*Write the answer out.*/ - "movq %%mm2,0x20(%[residue])\n\t" - "movq %%mm4,0x28(%[residue])\n\t" - "movq %%mm3,0x30(%[residue])\n\t" - "movq %%mm5,0x38(%[residue])\n\t" - /*mm2=[src+6*ystride]*/ - "movq (%[src],%[ystride],2),%%mm2\n\t" - /*mm3=[src+7*ystride]*/ - "movq (%[src],%[ystride3]),%%mm3\n\t" - /*Compute [src+4*ystride]-128 and [src+5*ystride]-128*/ - "movq %%mm0,%%mm4\n\t" - "punpcklbw %%mm7,%%mm0\n\t" - "movq %%mm1,%%mm5\n\t" - "punpckhbw %%mm7,%%mm4\n\t" - "psubw %%mm6,%%mm0\n\t" - "punpcklbw %%mm7,%%mm1\n\t" - "psubw %%mm6,%%mm4\n\t" - "punpckhbw %%mm7,%%mm5\n\t" - "psubw %%mm6,%%mm1\n\t" - "psubw %%mm6,%%mm5\n\t" - /*Write the answer out.*/ - "movq %%mm0,0x40(%[residue])\n\t" - "movq %%mm4,0x48(%[residue])\n\t" - "movq %%mm1,0x50(%[residue])\n\t" - "movq %%mm5,0x58(%[residue])\n\t" - /*Compute [src+6*ystride]-128 and [src+7*ystride]-128*/ - "movq %%mm2,%%mm4\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "movq %%mm3,%%mm5\n\t" - "punpckhbw %%mm7,%%mm4\n\t" - "psubw %%mm6,%%mm2\n\t" - "punpcklbw %%mm7,%%mm3\n\t" - "psubw %%mm6,%%mm4\n\t" - "punpckhbw %%mm7,%%mm5\n\t" - "psubw %%mm6,%%mm3\n\t" - "psubw %%mm6,%%mm5\n\t" - /*Write the answer out.*/ - "movq %%mm2,0x60(%[residue])\n\t" - "movq %%mm4,0x68(%[residue])\n\t" - "movq %%mm3,0x70(%[residue])\n\t" - "movq %%mm5,0x78(%[residue])\n\t" - :[src]"+r"(_src),[ystride3]"=&r"(ystride3) - :[residue]"r"(_residue),[ystride]"r"((ptrdiff_t)_ystride) - :"memory" - ); -} - -void oc_enc_frag_copy2_mmxext(unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride){ - oc_int_frag_copy2_mmxext(_dst,_ystride,_src1,_src2,_ystride); -} - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxfdct.c b/src/add-ons/media/plugins/theora/libtheora/x86/mmxfdct.c deleted file mode 100644 index 211875255e..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxfdct.c +++ /dev/null @@ -1,665 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 1999-2006 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ********************************************************************/ -/*MMX fDCT implementation for x86_32*/ -/*$Id: fdct_ses2.c 14579 2008-03-12 06:42:40Z xiphmont $*/ -#include "x86enc.h" - -#if defined(OC_X86_ASM) - -# define OC_FDCT_STAGE1_8x4 \ - "#OC_FDCT_STAGE1_8x4\n\t" \ - /*Stage 1:*/ \ - /*mm0=t7'=t0-t7*/ \ - "psubw %%mm7,%%mm0\n\t" \ - "paddw %%mm7,%%mm7\n\t" \ - /*mm1=t6'=t1-t6*/ \ - "psubw %%mm6,%%mm1\n\t" \ - "paddw %%mm6,%%mm6\n\t" \ - /*mm2=t5'=t2-t5*/ \ - "psubw %%mm5,%%mm2\n\t" \ - "paddw %%mm5,%%mm5\n\t" \ - /*mm3=t4'=t3-t4*/ \ - "psubw %%mm4,%%mm3\n\t" \ - "paddw %%mm4,%%mm4\n\t" \ - /*mm7=t0'=t0+t7*/ \ - "paddw %%mm0,%%mm7\n\t" \ - /*mm6=t1'=t1+t6*/ \ - "paddw %%mm1,%%mm6\n\t" \ - /*mm5=t2'=t2+t5*/ \ - "paddw %%mm2,%%mm5\n\t" \ - /*mm4=t3'=t3+t4*/ \ - "paddw %%mm3,%%mm4\n\t" \ - -# define OC_FDCT8x4(_r0,_r1,_r2,_r3,_r4,_r5,_r6,_r7) \ - "#OC_FDCT8x4\n\t" \ - /*Stage 2:*/ \ - /*mm7=t3''=t0'-t3'*/ \ - "psubw %%mm4,%%mm7\n\t" \ - "paddw %%mm4,%%mm4\n\t" \ - /*mm6=t2''=t1'-t2'*/ \ - "psubw %%mm5,%%mm6\n\t" \ - "movq %%mm7,"_r6"(%[y])\n\t" \ - "paddw %%mm5,%%mm5\n\t" \ - /*mm1=t5''=t6'-t5'*/ \ - "psubw %%mm2,%%mm1\n\t" \ - "movq %%mm6,"_r2"(%[y])\n\t" \ - /*mm4=t0''=t0'+t3'*/ \ - "paddw %%mm7,%%mm4\n\t" \ - "paddw %%mm2,%%mm2\n\t" \ - /*mm5=t1''=t1'+t2'*/ \ - "movq %%mm4,"_r0"(%[y])\n\t" \ - "paddw %%mm6,%%mm5\n\t" \ - /*mm2=t6''=t6'+t5'*/ \ - "paddw %%mm1,%%mm2\n\t" \ - "movq %%mm5,"_r4"(%[y])\n\t" \ - /*mm0=t7', mm1=t5'', mm2=t6'', mm3=t4'.*/ \ - /*mm4, mm5, mm6, mm7 are free.*/ \ - /*Stage 3:*/ \ - /*mm6={2}x4, mm7={27146,0xB500>>1}x2*/ \ - "mov $0x5A806A0A,%[a]\n\t" \ - "pcmpeqb %%mm6,%%mm6\n\t" \ - "movd %[a],%%mm7\n\t" \ - "psrlw $15,%%mm6\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "paddw %%mm6,%%mm6\n\t" \ - /*mm0=0, m2={-1}x4 \ - mm5:mm4=t5''*27146+0xB500*/ \ - "movq %%mm1,%%mm4\n\t" \ - "movq %%mm1,%%mm5\n\t" \ - "punpcklwd %%mm6,%%mm4\n\t" \ - "movq %%mm2,"_r3"(%[y])\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "movq %%mm0,"_r7"(%[y])\n\t" \ - "punpckhwd %%mm6,%%mm5\n\t" \ - "pxor %%mm0,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "pcmpeqb %%mm2,%%mm2\n\t" \ - /*mm2=t6'', mm1=t5''+(t5''!=0) \ - mm4=(t5''*27146+0xB500>>16)*/ \ - "pcmpeqw %%mm1,%%mm0\n\t" \ - "psrad $16,%%mm4\n\t" \ - "psubw %%mm2,%%mm0\n\t" \ - "movq "_r3"(%[y]),%%mm2\n\t" \ - "psrad $16,%%mm5\n\t" \ - "paddw %%mm0,%%mm1\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - /*mm4=s=(t5''*27146+0xB500>>16)+t5''+(t5''!=0)>>1*/ \ - "paddw %%mm1,%%mm4\n\t" \ - "movq "_r7"(%[y]),%%mm0\n\t" \ - "psraw $1,%%mm4\n\t" \ - "movq %%mm3,%%mm1\n\t" \ - /*mm3=t4''=t4'+s*/ \ - "paddw %%mm4,%%mm3\n\t" \ - /*mm1=t5'''=t4'-s*/ \ - "psubw %%mm4,%%mm1\n\t" \ - /*mm1=0, mm3={-1}x4 \ - mm5:mm4=t6''*27146+0xB500*/ \ - "movq %%mm2,%%mm4\n\t" \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklwd %%mm6,%%mm4\n\t" \ - "movq %%mm1,"_r5"(%[y])\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "movq %%mm3,"_r1"(%[y])\n\t" \ - "punpckhwd %%mm6,%%mm5\n\t" \ - "pxor %%mm1,%%mm1\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "pcmpeqb %%mm3,%%mm3\n\t" \ - /*mm2=t6''+(t6''!=0), mm4=(t6''*27146+0xB500>>16)*/ \ - "psrad $16,%%mm4\n\t" \ - "pcmpeqw %%mm2,%%mm1\n\t" \ - "psrad $16,%%mm5\n\t" \ - "psubw %%mm3,%%mm1\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "paddw %%mm1,%%mm2\n\t" \ - /*mm1=t1'' \ - mm4=s=(t6''*27146+0xB500>>16)+t6''+(t6''!=0)>>1*/ \ - "paddw %%mm2,%%mm4\n\t" \ - "movq "_r4"(%[y]),%%mm1\n\t" \ - "psraw $1,%%mm4\n\t" \ - "movq %%mm0,%%mm2\n\t" \ - /*mm7={54491-0x7FFF,0x7FFF}x2 \ - mm0=t7''=t7'+s*/ \ - "paddw %%mm4,%%mm0\n\t" \ - /*mm2=t6'''=t7'-s*/ \ - "psubw %%mm4,%%mm2\n\t" \ - /*Stage 4:*/ \ - /*mm0=0, mm2=t0'' \ - mm5:mm4=t1''*27146+0xB500*/ \ - "movq %%mm1,%%mm4\n\t" \ - "movq %%mm1,%%mm5\n\t" \ - "punpcklwd %%mm6,%%mm4\n\t" \ - "movq %%mm2,"_r3"(%[y])\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "movq "_r0"(%[y]),%%mm2\n\t" \ - "punpckhwd %%mm6,%%mm5\n\t" \ - "movq %%mm0,"_r7"(%[y])\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "pxor %%mm0,%%mm0\n\t" \ - /*mm7={27146,0x4000>>1}x2 \ - mm0=s=(t1''*27146+0xB500>>16)+t1''+(t1''!=0)*/ \ - "psrad $16,%%mm4\n\t" \ - "mov $0x20006A0A,%[a]\n\t" \ - "pcmpeqw %%mm1,%%mm0\n\t" \ - "movd %[a],%%mm7\n\t" \ - "psrad $16,%%mm5\n\t" \ - "psubw %%mm3,%%mm0\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "paddw %%mm1,%%mm0\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "paddw %%mm4,%%mm0\n\t" \ - /*mm6={0x00000E3D}x2 \ - mm1=-(t0''==0), mm5:mm4=t0''*27146+0x4000*/ \ - "movq %%mm2,%%mm4\n\t" \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklwd %%mm6,%%mm4\n\t" \ - "mov $0x0E3D,%[a]\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "punpckhwd %%mm6,%%mm5\n\t" \ - "movd %[a],%%mm6\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "pxor %%mm1,%%mm1\n\t" \ - "punpckldq %%mm6,%%mm6\n\t" \ - "pcmpeqw %%mm2,%%mm1\n\t" \ - /*mm4=r=(t0''*27146+0x4000>>16)+t0''+(t0''!=0)*/ \ - "psrad $16,%%mm4\n\t" \ - "psubw %%mm3,%%mm1\n\t" \ - "psrad $16,%%mm5\n\t" \ - "paddw %%mm1,%%mm2\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "movq "_r5"(%[y]),%%mm1\n\t" \ - "paddw %%mm2,%%mm4\n\t" \ - /*mm2=t6'', mm0=_y[0]=u=r+s>>1 \ - The naive implementation could cause overflow, so we use \ - u=(r&s)+((r^s)>>1).*/ \ - "movq "_r3"(%[y]),%%mm2\n\t" \ - "movq %%mm0,%%mm7\n\t" \ - "pxor %%mm4,%%mm0\n\t" \ - "pand %%mm4,%%mm7\n\t" \ - "psraw $1,%%mm0\n\t" \ - "mov $0x7FFF54DC,%[a]\n\t" \ - "paddw %%mm7,%%mm0\n\t" \ - "movd %[a],%%mm7\n\t" \ - /*mm7={54491-0x7FFF,0x7FFF}x2 \ - mm4=_y[4]=v=r-u*/ \ - "psubw %%mm0,%%mm4\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "movq %%mm4,"_r4"(%[y])\n\t" \ - /*mm0=0, mm7={36410}x4 \ - mm1=(t5'''!=0), mm5:mm4=54491*t5'''+0x0E3D*/ \ - "movq %%mm1,%%mm4\n\t" \ - "movq %%mm1,%%mm5\n\t" \ - "punpcklwd %%mm1,%%mm4\n\t" \ - "mov $0x8E3A8E3A,%[a]\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "movq %%mm0,"_r0"(%[y])\n\t" \ - "punpckhwd %%mm1,%%mm5\n\t" \ - "pxor %%mm0,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "pcmpeqw %%mm0,%%mm1\n\t" \ - "movd %[a],%%mm7\n\t" \ - "psubw %%mm3,%%mm1\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "paddd %%mm6,%%mm4\n\t" \ - "paddd %%mm6,%%mm5\n\t" \ - /*mm0=0 \ - mm3:mm1=36410*t6'''+((t5'''!=0)<<16)*/ \ - "movq %%mm2,%%mm6\n\t" \ - "movq %%mm2,%%mm3\n\t" \ - "pmulhw %%mm7,%%mm6\n\t" \ - "paddw %%mm2,%%mm1\n\t" \ - "pmullw %%mm7,%%mm3\n\t" \ - "pxor %%mm0,%%mm0\n\t" \ - "paddw %%mm1,%%mm6\n\t" \ - "movq %%mm3,%%mm1\n\t" \ - "punpckhwd %%mm6,%%mm3\n\t" \ - "punpcklwd %%mm6,%%mm1\n\t" \ - /*mm3={-1}x4, mm6={1}x4 \ - mm4=_y[5]=u=(54491*t5'''+36410*t6'''+0x0E3D>>16)+(t5'''!=0)*/ \ - "paddd %%mm3,%%mm5\n\t" \ - "paddd %%mm1,%%mm4\n\t" \ - "psrad $16,%%mm5\n\t" \ - "pxor %%mm6,%%mm6\n\t" \ - "psrad $16,%%mm4\n\t" \ - "pcmpeqb %%mm3,%%mm3\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "psubw %%mm3,%%mm6\n\t" \ - /*mm1=t7'', mm7={26568,0x3400}x2 \ - mm2=s=t6'''-(36410*u>>16)*/ \ - "movq %%mm4,%%mm1\n\t" \ - "mov $0x340067C8,%[a]\n\t" \ - "pmulhw %%mm7,%%mm4\n\t" \ - "movd %[a],%%mm7\n\t" \ - "movq %%mm1,"_r5"(%[y])\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "paddw %%mm1,%%mm4\n\t" \ - "movq "_r7"(%[y]),%%mm1\n\t" \ - "psubw %%mm4,%%mm2\n\t" \ - /*mm6={0x00007B1B}x2 \ - mm0=(s!=0), mm5:mm4=s*26568+0x3400*/ \ - "movq %%mm2,%%mm4\n\t" \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklwd %%mm6,%%mm4\n\t" \ - "pcmpeqw %%mm2,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "mov $0x7B1B,%[a]\n\t" \ - "punpckhwd %%mm6,%%mm5\n\t" \ - "movd %[a],%%mm6\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "psubw %%mm3,%%mm0\n\t" \ - "punpckldq %%mm6,%%mm6\n\t" \ - /*mm7={64277-0x7FFF,0x7FFF}x2 \ - mm2=_y[3]=v=(s*26568+0x3400>>17)+s+(s!=0)*/ \ - "psrad $17,%%mm4\n\t" \ - "paddw %%mm0,%%mm2\n\t" \ - "psrad $17,%%mm5\n\t" \ - "mov $0x7FFF7B16,%[a]\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "movd %[a],%%mm7\n\t" \ - "paddw %%mm4,%%mm2\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - /*mm0=0, mm7={12785}x4 \ - mm1=(t7''!=0), mm2=t4'', mm5:mm4=64277*t7''+0x7B1B*/ \ - "movq %%mm1,%%mm4\n\t" \ - "movq %%mm1,%%mm5\n\t" \ - "movq %%mm2,"_r3"(%[y])\n\t" \ - "punpcklwd %%mm1,%%mm4\n\t" \ - "movq "_r1"(%[y]),%%mm2\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "mov $0x31F131F1,%[a]\n\t" \ - "punpckhwd %%mm1,%%mm5\n\t" \ - "pxor %%mm0,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "pcmpeqw %%mm0,%%mm1\n\t" \ - "movd %[a],%%mm7\n\t" \ - "psubw %%mm3,%%mm1\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "paddd %%mm6,%%mm4\n\t" \ - "paddd %%mm6,%%mm5\n\t" \ - /*mm3:mm1=12785*t4'''+((t7''!=0)<<16)*/ \ - "movq %%mm2,%%mm6\n\t" \ - "movq %%mm2,%%mm3\n\t" \ - "pmulhw %%mm7,%%mm6\n\t" \ - "pmullw %%mm7,%%mm3\n\t" \ - "paddw %%mm1,%%mm6\n\t" \ - "movq %%mm3,%%mm1\n\t" \ - "punpckhwd %%mm6,%%mm3\n\t" \ - "punpcklwd %%mm6,%%mm1\n\t" \ - /*mm3={-1}x4, mm6={1}x4 \ - mm4=_y[1]=u=(12785*t4'''+64277*t7''+0x7B1B>>16)+(t7''!=0)*/ \ - "paddd %%mm3,%%mm5\n\t" \ - "paddd %%mm1,%%mm4\n\t" \ - "psrad $16,%%mm5\n\t" \ - "pxor %%mm6,%%mm6\n\t" \ - "psrad $16,%%mm4\n\t" \ - "pcmpeqb %%mm3,%%mm3\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "psubw %%mm3,%%mm6\n\t" \ - /*mm1=t3'', mm7={20539,0x3000}x2 \ - mm4=s=(12785*u>>16)-t4''*/ \ - "movq %%mm4,"_r1"(%[y])\n\t" \ - "pmulhw %%mm7,%%mm4\n\t" \ - "mov $0x3000503B,%[a]\n\t" \ - "movq "_r6"(%[y]),%%mm1\n\t" \ - "movd %[a],%%mm7\n\t" \ - "psubw %%mm2,%%mm4\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - /*mm6={0x00006CB7}x2 \ - mm0=(s!=0), mm5:mm4=s*20539+0x3000*/ \ - "movq %%mm4,%%mm5\n\t" \ - "movq %%mm4,%%mm2\n\t" \ - "punpcklwd %%mm6,%%mm4\n\t" \ - "pcmpeqw %%mm2,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "mov $0x6CB7,%[a]\n\t" \ - "punpckhwd %%mm6,%%mm5\n\t" \ - "movd %[a],%%mm6\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "psubw %%mm3,%%mm0\n\t" \ - "punpckldq %%mm6,%%mm6\n\t" \ - /*mm7={60547-0x7FFF,0x7FFF}x2 \ - mm2=_y[7]=v=(s*20539+0x3000>>20)+s+(s!=0)*/ \ - "psrad $20,%%mm4\n\t" \ - "paddw %%mm0,%%mm2\n\t" \ - "psrad $20,%%mm5\n\t" \ - "mov $0x7FFF6C84,%[a]\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - "movd %[a],%%mm7\n\t" \ - "paddw %%mm4,%%mm2\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - /*mm0=0, mm7={25080}x4 \ - mm2=t2'', mm5:mm4=60547*t3''+0x6CB7*/ \ - "movq %%mm1,%%mm4\n\t" \ - "movq %%mm1,%%mm5\n\t" \ - "movq %%mm2,"_r7"(%[y])\n\t" \ - "punpcklwd %%mm1,%%mm4\n\t" \ - "movq "_r2"(%[y]),%%mm2\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "mov $0x61F861F8,%[a]\n\t" \ - "punpckhwd %%mm1,%%mm5\n\t" \ - "pxor %%mm0,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm5\n\t" \ - "movd %[a],%%mm7\n\t" \ - "pcmpeqw %%mm0,%%mm1\n\t" \ - "psubw %%mm3,%%mm1\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "paddd %%mm6,%%mm4\n\t" \ - "paddd %%mm6,%%mm5\n\t" \ - /*mm3:mm1=25080*t2''+((t3''!=0)<<16)*/ \ - "movq %%mm2,%%mm6\n\t" \ - "movq %%mm2,%%mm3\n\t" \ - "pmulhw %%mm7,%%mm6\n\t" \ - "pmullw %%mm7,%%mm3\n\t" \ - "paddw %%mm1,%%mm6\n\t" \ - "movq %%mm3,%%mm1\n\t" \ - "punpckhwd %%mm6,%%mm3\n\t" \ - "punpcklwd %%mm6,%%mm1\n\t" \ - /*mm1={-1}x4 \ - mm4=u=(25080*t2''+60547*t3''+0x6CB7>>16)+(t3''!=0)*/ \ - "paddd %%mm3,%%mm5\n\t" \ - "paddd %%mm1,%%mm4\n\t" \ - "psrad $16,%%mm5\n\t" \ - "mov $0x28005460,%[a]\n\t" \ - "psrad $16,%%mm4\n\t" \ - "pcmpeqb %%mm1,%%mm1\n\t" \ - "packssdw %%mm5,%%mm4\n\t" \ - /*mm5={1}x4, mm6=_y[2]=u, mm7={21600,0x2800}x2 \ - mm4=s=(25080*u>>16)-t2''*/ \ - "movq %%mm4,%%mm6\n\t" \ - "pmulhw %%mm7,%%mm4\n\t" \ - "pxor %%mm5,%%mm5\n\t" \ - "movd %[a],%%mm7\n\t" \ - "psubw %%mm1,%%mm5\n\t" \ - "punpckldq %%mm7,%%mm7\n\t" \ - "psubw %%mm2,%%mm4\n\t" \ - /*mm2=s+(s!=0) \ - mm4:mm3=s*21600+0x2800*/ \ - "movq %%mm4,%%mm3\n\t" \ - "movq %%mm4,%%mm2\n\t" \ - "punpckhwd %%mm5,%%mm4\n\t" \ - "pcmpeqw %%mm2,%%mm0\n\t" \ - "pmaddwd %%mm7,%%mm4\n\t" \ - "psubw %%mm1,%%mm0\n\t" \ - "punpcklwd %%mm5,%%mm3\n\t" \ - "paddw %%mm0,%%mm2\n\t" \ - "pmaddwd %%mm7,%%mm3\n\t" \ - /*mm0=_y[4], mm1=_y[7], mm4=_y[0], mm5=_y[5] \ - mm3=_y[6]=v=(s*21600+0x2800>>18)+s+(s!=0)*/ \ - "movq "_r4"(%[y]),%%mm0\n\t" \ - "psrad $18,%%mm4\n\t" \ - "movq "_r5"(%[y]),%%mm5\n\t" \ - "psrad $18,%%mm3\n\t" \ - "movq "_r7"(%[y]),%%mm1\n\t" \ - "packssdw %%mm4,%%mm3\n\t" \ - "movq "_r0"(%[y]),%%mm4\n\t" \ - "paddw %%mm2,%%mm3\n\t" \ - -/*On input, mm4=_y[0], mm6=_y[2], mm0=_y[4], mm5=_y[5], mm3=_y[6], mm1=_y[7]. - On output, {_y[4],mm1,mm2,mm3} contains the transpose of _y[4...7] and - {mm4,mm5,mm6,mm7} contains the transpose of _y[0...3].*/ -# define OC_TRANSPOSE8x4(_r0,_r1,_r2,_r3,_r4,_r5,_r6,_r7) \ - "#OC_TRANSPOSE8x4\n\t" \ - /*First 4x4 transpose:*/ \ - /*mm0 = e3 e2 e1 e0 \ - mm5 = f3 f2 f1 f0 \ - mm3 = g3 g2 g1 g0 \ - mm1 = h3 h2 h1 h0*/ \ - "movq %%mm0,%%mm2\n\t" \ - "punpcklwd %%mm5,%%mm0\n\t" \ - "punpckhwd %%mm5,%%mm2\n\t" \ - "movq %%mm3,%%mm5\n\t" \ - "punpcklwd %%mm1,%%mm3\n\t" \ - "punpckhwd %%mm1,%%mm5\n\t" \ - /*mm0 = f1 e1 f0 e0 \ - mm2 = f3 e3 f2 e2 \ - mm3 = h1 g1 h0 g0 \ - mm5 = h3 g3 h2 g2*/ \ - "movq %%mm0,%%mm1\n\t" \ - "punpckldq %%mm3,%%mm0\n\t" \ - "movq %%mm0,"_r4"(%[y])\n\t" \ - "punpckhdq %%mm3,%%mm1\n\t" \ - "movq "_r1"(%[y]),%%mm0\n\t" \ - "movq %%mm2,%%mm3\n\t" \ - "punpckldq %%mm5,%%mm2\n\t" \ - "punpckhdq %%mm5,%%mm3\n\t" \ - "movq "_r3"(%[y]),%%mm5\n\t" \ - /*_y[4] = h0 g0 f0 e0 \ - mm1 = h1 g1 f1 e1 \ - mm2 = h2 g2 f2 e2 \ - mm3 = h3 g3 f3 e3*/ \ - /*Second 4x4 transpose:*/ \ - /*mm4 = a3 a2 a1 a0 \ - mm0 = b3 b2 b1 b0 \ - mm6 = c3 c2 c1 c0 \ - mm5 = d3 d2 d1 d0*/ \ - "movq %%mm4,%%mm7\n\t" \ - "punpcklwd %%mm0,%%mm4\n\t" \ - "punpckhwd %%mm0,%%mm7\n\t" \ - "movq %%mm6,%%mm0\n\t" \ - "punpcklwd %%mm5,%%mm6\n\t" \ - "punpckhwd %%mm5,%%mm0\n\t" \ - /*mm4 = b1 a1 b0 a0 \ - mm7 = b3 a3 b2 a2 \ - mm6 = d1 c1 d0 c0 \ - mm0 = d3 c3 d2 c2*/ \ - "movq %%mm4,%%mm5\n\t" \ - "punpckldq %%mm6,%%mm4\n\t" \ - "punpckhdq %%mm6,%%mm5\n\t" \ - "movq %%mm7,%%mm6\n\t" \ - "punpckhdq %%mm0,%%mm7\n\t" \ - "punpckldq %%mm0,%%mm6\n\t" \ - /*mm4 = d0 c0 b0 a0 \ - mm5 = d1 c1 b1 a1 \ - mm6 = d2 c2 b2 a2 \ - mm7 = d3 c3 b3 a3*/ \ - -/*MMX implementation of the fDCT.*/ -void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - ptrdiff_t a; - __asm__ __volatile__( - /*Add two extra bits of working precision to improve accuracy; any more and - we could overflow.*/ - /*We also add biases to correct for some systematic error that remains in - the full fDCT->iDCT round trip.*/ - "movq 0x00(%[x]),%%mm0\n\t" - "movq 0x10(%[x]),%%mm1\n\t" - "movq 0x20(%[x]),%%mm2\n\t" - "movq 0x30(%[x]),%%mm3\n\t" - "pcmpeqb %%mm4,%%mm4\n\t" - "pxor %%mm7,%%mm7\n\t" - "movq %%mm0,%%mm5\n\t" - "psllw $2,%%mm0\n\t" - "pcmpeqw %%mm7,%%mm5\n\t" - "movq 0x70(%[x]),%%mm7\n\t" - "psllw $2,%%mm1\n\t" - "psubw %%mm4,%%mm5\n\t" - "psllw $2,%%mm2\n\t" - "mov $1,%[a]\n\t" - "pslld $16,%%mm5\n\t" - "movd %[a],%%mm6\n\t" - "psllq $16,%%mm5\n\t" - "mov $0x10001,%[a]\n\t" - "psllw $2,%%mm3\n\t" - "movd %[a],%%mm4\n\t" - "punpckhwd %%mm6,%%mm5\n\t" - "psubw %%mm6,%%mm1\n\t" - "movq 0x60(%[x]),%%mm6\n\t" - "paddw %%mm5,%%mm0\n\t" - "movq 0x50(%[x]),%%mm5\n\t" - "paddw %%mm4,%%mm0\n\t" - "movq 0x40(%[x]),%%mm4\n\t" - /*We inline stage1 of the transform here so we can get better instruction - scheduling with the shifts.*/ - /*mm0=t7'=t0-t7*/ - "psllw $2,%%mm7\n\t" - "psubw %%mm7,%%mm0\n\t" - "psllw $2,%%mm6\n\t" - "paddw %%mm7,%%mm7\n\t" - /*mm1=t6'=t1-t6*/ - "psllw $2,%%mm5\n\t" - "psubw %%mm6,%%mm1\n\t" - "psllw $2,%%mm4\n\t" - "paddw %%mm6,%%mm6\n\t" - /*mm2=t5'=t2-t5*/ - "psubw %%mm5,%%mm2\n\t" - "paddw %%mm5,%%mm5\n\t" - /*mm3=t4'=t3-t4*/ - "psubw %%mm4,%%mm3\n\t" - "paddw %%mm4,%%mm4\n\t" - /*mm7=t0'=t0+t7*/ - "paddw %%mm0,%%mm7\n\t" - /*mm6=t1'=t1+t6*/ - "paddw %%mm1,%%mm6\n\t" - /*mm5=t2'=t2+t5*/ - "paddw %%mm2,%%mm5\n\t" - /*mm4=t3'=t3+t4*/ - "paddw %%mm3,%%mm4\n\t" - OC_FDCT8x4("0x00","0x10","0x20","0x30","0x40","0x50","0x60","0x70") - OC_TRANSPOSE8x4("0x00","0x10","0x20","0x30","0x40","0x50","0x60","0x70") - /*Swap out this 8x4 block for the next one.*/ - "movq 0x08(%[x]),%%mm0\n\t" - "movq %%mm7,0x30(%[y])\n\t" - "movq 0x78(%[x]),%%mm7\n\t" - "movq %%mm1,0x50(%[y])\n\t" - "movq 0x18(%[x]),%%mm1\n\t" - "movq %%mm6,0x20(%[y])\n\t" - "movq 0x68(%[x]),%%mm6\n\t" - "movq %%mm2,0x60(%[y])\n\t" - "movq 0x28(%[x]),%%mm2\n\t" - "movq %%mm5,0x10(%[y])\n\t" - "movq 0x58(%[x]),%%mm5\n\t" - "movq %%mm3,0x70(%[y])\n\t" - "movq 0x38(%[x]),%%mm3\n\t" - /*And increase its working precision, too.*/ - "psllw $2,%%mm0\n\t" - "movq %%mm4,0x00(%[y])\n\t" - "psllw $2,%%mm7\n\t" - "movq 0x48(%[x]),%%mm4\n\t" - /*We inline stage1 of the transform here so we can get better instruction - scheduling with the shifts.*/ - /*mm0=t7'=t0-t7*/ - "psubw %%mm7,%%mm0\n\t" - "psllw $2,%%mm1\n\t" - "paddw %%mm7,%%mm7\n\t" - "psllw $2,%%mm6\n\t" - /*mm1=t6'=t1-t6*/ - "psubw %%mm6,%%mm1\n\t" - "psllw $2,%%mm2\n\t" - "paddw %%mm6,%%mm6\n\t" - "psllw $2,%%mm5\n\t" - /*mm2=t5'=t2-t5*/ - "psubw %%mm5,%%mm2\n\t" - "psllw $2,%%mm3\n\t" - "paddw %%mm5,%%mm5\n\t" - "psllw $2,%%mm4\n\t" - /*mm3=t4'=t3-t4*/ - "psubw %%mm4,%%mm3\n\t" - "paddw %%mm4,%%mm4\n\t" - /*mm7=t0'=t0+t7*/ - "paddw %%mm0,%%mm7\n\t" - /*mm6=t1'=t1+t6*/ - "paddw %%mm1,%%mm6\n\t" - /*mm5=t2'=t2+t5*/ - "paddw %%mm2,%%mm5\n\t" - /*mm4=t3'=t3+t4*/ - "paddw %%mm3,%%mm4\n\t" - OC_FDCT8x4("0x08","0x18","0x28","0x38","0x48","0x58","0x68","0x78") - OC_TRANSPOSE8x4("0x08","0x18","0x28","0x38","0x48","0x58","0x68","0x78") - /*Here the first 4x4 block of output from the last transpose is the second - 4x4 block of input for the next transform. - We have cleverly arranged that it already be in the appropriate place, - so we only have to do half the stores and loads.*/ - "movq 0x00(%[y]),%%mm0\n\t" - "movq %%mm1,0x58(%[y])\n\t" - "movq 0x10(%[y]),%%mm1\n\t" - "movq %%mm2,0x68(%[y])\n\t" - "movq 0x20(%[y]),%%mm2\n\t" - "movq %%mm3,0x78(%[y])\n\t" - "movq 0x30(%[y]),%%mm3\n\t" - OC_FDCT_STAGE1_8x4 - OC_FDCT8x4("0x00","0x10","0x20","0x30","0x08","0x18","0x28","0x38") - OC_TRANSPOSE8x4("0x00","0x10","0x20","0x30","0x08","0x18","0x28","0x38") - /*mm0={-2}x4*/ - "pcmpeqw %%mm0,%%mm0\n\t" - "paddw %%mm0,%%mm0\n\t" - /*Round the results.*/ - "psubw %%mm0,%%mm1\n\t" - "psubw %%mm0,%%mm2\n\t" - "psraw $2,%%mm1\n\t" - "psubw %%mm0,%%mm3\n\t" - "movq %%mm1,0x18(%[y])\n\t" - "psraw $2,%%mm2\n\t" - "psubw %%mm0,%%mm4\n\t" - "movq 0x08(%[y]),%%mm1\n\t" - "psraw $2,%%mm3\n\t" - "psubw %%mm0,%%mm5\n\t" - "psraw $2,%%mm4\n\t" - "psubw %%mm0,%%mm6\n\t" - "psraw $2,%%mm5\n\t" - "psubw %%mm0,%%mm7\n\t" - "psraw $2,%%mm6\n\t" - "psubw %%mm0,%%mm1\n\t" - "psraw $2,%%mm7\n\t" - "movq 0x40(%[y]),%%mm0\n\t" - "psraw $2,%%mm1\n\t" - "movq %%mm7,0x30(%[y])\n\t" - "movq 0x78(%[y]),%%mm7\n\t" - "movq %%mm1,0x08(%[y])\n\t" - "movq 0x50(%[y]),%%mm1\n\t" - "movq %%mm6,0x20(%[y])\n\t" - "movq 0x68(%[y]),%%mm6\n\t" - "movq %%mm2,0x28(%[y])\n\t" - "movq 0x60(%[y]),%%mm2\n\t" - "movq %%mm5,0x10(%[y])\n\t" - "movq 0x58(%[y]),%%mm5\n\t" - "movq %%mm3,0x38(%[y])\n\t" - "movq 0x70(%[y]),%%mm3\n\t" - "movq %%mm4,0x00(%[y])\n\t" - "movq 0x48(%[y]),%%mm4\n\t" - OC_FDCT_STAGE1_8x4 - OC_FDCT8x4("0x40","0x50","0x60","0x70","0x48","0x58","0x68","0x78") - OC_TRANSPOSE8x4("0x40","0x50","0x60","0x70","0x48","0x58","0x68","0x78") - /*mm0={-2}x4*/ - "pcmpeqw %%mm0,%%mm0\n\t" - "paddw %%mm0,%%mm0\n\t" - /*Round the results.*/ - "psubw %%mm0,%%mm1\n\t" - "psubw %%mm0,%%mm2\n\t" - "psraw $2,%%mm1\n\t" - "psubw %%mm0,%%mm3\n\t" - "movq %%mm1,0x58(%[y])\n\t" - "psraw $2,%%mm2\n\t" - "psubw %%mm0,%%mm4\n\t" - "movq 0x48(%[y]),%%mm1\n\t" - "psraw $2,%%mm3\n\t" - "psubw %%mm0,%%mm5\n\t" - "movq %%mm2,0x68(%[y])\n\t" - "psraw $2,%%mm4\n\t" - "psubw %%mm0,%%mm6\n\t" - "movq %%mm3,0x78(%[y])\n\t" - "psraw $2,%%mm5\n\t" - "psubw %%mm0,%%mm7\n\t" - "movq %%mm4,0x40(%[y])\n\t" - "psraw $2,%%mm6\n\t" - "psubw %%mm0,%%mm1\n\t" - "movq %%mm5,0x50(%[y])\n\t" - "psraw $2,%%mm7\n\t" - "movq %%mm6,0x60(%[y])\n\t" - "psraw $2,%%mm1\n\t" - "movq %%mm7,0x70(%[y])\n\t" - "movq %%mm1,0x48(%[y])\n\t" - :[a]"=&r"(a) - :[y]"r"(_y),[x]"r"(_x) - :"memory" - ); -} - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxfrag.c b/src/add-ons/media/plugins/theora/libtheora/x86/mmxfrag.c deleted file mode 100644 index 2c732939c3..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxfrag.c +++ /dev/null @@ -1,293 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: mmxfrag.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -/*MMX acceleration of fragment reconstruction for motion compensation. - Originally written by Rudolf Marek. - Additional optimization by Nils Pipenbrinck. - Note: Loops are unrolled for best performance. - The iteration each instruction belongs to is marked in the comments as #i.*/ -#include -#include "x86int.h" -#include "mmxfrag.h" - -#if defined(OC_X86_ASM) - -/*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes - between rows.*/ -void oc_frag_copy_mmx(unsigned char *_dst, - const unsigned char *_src,int _ystride){ - OC_FRAG_COPY_MMX(_dst,_src,_ystride); -} - -void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride, - const ogg_int16_t *_residue){ - __asm__ __volatile__( - /*Set mm0 to 0xFFFFFFFFFFFFFFFF.*/ - "pcmpeqw %%mm0,%%mm0\n\t" - /*#0 Load low residue.*/ - "movq 0*8(%[residue]),%%mm1\n\t" - /*#0 Load high residue.*/ - "movq 1*8(%[residue]),%%mm2\n\t" - /*Set mm0 to 0x8000800080008000.*/ - "psllw $15,%%mm0\n\t" - /*#1 Load low residue.*/ - "movq 2*8(%[residue]),%%mm3\n\t" - /*#1 Load high residue.*/ - "movq 3*8(%[residue]),%%mm4\n\t" - /*Set mm0 to 0x0080008000800080.*/ - "psrlw $8,%%mm0\n\t" - /*#2 Load low residue.*/ - "movq 4*8(%[residue]),%%mm5\n\t" - /*#2 Load high residue.*/ - "movq 5*8(%[residue]),%%mm6\n\t" - /*#0 Bias low residue.*/ - "paddsw %%mm0,%%mm1\n\t" - /*#0 Bias high residue.*/ - "paddsw %%mm0,%%mm2\n\t" - /*#0 Pack to byte.*/ - "packuswb %%mm2,%%mm1\n\t" - /*#1 Bias low residue.*/ - "paddsw %%mm0,%%mm3\n\t" - /*#1 Bias high residue.*/ - "paddsw %%mm0,%%mm4\n\t" - /*#1 Pack to byte.*/ - "packuswb %%mm4,%%mm3\n\t" - /*#2 Bias low residue.*/ - "paddsw %%mm0,%%mm5\n\t" - /*#2 Bias high residue.*/ - "paddsw %%mm0,%%mm6\n\t" - /*#2 Pack to byte.*/ - "packuswb %%mm6,%%mm5\n\t" - /*#0 Write row.*/ - "movq %%mm1,(%[dst])\n\t" - /*#1 Write row.*/ - "movq %%mm3,(%[dst],%[ystride])\n\t" - /*#2 Write row.*/ - "movq %%mm5,(%[dst],%[ystride],2)\n\t" - /*#3 Load low residue.*/ - "movq 6*8(%[residue]),%%mm1\n\t" - /*#3 Load high residue.*/ - "movq 7*8(%[residue]),%%mm2\n\t" - /*#4 Load high residue.*/ - "movq 8*8(%[residue]),%%mm3\n\t" - /*#4 Load high residue.*/ - "movq 9*8(%[residue]),%%mm4\n\t" - /*#5 Load high residue.*/ - "movq 10*8(%[residue]),%%mm5\n\t" - /*#5 Load high residue.*/ - "movq 11*8(%[residue]),%%mm6\n\t" - /*#3 Bias low residue.*/ - "paddsw %%mm0,%%mm1\n\t" - /*#3 Bias high residue.*/ - "paddsw %%mm0,%%mm2\n\t" - /*#3 Pack to byte.*/ - "packuswb %%mm2,%%mm1\n\t" - /*#4 Bias low residue.*/ - "paddsw %%mm0,%%mm3\n\t" - /*#4 Bias high residue.*/ - "paddsw %%mm0,%%mm4\n\t" - /*#4 Pack to byte.*/ - "packuswb %%mm4,%%mm3\n\t" - /*#5 Bias low residue.*/ - "paddsw %%mm0,%%mm5\n\t" - /*#5 Bias high residue.*/ - "paddsw %%mm0,%%mm6\n\t" - /*#5 Pack to byte.*/ - "packuswb %%mm6,%%mm5\n\t" - /*#3 Write row.*/ - "movq %%mm1,(%[dst],%[ystride3])\n\t" - /*#4 Write row.*/ - "movq %%mm3,(%[dst4])\n\t" - /*#5 Write row.*/ - "movq %%mm5,(%[dst4],%[ystride])\n\t" - /*#6 Load low residue.*/ - "movq 12*8(%[residue]),%%mm1\n\t" - /*#6 Load high residue.*/ - "movq 13*8(%[residue]),%%mm2\n\t" - /*#7 Load low residue.*/ - "movq 14*8(%[residue]),%%mm3\n\t" - /*#7 Load high residue.*/ - "movq 15*8(%[residue]),%%mm4\n\t" - /*#6 Bias low residue.*/ - "paddsw %%mm0,%%mm1\n\t" - /*#6 Bias high residue.*/ - "paddsw %%mm0,%%mm2\n\t" - /*#6 Pack to byte.*/ - "packuswb %%mm2,%%mm1\n\t" - /*#7 Bias low residue.*/ - "paddsw %%mm0,%%mm3\n\t" - /*#7 Bias high residue.*/ - "paddsw %%mm0,%%mm4\n\t" - /*#7 Pack to byte.*/ - "packuswb %%mm4,%%mm3\n\t" - /*#6 Write row.*/ - "movq %%mm1,(%[dst4],%[ystride],2)\n\t" - /*#7 Write row.*/ - "movq %%mm3,(%[dst4],%[ystride3])\n\t" - : - :[residue]"r"(_residue), - [dst]"r"(_dst), - [dst4]"r"(_dst+(_ystride<<2)), - [ystride]"r"((ptrdiff_t)_ystride), - [ystride3]"r"((ptrdiff_t)_ystride*3) - :"memory" - ); -} - -void oc_frag_recon_inter_mmx(unsigned char *_dst,const unsigned char *_src, - int _ystride,const ogg_int16_t *_residue){ - int i; - /*Zero mm0.*/ - __asm__ __volatile__("pxor %%mm0,%%mm0\n\t"::); - for(i=4;i-->0;){ - __asm__ __volatile__( - /*#0 Load source.*/ - "movq (%[src]),%%mm3\n\t" - /*#1 Load source.*/ - "movq (%[src],%[ystride]),%%mm7\n\t" - /*#0 Get copy of src.*/ - "movq %%mm3,%%mm4\n\t" - /*#0 Expand high source.*/ - "punpckhbw %%mm0,%%mm4\n\t" - /*#0 Expand low source.*/ - "punpcklbw %%mm0,%%mm3\n\t" - /*#0 Add residue high.*/ - "paddsw 8(%[residue]),%%mm4\n\t" - /*#1 Get copy of src.*/ - "movq %%mm7,%%mm2\n\t" - /*#0 Add residue low.*/ - "paddsw (%[residue]), %%mm3\n\t" - /*#1 Expand high source.*/ - "punpckhbw %%mm0,%%mm2\n\t" - /*#0 Pack final row pixels.*/ - "packuswb %%mm4,%%mm3\n\t" - /*#1 Expand low source.*/ - "punpcklbw %%mm0,%%mm7\n\t" - /*#1 Add residue low.*/ - "paddsw 16(%[residue]),%%mm7\n\t" - /*#1 Add residue high.*/ - "paddsw 24(%[residue]),%%mm2\n\t" - /*Advance residue.*/ - "lea 32(%[residue]),%[residue]\n\t" - /*#1 Pack final row pixels.*/ - "packuswb %%mm2,%%mm7\n\t" - /*Advance src.*/ - "lea (%[src],%[ystride],2),%[src]\n\t" - /*#0 Write row.*/ - "movq %%mm3,(%[dst])\n\t" - /*#1 Write row.*/ - "movq %%mm7,(%[dst],%[ystride])\n\t" - /*Advance dst.*/ - "lea (%[dst],%[ystride],2),%[dst]\n\t" - :[residue]"+r"(_residue),[dst]"+r"(_dst),[src]"+r"(_src) - :[ystride]"r"((ptrdiff_t)_ystride) - :"memory" - ); - } -} - -void oc_frag_recon_inter2_mmx(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t *_residue){ - int i; - /*Zero mm7.*/ - __asm__ __volatile__("pxor %%mm7,%%mm7\n\t"::); - for(i=4;i-->0;){ - __asm__ __volatile__( - /*#0 Load src1.*/ - "movq (%[src1]),%%mm0\n\t" - /*#0 Load src2.*/ - "movq (%[src2]),%%mm2\n\t" - /*#0 Copy src1.*/ - "movq %%mm0,%%mm1\n\t" - /*#0 Copy src2.*/ - "movq %%mm2,%%mm3\n\t" - /*#1 Load src1.*/ - "movq (%[src1],%[ystride]),%%mm4\n\t" - /*#0 Unpack lower src1.*/ - "punpcklbw %%mm7,%%mm0\n\t" - /*#1 Load src2.*/ - "movq (%[src2],%[ystride]),%%mm5\n\t" - /*#0 Unpack higher src1.*/ - "punpckhbw %%mm7,%%mm1\n\t" - /*#0 Unpack lower src2.*/ - "punpcklbw %%mm7,%%mm2\n\t" - /*#0 Unpack higher src2.*/ - "punpckhbw %%mm7,%%mm3\n\t" - /*Advance src1 ptr.*/ - "lea (%[src1],%[ystride],2),%[src1]\n\t" - /*Advance src2 ptr.*/ - "lea (%[src2],%[ystride],2),%[src2]\n\t" - /*#0 Lower src1+src2.*/ - "paddsw %%mm2,%%mm0\n\t" - /*#0 Higher src1+src2.*/ - "paddsw %%mm3,%%mm1\n\t" - /*#1 Copy src1.*/ - "movq %%mm4,%%mm2\n\t" - /*#0 Build lo average.*/ - "psraw $1,%%mm0\n\t" - /*#1 Copy src2.*/ - "movq %%mm5,%%mm3\n\t" - /*#1 Unpack lower src1.*/ - "punpcklbw %%mm7,%%mm4\n\t" - /*#0 Build hi average.*/ - "psraw $1,%%mm1\n\t" - /*#1 Unpack higher src1.*/ - "punpckhbw %%mm7,%%mm2\n\t" - /*#0 low+=residue.*/ - "paddsw (%[residue]),%%mm0\n\t" - /*#1 Unpack lower src2.*/ - "punpcklbw %%mm7,%%mm5\n\t" - /*#0 high+=residue.*/ - "paddsw 8(%[residue]),%%mm1\n\t" - /*#1 Unpack higher src2.*/ - "punpckhbw %%mm7,%%mm3\n\t" - /*#1 Lower src1+src2.*/ - "paddsw %%mm4,%%mm5\n\t" - /*#0 Pack and saturate.*/ - "packuswb %%mm1,%%mm0\n\t" - /*#1 Higher src1+src2.*/ - "paddsw %%mm2,%%mm3\n\t" - /*#0 Write row.*/ - "movq %%mm0,(%[dst])\n\t" - /*#1 Build lo average.*/ - "psraw $1,%%mm5\n\t" - /*#1 Build hi average.*/ - "psraw $1,%%mm3\n\t" - /*#1 low+=residue.*/ - "paddsw 16(%[residue]),%%mm5\n\t" - /*#1 high+=residue.*/ - "paddsw 24(%[residue]),%%mm3\n\t" - /*#1 Pack and saturate.*/ - "packuswb %%mm3,%%mm5\n\t" - /*#1 Write row ptr.*/ - "movq %%mm5,(%[dst],%[ystride])\n\t" - /*Advance residue ptr.*/ - "add $32,%[residue]\n\t" - /*Advance dest ptr.*/ - "lea (%[dst],%[ystride],2),%[dst]\n\t" - :[dst]"+r"(_dst),[residue]"+r"(_residue), - [src1]"+%r"(_src1),[src2]"+r"(_src2) - :[ystride]"r"((ptrdiff_t)_ystride) - :"memory" - ); - } -} - -void oc_restore_fpu_mmx(void){ - __asm__ __volatile__("emms\n\t"); -} -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxfrag.h b/src/add-ons/media/plugins/theora/libtheora/x86/mmxfrag.h deleted file mode 100644 index a398427629..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxfrag.h +++ /dev/null @@ -1,64 +0,0 @@ -#if !defined(_x86_mmxfrag_H) -# define _x86_mmxfrag_H (1) -# include -# include "x86int.h" - -#if defined(OC_X86_ASM) - -/*Copies an 8x8 block of pixels from _src to _dst, assuming _ystride bytes - between rows.*/ -#define OC_FRAG_COPY_MMX(_dst,_src,_ystride) \ - do{ \ - const unsigned char *src; \ - unsigned char *dst; \ - ptrdiff_t ystride3; \ - src=(_src); \ - dst=(_dst); \ - __asm__ __volatile__( \ - /*src+0*ystride*/ \ - "movq (%[src]),%%mm0\n\t" \ - /*src+1*ystride*/ \ - "movq (%[src],%[ystride]),%%mm1\n\t" \ - /*ystride3=ystride*3*/ \ - "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" \ - /*src+2*ystride*/ \ - "movq (%[src],%[ystride],2),%%mm2\n\t" \ - /*src+3*ystride*/ \ - "movq (%[src],%[ystride3]),%%mm3\n\t" \ - /*dst+0*ystride*/ \ - "movq %%mm0,(%[dst])\n\t" \ - /*dst+1*ystride*/ \ - "movq %%mm1,(%[dst],%[ystride])\n\t" \ - /*Pointer to next 4.*/ \ - "lea (%[src],%[ystride],4),%[src]\n\t" \ - /*dst+2*ystride*/ \ - "movq %%mm2,(%[dst],%[ystride],2)\n\t" \ - /*dst+3*ystride*/ \ - "movq %%mm3,(%[dst],%[ystride3])\n\t" \ - /*Pointer to next 4.*/ \ - "lea (%[dst],%[ystride],4),%[dst]\n\t" \ - /*src+0*ystride*/ \ - "movq (%[src]),%%mm0\n\t" \ - /*src+1*ystride*/ \ - "movq (%[src],%[ystride]),%%mm1\n\t" \ - /*src+2*ystride*/ \ - "movq (%[src],%[ystride],2),%%mm2\n\t" \ - /*src+3*ystride*/ \ - "movq (%[src],%[ystride3]),%%mm3\n\t" \ - /*dst+0*ystride*/ \ - "movq %%mm0,(%[dst])\n\t" \ - /*dst+1*ystride*/ \ - "movq %%mm1,(%[dst],%[ystride])\n\t" \ - /*dst+2*ystride*/ \ - "movq %%mm2,(%[dst],%[ystride],2)\n\t" \ - /*dst+3*ystride*/ \ - "movq %%mm3,(%[dst],%[ystride3])\n\t" \ - :[dst]"+r"(dst),[src]"+r"(src),[ystride3]"=&r"(ystride3) \ - :[ystride]"r"((ptrdiff_t)(_ystride)) \ - :"memory" \ - ); \ - } \ - while(0) - -# endif -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxidct.c b/src/add-ons/media/plugins/theora/libtheora/x86/mmxidct.c deleted file mode 100644 index 76424e6364..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxidct.c +++ /dev/null @@ -1,564 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: mmxidct.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -/*MMX acceleration of Theora's iDCT. - Originally written by Rudolf Marek, based on code from On2's VP3.*/ -#include "x86int.h" -#include "../dct.h" - -#if defined(OC_X86_ASM) - -/*These are offsets into the table of constants below.*/ -/*7 rows of cosines, in order: pi/16 * (1 ... 7).*/ -#define OC_COSINE_OFFSET (0) -/*A row of 8's.*/ -#define OC_EIGHT_OFFSET (56) - - - -/*A table of constants used by the MMX routines.*/ -static const ogg_uint16_t __attribute__((aligned(8),used)) - OC_IDCT_CONSTS[(7+1)*4]={ - (ogg_uint16_t)OC_C1S7,(ogg_uint16_t)OC_C1S7, - (ogg_uint16_t)OC_C1S7,(ogg_uint16_t)OC_C1S7, - (ogg_uint16_t)OC_C2S6,(ogg_uint16_t)OC_C2S6, - (ogg_uint16_t)OC_C2S6,(ogg_uint16_t)OC_C2S6, - (ogg_uint16_t)OC_C3S5,(ogg_uint16_t)OC_C3S5, - (ogg_uint16_t)OC_C3S5,(ogg_uint16_t)OC_C3S5, - (ogg_uint16_t)OC_C4S4,(ogg_uint16_t)OC_C4S4, - (ogg_uint16_t)OC_C4S4,(ogg_uint16_t)OC_C4S4, - (ogg_uint16_t)OC_C5S3,(ogg_uint16_t)OC_C5S3, - (ogg_uint16_t)OC_C5S3,(ogg_uint16_t)OC_C5S3, - (ogg_uint16_t)OC_C6S2,(ogg_uint16_t)OC_C6S2, - (ogg_uint16_t)OC_C6S2,(ogg_uint16_t)OC_C6S2, - (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1, - (ogg_uint16_t)OC_C7S1,(ogg_uint16_t)OC_C7S1, - 8, 8, 8, 8 -}; - -/*Converts the expression in the argument to a string.*/ -#define OC_M2STR(_s) #_s - -/*38 cycles*/ -#define OC_IDCT_BEGIN \ - "#OC_IDCT_BEGIN\n\t" \ - "movq "OC_I(3)",%%mm2\n\t" \ - "movq "OC_C(3)",%%mm6\n\t" \ - "movq %%mm2,%%mm4\n\t" \ - "movq "OC_J(5)",%%mm7\n\t" \ - "pmulhw %%mm6,%%mm4\n\t" \ - "movq "OC_C(5)",%%mm1\n\t" \ - "pmulhw %%mm7,%%mm6\n\t" \ - "movq %%mm1,%%mm5\n\t" \ - "pmulhw %%mm2,%%mm1\n\t" \ - "movq "OC_I(1)",%%mm3\n\t" \ - "pmulhw %%mm7,%%mm5\n\t" \ - "movq "OC_C(1)",%%mm0\n\t" \ - "paddw %%mm2,%%mm4\n\t" \ - "paddw %%mm7,%%mm6\n\t" \ - "paddw %%mm1,%%mm2\n\t" \ - "movq "OC_J(7)",%%mm1\n\t" \ - "paddw %%mm5,%%mm7\n\t" \ - "movq %%mm0,%%mm5\n\t" \ - "pmulhw %%mm3,%%mm0\n\t" \ - "paddw %%mm7,%%mm4\n\t" \ - "pmulhw %%mm1,%%mm5\n\t" \ - "movq "OC_C(7)",%%mm7\n\t" \ - "psubw %%mm2,%%mm6\n\t" \ - "paddw %%mm3,%%mm0\n\t" \ - "pmulhw %%mm7,%%mm3\n\t" \ - "movq "OC_I(2)",%%mm2\n\t" \ - "pmulhw %%mm1,%%mm7\n\t" \ - "paddw %%mm1,%%mm5\n\t" \ - "movq %%mm2,%%mm1\n\t" \ - "pmulhw "OC_C(2)",%%mm2\n\t" \ - "psubw %%mm5,%%mm3\n\t" \ - "movq "OC_J(6)",%%mm5\n\t" \ - "paddw %%mm7,%%mm0\n\t" \ - "movq %%mm5,%%mm7\n\t" \ - "psubw %%mm4,%%mm0\n\t" \ - "pmulhw "OC_C(2)",%%mm5\n\t" \ - "paddw %%mm1,%%mm2\n\t" \ - "pmulhw "OC_C(6)",%%mm1\n\t" \ - "paddw %%mm4,%%mm4\n\t" \ - "paddw %%mm0,%%mm4\n\t" \ - "psubw %%mm6,%%mm3\n\t" \ - "paddw %%mm7,%%mm5\n\t" \ - "paddw %%mm6,%%mm6\n\t" \ - "pmulhw "OC_C(6)",%%mm7\n\t" \ - "paddw %%mm3,%%mm6\n\t" \ - "movq %%mm4,"OC_I(1)"\n\t" \ - "psubw %%mm5,%%mm1\n\t" \ - "movq "OC_C(4)",%%mm4\n\t" \ - "movq %%mm3,%%mm5\n\t" \ - "pmulhw %%mm4,%%mm3\n\t" \ - "paddw %%mm2,%%mm7\n\t" \ - "movq %%mm6,"OC_I(2)"\n\t" \ - "movq %%mm0,%%mm2\n\t" \ - "movq "OC_I(0)",%%mm6\n\t" \ - "pmulhw %%mm4,%%mm0\n\t" \ - "paddw %%mm3,%%mm5\n\t" \ - "movq "OC_J(4)",%%mm3\n\t" \ - "psubw %%mm1,%%mm5\n\t" \ - "paddw %%mm0,%%mm2\n\t" \ - "psubw %%mm3,%%mm6\n\t" \ - "movq %%mm6,%%mm0\n\t" \ - "pmulhw %%mm4,%%mm6\n\t" \ - "paddw %%mm3,%%mm3\n\t" \ - "paddw %%mm1,%%mm1\n\t" \ - "paddw %%mm0,%%mm3\n\t" \ - "paddw %%mm5,%%mm1\n\t" \ - "pmulhw %%mm3,%%mm4\n\t" \ - "paddw %%mm0,%%mm6\n\t" \ - "psubw %%mm2,%%mm6\n\t" \ - "paddw %%mm2,%%mm2\n\t" \ - "movq "OC_I(1)",%%mm0\n\t" \ - "paddw %%mm6,%%mm2\n\t" \ - "paddw %%mm3,%%mm4\n\t" \ - "psubw %%mm1,%%mm2\n\t" \ - "#end OC_IDCT_BEGIN\n\t" \ - -/*38+8=46 cycles.*/ -#define OC_ROW_IDCT \ - "#OC_ROW_IDCT\n" \ - OC_IDCT_BEGIN \ - /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ - /*r4=E'=E-G*/ \ - "psubw %%mm7,%%mm4\n\t" \ - /*r1=H'+H'*/ \ - "paddw %%mm1,%%mm1\n\t" \ - /*r7=G+G*/ \ - "paddw %%mm7,%%mm7\n\t" \ - /*r1=R1=A''+H'*/ \ - "paddw %%mm2,%%mm1\n\t" \ - /*r7=G'=E+G*/ \ - "paddw %%mm4,%%mm7\n\t" \ - /*r4=R4=E'-D'*/ \ - "psubw %%mm3,%%mm4\n\t" \ - "paddw %%mm3,%%mm3\n\t" \ - /*r6=R6=F'-B''*/ \ - "psubw %%mm5,%%mm6\n\t" \ - "paddw %%mm5,%%mm5\n\t" \ - /*r3=R3=E'+D'*/ \ - "paddw %%mm4,%%mm3\n\t" \ - /*r5=R5=F'+B''*/ \ - "paddw %%mm6,%%mm5\n\t" \ - /*r7=R7=G'-C'*/ \ - "psubw %%mm0,%%mm7\n\t" \ - "paddw %%mm0,%%mm0\n\t" \ - /*Save R1.*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ - /*r0=R0=G.+C.*/ \ - "paddw %%mm7,%%mm0\n\t" \ - "#end OC_ROW_IDCT\n\t" \ - -/*The following macro does two 4x4 transposes in place. - At entry, we assume: - r0 = a3 a2 a1 a0 - I(1) = b3 b2 b1 b0 - r2 = c3 c2 c1 c0 - r3 = d3 d2 d1 d0 - - r4 = e3 e2 e1 e0 - r5 = f3 f2 f1 f0 - r6 = g3 g2 g1 g0 - r7 = h3 h2 h1 h0 - - At exit, we have: - I(0) = d0 c0 b0 a0 - I(1) = d1 c1 b1 a1 - I(2) = d2 c2 b2 a2 - I(3) = d3 c3 b3 a3 - - J(4) = h0 g0 f0 e0 - J(5) = h1 g1 f1 e1 - J(6) = h2 g2 f2 e2 - J(7) = h3 g3 f3 e3 - - I(0) I(1) I(2) I(3) is the transpose of r0 I(1) r2 r3. - J(4) J(5) J(6) J(7) is the transpose of r4 r5 r6 r7. - - Since r1 is free at entry, we calculate the Js first.*/ -/*19 cycles.*/ -#define OC_TRANSPOSE \ - "#OC_TRANSPOSE\n\t" \ - "movq %%mm4,%%mm1\n\t" \ - "punpcklwd %%mm5,%%mm4\n\t" \ - "movq %%mm0,"OC_I(0)"\n\t" \ - "punpckhwd %%mm5,%%mm1\n\t" \ - "movq %%mm6,%%mm0\n\t" \ - "punpcklwd %%mm7,%%mm6\n\t" \ - "movq %%mm4,%%mm5\n\t" \ - "punpckldq %%mm6,%%mm4\n\t" \ - "punpckhdq %%mm6,%%mm5\n\t" \ - "movq %%mm1,%%mm6\n\t" \ - "movq %%mm4,"OC_J(4)"\n\t" \ - "punpckhwd %%mm7,%%mm0\n\t" \ - "movq %%mm5,"OC_J(5)"\n\t" \ - "punpckhdq %%mm0,%%mm6\n\t" \ - "movq "OC_I(0)",%%mm4\n\t" \ - "punpckldq %%mm0,%%mm1\n\t" \ - "movq "OC_I(1)",%%mm5\n\t" \ - "movq %%mm4,%%mm0\n\t" \ - "movq %%mm6,"OC_J(7)"\n\t" \ - "punpcklwd %%mm5,%%mm0\n\t" \ - "movq %%mm1,"OC_J(6)"\n\t" \ - "punpckhwd %%mm5,%%mm4\n\t" \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklwd %%mm3,%%mm2\n\t" \ - "movq %%mm0,%%mm1\n\t" \ - "punpckldq %%mm2,%%mm0\n\t" \ - "punpckhdq %%mm2,%%mm1\n\t" \ - "movq %%mm4,%%mm2\n\t" \ - "movq %%mm0,"OC_I(0)"\n\t" \ - "punpckhwd %%mm3,%%mm5\n\t" \ - "movq %%mm1,"OC_I(1)"\n\t" \ - "punpckhdq %%mm5,%%mm4\n\t" \ - "punpckldq %%mm5,%%mm2\n\t" \ - "movq %%mm4,"OC_I(3)"\n\t" \ - "movq %%mm2,"OC_I(2)"\n\t" \ - "#end OC_TRANSPOSE\n\t" \ - -/*38+19=57 cycles.*/ -#define OC_COLUMN_IDCT \ - "#OC_COLUMN_IDCT\n" \ - OC_IDCT_BEGIN \ - "paddw "OC_8",%%mm2\n\t" \ - /*r1=H'+H'*/ \ - "paddw %%mm1,%%mm1\n\t" \ - /*r1=R1=A''+H'*/ \ - "paddw %%mm2,%%mm1\n\t" \ - /*r2=NR2*/ \ - "psraw $4,%%mm2\n\t" \ - /*r4=E'=E-G*/ \ - "psubw %%mm7,%%mm4\n\t" \ - /*r1=NR1*/ \ - "psraw $4,%%mm1\n\t" \ - /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ - /*r7=G+G*/ \ - "paddw %%mm7,%%mm7\n\t" \ - /*Store NR2 at I(2).*/ \ - "movq %%mm2,"OC_I(2)"\n\t" \ - /*r7=G'=E+G*/ \ - "paddw %%mm4,%%mm7\n\t" \ - /*Store NR1 at I(1).*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ - /*r4=R4=E'-D'*/ \ - "psubw %%mm3,%%mm4\n\t" \ - "paddw "OC_8",%%mm4\n\t" \ - /*r3=D'+D'*/ \ - "paddw %%mm3,%%mm3\n\t" \ - /*r3=R3=E'+D'*/ \ - "paddw %%mm4,%%mm3\n\t" \ - /*r4=NR4*/ \ - "psraw $4,%%mm4\n\t" \ - /*r6=R6=F'-B''*/ \ - "psubw %%mm5,%%mm6\n\t" \ - /*r3=NR3*/ \ - "psraw $4,%%mm3\n\t" \ - "paddw "OC_8",%%mm6\n\t" \ - /*r5=B''+B''*/ \ - "paddw %%mm5,%%mm5\n\t" \ - /*r5=R5=F'+B''*/ \ - "paddw %%mm6,%%mm5\n\t" \ - /*r6=NR6*/ \ - "psraw $4,%%mm6\n\t" \ - /*Store NR4 at J(4).*/ \ - "movq %%mm4,"OC_J(4)"\n\t" \ - /*r5=NR5*/ \ - "psraw $4,%%mm5\n\t" \ - /*Store NR3 at I(3).*/ \ - "movq %%mm3,"OC_I(3)"\n\t" \ - /*r7=R7=G'-C'*/ \ - "psubw %%mm0,%%mm7\n\t" \ - "paddw "OC_8",%%mm7\n\t" \ - /*r0=C'+C'*/ \ - "paddw %%mm0,%%mm0\n\t" \ - /*r0=R0=G'+C'*/ \ - "paddw %%mm7,%%mm0\n\t" \ - /*r7=NR7*/ \ - "psraw $4,%%mm7\n\t" \ - /*Store NR6 at J(6).*/ \ - "movq %%mm6,"OC_J(6)"\n\t" \ - /*r0=NR0*/ \ - "psraw $4,%%mm0\n\t" \ - /*Store NR5 at J(5).*/ \ - "movq %%mm5,"OC_J(5)"\n\t" \ - /*Store NR7 at J(7).*/ \ - "movq %%mm7,"OC_J(7)"\n\t" \ - /*Store NR0 at I(0).*/ \ - "movq %%mm0,"OC_I(0)"\n\t" \ - "#end OC_COLUMN_IDCT\n\t" \ - -#define OC_MID(_m,_i) OC_M2STR(_m+(_i)*8)"(%[c])" -#define OC_C(_i) OC_MID(OC_COSINE_OFFSET,_i-1) -#define OC_8 OC_MID(OC_EIGHT_OFFSET,0) - -static void oc_idct8x8_slow(ogg_int16_t _y[64]){ - /*This routine accepts an 8x8 matrix, but in partially transposed form. - Every 4x4 block is transposed.*/ - __asm__ __volatile__( -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_M2STR(((_k-4)*16)+8)"(%[y])" - OC_ROW_IDCT - OC_TRANSPOSE -#undef OC_I -#undef OC_J -#define OC_I(_k) OC_M2STR((_k*16)+64)"(%[y])" -#define OC_J(_k) OC_M2STR(((_k-4)*16)+72)"(%[y])" - OC_ROW_IDCT - OC_TRANSPOSE -#undef OC_I -#undef OC_J -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT -#undef OC_I -#undef OC_J -#define OC_I(_k) OC_M2STR((_k*16)+8)"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT -#undef OC_I -#undef OC_J - : - :[y]"r"(_y),[c]"r"(OC_IDCT_CONSTS) - ); -} - -/*25 cycles.*/ -#define OC_IDCT_BEGIN_10 \ - "#OC_IDCT_BEGIN_10\n\t" \ - "movq "OC_I(3)",%%mm2\n\t" \ - "nop\n\t" \ - "movq "OC_C(3)",%%mm6\n\t" \ - "movq %%mm2,%%mm4\n\t" \ - "movq "OC_C(5)",%%mm1\n\t" \ - "pmulhw %%mm6,%%mm4\n\t" \ - "movq "OC_I(1)",%%mm3\n\t" \ - "pmulhw %%mm2,%%mm1\n\t" \ - "movq "OC_C(1)",%%mm0\n\t" \ - "paddw %%mm2,%%mm4\n\t" \ - "pxor %%mm6,%%mm6\n\t" \ - "paddw %%mm1,%%mm2\n\t" \ - "movq "OC_I(2)",%%mm5\n\t" \ - "pmulhw %%mm3,%%mm0\n\t" \ - "movq %%mm5,%%mm1\n\t" \ - "paddw %%mm3,%%mm0\n\t" \ - "pmulhw "OC_C(7)",%%mm3\n\t" \ - "psubw %%mm2,%%mm6\n\t" \ - "pmulhw "OC_C(2)",%%mm5\n\t" \ - "psubw %%mm4,%%mm0\n\t" \ - "movq "OC_I(2)",%%mm7\n\t" \ - "paddw %%mm4,%%mm4\n\t" \ - "paddw %%mm5,%%mm7\n\t" \ - "paddw %%mm0,%%mm4\n\t" \ - "pmulhw "OC_C(6)",%%mm1\n\t" \ - "psubw %%mm6,%%mm3\n\t" \ - "movq %%mm4,"OC_I(1)"\n\t" \ - "paddw %%mm6,%%mm6\n\t" \ - "movq "OC_C(4)",%%mm4\n\t" \ - "paddw %%mm3,%%mm6\n\t" \ - "movq %%mm3,%%mm5\n\t" \ - "pmulhw %%mm4,%%mm3\n\t" \ - "movq %%mm6,"OC_I(2)"\n\t" \ - "movq %%mm0,%%mm2\n\t" \ - "movq "OC_I(0)",%%mm6\n\t" \ - "pmulhw %%mm4,%%mm0\n\t" \ - "paddw %%mm3,%%mm5\n\t" \ - "paddw %%mm0,%%mm2\n\t" \ - "psubw %%mm1,%%mm5\n\t" \ - "pmulhw %%mm4,%%mm6\n\t" \ - "paddw "OC_I(0)",%%mm6\n\t" \ - "paddw %%mm1,%%mm1\n\t" \ - "movq %%mm6,%%mm4\n\t" \ - "paddw %%mm5,%%mm1\n\t" \ - "psubw %%mm2,%%mm6\n\t" \ - "paddw %%mm2,%%mm2\n\t" \ - "movq "OC_I(1)",%%mm0\n\t" \ - "paddw %%mm6,%%mm2\n\t" \ - "psubw %%mm1,%%mm2\n\t" \ - "nop\n\t" \ - "#end OC_IDCT_BEGIN_10\n\t" \ - -/*25+8=33 cycles.*/ -#define OC_ROW_IDCT_10 \ - "#OC_ROW_IDCT_10\n\t" \ - OC_IDCT_BEGIN_10 \ - /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ - /*r4=E'=E-G*/ \ - "psubw %%mm7,%%mm4\n\t" \ - /*r1=H'+H'*/ \ - "paddw %%mm1,%%mm1\n\t" \ - /*r7=G+G*/ \ - "paddw %%mm7,%%mm7\n\t" \ - /*r1=R1=A''+H'*/ \ - "paddw %%mm2,%%mm1\n\t" \ - /*r7=G'=E+G*/ \ - "paddw %%mm4,%%mm7\n\t" \ - /*r4=R4=E'-D'*/ \ - "psubw %%mm3,%%mm4\n\t" \ - "paddw %%mm3,%%mm3\n\t" \ - /*r6=R6=F'-B''*/ \ - "psubw %%mm5,%%mm6\n\t" \ - "paddw %%mm5,%%mm5\n\t" \ - /*r3=R3=E'+D'*/ \ - "paddw %%mm4,%%mm3\n\t" \ - /*r5=R5=F'+B''*/ \ - "paddw %%mm6,%%mm5\n\t" \ - /*r7=R7=G'-C'*/ \ - "psubw %%mm0,%%mm7\n\t" \ - "paddw %%mm0,%%mm0\n\t" \ - /*Save R1.*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ - /*r0=R0=G'+C'*/ \ - "paddw %%mm7,%%mm0\n\t" \ - "#end OC_ROW_IDCT_10\n\t" \ - -/*25+19=44 cycles'*/ -#define OC_COLUMN_IDCT_10 \ - "#OC_COLUMN_IDCT_10\n\t" \ - OC_IDCT_BEGIN_10 \ - "paddw "OC_8",%%mm2\n\t" \ - /*r1=H'+H'*/ \ - "paddw %%mm1,%%mm1\n\t" \ - /*r1=R1=A''+H'*/ \ - "paddw %%mm2,%%mm1\n\t" \ - /*r2=NR2*/ \ - "psraw $4,%%mm2\n\t" \ - /*r4=E'=E-G*/ \ - "psubw %%mm7,%%mm4\n\t" \ - /*r1=NR1*/ \ - "psraw $4,%%mm1\n\t" \ - /*r3=D'*/ \ - "movq "OC_I(2)",%%mm3\n\t" \ - /*r7=G+G*/ \ - "paddw %%mm7,%%mm7\n\t" \ - /*Store NR2 at I(2).*/ \ - "movq %%mm2,"OC_I(2)"\n\t" \ - /*r7=G'=E+G*/ \ - "paddw %%mm4,%%mm7\n\t" \ - /*Store NR1 at I(1).*/ \ - "movq %%mm1,"OC_I(1)"\n\t" \ - /*r4=R4=E'-D'*/ \ - "psubw %%mm3,%%mm4\n\t" \ - "paddw "OC_8",%%mm4\n\t" \ - /*r3=D'+D'*/ \ - "paddw %%mm3,%%mm3\n\t" \ - /*r3=R3=E'+D'*/ \ - "paddw %%mm4,%%mm3\n\t" \ - /*r4=NR4*/ \ - "psraw $4,%%mm4\n\t" \ - /*r6=R6=F'-B''*/ \ - "psubw %%mm5,%%mm6\n\t" \ - /*r3=NR3*/ \ - "psraw $4,%%mm3\n\t" \ - "paddw "OC_8",%%mm6\n\t" \ - /*r5=B''+B''*/ \ - "paddw %%mm5,%%mm5\n\t" \ - /*r5=R5=F'+B''*/ \ - "paddw %%mm6,%%mm5\n\t" \ - /*r6=NR6*/ \ - "psraw $4,%%mm6\n\t" \ - /*Store NR4 at J(4).*/ \ - "movq %%mm4,"OC_J(4)"\n\t" \ - /*r5=NR5*/ \ - "psraw $4,%%mm5\n\t" \ - /*Store NR3 at I(3).*/ \ - "movq %%mm3,"OC_I(3)"\n\t" \ - /*r7=R7=G'-C'*/ \ - "psubw %%mm0,%%mm7\n\t" \ - "paddw "OC_8",%%mm7\n\t" \ - /*r0=C'+C'*/ \ - "paddw %%mm0,%%mm0\n\t" \ - /*r0=R0=G'+C'*/ \ - "paddw %%mm7,%%mm0\n\t" \ - /*r7=NR7*/ \ - "psraw $4,%%mm7\n\t" \ - /*Store NR6 at J(6).*/ \ - "movq %%mm6,"OC_J(6)"\n\t" \ - /*r0=NR0*/ \ - "psraw $4,%%mm0\n\t" \ - /*Store NR5 at J(5).*/ \ - "movq %%mm5,"OC_J(5)"\n\t" \ - /*Store NR7 at J(7).*/ \ - "movq %%mm7,"OC_J(7)"\n\t" \ - /*Store NR0 at I(0).*/ \ - "movq %%mm0,"OC_I(0)"\n\t" \ - "#end OC_COLUMN_IDCT_10\n\t" \ - -static void oc_idct8x8_10(ogg_int16_t _y[64]){ - __asm__ __volatile__( -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_M2STR(((_k-4)*16)+8)"(%[y])" - /*Done with dequant, descramble, and partial transpose. - Now do the iDCT itself.*/ - OC_ROW_IDCT_10 - OC_TRANSPOSE -#undef OC_I -#undef OC_J -#define OC_I(_k) OC_M2STR((_k*16))"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT_10 -#undef OC_I -#undef OC_J -#define OC_I(_k) OC_M2STR((_k*16)+8)"(%[y])" -#define OC_J(_k) OC_I(_k) - OC_COLUMN_IDCT_10 -#undef OC_I -#undef OC_J - : - :[y]"r"(_y),[c]"r"(OC_IDCT_CONSTS) - ); -} - -/*Performs an inverse 8x8 Type-II DCT transform. - The input is assumed to be scaled by a factor of 4 relative to orthonormal - version of the transform.*/ -void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi){ - /*_last_zzi is subtly different from an actual count of the number of - coefficients we decoded for this block. - It contains the value of zzi BEFORE the final token in the block was - decoded. - In most cases this is an EOB token (the continuation of an EOB run from a - previous block counts), and so this is the same as the coefficient count. - However, in the case that the last token was NOT an EOB token, but filled - the block up with exactly 64 coefficients, _last_zzi will be less than 64. - Provided the last token was not a pure zero run, the minimum value it can - be is 46, and so that doesn't affect any of the cases in this routine. - However, if the last token WAS a pure zero run of length 63, then _last_zzi - will be 1 while the number of coefficients decoded is 64. - Thus, we will trigger the following special case, where the real - coefficient count would not. - Note also that a zero run of length 64 will give _last_zzi a value of 0, - but we still process the DC coefficient, which might have a non-zero value - due to DC prediction. - Although convoluted, this is arguably the correct behavior: it allows us to - use a smaller transform when the block ends with a long zero run instead - of a normal EOB token. - It could be smarter... multiple separate zero runs at the end of a block - will fool it, but an encoder that generates these really deserves what it - gets. - Needless to say we inherited this approach from VP3.*/ - /*Then perform the iDCT.*/ - if(_last_zzi<10)oc_idct8x8_10(_y); - else oc_idct8x8_slow(_y); -} - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxloop.h b/src/add-ons/media/plugins/theora/libtheora/x86/mmxloop.h deleted file mode 100644 index 2e870c795d..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxloop.h +++ /dev/null @@ -1,215 +0,0 @@ -#if !defined(_x86_mmxloop_H) -# define _x86_mmxloop_H (1) -# include -# include "x86int.h" - -#if defined(OC_X86_ASM) - -/*On entry, mm0={a0,...,a7}, mm1={b0,...,b7}, mm2={c0,...,c7}, mm3={d0,...d7}. - On exit, mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)} and - mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}; mm0 and mm3 are clobbered.*/ -#define OC_LOOP_FILTER8_MMX \ - "#OC_LOOP_FILTER8_MMX\n\t" \ - /*mm7=0*/ \ - "pxor %%mm7,%%mm7\n\t" \ - /*mm6:mm0={a0,...,a7}*/ \ - "movq %%mm0,%%mm6\n\t" \ - "punpcklbw %%mm7,%%mm0\n\t" \ - "punpckhbw %%mm7,%%mm6\n\t" \ - /*mm3:mm5={d0,...,d7}*/ \ - "movq %%mm3,%%mm5\n\t" \ - "punpcklbw %%mm7,%%mm3\n\t" \ - "punpckhbw %%mm7,%%mm5\n\t" \ - /*mm6:mm0={a0-d0,...,a7-d7}*/ \ - "psubw %%mm3,%%mm0\n\t" \ - "psubw %%mm5,%%mm6\n\t" \ - /*mm3:mm1={b0,...,b7}*/ \ - "movq %%mm1,%%mm3\n\t" \ - "punpcklbw %%mm7,%%mm1\n\t" \ - "movq %%mm2,%%mm4\n\t" \ - "punpckhbw %%mm7,%%mm3\n\t" \ - /*mm5:mm4={c0,...,c7}*/ \ - "movq %%mm2,%%mm5\n\t" \ - "punpcklbw %%mm7,%%mm4\n\t" \ - "punpckhbw %%mm7,%%mm5\n\t" \ - /*mm7={3}x4 \ - mm5:mm4={c0-b0,...,c7-b7}*/ \ - "pcmpeqw %%mm7,%%mm7\n\t" \ - "psubw %%mm1,%%mm4\n\t" \ - "psrlw $14,%%mm7\n\t" \ - "psubw %%mm3,%%mm5\n\t" \ - /*Scale by 3.*/ \ - "pmullw %%mm7,%%mm4\n\t" \ - "pmullw %%mm7,%%mm5\n\t" \ - /*mm7={4}x4 \ - mm5:mm4=f={a0-d0+3*(c0-b0),...,a7-d7+3*(c7-b7)}*/ \ - "psrlw $1,%%mm7\n\t" \ - "paddw %%mm0,%%mm4\n\t" \ - "psllw $2,%%mm7\n\t" \ - "movq (%[ll]),%%mm0\n\t" \ - "paddw %%mm6,%%mm5\n\t" \ - /*R_i has the range [-127,128], so we compute -R_i instead. \ - mm4=-R_i=-(f+4>>3)=0xFF^(f-4>>3)*/ \ - "psubw %%mm7,%%mm4\n\t" \ - "psubw %%mm7,%%mm5\n\t" \ - "psraw $3,%%mm4\n\t" \ - "psraw $3,%%mm5\n\t" \ - "pcmpeqb %%mm7,%%mm7\n\t" \ - "packsswb %%mm5,%%mm4\n\t" \ - "pxor %%mm6,%%mm6\n\t" \ - "pxor %%mm7,%%mm4\n\t" \ - "packuswb %%mm3,%%mm1\n\t" \ - /*Now compute lflim of -mm4 cf. Section 7.10 of the sepc.*/ \ - /*There's no unsigned byte+signed byte with unsigned saturation op code, so \ - we have to split things by sign (the other option is to work in 16 bits, \ - but working in 8 bits gives much better parallelism). \ - We compute abs(R_i), but save a mask of which terms were negative in mm6. \ - Then we compute mm4=abs(lflim(R_i,L))=min(abs(R_i),max(2*L-abs(R_i),0)). \ - Finally, we split mm4 into positive and negative pieces using the mask in \ - mm6, and add and subtract them as appropriate.*/ \ - /*mm4=abs(-R_i)*/ \ - /*mm7=255-2*L*/ \ - "pcmpgtb %%mm4,%%mm6\n\t" \ - "psubb %%mm0,%%mm7\n\t" \ - "pxor %%mm6,%%mm4\n\t" \ - "psubb %%mm0,%%mm7\n\t" \ - "psubb %%mm6,%%mm4\n\t" \ - /*mm7=255-max(2*L-abs(R_i),0)*/ \ - "paddusb %%mm4,%%mm7\n\t" \ - /*mm4=min(abs(R_i),max(2*L-abs(R_i),0))*/ \ - "paddusb %%mm7,%%mm4\n\t" \ - "psubusb %%mm7,%%mm4\n\t" \ - /*Now split mm4 by the original sign of -R_i.*/ \ - "movq %%mm4,%%mm5\n\t" \ - "pand %%mm6,%%mm4\n\t" \ - "pandn %%mm5,%%mm6\n\t" \ - /*mm1={b0+lflim(R_0,L),...,b7+lflim(R_7,L)}*/ \ - /*mm2={c0-lflim(R_0,L),...,c7-lflim(R_7,L)}*/ \ - "paddusb %%mm4,%%mm1\n\t" \ - "psubusb %%mm4,%%mm2\n\t" \ - "psubusb %%mm6,%%mm1\n\t" \ - "paddusb %%mm6,%%mm2\n\t" \ - -#define OC_LOOP_FILTER_V_MMX(_pix,_ystride,_ll) \ - do{ \ - ptrdiff_t ystride3__; \ - __asm__ __volatile__( \ - /*mm0={a0,...,a7}*/ \ - "movq (%[pix]),%%mm0\n\t" \ - /*ystride3=_ystride*3*/ \ - "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" \ - /*mm3={d0,...,d7}*/ \ - "movq (%[pix],%[ystride3]),%%mm3\n\t" \ - /*mm1={b0,...,b7}*/ \ - "movq (%[pix],%[ystride]),%%mm1\n\t" \ - /*mm2={c0,...,c7}*/ \ - "movq (%[pix],%[ystride],2),%%mm2\n\t" \ - OC_LOOP_FILTER8_MMX \ - /*Write it back out.*/ \ - "movq %%mm1,(%[pix],%[ystride])\n\t" \ - "movq %%mm2,(%[pix],%[ystride],2)\n\t" \ - :[ystride3]"=&r"(ystride3__) \ - :[pix]"r"(_pix-_ystride*2),[ystride]"r"((ptrdiff_t)(_ystride)), \ - [ll]"r"(_ll) \ - :"memory" \ - ); \ - } \ - while(0) - -#define OC_LOOP_FILTER_H_MMX(_pix,_ystride,_ll) \ - do{ \ - unsigned char *pix__; \ - ptrdiff_t ystride3__; \ - ptrdiff_t d__; \ - pix__=(_pix)-2; \ - __asm__ __volatile__( \ - /*x x x x d0 c0 b0 a0*/ \ - "movd (%[pix]),%%mm0\n\t" \ - /*x x x x d1 c1 b1 a1*/ \ - "movd (%[pix],%[ystride]),%%mm1\n\t" \ - /*ystride3=_ystride*3*/ \ - "lea (%[ystride],%[ystride],2),%[ystride3]\n\t" \ - /*x x x x d2 c2 b2 a2*/ \ - "movd (%[pix],%[ystride],2),%%mm2\n\t" \ - /*x x x x d3 c3 b3 a3*/ \ - "lea (%[pix],%[ystride],4),%[d]\n\t" \ - "movd (%[pix],%[ystride3]),%%mm3\n\t" \ - /*x x x x d4 c4 b4 a4*/ \ - "movd (%[d]),%%mm4\n\t" \ - /*x x x x d5 c5 b5 a5*/ \ - "movd (%[d],%[ystride]),%%mm5\n\t" \ - /*x x x x d6 c6 b6 a6*/ \ - "movd (%[d],%[ystride],2),%%mm6\n\t" \ - /*x x x x d7 c7 b7 a7*/ \ - "movd (%[d],%[ystride3]),%%mm7\n\t" \ - /*mm0=d1 d0 c1 c0 b1 b0 a1 a0*/ \ - "punpcklbw %%mm1,%%mm0\n\t" \ - /*mm2=d3 d2 c3 c2 b3 b2 a3 a2*/ \ - "punpcklbw %%mm3,%%mm2\n\t" \ - /*mm3=d1 d0 c1 c0 b1 b0 a1 a0*/ \ - "movq %%mm0,%%mm3\n\t" \ - /*mm0=b3 b2 b1 b0 a3 a2 a1 a0*/ \ - "punpcklwd %%mm2,%%mm0\n\t" \ - /*mm3=d3 d2 d1 d0 c3 c2 c1 c0*/ \ - "punpckhwd %%mm2,%%mm3\n\t" \ - /*mm1=b3 b2 b1 b0 a3 a2 a1 a0*/ \ - "movq %%mm0,%%mm1\n\t" \ - /*mm4=d5 d4 c5 c4 b5 b4 a5 a4*/ \ - "punpcklbw %%mm5,%%mm4\n\t" \ - /*mm6=d7 d6 c7 c6 b7 b6 a7 a6*/ \ - "punpcklbw %%mm7,%%mm6\n\t" \ - /*mm5=d5 d4 c5 c4 b5 b4 a5 a4*/ \ - "movq %%mm4,%%mm5\n\t" \ - /*mm4=b7 b6 b5 b4 a7 a6 a5 a4*/ \ - "punpcklwd %%mm6,%%mm4\n\t" \ - /*mm5=d7 d6 d5 d4 c7 c6 c5 c4*/ \ - "punpckhwd %%mm6,%%mm5\n\t" \ - /*mm2=d3 d2 d1 d0 c3 c2 c1 c0*/ \ - "movq %%mm3,%%mm2\n\t" \ - /*mm0=a7 a6 a5 a4 a3 a2 a1 a0*/ \ - "punpckldq %%mm4,%%mm0\n\t" \ - /*mm1=b7 b6 b5 b4 b3 b2 b1 b0*/ \ - "punpckhdq %%mm4,%%mm1\n\t" \ - /*mm2=c7 c6 c5 c4 c3 c2 c1 c0*/ \ - "punpckldq %%mm5,%%mm2\n\t" \ - /*mm3=d7 d6 d5 d4 d3 d2 d1 d0*/ \ - "punpckhdq %%mm5,%%mm3\n\t" \ - OC_LOOP_FILTER8_MMX \ - /*mm2={b0+R_0'',...,b7+R_7''}*/ \ - "movq %%mm1,%%mm0\n\t" \ - /*mm1={b0+R_0'',c0-R_0'',...,b3+R_3'',c3-R_3''}*/ \ - "punpcklbw %%mm2,%%mm1\n\t" \ - /*mm2={b4+R_4'',c4-R_4'',...,b7+R_7'',c7-R_7''}*/ \ - "punpckhbw %%mm2,%%mm0\n\t" \ - /*[d]=c1 b1 c0 b0*/ \ - "movd %%mm1,%[d]\n\t" \ - "movw %w[d],1(%[pix])\n\t" \ - "psrlq $32,%%mm1\n\t" \ - "shr $16,%[d]\n\t" \ - "movw %w[d],1(%[pix],%[ystride])\n\t" \ - /*[d]=c3 b3 c2 b2*/ \ - "movd %%mm1,%[d]\n\t" \ - "movw %w[d],1(%[pix],%[ystride],2)\n\t" \ - "shr $16,%[d]\n\t" \ - "movw %w[d],1(%[pix],%[ystride3])\n\t" \ - "lea (%[pix],%[ystride],4),%[pix]\n\t" \ - /*[d]=c5 b5 c4 b4*/ \ - "movd %%mm0,%[d]\n\t" \ - "movw %w[d],1(%[pix])\n\t" \ - "psrlq $32,%%mm0\n\t" \ - "shr $16,%[d]\n\t" \ - "movw %w[d],1(%[pix],%[ystride])\n\t" \ - /*[d]=c7 b7 c6 b6*/ \ - "movd %%mm0,%[d]\n\t" \ - "movw %w[d],1(%[pix],%[ystride],2)\n\t" \ - "shr $16,%[d]\n\t" \ - "movw %w[d],1(%[pix],%[ystride3])\n\t" \ - :[pix]"+r"(pix__),[ystride3]"=&r"(ystride3__),[d]"=&r"(d__) \ - :[ystride]"r"((ptrdiff_t)(_ystride)),[ll]"r"(_ll) \ - :"memory" \ - ); \ - } \ - while(0) - -# endif -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/mmxstate.c b/src/add-ons/media/plugins/theora/libtheora/x86/mmxstate.c deleted file mode 100644 index 808b0a789b..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/mmxstate.c +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: mmxstate.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -/*MMX acceleration of complete fragment reconstruction algorithm. - Originally written by Rudolf Marek.*/ -#include -#include "x86int.h" -#include "mmxfrag.h" -#include "mmxloop.h" - -#if defined(OC_X86_ASM) - -void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant){ - unsigned char *dst; - ptrdiff_t frag_buf_off; - int ystride; - int mb_mode; - /*Apply the inverse transform.*/ - /*Special case only having a DC component.*/ - if(_last_zzi<2){ - /*Note that this value must be unsigned, to keep the __asm__ block from - sign-extending it when it puts it in a register.*/ - ogg_uint16_t p; - /*We round this dequant product (and not any of the others) because there's - no iDCT rounding.*/ - p=(ogg_int16_t)(_dct_coeffs[0]*(ogg_int32_t)_dc_quant+15>>5); - /*Fill _dct_coeffs with p.*/ - __asm__ __volatile__( - /*mm0=0000 0000 0000 AAAA*/ - "movd %[p],%%mm0\n\t" - /*mm0=0000 0000 AAAA AAAA*/ - "punpcklwd %%mm0,%%mm0\n\t" - /*mm0=AAAA AAAA AAAA AAAA*/ - "punpckldq %%mm0,%%mm0\n\t" - "movq %%mm0,(%[y])\n\t" - "movq %%mm0,8(%[y])\n\t" - "movq %%mm0,16(%[y])\n\t" - "movq %%mm0,24(%[y])\n\t" - "movq %%mm0,32(%[y])\n\t" - "movq %%mm0,40(%[y])\n\t" - "movq %%mm0,48(%[y])\n\t" - "movq %%mm0,56(%[y])\n\t" - "movq %%mm0,64(%[y])\n\t" - "movq %%mm0,72(%[y])\n\t" - "movq %%mm0,80(%[y])\n\t" - "movq %%mm0,88(%[y])\n\t" - "movq %%mm0,96(%[y])\n\t" - "movq %%mm0,104(%[y])\n\t" - "movq %%mm0,112(%[y])\n\t" - "movq %%mm0,120(%[y])\n\t" - : - :[y]"r"(_dct_coeffs),[p]"r"((unsigned)p) - :"memory" - ); - } - else{ - /*Dequantize the DC coefficient.*/ - _dct_coeffs[0]=(ogg_int16_t)(_dct_coeffs[0]*(int)_dc_quant); - oc_idct8x8_mmx(_dct_coeffs,_last_zzi); - } - /*Fill in the target buffer.*/ - frag_buf_off=_state->frag_buf_offs[_fragi]; - mb_mode=_state->frags[_fragi].mb_mode; - ystride=_state->ref_ystride[_pli]; - dst=_state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_SELF]]+frag_buf_off; - if(mb_mode==OC_MODE_INTRA)oc_frag_recon_intra_mmx(dst,ystride,_dct_coeffs); - else{ - const unsigned char *ref; - int mvoffsets[2]; - ref= - _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]] - +frag_buf_off; - if(oc_state_get_mv_offsets(_state,mvoffsets,_pli, - _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){ - oc_frag_recon_inter2_mmx(dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride, - _dct_coeffs); - } - else oc_frag_recon_inter_mmx(dst,ref+mvoffsets[0],ystride,_dct_coeffs); - } -} - -/*We copy these entire function to inline the actual MMX routines so that we - use only a single indirect call.*/ - -/*Copies the fragments specified by the lists of fragment indices from one - frame to another. - _fragis: A pointer to a list of fragment indices. - _nfragis: The number of fragment indices to copy. - _dst_frame: The reference frame to copy to. - _src_frame: The reference frame to copy from. - _pli: The color plane the fragments lie in.*/ -void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli){ - const ptrdiff_t *frag_buf_offs; - const unsigned char *src_frame_data; - unsigned char *dst_frame_data; - ptrdiff_t fragii; - int ystride; - dst_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_dst_frame]]; - src_frame_data=_state->ref_frame_data[_state->ref_frame_idx[_src_frame]]; - ystride=_state->ref_ystride[_pli]; - frag_buf_offs=_state->frag_buf_offs; - for(fragii=0;fragii<_nfragis;fragii++){ - ptrdiff_t frag_buf_off; - frag_buf_off=frag_buf_offs[_fragis[fragii]]; - OC_FRAG_COPY_MMX(dst_frame_data+frag_buf_off, - src_frame_data+frag_buf_off,ystride); - } -} - -/*Apply the loop filter to a given set of fragment rows in the given plane. - The filter may be run on the bottom edge, affecting pixels in the next row of - fragments, so this row also needs to be available. - _bv: The bounding values array. - _refi: The index of the frame buffer to filter. - _pli: The color plane to filter. - _fragy0: The Y coordinate of the first fragment row to filter. - _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/ -void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end){ - OC_ALIGN8(unsigned char ll[8]); - const oc_fragment_plane *fplane; - const oc_fragment *frags; - const ptrdiff_t *frag_buf_offs; - unsigned char *ref_frame_data; - ptrdiff_t fragi_top; - ptrdiff_t fragi_bot; - ptrdiff_t fragi0; - ptrdiff_t fragi0_end; - int ystride; - int nhfrags; - memset(ll,_state->loop_filter_limits[_state->qis[0]],sizeof(ll)); - fplane=_state->fplanes+_pli; - nhfrags=fplane->nhfrags; - fragi_top=fplane->froffset; - fragi_bot=fragi_top+fplane->nfrags; - fragi0=fragi_top+_fragy0*(ptrdiff_t)nhfrags; - fragi0_end=fragi0+(_fragy_end-_fragy0)*(ptrdiff_t)nhfrags; - ystride=_state->ref_ystride[_pli]; - frags=_state->frags; - frag_buf_offs=_state->frag_buf_offs; - ref_frame_data=_state->ref_frame_data[_refi]; - /*The following loops are constructed somewhat non-intuitively on purpose. - The main idea is: if a block boundary has at least one coded fragment on - it, the filter is applied to it. - However, the order that the filters are applied in matters, and VP3 chose - the somewhat strange ordering used below.*/ - while(fragi0fragi0)OC_LOOP_FILTER_H_MMX(ref,ystride,ll); - if(fragi0>fragi_top)OC_LOOP_FILTER_V_MMX(ref,ystride,ll); - if(fragi+1 -#include "x86enc.h" - -#if defined(OC_X86_64_ASM) - -# define OC_FDCT8x8 \ - /*Note: xmm15={0}x8 and xmm14={-1}x8.*/ \ - "#OC_FDCT8x8\n\t" \ - /*Stage 1:*/ \ - "movdqa %%xmm0,%%xmm11\n\t" \ - "movdqa %%xmm1,%%xmm10\n\t" \ - "movdqa %%xmm2,%%xmm9\n\t" \ - "movdqa %%xmm3,%%xmm8\n\t" \ - /*xmm11=t7'=t0-t7*/ \ - "psubw %%xmm7,%%xmm11\n\t" \ - /*xmm10=t6'=t1-t6*/ \ - "psubw %%xmm6,%%xmm10\n\t" \ - /*xmm9=t5'=t2-t5*/ \ - "psubw %%xmm5,%%xmm9\n\t" \ - /*xmm8=t4'=t3-t4*/ \ - "psubw %%xmm4,%%xmm8\n\t" \ - /*xmm0=t0'=t0+t7*/ \ - "paddw %%xmm7,%%xmm0\n\t" \ - /*xmm1=t1'=t1+t6*/ \ - "paddw %%xmm6,%%xmm1\n\t" \ - /*xmm5=t2'=t2+t5*/ \ - "paddw %%xmm2,%%xmm5\n\t" \ - /*xmm4=t3'=t3+t4*/ \ - "paddw %%xmm3,%%xmm4\n\t" \ - /*xmm2,3,6,7 are now free.*/ \ - /*Stage 2:*/ \ - "movdqa %%xmm0,%%xmm3\n\t" \ - "mov $0x5A806A0A,%[a]\n\t" \ - "movdqa %%xmm1,%%xmm2\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "movdqa %%xmm10,%%xmm6\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - /*xmm2=t2''=t1'-t2'*/ \ - "psubw %%xmm5,%%xmm2\n\t" \ - "pxor %%xmm12,%%xmm12\n\t" \ - /*xmm3=t3''=t0'-t3'*/ \ - "psubw %%xmm4,%%xmm3\n\t" \ - "psubw %%xmm14,%%xmm12\n\t" \ - /*xmm10=t5''=t6'-t5'*/ \ - "psubw %%xmm9,%%xmm10\n\t" \ - "paddw %%xmm12,%%xmm12\n\t" \ - /*xmm4=t0''=t0'+t3'*/ \ - "paddw %%xmm0,%%xmm4\n\t" \ - /*xmm1=t1''=t1'+t2'*/ \ - "paddw %%xmm5,%%xmm1\n\t" \ - /*xmm6=t6''=t6'+t5'*/ \ - "paddw %%xmm9,%%xmm6\n\t" \ - /*xmm0,xmm5,xmm9 are now free.*/ \ - /*Stage 3:*/ \ - /*xmm10:xmm5=t5''*27146+0xB500 \ - xmm0=t5''*/ \ - "movdqa %%xmm10,%%xmm5\n\t" \ - "movdqa %%xmm10,%%xmm0\n\t" \ - "punpckhwd %%xmm12,%%xmm10\n\t" \ - "pmaddwd %%xmm13,%%xmm10\n\t" \ - "punpcklwd %%xmm12,%%xmm5\n\t" \ - "pmaddwd %%xmm13,%%xmm5\n\t" \ - /*xmm5=(t5''*27146+0xB500>>16)+t5''*/ \ - "psrad $16,%%xmm10\n\t" \ - "psrad $16,%%xmm5\n\t" \ - "packssdw %%xmm10,%%xmm5\n\t" \ - "paddw %%xmm0,%%xmm5\n\t" \ - /*xmm0=s=(t5''*27146+0xB500>>16)+t5''+(t5''!=0)>>1*/ \ - "pcmpeqw %%xmm15,%%xmm0\n\t" \ - "psubw %%xmm14,%%xmm0\n\t" \ - "paddw %%xmm5,%%xmm0\n\t" \ - "movdqa %%xmm8,%%xmm5\n\t" \ - "psraw $1,%%xmm0\n\t" \ - /*xmm5=t5'''=t4'-s*/ \ - "psubw %%xmm0,%%xmm5\n\t" \ - /*xmm8=t4''=t4'+s*/ \ - "paddw %%xmm0,%%xmm8\n\t" \ - /*xmm0,xmm7,xmm9,xmm10 are free.*/ \ - /*xmm7:xmm9=t6''*27146+0xB500*/ \ - "movdqa %%xmm6,%%xmm7\n\t" \ - "movdqa %%xmm6,%%xmm9\n\t" \ - "punpckhwd %%xmm12,%%xmm7\n\t" \ - "pmaddwd %%xmm13,%%xmm7\n\t" \ - "punpcklwd %%xmm12,%%xmm9\n\t" \ - "pmaddwd %%xmm13,%%xmm9\n\t" \ - /*xmm9=(t6''*27146+0xB500>>16)+t6''*/ \ - "psrad $16,%%xmm7\n\t" \ - "psrad $16,%%xmm9\n\t" \ - "packssdw %%xmm7,%%xmm9\n\t" \ - "paddw %%xmm6,%%xmm9\n\t" \ - /*xmm9=s=(t6''*27146+0xB500>>16)+t6''+(t6''!=0)>>1*/ \ - "pcmpeqw %%xmm15,%%xmm6\n\t" \ - "psubw %%xmm14,%%xmm6\n\t" \ - "paddw %%xmm6,%%xmm9\n\t" \ - "movdqa %%xmm11,%%xmm7\n\t" \ - "psraw $1,%%xmm9\n\t" \ - /*xmm7=t6'''=t7'-s*/ \ - "psubw %%xmm9,%%xmm7\n\t" \ - /*xmm9=t7''=t7'+s*/ \ - "paddw %%xmm11,%%xmm9\n\t" \ - /*xmm0,xmm6,xmm10,xmm11 are free.*/ \ - /*Stage 4:*/ \ - /*xmm10:xmm0=t1''*27146+0xB500*/ \ - "movdqa %%xmm1,%%xmm0\n\t" \ - "movdqa %%xmm1,%%xmm10\n\t" \ - "punpcklwd %%xmm12,%%xmm0\n\t" \ - "pmaddwd %%xmm13,%%xmm0\n\t" \ - "punpckhwd %%xmm12,%%xmm10\n\t" \ - "pmaddwd %%xmm13,%%xmm10\n\t" \ - /*xmm0=(t1''*27146+0xB500>>16)+t1''*/ \ - "psrad $16,%%xmm0\n\t" \ - "psrad $16,%%xmm10\n\t" \ - "mov $0x20006A0A,%[a]\n\t" \ - "packssdw %%xmm10,%%xmm0\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "paddw %%xmm1,%%xmm0\n\t" \ - /*xmm0=s=(t1''*27146+0xB500>>16)+t1''+(t1''!=0)*/ \ - "pcmpeqw %%xmm15,%%xmm1\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "psubw %%xmm14,%%xmm1\n\t" \ - "paddw %%xmm1,%%xmm0\n\t" \ - /*xmm10:xmm4=t0''*27146+0x4000*/ \ - "movdqa %%xmm4,%%xmm1\n\t" \ - "movdqa %%xmm4,%%xmm10\n\t" \ - "punpcklwd %%xmm12,%%xmm4\n\t" \ - "pmaddwd %%xmm13,%%xmm4\n\t" \ - "punpckhwd %%xmm12,%%xmm10\n\t" \ - "pmaddwd %%xmm13,%%xmm10\n\t" \ - /*xmm4=(t0''*27146+0x4000>>16)+t0''*/ \ - "psrad $16,%%xmm4\n\t" \ - "psrad $16,%%xmm10\n\t" \ - "mov $0x6CB7,%[a]\n\t" \ - "packssdw %%xmm10,%%xmm4\n\t" \ - "movd %[a],%%xmm12\n\t" \ - "paddw %%xmm1,%%xmm4\n\t" \ - /*xmm4=r=(t0''*27146+0x4000>>16)+t0''+(t0''!=0)*/ \ - "pcmpeqw %%xmm15,%%xmm1\n\t" \ - "pshufd $00,%%xmm12,%%xmm12\n\t" \ - "psubw %%xmm14,%%xmm1\n\t" \ - "mov $0x7FFF6C84,%[a]\n\t" \ - "paddw %%xmm1,%%xmm4\n\t" \ - /*xmm0=_y[0]=u=r+s>>1 \ - The naive implementation could cause overflow, so we use \ - u=(r&s)+((r^s)>>1).*/ \ - "movdqa %%xmm0,%%xmm6\n\t" \ - "pxor %%xmm4,%%xmm0\n\t" \ - "pand %%xmm4,%%xmm6\n\t" \ - "psraw $1,%%xmm0\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "paddw %%xmm6,%%xmm0\n\t" \ - /*xmm4=_y[4]=v=r-u*/ \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "psubw %%xmm0,%%xmm4\n\t" \ - /*xmm1,xmm6,xmm10,xmm11 are free.*/ \ - /*xmm6:xmm10=60547*t3''+0x6CB7*/ \ - "movdqa %%xmm3,%%xmm10\n\t" \ - "movdqa %%xmm3,%%xmm6\n\t" \ - "punpcklwd %%xmm3,%%xmm10\n\t" \ - "pmaddwd %%xmm13,%%xmm10\n\t" \ - "mov $0x61F861F8,%[a]\n\t" \ - "punpckhwd %%xmm3,%%xmm6\n\t" \ - "pmaddwd %%xmm13,%%xmm6\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "paddd %%xmm12,%%xmm10\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "paddd %%xmm12,%%xmm6\n\t" \ - /*xmm1:xmm2=25080*t2'' \ - xmm12=t2''*/ \ - "movdqa %%xmm2,%%xmm11\n\t" \ - "movdqa %%xmm2,%%xmm12\n\t" \ - "pmullw %%xmm13,%%xmm2\n\t" \ - "pmulhw %%xmm13,%%xmm11\n\t" \ - "movdqa %%xmm2,%%xmm1\n\t" \ - "punpcklwd %%xmm11,%%xmm2\n\t" \ - "punpckhwd %%xmm11,%%xmm1\n\t" \ - /*xmm10=u=(25080*t2''+60547*t3''+0x6CB7>>16)+(t3''!=0)*/ \ - "paddd %%xmm2,%%xmm10\n\t" \ - "paddd %%xmm1,%%xmm6\n\t" \ - "psrad $16,%%xmm10\n\t" \ - "pcmpeqw %%xmm15,%%xmm3\n\t" \ - "psrad $16,%%xmm6\n\t" \ - "psubw %%xmm14,%%xmm3\n\t" \ - "packssdw %%xmm6,%%xmm10\n\t" \ - "paddw %%xmm3,%%xmm10\n\t" \ - /*xmm2=_y[2]=u \ - xmm10=s=(25080*u>>16)-t2''*/ \ - "movdqa %%xmm10,%%xmm2\n\t" \ - "pmulhw %%xmm13,%%xmm10\n\t" \ - "psubw %%xmm12,%%xmm10\n\t" \ - /*xmm1:xmm6=s*21600+0x2800*/ \ - "pxor %%xmm12,%%xmm12\n\t" \ - "psubw %%xmm14,%%xmm12\n\t" \ - "mov $0x28005460,%[a]\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "movdqa %%xmm10,%%xmm6\n\t" \ - "movdqa %%xmm10,%%xmm1\n\t" \ - "punpcklwd %%xmm12,%%xmm6\n\t" \ - "pmaddwd %%xmm13,%%xmm6\n\t" \ - "mov $0x0E3D,%[a]\n\t" \ - "punpckhwd %%xmm12,%%xmm1\n\t" \ - "pmaddwd %%xmm13,%%xmm1\n\t" \ - /*xmm6=(s*21600+0x2800>>18)+s*/ \ - "psrad $18,%%xmm6\n\t" \ - "psrad $18,%%xmm1\n\t" \ - "movd %[a],%%xmm12\n\t" \ - "packssdw %%xmm1,%%xmm6\n\t" \ - "pshufd $00,%%xmm12,%%xmm12\n\t" \ - "paddw %%xmm10,%%xmm6\n\t" \ - /*xmm6=_y[6]=v=(s*21600+0x2800>>18)+s+(s!=0)*/ \ - "mov $0x7FFF54DC,%[a]\n\t" \ - "pcmpeqw %%xmm15,%%xmm10\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "psubw %%xmm14,%%xmm10\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "paddw %%xmm10,%%xmm6\n\t " \ - /*xmm1,xmm3,xmm10,xmm11 are free.*/ \ - /*xmm11:xmm10=54491*t5'''+0x0E3D*/ \ - "movdqa %%xmm5,%%xmm10\n\t" \ - "movdqa %%xmm5,%%xmm11\n\t" \ - "punpcklwd %%xmm5,%%xmm10\n\t" \ - "pmaddwd %%xmm13,%%xmm10\n\t" \ - "mov $0x8E3A8E3A,%[a]\n\t" \ - "punpckhwd %%xmm5,%%xmm11\n\t" \ - "pmaddwd %%xmm13,%%xmm11\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "paddd %%xmm12,%%xmm10\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "paddd %%xmm12,%%xmm11\n\t" \ - /*xmm7:xmm12=36410*t6''' \ - xmm1=t6'''*/ \ - "movdqa %%xmm7,%%xmm3\n\t" \ - "movdqa %%xmm7,%%xmm1\n\t" \ - "pmulhw %%xmm13,%%xmm3\n\t" \ - "pmullw %%xmm13,%%xmm7\n\t" \ - "paddw %%xmm1,%%xmm3\n\t" \ - "movdqa %%xmm7,%%xmm12\n\t" \ - "punpckhwd %%xmm3,%%xmm7\n\t" \ - "punpcklwd %%xmm3,%%xmm12\n\t" \ - /*xmm10=u=(54491*t5'''+36410*t6'''+0x0E3D>>16)+(t5'''!=0)*/ \ - "paddd %%xmm12,%%xmm10\n\t" \ - "paddd %%xmm7,%%xmm11\n\t" \ - "psrad $16,%%xmm10\n\t" \ - "pcmpeqw %%xmm15,%%xmm5\n\t" \ - "psrad $16,%%xmm11\n\t" \ - "psubw %%xmm14,%%xmm5\n\t" \ - "packssdw %%xmm11,%%xmm10\n\t" \ - "pxor %%xmm12,%%xmm12\n\t" \ - "paddw %%xmm5,%%xmm10\n\t" \ - /*xmm5=_y[5]=u \ - xmm1=s=t6'''-(36410*u>>16)*/ \ - "psubw %%xmm14,%%xmm12\n\t" \ - "movdqa %%xmm10,%%xmm5\n\t" \ - "mov $0x340067C8,%[a]\n\t" \ - "pmulhw %%xmm13,%%xmm10\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "paddw %%xmm5,%%xmm10\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "psubw %%xmm10,%%xmm1\n\t" \ - /*xmm11:xmm3=s*26568+0x3400*/ \ - "movdqa %%xmm1,%%xmm3\n\t" \ - "movdqa %%xmm1,%%xmm11\n\t" \ - "punpcklwd %%xmm12,%%xmm3\n\t" \ - "pmaddwd %%xmm13,%%xmm3\n\t" \ - "mov $0x7B1B,%[a]\n\t" \ - "punpckhwd %%xmm12,%%xmm11\n\t" \ - "pmaddwd %%xmm13,%%xmm11\n\t" \ - /*xmm3=(s*26568+0x3400>>17)+s*/ \ - "psrad $17,%%xmm3\n\t" \ - "psrad $17,%%xmm11\n\t" \ - "movd %[a],%%xmm12\n\t" \ - "packssdw %%xmm11,%%xmm3\n\t" \ - "pshufd $00,%%xmm12,%%xmm12\n\t" \ - "paddw %%xmm1,%%xmm3\n\t" \ - /*xmm3=_y[3]=v=(s*26568+0x3400>>17)+s+(s!=0)*/ \ - "mov $0x7FFF7B16,%[a]\n\t" \ - "pcmpeqw %%xmm15,%%xmm1\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "psubw %%xmm14,%%xmm1\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "paddw %%xmm1,%%xmm3\n\t " \ - /*xmm1,xmm7,xmm10,xmm11 are free.*/ \ - /*xmm11:xmm10=64277*t7''+0x7B1B*/ \ - "movdqa %%xmm9,%%xmm10\n\t" \ - "movdqa %%xmm9,%%xmm11\n\t" \ - "punpcklwd %%xmm9,%%xmm10\n\t" \ - "pmaddwd %%xmm13,%%xmm10\n\t" \ - "mov $0x31F131F1,%[a]\n\t" \ - "punpckhwd %%xmm9,%%xmm11\n\t" \ - "pmaddwd %%xmm13,%%xmm11\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "paddd %%xmm12,%%xmm10\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - "paddd %%xmm12,%%xmm11\n\t" \ - /*xmm12:xmm7=12785*t4''*/ \ - "movdqa %%xmm8,%%xmm7\n\t" \ - "movdqa %%xmm8,%%xmm1\n\t" \ - "pmullw %%xmm13,%%xmm7\n\t" \ - "pmulhw %%xmm13,%%xmm1\n\t" \ - "movdqa %%xmm7,%%xmm12\n\t" \ - "punpcklwd %%xmm1,%%xmm7\n\t" \ - "punpckhwd %%xmm1,%%xmm12\n\t" \ - /*xmm10=u=(12785*t4''+64277*t7''+0x7B1B>>16)+(t7''!=0)*/ \ - "paddd %%xmm7,%%xmm10\n\t" \ - "paddd %%xmm12,%%xmm11\n\t" \ - "psrad $16,%%xmm10\n\t" \ - "pcmpeqw %%xmm15,%%xmm9\n\t" \ - "psrad $16,%%xmm11\n\t" \ - "psubw %%xmm14,%%xmm9\n\t" \ - "packssdw %%xmm11,%%xmm10\n\t" \ - "pxor %%xmm12,%%xmm12\n\t" \ - "paddw %%xmm9,%%xmm10\n\t" \ - /*xmm1=_y[1]=u \ - xmm10=s=(12785*u>>16)-t4''*/ \ - "psubw %%xmm14,%%xmm12\n\t" \ - "movdqa %%xmm10,%%xmm1\n\t" \ - "mov $0x3000503B,%[a]\n\t" \ - "pmulhw %%xmm13,%%xmm10\n\t" \ - "movd %[a],%%xmm13\n\t" \ - "psubw %%xmm8,%%xmm10\n\t" \ - "pshufd $00,%%xmm13,%%xmm13\n\t" \ - /*xmm8:xmm7=s*20539+0x3000*/ \ - "movdqa %%xmm10,%%xmm7\n\t" \ - "movdqa %%xmm10,%%xmm8\n\t" \ - "punpcklwd %%xmm12,%%xmm7\n\t" \ - "pmaddwd %%xmm13,%%xmm7\n\t" \ - "punpckhwd %%xmm12,%%xmm8\n\t" \ - "pmaddwd %%xmm13,%%xmm8\n\t" \ - /*xmm7=(s*20539+0x3000>>20)+s*/ \ - "psrad $20,%%xmm7\n\t" \ - "psrad $20,%%xmm8\n\t" \ - "packssdw %%xmm8,%%xmm7\n\t" \ - "paddw %%xmm10,%%xmm7\n\t" \ - /*xmm7=_y[7]=v=(s*20539+0x3000>>20)+s+(s!=0)*/ \ - "pcmpeqw %%xmm15,%%xmm10\n\t" \ - "psubw %%xmm14,%%xmm10\n\t" \ - "paddw %%xmm10,%%xmm7\n\t " \ - -# define OC_TRANSPOSE8x8 \ - "#OC_TRANSPOSE8x8\n\t" \ - "movdqa %%xmm4,%%xmm8\n\t" \ - /*xmm4 = f3 e3 f2 e2 f1 e1 f0 e0*/ \ - "punpcklwd %%xmm5,%%xmm4\n\t" \ - /*xmm8 = f7 e7 f6 e6 f5 e5 f4 e4*/ \ - "punpckhwd %%xmm5,%%xmm8\n\t" \ - /*xmm5 is free.*/ \ - "movdqa %%xmm0,%%xmm5\n\t" \ - /*xmm0 = b3 a3 b2 a2 b1 a1 b0 a0*/ \ - "punpcklwd %%xmm1,%%xmm0\n\t" \ - /*xmm5 = b7 a7 b6 a6 b5 a5 b4 a4*/ \ - "punpckhwd %%xmm1,%%xmm5\n\t" \ - /*xmm1 is free.*/ \ - "movdqa %%xmm6,%%xmm1\n\t" \ - /*xmm6 = h3 g3 h2 g2 h1 g1 h0 g0*/ \ - "punpcklwd %%xmm7,%%xmm6\n\t" \ - /*xmm1 = h7 g7 h6 g6 h5 g5 h4 g4*/ \ - "punpckhwd %%xmm7,%%xmm1\n\t" \ - /*xmm7 is free.*/ \ - "movdqa %%xmm2,%%xmm7\n\t" \ - /*xmm7 = d3 c3 d2 c2 d1 c1 d0 c0*/ \ - "punpcklwd %%xmm3,%%xmm7\n\t" \ - /*xmm2 = d7 c7 d6 c6 d5 c5 d4 c4*/ \ - "punpckhwd %%xmm3,%%xmm2\n\t" \ - /*xmm3 is free.*/ \ - "movdqa %%xmm0,%%xmm3\n\t" \ - /*xmm0 = d1 c1 b1 a1 d0 c0 b0 a0*/ \ - "punpckldq %%xmm7,%%xmm0\n\t" \ - /*xmm3 = d3 c3 b3 a3 d2 c2 b2 a2*/ \ - "punpckhdq %%xmm7,%%xmm3\n\t" \ - /*xmm7 is free.*/ \ - "movdqa %%xmm5,%%xmm7\n\t" \ - /*xmm5 = d5 c5 b5 a5 d4 c4 b4 a4*/ \ - "punpckldq %%xmm2,%%xmm5\n\t" \ - /*xmm7 = d7 c7 b7 a7 d6 c6 b6 a6*/ \ - "punpckhdq %%xmm2,%%xmm7\n\t" \ - /*xmm2 is free.*/ \ - "movdqa %%xmm4,%%xmm2\n\t" \ - /*xmm2 = h1 g1 f1 e1 h0 g0 f0 e0*/ \ - "punpckldq %%xmm6,%%xmm2\n\t" \ - /*xmm4 = h3 g3 f3 e3 h2 g2 f2 e2*/ \ - "punpckhdq %%xmm6,%%xmm4\n\t" \ - /*xmm6 is free.*/ \ - "movdqa %%xmm8,%%xmm6\n\t" \ - /*xmm6 = h5 g5 f5 e5 h4 g4 f4 e4*/ \ - "punpckldq %%xmm1,%%xmm6\n\t" \ - /*xmm8 = h7 g7 f7 e7 h6 g6 f6 e6*/ \ - "punpckhdq %%xmm1,%%xmm8\n\t" \ - /*xmm1 is free.*/ \ - "movdqa %%xmm0,%%xmm1\n\t" \ - /*xmm0 = h0 g0 f0 e0 d0 c0 b0 a0*/ \ - "punpcklqdq %%xmm2,%%xmm0\n\t" \ - /*xmm1 = h1 g1 f1 e1 d1 c1 b1 a1*/ \ - "punpckhqdq %%xmm2,%%xmm1\n\t" \ - /*xmm2 is free.*/ \ - "movdqa %%xmm3,%%xmm2\n\t" \ - /*xmm2 = h2 g2 f2 e2 d2 c2 b2 a2*/ \ - "punpcklqdq %%xmm4,%%xmm2\n\t" \ - /*xmm3 = h3 g3 f3 e3 d3 c3 b3 a3*/ \ - "punpckhqdq %%xmm4,%%xmm3\n\t" \ - /*xmm4 is free.*/ \ - "movdqa %%xmm5,%%xmm4\n\t" \ - /*xmm4 = h4 g4 f4 e4 d4 c4 b4 a4*/ \ - "punpcklqdq %%xmm6,%%xmm4\n\t" \ - /*xmm5 = h5 g5 f5 e5 d5 c5 b5 a5*/ \ - "punpckhqdq %%xmm6,%%xmm5\n\t" \ - /*xmm6 is free.*/ \ - "movdqa %%xmm7,%%xmm6\n\t" \ - /*xmm6 = h6 g6 f6 e6 d6 c6 b6 a6*/ \ - "punpcklqdq %%xmm8,%%xmm6\n\t" \ - /*xmm7 = h7 g7 f7 e7 d7 c7 b7 a7*/ \ - "punpckhqdq %%xmm8,%%xmm7\n\t" \ - /*xmm8 is free.*/ \ - -/*SSE2 implementation of the fDCT for x86-64 only. - Because of the 8 extra XMM registers on x86-64, this version can operate - without any temporary stack access at all.*/ -void oc_enc_fdct8x8_x86_64sse2(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ - ptrdiff_t a; - __asm__ __volatile__( - /*Load the input.*/ - "movdqa 0x00(%[x]),%%xmm0\n\t" - "movdqa 0x10(%[x]),%%xmm1\n\t" - "movdqa 0x20(%[x]),%%xmm2\n\t" - "movdqa 0x30(%[x]),%%xmm3\n\t" - "movdqa 0x40(%[x]),%%xmm4\n\t" - "movdqa 0x50(%[x]),%%xmm5\n\t" - "movdqa 0x60(%[x]),%%xmm6\n\t" - "movdqa 0x70(%[x]),%%xmm7\n\t" - /*Add two extra bits of working precision to improve accuracy; any more and - we could overflow.*/ - /*We also add a few biases to correct for some systematic error that - remains in the full fDCT->iDCT round trip.*/ - /*xmm15={0}x8*/ - "pxor %%xmm15,%%xmm15\n\t" - /*xmm14={-1}x8*/ - "pcmpeqb %%xmm14,%%xmm14\n\t" - "psllw $2,%%xmm0\n\t" - /*xmm8=xmm0*/ - "movdqa %%xmm0,%%xmm8\n\t" - "psllw $2,%%xmm1\n\t" - /*xmm8={_x[7...0]==0}*/ - "pcmpeqw %%xmm15,%%xmm8\n\t" - "psllw $2,%%xmm2\n\t" - /*xmm8={_x[7...0]!=0}*/ - "psubw %%xmm14,%%xmm8\n\t" - "psllw $2,%%xmm3\n\t" - /*%[a]=1*/ - "mov $1,%[a]\n\t" - /*xmm8={_x[6]!=0,0,_x[4]!=0,0,_x[2]!=0,0,_x[0]!=0,0}*/ - "pslld $16,%%xmm8\n\t" - "psllw $2,%%xmm4\n\t" - /*xmm9={0,0,0,0,0,0,0,1}*/ - "movd %[a],%%xmm9\n\t" - /*xmm8={0,0,_x[2]!=0,0,_x[0]!=0,0}*/ - "pshufhw $0x00,%%xmm8,%%xmm8\n\t" - "psllw $2,%%xmm5\n\t" - /*%[a]={1}x2*/ - "mov $0x10001,%[a]\n\t" - /*xmm8={0,0,0,0,0,0,0,_x[0]!=0}*/ - "pshuflw $0x01,%%xmm8,%%xmm8\n\t" - "psllw $2,%%xmm6\n\t" - /*xmm10={0,0,0,0,0,0,1,1}*/ - "movd %[a],%%xmm10\n\t" - /*xmm0=_x[7...0]+{0,0,0,0,0,0,0,_x[0]!=0}*/ - "paddw %%xmm8,%%xmm0\n\t" - "psllw $2,%%xmm7\n\t" - /*xmm0=_x[7...0]+{0,0,0,0,0,0,1,(_x[0]!=0)+1}*/ - "paddw %%xmm10,%%xmm0\n\t" - /*xmm1=_x[15...8]-{0,0,0,0,0,0,0,1}*/ - "psubw %%xmm9,%%xmm1\n\t" - /*Transform columns.*/ - OC_FDCT8x8 - /*Transform rows.*/ - OC_TRANSPOSE8x8 - OC_FDCT8x8 - /*TODO: zig-zag ordering?*/ - OC_TRANSPOSE8x8 - /*xmm14={-2,-2,-2,-2,-2,-2,-2,-2}*/ - "paddw %%xmm14,%%xmm14\n\t" - "psubw %%xmm14,%%xmm0\n\t" - "psubw %%xmm14,%%xmm1\n\t" - "psraw $2,%%xmm0\n\t" - "psubw %%xmm14,%%xmm2\n\t" - "psraw $2,%%xmm1\n\t" - "psubw %%xmm14,%%xmm3\n\t" - "psraw $2,%%xmm2\n\t" - "psubw %%xmm14,%%xmm4\n\t" - "psraw $2,%%xmm3\n\t" - "psubw %%xmm14,%%xmm5\n\t" - "psraw $2,%%xmm4\n\t" - "psubw %%xmm14,%%xmm6\n\t" - "psraw $2,%%xmm5\n\t" - "psubw %%xmm14,%%xmm7\n\t" - "psraw $2,%%xmm6\n\t" - "psraw $2,%%xmm7\n\t" - /*Store the result.*/ - "movdqa %%xmm0,0x00(%[y])\n\t" - "movdqa %%xmm1,0x10(%[y])\n\t" - "movdqa %%xmm2,0x20(%[y])\n\t" - "movdqa %%xmm3,0x30(%[y])\n\t" - "movdqa %%xmm4,0x40(%[y])\n\t" - "movdqa %%xmm5,0x50(%[y])\n\t" - "movdqa %%xmm6,0x60(%[y])\n\t" - "movdqa %%xmm7,0x70(%[y])\n\t" - :[a]"=&r"(a) - :[y]"r"(_y),[x]"r"(_x) - :"memory" - ); -} -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/x86enc.c b/src/add-ons/media/plugins/theora/libtheora/x86/x86enc.c deleted file mode 100644 index 43b7be3ea3..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/x86enc.c +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: x86state.c 15675 2009-02-06 09:43:27Z tterribe $ - - ********************************************************************/ -#include "x86enc.h" - -#if defined(OC_X86_ASM) - -#include "../cpu.c" - -void oc_enc_vtable_init_x86(oc_enc_ctx *_enc){ - ogg_uint32_t cpu_flags; - cpu_flags=oc_cpu_flags_get(); - oc_enc_vtable_init_c(_enc); - if(cpu_flags&OC_CPU_X86_MMX){ - _enc->opt_vtable.frag_sub=oc_enc_frag_sub_mmx; - _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_mmx; - _enc->opt_vtable.frag_recon_intra=oc_frag_recon_intra_mmx; - _enc->opt_vtable.frag_recon_inter=oc_frag_recon_inter_mmx; - _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_mmx; - } - if(cpu_flags&OC_CPU_X86_MMXEXT){ - _enc->opt_vtable.frag_sad=oc_enc_frag_sad_mmxext; - _enc->opt_vtable.frag_sad_thresh=oc_enc_frag_sad_thresh_mmxext; - _enc->opt_vtable.frag_sad2_thresh=oc_enc_frag_sad2_thresh_mmxext; - _enc->opt_vtable.frag_satd_thresh=oc_enc_frag_satd_thresh_mmxext; - _enc->opt_vtable.frag_satd2_thresh=oc_enc_frag_satd2_thresh_mmxext; - _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_mmxext; - _enc->opt_vtable.frag_copy2=oc_enc_frag_copy2_mmxext; - } - if(cpu_flags&OC_CPU_X86_SSE2){ -# if defined(OC_X86_64_ASM) - /*_enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_x86_64sse2;*/ -# endif - } -} -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/x86enc.h b/src/add-ons/media/plugins/theora/libtheora/x86/x86enc.h deleted file mode 100644 index 06c3908bcd..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/x86enc.h +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: x86int.h 15675 2009-02-06 09:43:27Z tterribe $ - - ********************************************************************/ - -#if !defined(_x86_x86enc_H) -# define _x86_x86enc_H (1) -# include "../encint.h" -# include "x86int.h" - -void oc_enc_vtable_init_x86(oc_enc_ctx *_enc); - -unsigned oc_enc_frag_sad_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride); -unsigned oc_enc_frag_sad_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_sad2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_satd_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref,int _ystride,unsigned _thresh); -unsigned oc_enc_frag_satd2_thresh_mmxext(const unsigned char *_src, - const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, - unsigned _thresh); -unsigned oc_enc_frag_intra_satd_mmxext(const unsigned char *_src,int _ystride); -void oc_enc_frag_sub_mmx(ogg_int16_t _diff[64], - const unsigned char *_x,const unsigned char *_y,int _stride); -void oc_enc_frag_sub_128_mmx(ogg_int16_t _diff[64], - const unsigned char *_x,int _stride); -void oc_enc_frag_copy2_mmxext(unsigned char *_dst, - const unsigned char *_src1,const unsigned char *_src2,int _ystride); -void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]); -void oc_enc_fdct8x8_x86_64sse2(ogg_int16_t _y[64],const ogg_int16_t _x[64]); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/x86int.h b/src/add-ons/media/plugins/theora/libtheora/x86/x86int.h deleted file mode 100644 index ede724f5aa..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/x86int.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: x86int.h 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#if !defined(_x86_x86int_H) -# define _x86_x86int_H (1) -# include "../internal.h" - -void oc_state_vtable_init_x86(oc_theora_state *_state); - -void oc_frag_copy_mmx(unsigned char *_dst, - const unsigned char *_src,int _ystride); -void oc_frag_recon_intra_mmx(unsigned char *_dst,int _ystride, - const ogg_int16_t *_residue); -void oc_frag_recon_inter_mmx(unsigned char *_dst, - const unsigned char *_src,int _ystride,const ogg_int16_t *_residue); -void oc_frag_recon_inter2_mmx(unsigned char *_dst,const unsigned char *_src1, - const unsigned char *_src2,int _ystride,const ogg_int16_t *_residue); -void oc_idct8x8_mmx(ogg_int16_t _y[64],int _last_zzi); -void oc_state_frag_recon_mmx(const oc_theora_state *_state,ptrdiff_t _fragi, - int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,ogg_uint16_t _dc_quant); -void oc_state_frag_copy_list_mmx(const oc_theora_state *_state, - const ptrdiff_t *_fragis,ptrdiff_t _nfragis, - int _dst_frame,int _src_frame,int _pli); -void oc_state_loop_filter_frag_rows_mmx(const oc_theora_state *_state, - int _bv[256],int _refi,int _pli,int _fragy0,int _fragy_end); -void oc_restore_fpu_mmx(void); - -#endif diff --git a/src/add-ons/media/plugins/theora/libtheora/x86/x86state.c b/src/add-ons/media/plugins/theora/libtheora/x86/x86state.c deleted file mode 100644 index a786bec284..0000000000 --- a/src/add-ons/media/plugins/theora/libtheora/x86/x86state.c +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * - * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * - * * - ******************************************************************** - - function: - last mod: $Id: x86state.c 16503 2009-08-22 18:14:02Z giles $ - - ********************************************************************/ - -#include "x86int.h" - -#if defined(OC_X86_ASM) - -#include "../cpu.c" - -/*This table has been modified from OC_FZIG_ZAG by baking a 4x4 transpose into - each quadrant of the destination.*/ -static const unsigned char OC_FZIG_ZAG_MMX[128]={ - 0, 8, 1, 2, 9,16,24,17, - 10, 3,32,11,18,25, 4,12, - 5,26,19,40,33,34,41,48, - 27, 6,13,20,28,21,14, 7, - 56,49,42,35,43,50,57,36, - 15,22,29,30,23,44,37,58, - 51,59,38,45,52,31,60,53, - 46,39,47,54,61,62,55,63, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64, -}; - -void oc_state_vtable_init_x86(oc_theora_state *_state){ - _state->cpu_flags=oc_cpu_flags_get(); - if(_state->cpu_flags&OC_CPU_X86_MMX){ - _state->opt_vtable.frag_copy=oc_frag_copy_mmx; - _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_mmx; - _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_mmx; - _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_mmx; - _state->opt_vtable.idct8x8=oc_idct8x8_mmx; - _state->opt_vtable.state_frag_recon=oc_state_frag_recon_mmx; - _state->opt_vtable.state_frag_copy_list=oc_state_frag_copy_list_mmx; - _state->opt_vtable.state_loop_filter_frag_rows= - oc_state_loop_filter_frag_rows_mmx; - _state->opt_vtable.restore_fpu=oc_restore_fpu_mmx; - _state->opt_data.dct_fzig_zag=OC_FZIG_ZAG_MMX; - } - else oc_state_vtable_init_c(_state); -} -#endif diff --git a/src/add-ons/media/plugins/theora/theoraCodecPlugin.cpp b/src/add-ons/media/plugins/theora/theoraCodecPlugin.cpp deleted file mode 100644 index f7d9532688..0000000000 --- a/src/add-ons/media/plugins/theora/theoraCodecPlugin.cpp +++ /dev/null @@ -1,296 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "theoraCodecPlugin.h" -#include "OggTheoraFormats.h" - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) -#endif - -#define DECODE_BUFFER_SIZE (32 * 1024) - - -static media_format -theora_decoded_media_format() -{ - media_format format; - format.type = B_MEDIA_RAW_VIDEO; - init_theora_media_raw_video_format(&format.u.raw_video); - return format; -} - - -/* - * TheoraDecoder - */ - - -TheoraDecoder::TheoraDecoder() -{ - TRACE("TheoraDecoder::TheoraDecoder\n"); - theora_info_init(&fInfo); - theora_comment_init(&fComment); - fStartTime = 0; - memset(&fOutput, sizeof(fOutput), 0); -} - - -TheoraDecoder::~TheoraDecoder() -{ - TRACE("TheoraDecoder::~TheoraDecoder\n"); - theora_info_clear(&fInfo); - theora_comment_clear(&fComment); -} - - -void -TheoraDecoder::GetCodecInfo(media_codec_info *info) -{ - strncpy(info->short_name, "theora-libtheora", sizeof(info->short_name)); - strncpy(info->pretty_name, "theora decoder[libtheora] by AndrewBachmann", sizeof(info->pretty_name)); -} - - -status_t -TheoraDecoder::Setup(media_format *inputFormat, - const void *infoBuffer, size_t infoSize) -{ - TRACE("TheoraDecoder::Setup\n"); - if (!format_is_compatible(theora_encoded_media_format(),*inputFormat)) { - return B_MEDIA_BAD_FORMAT; - } - // grab header packets from meta data - if (inputFormat->MetaDataSize() != sizeof(std::vector)) { - TRACE("TheoraDecoder::Setup not called with ogg_packet meta data: not theora\n"); - return B_ERROR; - } - std::vector * packets = (std::vector *)inputFormat->MetaData(); - if (packets->size() != 3) { - TRACE("TheoraDecoder::Setup not called with three ogg_packets: not theora\n"); - return B_ERROR; - } - // parse header packet - if (theora_decode_header(&fInfo,&fComment,&(*packets)[0]) != 0) { - TRACE("TheoraDecoder::Setup: theora_synthesis_headerin failed: not theora header\n"); - return B_ERROR; - } - // parse comment packet - if (theora_decode_header(&fInfo,&fComment,&(*packets)[1]) != 0) { - TRACE("theoraDecoder::Setup: theora_synthesis_headerin failed: not theora comment\n"); - return B_ERROR; - } - // parse codec setup packet - if (theora_decode_header(&fInfo,&fComment,&(*packets)[2]) != 0) { - TRACE("theoraDecoder::Setup: theora_synthesis_headerin failed: not theora codec setup\n"); - return B_ERROR; - } - // initialize decoder - theora_decode_init(&fState,&fInfo); - // setup default output - media_format requested_format = theora_decoded_media_format(); - ((media_raw_video_format)requested_format.u.raw_video) = inputFormat->u.encoded_video.output; - return NegotiateOutputFormat(&requested_format); -} - - -status_t -TheoraDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat) -{ - TRACE("TheoraDecoder::NegotiateOutputFormat\n"); - // BMediaTrack::DecodedFormat - // Pass in ioFormat the format that you want (with wildcards - // as applicable). The codec will find and return in ioFormat - // its best matching format. - // - // BMediaDecoder::SetOutputFormat - // sets the format the decoder should output. On return, - // the outputFormat is changed to match the actual format - // that will be output; this can be different if you - // specified any wildcards. - // - // Be R5 behavior seems to be that we can never fail. If we - // don't support the requested format, just return one we do. - media_format format = theora_decoded_media_format(); - if (fInfo.fps_denominator != 0) { - format.u.raw_video.field_rate = - (double)fInfo.fps_numerator / (double)fInfo.fps_denominator; - } - format.u.raw_video.first_active = fInfo.offset_y; - format.u.raw_video.last_active = fInfo.offset_y + fInfo.frame_height; - format.u.raw_video.pixel_width_aspect = fInfo.aspect_numerator; - format.u.raw_video.pixel_height_aspect = fInfo.aspect_denominator; - format.u.raw_video.display.line_width = fInfo.frame_width; - format.u.raw_video.display.line_count = fInfo.frame_height; - if (!format_is_compatible(format,*ioDecodedFormat)) { - *ioDecodedFormat = format; - } - ioDecodedFormat->SpecializeTo(&format); - // setup output variables - fOutput = ioDecodedFormat->u.raw_video; - return B_OK; -} - - -status_t -TheoraDecoder::Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time) -{ - TRACE("TheoraDecoder::Seek\n"); - // throw the old samples away! -/* int samples = theora_synthesis_pcmout(&fDspState,&pcm); - theora_synthesis_read(&fDspState,samples); -*/ - return B_OK; -} - - -status_t -TheoraDecoder::Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info /* = 0 */) -{ - TRACE("TheoraDecoder::Decode\n"); - status_t status = B_OK; - - bool synced = false; - - // get a new packet - const void *chunkBuffer; - size_t chunkSize; - media_header mh; - status = GetNextChunk(&chunkBuffer, &chunkSize, &mh); - if (status == B_LAST_BUFFER_ERROR) { - goto done; - } - if (status != B_OK) { - TRACE("TheoraDecoder::Decode: GetNextChunk failed\n"); - return status; - } - if (chunkSize != sizeof(ogg_packet)) { - TRACE("TheoraDecoder::Decode: chunk not ogg_packet-sized\n"); - return B_ERROR; - } - - // decode the packet - { - ogg_packet packet; - if (mh.user_data_type == OGG_PACKET_DATA_TYPE) { - memcpy(&packet, mh.user_data, sizeof(packet)); - } else { - // According to http://lists.xiph.org/pipermail/theora-dev/2004-May/002161.html - // this is invalid, but results from it are tolerable and better than nothing. - TRACE("TheoraDecoder::Decode: using compatibility chunk interpretation\n"); - packet.b_o_s = 0; - packet.e_o_s = 0; - packet.granulepos = -1; - packet.packetno = 7; - } - packet.packet = (unsigned char *)chunkBuffer; - packet.bytes = chunkSize; - // push the packet in and get the decoded yuv output - theora_decode_packetin(&fState, &packet); - yuv_buffer yuv; - theora_decode_YUVout(&fState, &yuv); - // now copy the decoded yuv output to the buffer - uint8 * out = static_cast(buffer); - // the following represents a simple YV12 [YUV12?] -> YUY2 [YCbCr422] transform - // it possibly (probably) doesn't work when bytes_per_line != line_width - uint draw_bytes_per_line = yuv.y_width + yuv.uv_width*2; - uint bytes_per_line = draw_bytes_per_line; - for (uint line = 0 ; line < fOutput.display.line_count ; line++) { - unsigned char * y = yuv.y; - unsigned char * u = yuv.u; - unsigned char * v = yuv.v; - for (uint pos = 0 ; pos < draw_bytes_per_line ; pos += 4) { - out[pos] = *(y++); - out[pos+1] = *(u++); - out[pos+2] = *(y++); - out[pos+3] = *(v++); - } - out += bytes_per_line; - yuv.y += yuv.y_stride; - if (line % 2 == 1) { - yuv.u += yuv.uv_stride; - yuv.v += yuv.uv_stride; - } - } - } - - if (!synced) { - if (mh.start_time > 0) { - mediaHeader->start_time = mh.start_time - (bigtime_t) (1000000LL / fOutput.field_rate); - synced = true; - } - } -done: - if (!synced) { - mediaHeader->start_time = fStartTime; - } - fStartTime = (bigtime_t) mediaHeader->start_time + (bigtime_t) (1000000LL / fOutput.field_rate); - - *frameCount = 1; - - return status; -} - - -/* - * TheoraDecoderPlugin - */ - - -Decoder * -TheoraDecoderPlugin::NewDecoder(uint index) -{ - static BLocker locker; - static bool initdone = false; - BAutolock lock(locker); - if (!initdone) { - initdone = true; - } - return new TheoraDecoder; -} - -static media_format theora_formats[1]; - -status_t -TheoraDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count) -{ - media_format_description description = theora_description(); - media_format format = theora_encoded_media_format(); - - BMediaFormats mediaFormats; - status_t result = mediaFormats.InitCheck(); - if (result != B_OK) { - return result; - } - result = mediaFormats.MakeFormatFor(&description, 1, &format); - if (result != B_OK) { - return result; - } - theora_formats[0] = format; - - *formats = theora_formats; - *count = 1; - - return result; -} - - -/* - * instantiate_plugin - */ - - -MediaPlugin *instantiate_plugin() -{ - return new TheoraDecoderPlugin; -} diff --git a/src/add-ons/media/plugins/theora/theoraCodecPlugin.h b/src/add-ons/media/plugins/theora/theoraCodecPlugin.h deleted file mode 100644 index cf2a6f88f1..0000000000 --- a/src/add-ons/media/plugins/theora/theoraCodecPlugin.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _THEORA_CODEC_PLUGIN_H_ -#define _THEORA_CODEC_PLUGIN_H_ - -#include "DecoderPlugin.h" - -#include "libtheora/theora/theora.h" - -class TheoraDecoder : public Decoder -{ -public: - TheoraDecoder(); - ~TheoraDecoder(); - - void GetCodecInfo(media_codec_info *info); - status_t Setup(media_format *inputFormat, - const void *infoBuffer, size_t infoSize); - - status_t NegotiateOutputFormat(media_format *ioDecodedFormat); - - status_t Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time); - - - status_t Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info); - -private: - theora_info fInfo; - theora_comment fComment; - theora_state fState; - - bigtime_t fStartTime; - media_raw_video_format fOutput; -}; - - -class TheoraDecoderPlugin : public DecoderPlugin -{ -public: - Decoder * NewDecoder(uint index); - status_t GetSupportedFormats(media_format ** formats, size_t * count); -}; - -#endif // _THEORA_CODEC_PLUGIN_H_ - diff --git a/src/add-ons/media/plugins/vorbis/Jamfile b/src/add-ons/media/plugins/vorbis/Jamfile deleted file mode 100644 index 2981ffe558..0000000000 --- a/src/add-ons/media/plugins/vorbis/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins vorbis ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -UsePrivateHeaders media ; - -SubDirHdrs $(SUBDIR) .. ogg ; -SubDirSysHdrs $(SUBDIR) .. ogg libogg ; -SubDirHdrs $(SUBDIR) libvorbis vorbis ; - -Addon vorbis : - vorbisCodecPlugin.cpp - : libvorbis.a libogg.a be libmedia.so $(TARGET_LIBSUPC++) -; - -SubInclude HAIKU_TOP src add-ons media plugins vorbis libvorbis ; diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/COPYING b/src/add-ons/media/plugins/vorbis/libvorbis/COPYING deleted file mode 100644 index 928afad347..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2002, Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/Jamfile b/src/add-ons/media/plugins/vorbis/libvorbis/Jamfile deleted file mode 100644 index 73c9ae8465..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -SubDir HAIKU_TOP src add-ons media plugins vorbis libvorbis ; - -SubDirSysHdrs [ FDirName $(SUBDIR) .. .. ogg libogg ] ; - -SubDirCcFlags -DPACKAGE=\\\"libvorbis\\\" -DVERSION=\\\"1.0\\\" -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_SQRTF=1 -DHAVE_LOGF=1 -DHAVE_EXPF=1 -DHAVE_ACOSF=1 -DHAVE_ATANF=1 -DHAVE_FREXPF=1 -DHAVE_RINTF=1 -DHAVE_FLOORF=1 ; -SubDirCcFlags -D__NO_MATH_INLINES -fsigned-char -DPIC -w ; - -StaticLibrary libvorbis.a : - analysis.c - bitrate.c - block.c - codebook.c - envelope.c - floor0.c - floor1.c - info.c - lookup.c - lpc.c - lsp.c - mapping0.c - mdct.c - psy.c - registry.c - res0.c - sharedbook.c - smallft.c - synthesis.c - window.c -; diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/analysis.c b/src/add-ons/media/plugins/vorbis/libvorbis/analysis.c deleted file mode 100644 index b8ffd453fa..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/analysis.c +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: single-block PCM analysis mode dispatch - last mod: $Id: analysis.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "registry.h" -#include "scales.h" -#include "os.h" -#include "misc.h" - -int analysis_noisy=1; - -/* decides between modes, dispatches to the appropriate mapping. */ -int vorbis_analysis(vorbis_block *vb, ogg_packet *op){ - int ret; - - vb->glue_bits=0; - vb->time_bits=0; - vb->floor_bits=0; - vb->res_bits=0; - - /* first things first. Make sure encode is ready */ - oggpack_reset(&vb->opb); - - /* we only have one mapping type (0), and we let the mapping code - itself figure out what soft mode to use. This allows easier - bitrate management */ - - if((ret=_mapping_P[0]->forward(vb))) - return(ret); - - if(op){ - if(vorbis_bitrate_managed(vb)) - /* The app is using a bitmanaged mode... but not using the - bitrate management interface. */ - return(OV_EINVAL); - - op->packet=oggpack_get_buffer(&vb->opb); - op->bytes=oggpack_bytes(&vb->opb); - op->b_o_s=0; - op->e_o_s=vb->eofflag; - op->granulepos=vb->granulepos; - op->packetno=vb->sequence; /* for sake of completeness */ - } - return(0); -} - -/* there was no great place to put this.... */ -void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){ - int j; - FILE *of; - char buffer[80]; - - /* if(i==5870){*/ - sprintf(buffer,"%s_%d.m",base,i); - of=fopen(buffer,"w"); - - if(!of)perror("failed to open data dump file"); - - for(j=0;j -#include "scales.h" -int main(){ - int i; - double rate; - for(i=64;i<32000;i*=2){ - rate=48000.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - rate=44100.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - rate=32000.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - rate=22050.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - rate=16000.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - rate=11025.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - rate=8000.f; - fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n\n", - rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); - - - } - { - float i; - int j; - for(i=0.,j=0;i<28;i+=1,j++){ - fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n", - j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.)); - } - } - return(0); -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/bitrate.c b/src/add-ons/media/plugins/vorbis/libvorbis/bitrate.c deleted file mode 100644 index 8fc100204b..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/bitrate.c +++ /dev/null @@ -1,531 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: bitrate tracking and management - last mod: $Id: bitrate.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "os.h" -#include "misc.h" -#include "bitrate.h" - - -static long BINBYTES(bitrate_manager_state *bm,long pos,long bin){ - int bins=bm->queue_bins; - return(bm->queue_binned[pos*bins+bin]); -} - -#define LIMITBYTES(pos,bin) (bm->minmax_binstack[(pos)*bins*2+((bin)+bins)]) - -static long LACING_ADJUST(long bytes){ - int addto=bytes/255+1; - return(bytes+addto); -} - -static int floater_interpolate(bitrate_manager_state *bm,vorbis_info *vi, - double desired_rate){ - int bin=rint(bm->avgfloat); - double lobitrate,hibitrate; - - - lobitrate=(double)(bm->avg_binacc[bin]*8)/bm->avg_sampleacc*vi->rate; - while(lobitrate>desired_rate && bin>0){ - bin--; - lobitrate=(double)(bm->avg_binacc[bin]*8)/bm->avg_sampleacc*vi->rate; - } - - if(bin+1queue_bins){ - hibitrate=(double)(bm->avg_binacc[bin+1]*8)/bm->avg_sampleacc*vi->rate; - if(fabs(hibitrate-desired_rate) < fabs(lobitrate-desired_rate))bin++; - } - return(bin); -} - -/* try out a new limit */ -static long limit_sum(bitrate_manager_state *bm,int limit){ - int i=bm->minmax_stackptr; - long acc=bm->minmax_acctotal; - long bins=bm->queue_bins; - - acc-=LIMITBYTES(i,0); - acc+=LIMITBYTES(i,limit); - - while(i-->0){ - if(bm->minmax_limitstack[i]<=limit)break; - acc-=LIMITBYTES(i,bm->minmax_limitstack[i]); - acc+=LIMITBYTES(i,limit); - } - return(acc); -} - -/* compute bitrate tracking setup, allocate circular packet size queue */ -void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){ - int i; - codec_setup_info *ci=vi->codec_setup; - bitrate_manager_info *bi=&ci->bi; - long maxlatency; - - memset(bm,0,sizeof(*bm)); - - if(bi){ - - bm->avg_sampledesired=bi->queue_avg_time*vi->rate; - bm->avg_centerdesired=bi->queue_avg_time*vi->rate*bi->queue_avg_center; - bm->minmax_sampledesired=bi->queue_minmax_time*vi->rate; - - /* first find the max possible needed queue size */ - maxlatency=max(bm->avg_sampledesired-bm->avg_centerdesired, - bm->minmax_sampledesired)+bm->avg_centerdesired; - - if(maxlatency>0 && - (bi->queue_avgmin>0 || bi->queue_avgmax>0 || bi->queue_hardmax>0 || - bi->queue_hardmin>0)){ - long maxpackets=maxlatency/(ci->blocksizes[0]>>1)+3; - long bins=PACKETBLOBS; - - bm->queue_size=maxpackets; - bm->queue_bins=bins; - bm->queue_binned=_ogg_calloc(maxpackets,bins*sizeof(*bm->queue_binned)); - bm->queue_actual=_ogg_calloc(maxpackets,sizeof(*bm->queue_actual)); - - if((bi->queue_avgmin>0 || bi->queue_avgmax>0) && - bi->queue_avg_time>0){ - - bm->avg_binacc=_ogg_calloc(bins,sizeof(*bm->avg_binacc)); - bm->avgfloat=PACKETBLOBS/2; - - }else{ - bm->avg_tail= -1; - } - - if((bi->queue_hardmin>0 || bi->queue_hardmax>0) && - bi->queue_minmax_time>0){ - - bm->minmax_binstack=_ogg_calloc((bins*2+1)*bins*2, - sizeof(*bm->minmax_binstack)); - bm->minmax_posstack=_ogg_calloc((bins*2+1), - sizeof(*bm->minmax_posstack)); - bm->minmax_limitstack=_ogg_calloc((bins*2+1), - sizeof(*bm->minmax_limitstack)); - }else{ - bm->minmax_tail= -1; - } - - /* space for the packet queueing */ - bm->packetbuffers=_ogg_calloc(maxpackets,sizeof(*bm->packetbuffers)); - bm->packets=_ogg_calloc(maxpackets,sizeof(*bm->packets)); - for(i=0;ipacketbuffers+i); - - }else{ - bm->packetbuffers=_ogg_calloc(1,sizeof(*bm->packetbuffers)); - bm->packets=_ogg_calloc(1,sizeof(*bm->packets)); - oggpack_writeinit(bm->packetbuffers); - - } - } -} - -void vorbis_bitrate_clear(bitrate_manager_state *bm){ - int i; - if(bm){ - if(bm->queue_binned)_ogg_free(bm->queue_binned); - if(bm->queue_actual)_ogg_free(bm->queue_actual); - if(bm->avg_binacc)_ogg_free(bm->avg_binacc); - if(bm->minmax_binstack)_ogg_free(bm->minmax_binstack); - if(bm->minmax_posstack)_ogg_free(bm->minmax_posstack); - if(bm->minmax_limitstack)_ogg_free(bm->minmax_limitstack); - - if(bm->packetbuffers){ - if(bm->queue_size==0){ - oggpack_writeclear(bm->packetbuffers); - }else{ - for(i=0;iqueue_size;i++) - oggpack_writeclear(bm->packetbuffers+i); - } - _ogg_free(bm->packetbuffers); - } - if(bm->packets)_ogg_free(bm->packets); - - memset(bm,0,sizeof(*bm)); - } -} - -int vorbis_bitrate_managed(vorbis_block *vb){ - vorbis_dsp_state *vd=vb->vd; - backend_lookup_state *b=vd->backend_state; - bitrate_manager_state *bm=&b->bms; - - if(bm->queue_binned)return(1); - return(0); -} - -/* finish taking in the block we just processed */ -int vorbis_bitrate_addblock(vorbis_block *vb){ - int i; - vorbis_block_internal *vbi=vb->internal; - vorbis_dsp_state *vd=vb->vd; - backend_lookup_state *b=vd->backend_state; - bitrate_manager_state *bm=&b->bms; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - bitrate_manager_info *bi=&ci->bi; - int eofflag=vb->eofflag; - int head=bm->queue_head; - int next_head=head+1; - int bins=bm->queue_bins; - int minmax_head,new_minmax_head; - - ogg_uint32_t *head_ptr; - oggpack_buffer temp; - - if(!bm->queue_binned){ - oggpack_buffer temp; - /* not a bitrate managed stream, but for API simplicity, we'll - buffer one packet to keep the code path clean */ - - if(bm->queue_head)return(-1); /* one has been submitted without - being claimed */ - bm->queue_head++; - - bm->packets[0].packet=oggpack_get_buffer(&vb->opb); - bm->packets[0].bytes=oggpack_bytes(&vb->opb); - bm->packets[0].b_o_s=0; - bm->packets[0].e_o_s=vb->eofflag; - bm->packets[0].granulepos=vb->granulepos; - bm->packets[0].packetno=vb->sequence; /* for sake of completeness */ - - memcpy(&temp,bm->packetbuffers,sizeof(vb->opb)); - memcpy(bm->packetbuffers,&vb->opb,sizeof(vb->opb)); - memcpy(&vb->opb,&temp,sizeof(vb->opb)); - - return(0); - } - - /* add encoded packet to head */ - if(next_head>=bm->queue_size)next_head=0; - head_ptr=bm->queue_binned+bins*head; - - /* is there room to add a block? In proper use of the API, this will - never come up... but guard it anyway */ - if(next_head==bm->avg_tail || next_head==bm->minmax_tail)return(-1); - - /* add the block to the toplevel queue */ - bm->queue_head=next_head; - bm->queue_actual[head]=(vb->W?0x80000000UL:0); - - /* buffer packet fields */ - bm->packets[head].packet=oggpack_get_buffer(&vb->opb); - bm->packets[head].bytes=oggpack_bytes(&vb->opb); - bm->packets[head].b_o_s=0; - bm->packets[head].e_o_s=vb->eofflag; - bm->packets[head].granulepos=vb->granulepos; - bm->packets[head].packetno=vb->sequence; /* for sake of completeness */ - - /* swap packet buffers */ - memcpy(&temp,bm->packetbuffers+head,sizeof(vb->opb)); - memcpy(bm->packetbuffers+head,&vb->opb,sizeof(vb->opb)); - memcpy(&vb->opb,&temp,sizeof(vb->opb)); - - /* save markers */ - head_ptr[0]=vbi->packetblob_markers[0]; - for(i=1;ipacketblob_markers[i]-vbi->packetblob_markers[i-1]; - } - - if(bm->avg_binacc) - new_minmax_head=minmax_head=bm->avg_center; - else - new_minmax_head=minmax_head=head; - - /* the average tracking queue is updated first; its results (if it's - in use) are taken into account by the min/max limiter (if min/max - is in use) */ - if(bm->avg_binacc){ - unsigned long desired_center=bm->avg_centerdesired; - if(eofflag)desired_center=0; - - /* update the avg head */ - for(i=0;iavg_binacc[i]+=LACING_ADJUST(head_ptr[i]); - bm->avg_sampleacc+=ci->blocksizes[vb->W]>>1; - bm->avg_centeracc+=ci->blocksizes[vb->W]>>1; - - if(bm->avg_sampleacc>bm->avg_sampledesired || eofflag){ - - /* update the avg center */ - if(bm->avg_centeracc>desired_center){ - /* choose the new average floater */ - int samples=ci->blocksizes[vb->W]>>1; - double upper=floater_interpolate(bm,vi,bi->queue_avgmax); - double lower=floater_interpolate(bm,vi,bi->queue_avgmin); - double new=PACKETBLOBS/2.,slew; - int bin; - - if(uppernew)new=lower; - - slew=(new-bm->avgfloat)/samples*vi->rate; - - if(slewavgfloat_downslew_max) - new=bm->avgfloat+bi->avgfloat_downslew_max/vi->rate*samples; - if(slew>bi->avgfloat_upslew_max) - new=bm->avgfloat+bi->avgfloat_upslew_max/vi->rate*samples; - - bm->avgfloat=new; - /* apply the average floater to new blocks */ - bin=rint(bm->avgfloat); - - /*fprintf(stderr,"%d ",bin);*/ - - while(bm->avg_centeracc>desired_center){ - samples=ci->blocksizes[bm->queue_actual[bm->avg_center]& - 0x80000000UL?1:0]>>1; - - bm->queue_actual[bm->avg_center]|=bin; - - bm->avg_centeracc-=samples; - bm->avg_center++; - if(bm->avg_center>=bm->queue_size)bm->avg_center=0; - } - new_minmax_head=bm->avg_center; - - } - - /* update the avg tail if needed */ - while(bm->avg_sampleacc>bm->avg_sampledesired){ - int samples= - ci->blocksizes[bm->queue_actual[bm->avg_tail]&0x80000000UL?1:0]>>1; - for(i=0;iqueue_bins;i++) - bm->avg_binacc[i]-=LACING_ADJUST(bm->queue_binned[bins*bm->avg_tail+i]); - bm->avg_sampleacc-=samples; - bm->avg_tail++; - if(bm->avg_tail>=bm->queue_size)bm->avg_tail=0; - } - - - } - }else{ - /* if we're not using an average tracker, the 'float' is nailed to - the avgfloat_initial value. It needs to be set for the min/max - to deal properly */ - long bin=PACKETBLOBS/2; - bm->queue_actual[head]|=bin; - new_minmax_head=next_head; - } - - /* update the min/max queues and enforce limits */ - if(bm->minmax_binstack){ - unsigned long sampledesired=eofflag?0:bm->minmax_sampledesired; - - /* add to stack recent */ - while(minmax_head!=new_minmax_head){ - unsigned int i; - int samples=ci->blocksizes[bm->queue_actual[minmax_head]& - 0x80000000UL?1:0]>>1; - int actual=bm->queue_actual[minmax_head]&0x7fffffffUL; - - for(i=0;i<(unsigned int)bins;i++){ - bm->minmax_binstack[bm->minmax_stackptr*bins*2+bins+i]+= - LACING_ADJUST(BINBYTES(bm,minmax_head, - actual>i?actual:i)); - - bm->minmax_binstack[bm->minmax_stackptr*bins*2+i]+= - LACING_ADJUST(BINBYTES(bm,minmax_head, - actualminmax_posstack[bm->minmax_stackptr]=minmax_head; /* not one - past - like - typical */ - bm->minmax_limitstack[bm->minmax_stackptr]=0; - bm->minmax_sampleacc+=samples; - bm->minmax_acctotal+= - LACING_ADJUST(BINBYTES(bm,minmax_head,actual)); - - minmax_head++; - if(minmax_head>=bm->queue_size)minmax_head=0; - - - } - - /* check limits, enforce changes */ - if(bm->minmax_sampleacc>sampledesired){ - double bitrate=(double)(bm->minmax_acctotal*8)/ - bm->minmax_sampleacc*vi->rate; - int limit=0; - - if((bi->queue_hardmax>0 && bitrate>bi->queue_hardmax) || - (bi->queue_hardmin>0 && bitratequeue_hardmin)){ - int newstack; - int stackctr; - long bitsum=bm->minmax_acctotal*8; - - bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate; - - /* we're off rate. Iteratively try out new hard floater - limits until we find one that brings us inside. Here's - where we see the whole point of the limit stacks. */ - if(bi->queue_hardmax>0 && bitrate>bi->queue_hardmax){ - for(limit=-1;limit>-bins+1;limit--){ - long bitsum=limit_sum(bm,limit)*8; - bitrate=(double)bitsum/bm->minmax_sampleacc*vi->rate; - if(bitrate<=bi->queue_hardmax)break; - } - }else if(bitratequeue_hardmin){ - for(limit=1;limitminmax_sampleacc*vi->rate; - if(bitrate>=bi->queue_hardmin)break; - } - if(bitrate>bi->queue_hardmax)limit--; - } - - /* trace the limit backward, stop when we see a lower limit */ - newstack=bm->minmax_stackptr-1; - while(newstack>=0){ - if(bm->minmax_limitstack[newstack]minmax_stackptr; - while(stackctr>newstack){ - bm->minmax_acctotal-= - LIMITBYTES(stackctr,bm->minmax_limitstack[stackctr]); - bm->minmax_acctotal+=LIMITBYTES(stackctr,limit); - - if(stackctrminmax_stackptr) - for(i=0;iminmax_binstack[stackctr*bins*2+i]+= - bm->minmax_binstack[(stackctr+1)*bins*2+i]; - - stackctr--; - } - stackctr++; - bm->minmax_posstack[stackctr]=bm->minmax_posstack[bm->minmax_stackptr]; - bm->minmax_limitstack[stackctr]=limit; - - /* set up new blank stack entry */ - stackctr++; - bm->minmax_stackptr=stackctr; - memset(&bm->minmax_binstack[stackctr*bins*2], - 0, - sizeof(*bm->minmax_binstack)*bins*2); - bm->minmax_limitstack[stackctr]=0; - bm->minmax_posstack[stackctr]=-1; - - } - } - - /* remove from tail */ - while(bm->minmax_sampleacc>sampledesired){ - int samples= - ci->blocksizes[bm->queue_actual[bm->minmax_tail]&0x80000000UL?1:0]>>1; - int actual=bm->queue_actual[bm->minmax_tail]&0x7fffffffUL; - - for(i=0;iminmax_binstack[bins+i]-= /* always comes off the stack bottom */ - LACING_ADJUST(BINBYTES(bm,bm->minmax_tail, - actual>i? - actual:i)); - bm->minmax_binstack[i]-= - LACING_ADJUST(BINBYTES(bm,bm->minmax_tail, - actualminmax_limitstack[0]>actual) - actual=bm->minmax_limitstack[0]; - if(bins+bm->minmax_limitstack[0]minmax_limitstack[0]; - - bm->minmax_acctotal-=LACING_ADJUST(BINBYTES(bm,bm->minmax_tail,actual)); - bm->minmax_sampleacc-=samples; - - /* revise queue_actual to reflect the limit */ - bm->queue_actual[bm->minmax_tail]&=0x80000000UL; - bm->queue_actual[bm->minmax_tail]|=actual; - - if(bm->minmax_tail==bm->minmax_posstack[0]){ - /* the stack becomes a FIFO; the first data has fallen off */ - memmove(bm->minmax_binstack,bm->minmax_binstack+bins*2, - sizeof(*bm->minmax_binstack)*bins*2*bm->minmax_stackptr); - memmove(bm->minmax_posstack,bm->minmax_posstack+1, - sizeof(*bm->minmax_posstack)*bm->minmax_stackptr); - memmove(bm->minmax_limitstack,bm->minmax_limitstack+1, - sizeof(*bm->minmax_limitstack)*bm->minmax_stackptr); - bm->minmax_stackptr--; - } - - bm->minmax_tail++; - if(bm->minmax_tail>=bm->queue_size)bm->minmax_tail=0; - - } - - - bm->last_to_flush=bm->minmax_tail; - }else{ - bm->last_to_flush=bm->avg_center; - } - if(eofflag) - bm->last_to_flush=bm->queue_head; - return(0); -} - -int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){ - backend_lookup_state *b=vd->backend_state; - bitrate_manager_state *bm=&b->bms; - - if(bm->queue_size==0){ - if(bm->queue_head==0)return(0); - - memcpy(op,bm->packets,sizeof(*op)); - bm->queue_head=0; - - }else{ - - if(bm->next_to_flush==bm->last_to_flush)return(0); - - { - long bin=bm->queue_actual[bm->next_to_flush]&0x7fffffff,i; - long bins=bm->queue_bins; - ogg_uint32_t *markers=bm->queue_binned+bins*bm->next_to_flush; - long bytes=markers[bin]; - - memcpy(op,bm->packets+bm->next_to_flush,sizeof(*op)); - - /* we have [PACKETBLOBS] possible packets all squished together in - the buffer, in sequence. count in to number [bin] */ - for(i=0;ipacket+=markers[i]; - op->bytes=bytes; - - } - - bm->next_to_flush++; - if(bm->next_to_flush>=bm->queue_size)bm->next_to_flush=0; - - } - - return(1); -} diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/bitrate.h b/src/add-ons/media/plugins/vorbis/libvorbis/bitrate.h deleted file mode 100644 index 33e712e0da..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/bitrate.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: bitrate tracking and management - last mod: $Id: bitrate.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_BITRATE_H_ -#define _V_BITRATE_H_ - -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "os.h" - -/* encode side bitrate tracking */ -typedef struct bitrate_manager_state { - ogg_uint32_t *queue_binned; - ogg_uint32_t *queue_actual; - int queue_size; - - int queue_head; - int queue_bins; - - long *avg_binacc; - int avg_center; - int avg_tail; - ogg_uint32_t avg_centeracc; - ogg_uint32_t avg_sampleacc; - ogg_uint32_t avg_sampledesired; - ogg_uint32_t avg_centerdesired; - - long *minmax_binstack; - long *minmax_posstack; - long *minmax_limitstack; - long minmax_stackptr; - - long minmax_acctotal; - int minmax_tail; - ogg_uint32_t minmax_sampleacc; - ogg_uint32_t minmax_sampledesired; - - int next_to_flush; - int last_to_flush; - - double avgfloat; - - /* unfortunately, we need to hold queued packet data somewhere */ - oggpack_buffer *packetbuffers; - ogg_packet *packets; - -} bitrate_manager_state; - -typedef struct bitrate_manager_info{ - /* detailed bitrate management setup */ - double queue_avg_time; - double queue_avg_center; - double queue_minmax_time; - double queue_hardmin; - double queue_hardmax; - double queue_avgmin; - double queue_avgmax; - - double avgfloat_downslew_max; - double avgfloat_upslew_max; - -} bitrate_manager_info; - -extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs); -extern void vorbis_bitrate_clear(bitrate_manager_state *bs); -extern int vorbis_bitrate_managed(vorbis_block *vb); -extern int vorbis_bitrate_addblock(vorbis_block *vb); -extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op); - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/block.c b/src/add-ons/media/plugins/vorbis/libvorbis/block.c deleted file mode 100644 index c9561870eb..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/block.c +++ /dev/null @@ -1,833 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: PCM data vector blocking, windowing and dis/reassembly - last mod: $Id: block.c 5664 2003-12-13 20:17:56Z shatty $ - - Handle windowing, overlap-add, etc of the PCM vectors. This is made - more amusing by Vorbis' current two allowed block sizes. - - ********************************************************************/ - -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" - -#include "window.h" -#include "mdct.h" -#include "lpc.h" -#include "registry.h" -#include "misc.h" - -static int ilog2(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -/* pcm accumulator examples (not exhaustive): - - <-------------- lW ----------------> - <--------------- W ----------------> -: .....|..... _______________ | -: .''' | '''_--- | |\ | -:.....''' |_____--- '''......| | \_______| -:.................|__________________|_______|__|______| - |<------ Sl ------>| > Sr < |endW - |beginSl |endSl | |endSr - |beginW |endlW |beginSr - - - |< lW >| - <--------------- W ----------------> - | | .. ______________ | - | | ' `/ | ---_ | - |___.'___/`. | ---_____| - |_______|__|_______|_________________| - | >|Sl|< |<------ Sr ----->|endW - | | |endSl |beginSr |endSr - |beginW | |endlW - mult[0] |beginSl mult[n] - - <-------------- lW -----------------> - |<--W-->| -: .............. ___ | | -: .''' |`/ \ | | -:.....''' |/`....\|...| -:.........................|___|___|___| - |Sl |Sr |endW - | | |endSr - | |beginSr - | |endSl - |beginSl - |beginW -*/ - -/* block abstraction setup *********************************************/ - -#ifndef WORD_ALIGN -#define WORD_ALIGN 8 -#endif - -int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ - memset(vb,0,sizeof(*vb)); - vb->vd=v; - vb->localalloc=0; - vb->localstore=NULL; - if(v->analysisp){ - vorbis_block_internal *vbi= - vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal)); - oggpack_writeinit(&vb->opb); - vbi->ampmax=-9999; - } - - return(0); -} - -void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ - bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); - if(bytes+vb->localtop>vb->localalloc){ - /* can't just _ogg_realloc... there are outstanding pointers */ - if(vb->localstore){ - struct alloc_chain *link=_ogg_malloc(sizeof(*link)); - vb->totaluse+=vb->localtop; - link->next=vb->reap; - link->ptr=vb->localstore; - vb->reap=link; - } - /* highly conservative */ - vb->localalloc=bytes; - vb->localstore=_ogg_malloc(vb->localalloc); - vb->localtop=0; - } - { - void *ret=(void *)(((char *)vb->localstore)+vb->localtop); - vb->localtop+=bytes; - return ret; - } -} - -/* reap the chain, pull the ripcord */ -void _vorbis_block_ripcord(vorbis_block *vb){ - /* reap the chain */ - struct alloc_chain *reap=vb->reap; - while(reap){ - struct alloc_chain *next=reap->next; - _ogg_free(reap->ptr); - memset(reap,0,sizeof(*reap)); - _ogg_free(reap); - reap=next; - } - /* consolidate storage */ - if(vb->totaluse){ - vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); - vb->localalloc+=vb->totaluse; - vb->totaluse=0; - } - - /* pull the ripcord */ - vb->localtop=0; - vb->reap=NULL; -} - -int vorbis_block_clear(vorbis_block *vb){ - if(vb->vd) - if(vb->vd->analysisp) - oggpack_writeclear(&vb->opb); - _vorbis_block_ripcord(vb); - if(vb->localstore)_ogg_free(vb->localstore); - - if(vb->internal) - _ogg_free(vb->internal); - - memset(vb,0,sizeof(*vb)); - return(0); -} - -/* Analysis side code, but directly related to blocking. Thus it's - here and not in analysis.c (which is for analysis transforms only). - The init is here because some of it is shared */ - -static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ - int i; - codec_setup_info *ci=vi->codec_setup; - backend_lookup_state *b=NULL; - - memset(v,0,sizeof(*v)); - b=v->backend_state=_ogg_calloc(1,sizeof(*b)); - - v->vi=vi; - b->modebits=ilog2(ci->modes); - - b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0])); - b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1])); - - /* MDCT is tranform 0 */ - - b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup)); - b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup)); - mdct_init(b->transform[0][0],ci->blocksizes[0]); - mdct_init(b->transform[1][0],ci->blocksizes[1]); - - /* Vorbis I uses only window type 0 */ - b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2); - b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2); - - if(encp){ /* encode/decode differ here */ - - /* analysis always needs an fft */ - drft_init(&b->fft_look[0],ci->blocksizes[0]); - drft_init(&b->fft_look[1],ci->blocksizes[1]); - - /* finish the codebooks */ - if(!ci->fullbooks){ - ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); - for(i=0;ibooks;i++) - vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]); - } - - b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy)); - for(i=0;ipsys;i++){ - _vp_psy_init(b->psy+i, - ci->psy_param[i], - &ci->psy_g_param, - ci->blocksizes[ci->psy_param[i]->blockflag]/2, - vi->rate); - } - - v->analysisp=1; - }else{ - /* finish the codebooks */ - if(!ci->fullbooks){ - ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); - for(i=0;ibooks;i++){ - vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); - /* decode codebooks are now standalone after init */ - vorbis_staticbook_destroy(ci->book_param[i]); - ci->book_param[i]=NULL; - } - } - } - - /* initialize the storage vectors. blocksize[1] is small for encode, - but the correct size for decode */ - v->pcm_storage=ci->blocksizes[1]; - v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm)); - v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret)); - { - int i; - for(i=0;ichannels;i++) - v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); - } - - /* all 1 (large block) or 0 (small block) */ - /* explicitly set for the sake of clarity */ - v->lW=0; /* previous window size */ - v->W=0; /* current window size */ - - /* all vector indexes */ - v->centerW=ci->blocksizes[1]/2; - - v->pcm_current=v->centerW; - - /* initialize all the backend lookups */ - b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr)); - b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue)); - - for(i=0;ifloors;i++) - b->flr[i]=_floor_P[ci->floor_type[i]]-> - look(v,ci->floor_param[i]); - - for(i=0;iresidues;i++) - b->residue[i]=_residue_P[ci->residue_type[i]]-> - look(v,ci->residue_param[i]); - - return(0); -} - -/* arbitrary settings and spec-mandated numbers get filled in here */ -int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){ - backend_lookup_state *b=NULL; - - _vds_shared_init(v,vi,1); - b=v->backend_state; - b->psy_g_look=_vp_global_look(vi); - - /* Initialize the envelope state storage */ - b->ve=_ogg_calloc(1,sizeof(*b->ve)); - _ve_envelope_init(b->ve,vi); - - vorbis_bitrate_init(vi,&b->bms); - - return(0); -} - -void vorbis_dsp_clear(vorbis_dsp_state *v){ - int i; - if(v){ - vorbis_info *vi=v->vi; - codec_setup_info *ci=(vi?vi->codec_setup:NULL); - backend_lookup_state *b=v->backend_state; - - if(b){ - if(b->window[0]) - _ogg_free(b->window[0]); - if(b->window[1]) - _ogg_free(b->window[1]); - - if(b->ve){ - _ve_envelope_clear(b->ve); - _ogg_free(b->ve); - } - - if(b->transform[0]){ - mdct_clear(b->transform[0][0]); - _ogg_free(b->transform[0][0]); - _ogg_free(b->transform[0]); - } - if(b->transform[1]){ - mdct_clear(b->transform[1][0]); - _ogg_free(b->transform[1][0]); - _ogg_free(b->transform[1]); - } - - if(b->flr){ - for(i=0;ifloors;i++) - _floor_P[ci->floor_type[i]]-> - free_look(b->flr[i]); - _ogg_free(b->flr); - } - if(b->residue){ - for(i=0;iresidues;i++) - _residue_P[ci->residue_type[i]]-> - free_look(b->residue[i]); - _ogg_free(b->residue); - } - if(b->psy){ - for(i=0;ipsys;i++) - _vp_psy_clear(b->psy+i); - _ogg_free(b->psy); - } - - if(b->psy_g_look)_vp_global_free(b->psy_g_look); - vorbis_bitrate_clear(&b->bms); - - drft_clear(&b->fft_look[0]); - drft_clear(&b->fft_look[1]); - - } - - if(v->pcm){ - for(i=0;ichannels;i++) - if(v->pcm[i])_ogg_free(v->pcm[i]); - _ogg_free(v->pcm); - if(v->pcmret)_ogg_free(v->pcmret); - } - - if(b){ - /* free header, header1, header2 */ - if(b->header)_ogg_free(b->header); - if(b->header1)_ogg_free(b->header1); - if(b->header2)_ogg_free(b->header2); - _ogg_free(b); - } - - memset(v,0,sizeof(*v)); - } -} - -float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){ - int i; - vorbis_info *vi=v->vi; - backend_lookup_state *b=v->backend_state; - - /* free header, header1, header2 */ - if(b->header)_ogg_free(b->header);b->header=NULL; - if(b->header1)_ogg_free(b->header1);b->header1=NULL; - if(b->header2)_ogg_free(b->header2);b->header2=NULL; - - /* Do we have enough storage space for the requested buffer? If not, - expand the PCM (and envelope) storage */ - - if(v->pcm_current+vals>=v->pcm_storage){ - v->pcm_storage=v->pcm_current+vals*2; - - for(i=0;ichannels;i++){ - v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i])); - } - } - - for(i=0;ichannels;i++) - v->pcmret[i]=v->pcm[i]+v->pcm_current; - - return(v->pcmret); -} - -static void _preextrapolate_helper(vorbis_dsp_state *v){ - int i; - int order=32; - float *lpc=alloca(order*sizeof(*lpc)); - float *work=alloca(v->pcm_current*sizeof(*work)); - long j; - v->preextrapolate=1; - - if(v->pcm_current-v->centerW>order*2){ /* safety */ - for(i=0;ivi->channels;i++){ - /* need to run the extrapolation in reverse! */ - for(j=0;jpcm_current;j++) - work[j]=v->pcm[i][v->pcm_current-j-1]; - - /* prime as above */ - vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order); - - /* run the predictor filter */ - vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order, - order, - work+v->pcm_current-v->centerW, - v->centerW); - - for(j=0;jpcm_current;j++) - v->pcm[i][v->pcm_current-j-1]=work[j]; - - } - } -} - - -/* call with val<=0 to set eof */ - -int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){ - vorbis_info *vi=v->vi; - codec_setup_info *ci=vi->codec_setup; - /*backend_lookup_state *b=v->backend_state;*/ - - if(vals<=0){ - int order=32; - int i; - float *lpc=alloca(order*sizeof(*lpc)); - - /* if it wasn't done earlier (very short sample) */ - if(!v->preextrapolate) - _preextrapolate_helper(v); - - /* We're encoding the end of the stream. Just make sure we have - [at least] a few full blocks of zeroes at the end. */ - /* actually, we don't want zeroes; that could drop a large - amplitude off a cliff, creating spread spectrum noise that will - suck to encode. Extrapolate for the sake of cleanliness. */ - - vorbis_analysis_buffer(v,ci->blocksizes[1]*3); - v->eofflag=v->pcm_current; - v->pcm_current+=ci->blocksizes[1]*3; - - for(i=0;ichannels;i++){ - if(v->eofflag>order*2){ - /* extrapolate with LPC to fill in */ - long n; - - /* make a predictor filter */ - n=v->eofflag; - if(n>ci->blocksizes[1])n=ci->blocksizes[1]; - vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order); - - /* run the predictor filter */ - vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order, - v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag); - }else{ - /* not enough data to extrapolate (unlikely to happen due to - guarding the overlap, but bulletproof in case that - assumtion goes away). zeroes will do. */ - memset(v->pcm[i]+v->eofflag,0, - (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i])); - - } - } - }else{ - - if(v->pcm_current+vals>v->pcm_storage) - return(OV_EINVAL); - - v->pcm_current+=vals; - - /* we may want to reverse extrapolate the beginning of a stream - too... in case we're beginning on a cliff! */ - /* clumsy, but simple. It only runs once, so simple is good. */ - if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1]) - _preextrapolate_helper(v); - - } - return(0); -} - -/* do the deltas, envelope shaping, pre-echo and determine the size of - the next block on which to continue analysis */ -int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){ - int i; - vorbis_info *vi=v->vi; - codec_setup_info *ci=vi->codec_setup; - backend_lookup_state *b=v->backend_state; - vorbis_look_psy_global *g=b->psy_g_look; - vorbis_info_psy_global *gi=&ci->psy_g_param; - long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext; - vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; - - /* check to see if we're started... */ - if(!v->preextrapolate)return(0); - - /* check to see if we're done... */ - if(v->eofflag==-1)return(0); - - /* By our invariant, we have lW, W and centerW set. Search for - the next boundary so we can determine nW (the next window size) - which lets us compute the shape of the current block's window */ - - /* we do an envelope search even on a single blocksize; we may still - be throwing more bits at impulses, and envelope search handles - marking impulses too. */ - { - long bp=_ve_envelope_search(v); - if(bp==-1){ - - if(v->eofflag==0)return(0); /* not enough data currently to search for a - full long block */ - v->nW=0; - }else{ - - if(ci->blocksizes[0]==ci->blocksizes[1]) - v->nW=0; - else - v->nW=bp; - } - } - - centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4; - - { - /* center of next block + next block maximum right side. */ - - long blockbound=centerNext+ci->blocksizes[v->nW]/2; - if(v->pcm_currentlW=v->lW; - vb->W=v->W; - vb->nW=v->nW; - - if(v->W){ - if(!v->lW || !v->nW){ - vbi->blocktype=BLOCKTYPE_TRANSITION; - /*fprintf(stderr,"-");*/ - }else{ - vbi->blocktype=BLOCKTYPE_LONG; - /*fprintf(stderr,"_");*/ - } - }else{ - if(_ve_envelope_mark(v)){ - vbi->blocktype=BLOCKTYPE_IMPULSE; - /*fprintf(stderr,"|");*/ - - }else{ - vbi->blocktype=BLOCKTYPE_PADDING; - /*fprintf(stderr,".");*/ - - } - } - - vb->vd=v; - vb->sequence=v->sequence++; - vb->granulepos=v->granulepos; - vb->pcmend=ci->blocksizes[v->W]; - - /* copy the vectors; this uses the local storage in vb */ - - /* this tracks 'strongest peak' for later psychoacoustics */ - /* moved to the global psy state; clean this mess up */ - if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax; - g->ampmax=_vp_ampmax_decay(g->ampmax,v); - vbi->ampmax=g->ampmax; - - vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); - vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels); - for(i=0;ichannels;i++){ - vbi->pcmdelay[i]= - _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i])); - memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i])); - vb->pcm[i]=vbi->pcmdelay[i]+beginW; - - /* before we added the delay - vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); - memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i])); - */ - - } - - /* handle eof detection: eof==0 means that we've not yet received EOF - eof>0 marks the last 'real' sample in pcm[] - eof<0 'no more to do'; doesn't get here */ - - if(v->eofflag){ - if(v->centerW>=v->eofflag){ - v->eofflag=-1; - vb->eofflag=1; - return(1); - } - } - - /* advance storage vectors and clean up */ - { - int new_centerNext=ci->blocksizes[1]/2; - int movementW=centerNext-new_centerNext; - - if(movementW>0){ - - _ve_envelope_shift(b->ve,movementW); - v->pcm_current-=movementW; - - for(i=0;ichannels;i++) - memmove(v->pcm[i],v->pcm[i]+movementW, - v->pcm_current*sizeof(*v->pcm[i])); - - - v->lW=v->W; - v->W=v->nW; - v->centerW=new_centerNext; - - if(v->eofflag){ - v->eofflag-=movementW; - if(v->eofflag<=0)v->eofflag=-1; - /* do not add padding to end of stream! */ - if(v->centerW>=v->eofflag){ - v->granulepos+=movementW-(v->centerW-v->eofflag); - }else{ - v->granulepos+=movementW; - } - }else{ - v->granulepos+=movementW; - } - } - } - - /* done */ - return(1); -} - -int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ - _vds_shared_init(v,vi,0); - - v->pcm_returned=-1; - v->granulepos=-1; - v->sequence=-1; - - return(0); -} - -/* Unlike in analysis, the window is only partially applied for each - block. The time domain envelope is not yet handled at the point of - calling (as it relies on the previous block). */ - -int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ - vorbis_info *vi=v->vi; - codec_setup_info *ci=vi->codec_setup; - int i,j; - - if(!vb)return(OV_EINVAL); - if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); - - v->lW=v->W; - v->W=vb->W; - v->nW=-1; - - if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence; - lose count */ - v->sequence=vb->sequence; - - if(vb->pcm){ /* not pcm to process if vorbis_synthesis_trackonly - was called on block */ - int n=ci->blocksizes[v->W]/2; - int n0=ci->blocksizes[0]/2; - int n1=ci->blocksizes[1]/2; - - int thisCenter; - int prevCenter; - - v->glue_bits+=vb->glue_bits; - v->time_bits+=vb->time_bits; - v->floor_bits+=vb->floor_bits; - v->res_bits+=vb->res_bits; - - if(v->centerW){ - thisCenter=n1; - prevCenter=0; - }else{ - thisCenter=0; - prevCenter=n1; - } - - /* v->pcm is now used like a two-stage double buffer. We don't want - to have to constantly shift *or* adjust memory usage. Don't - accept a new block until the old is shifted out */ - - /* overlap/add PCM */ - - for(j=0;jchannels;j++){ - /* the overlap/add section */ - if(v->lW){ - if(v->W){ - /* large/large */ - float *pcm=v->pcm[j]+prevCenter; - float *p=vb->pcm[j]; - for(i=0;ipcm[j]+prevCenter+n1/2-n0/2; - float *p=vb->pcm[j]; - for(i=0;iW){ - /* small/large */ - float *pcm=v->pcm[j]+prevCenter; - float *p=vb->pcm[j]+n1/2-n0/2; - for(i=0;ipcm[j]+prevCenter; - float *p=vb->pcm[j]; - for(i=0;ipcm[j]+thisCenter; - float *p=vb->pcm[j]+n; - for(i=0;icenterW) - v->centerW=0; - else - v->centerW=n1; - - /* deal with initial packet state; we do this using the explicit - pcm_returned==-1 flag otherwise we're sensitive to first block - being short or long */ - - if(v->pcm_returned==-1){ - v->pcm_returned=thisCenter; - v->pcm_current=thisCenter; - }else{ - v->pcm_returned=prevCenter; - v->pcm_current=prevCenter+ - ci->blocksizes[v->lW]/4+ - ci->blocksizes[v->W]/4; - } - - } - - /* track the frame number... This is for convenience, but also - making sure our last packet doesn't end with added padding. If - the last packet is partial, the number of samples we'll have to - return will be past the vb->granulepos. - - This is not foolproof! It will be confused if we begin - decoding at the last page after a seek or hole. In that case, - we don't have a starting point to judge where the last frame - is. For this reason, vorbisfile will always try to make sure - it reads the last two marked pages in proper sequence */ - - if(v->granulepos==-1){ - if(vb->granulepos!=-1){ /* only set if we have a position to set to */ - v->granulepos=vb->granulepos; - } - }else{ - v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; - if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ - - if(v->granulepos>vb->granulepos){ - long extra=v->granulepos-vb->granulepos; - - if(vb->eofflag){ - /* partial last frame. Strip the extra samples off */ - v->pcm_current-=extra; - }else if(vb->sequence == 1){ - /* ^^^ argh, this can be 1 from seeking! */ - - - /* partial first frame. Discard extra leading samples */ - v->pcm_returned+=extra; - if(v->pcm_returned>v->pcm_current) - v->pcm_returned=v->pcm_current; - - } /* else {Shouldn't happen *unless* the bitstream is out of - spec. Either way, believe the bitstream } */ - } /* else {Shouldn't happen *unless* the bitstream is out of - spec. Either way, believe the bitstream } */ - v->granulepos=vb->granulepos; - } - } - - /* Update, cleanup */ - - if(vb->eofflag)v->eofflag=1; - return(0); - -} - -/* pcm==NULL indicates we just want the pending samples, no more */ -int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){ - vorbis_info *vi=v->vi; - if(v->pcm_returned>-1 && v->pcm_returnedpcm_current){ - if(pcm){ - int i; - for(i=0;ichannels;i++) - v->pcmret[i]=v->pcm[i]+v->pcm_returned; - *pcm=v->pcmret; - } - return(v->pcm_current-v->pcm_returned); - } - return(0); -} - -int vorbis_synthesis_read(vorbis_dsp_state *v,int n){ - if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL); - v->pcm_returned+=n; - return(0); -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/codebook.c b/src/add-ons/media/plugins/vorbis/libvorbis/codebook.c deleted file mode 100644 index c046cd0e85..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/codebook.c +++ /dev/null @@ -1,615 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: basic codebook pack/unpack/code/decode operations - last mod: $Id: codebook.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codebook.h" -#include "scales.h" -#include "misc.h" -#include "os.h" - -/* packs the given codebook into the bitstream **************************/ - -int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ - long i,j; - int ordered=0; - - /* first the basic parameters */ - oggpack_write(opb,0x564342,24); - oggpack_write(opb,c->dim,16); - oggpack_write(opb,c->entries,24); - - /* pack the codewords. There are two packings; length ordered and - length random. Decide between the two now. */ - - for(i=1;ientries;i++) - if(c->lengthlist[i-1]==0 || c->lengthlist[i]lengthlist[i-1])break; - if(i==c->entries)ordered=1; - - if(ordered){ - /* length ordered. We only need to say how many codewords of - each length. The actual codewords are generated - deterministically */ - - long count=0; - oggpack_write(opb,1,1); /* ordered */ - oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ - - for(i=1;ientries;i++){ - long this=c->lengthlist[i]; - long last=c->lengthlist[i-1]; - if(this>last){ - for(j=last;jentries-count)); - count=i; - } - } - } - oggpack_write(opb,i-count,_ilog(c->entries-count)); - - }else{ - /* length random. Again, we don't code the codeword itself, just - the length. This time, though, we have to encode each length */ - oggpack_write(opb,0,1); /* unordered */ - - /* algortihmic mapping has use for 'unused entries', which we tag - here. The algorithmic mapping happens as usual, but the unused - entry has no codeword. */ - for(i=0;ientries;i++) - if(c->lengthlist[i]==0)break; - - if(i==c->entries){ - oggpack_write(opb,0,1); /* no unused entries */ - for(i=0;ientries;i++) - oggpack_write(opb,c->lengthlist[i]-1,5); - }else{ - oggpack_write(opb,1,1); /* we have unused entries; thus we tag */ - for(i=0;ientries;i++){ - if(c->lengthlist[i]==0){ - oggpack_write(opb,0,1); - }else{ - oggpack_write(opb,1,1); - oggpack_write(opb,c->lengthlist[i]-1,5); - } - } - } - } - - /* is the entry number the desired return value, or do we have a - mapping? If we have a mapping, what type? */ - oggpack_write(opb,c->maptype,4); - switch(c->maptype){ - case 0: - /* no mapping */ - break; - case 1:case 2: - /* implicitly populated value mapping */ - /* explicitly populated value mapping */ - - if(!c->quantlist){ - /* no quantlist? error */ - return(-1); - } - - /* values that define the dequantization */ - oggpack_write(opb,c->q_min,32); - oggpack_write(opb,c->q_delta,32); - oggpack_write(opb,c->q_quant-1,4); - oggpack_write(opb,c->q_sequencep,1); - - { - int quantvals; - switch(c->maptype){ - case 1: - /* a single column of (c->entries/c->dim) quantized values for - building a full value list algorithmically (square lattice) */ - quantvals=_book_maptype1_quantvals(c); - break; - case 2: - /* every value (c->entries*c->dim total) specified explicitly */ - quantvals=c->entries*c->dim; - break; - default: /* NOT_REACHABLE */ - quantvals=-1; - } - - /* quantized values */ - for(i=0;iquantlist[i]),c->q_quant); - - } - break; - default: - /* error case; we don't have any other map types now */ - return(-1); - } - - return(0); -} - -/* unpacks a codebook from the packet buffer into the codebook struct, - readies the codebook auxiliary structures for decode *************/ -int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ - long i,j; - memset(s,0,sizeof(*s)); - s->allocedp=1; - - /* make sure alignment is correct */ - if(oggpack_read(opb,24)!=0x564342)goto _eofout; - - /* first the basic parameters */ - s->dim=oggpack_read(opb,16); - s->entries=oggpack_read(opb,24); - if(s->entries==-1)goto _eofout; - - /* codeword ordering.... length ordered or unordered? */ - switch((int)oggpack_read(opb,1)){ - case 0: - /* unordered */ - s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); - - /* allocated but unused entries? */ - if(oggpack_read(opb,1)){ - /* yes, unused entries */ - - for(i=0;ientries;i++){ - if(oggpack_read(opb,1)){ - long num=oggpack_read(opb,5); - if(num==-1)goto _eofout; - s->lengthlist[i]=num+1; - }else - s->lengthlist[i]=0; - } - }else{ - /* all entries used; no tagging */ - for(i=0;ientries;i++){ - long num=oggpack_read(opb,5); - if(num==-1)goto _eofout; - s->lengthlist[i]=num+1; - } - } - - break; - case 1: - /* ordered */ - { - long length=oggpack_read(opb,5)+1; - s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); - - for(i=0;ientries;){ - long num=oggpack_read(opb,_ilog(s->entries-i)); - if(num==-1)goto _eofout; - for(j=0;jentries;j++,i++) - s->lengthlist[i]=length; - length++; - } - } - break; - default: - /* EOF */ - return(-1); - } - - /* Do we have a mapping to unpack? */ - switch((s->maptype=oggpack_read(opb,4))){ - case 0: - /* no mapping */ - break; - case 1: case 2: - /* implicitly populated value mapping */ - /* explicitly populated value mapping */ - - s->q_min=oggpack_read(opb,32); - s->q_delta=oggpack_read(opb,32); - s->q_quant=oggpack_read(opb,4)+1; - s->q_sequencep=oggpack_read(opb,1); - - { - int quantvals=0; - switch(s->maptype){ - case 1: - quantvals=_book_maptype1_quantvals(s); - break; - case 2: - quantvals=s->entries*s->dim; - break; - } - - /* quantized values */ - s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals); - for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); - - if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; - } - break; - default: - goto _errout; - } - - /* all set */ - return(0); - - _errout: - _eofout: - vorbis_staticbook_clear(s); - return(-1); -} - -/* returns the number of bits ************************************************/ -int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){ - oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); - return(book->c->lengthlist[a]); -} - -/* One the encode side, our vector writers are each designed for a -specific purpose, and the encoder is not flexible without modification: - -The LSP vector coder uses a single stage nearest-match with no -interleave, so no step and no error return. This is specced by floor0 -and doesn't change. - -Residue0 encoding interleaves, uses multiple stages, and each stage -peels of a specific amount of resolution from a lattice (thus we want -to match by threshold, not nearest match). Residue doesn't *have* to -be encoded that way, but to change it, one will need to add more -infrastructure on the encode side (decode side is specced and simpler) */ - -/* floor0 LSP (single stage, non interleaved, nearest match) */ -/* returns entry number and *modifies a* to the quantization value *****/ -int vorbis_book_errorv(codebook *book,float *a){ - int dim=book->dim,k; - int best=_best(book,a,1); - for(k=0;kvaluelist+best*dim)[k]; - return(best); -} - -/* returns the number of bits and *modifies a* to the quantization value *****/ -int vorbis_book_encodev(codebook *book,int best,float *a,oggpack_buffer *b){ - int k,dim=book->dim; - for(k=0;kvaluelist+best*dim)[k]; - return(vorbis_book_encode(book,best,b)); -} - -/* the 'eliminate the decode tree' optimization actually requires the - codewords to be MSb first, not LSb. This is an annoying inelegancy - (and one of the first places where carefully thought out design - turned out to be wrong; Vorbis II and future Ogg codecs should go - to an MSb bitpacker), but not actually the huge hit it appears to - be. The first-stage decode table catches most words so that - bitreverse is not in the main execution path. */ - -static ogg_uint32_t bitreverse(ogg_uint32_t x){ - x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); - x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); - x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); - x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); - return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); -} - -STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){ - int read=book->dec_maxlength; - long lo,hi; - long lok = oggpack_look(b,book->dec_firsttablen); - - if (lok >= 0) { - long entry = book->dec_firsttable[lok]; - if(entry&0x80000000UL){ - lo=(entry>>15)&0x7fff; - hi=book->used_entries-(entry&0x7fff); - }else{ - oggpack_adv(b, book->dec_codelengths[entry-1]); - return(entry-1); - } - }else{ - lo=0; - hi=book->used_entries; - } - - lok = oggpack_look(b, read); - - while(lok<0 && read>1) - lok = oggpack_look(b, --read); - if(lok<0)return -1; - - /* bisect search for the codeword in the ordered list */ - { - ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); - - while(hi-lo>1){ - long p=(hi-lo)>>1; - long test=book->codelist[lo+p]>testword; - lo+=p&(test-1); - hi-=p&(-test); - } - - if(book->dec_codelengths[lo]<=read){ - oggpack_adv(b, book->dec_codelengths[lo]); - return(lo); - } - } - - oggpack_adv(b, read); - return(-1); -} - -/* Decode side is specced and easier, because we don't need to find - matches using different criteria; we simply read and map. There are - two things we need to do 'depending': - - We may need to support interleave. We don't really, but it's - convenient to do it here rather than rebuild the vector later. - - Cascades may be additive or multiplicitive; this is not inherent in - the codebook, but set in the code using the codebook. Like - interleaving, it's easiest to do it here. - addmul==0 -> declarative (set the value) - addmul==1 -> additive - addmul==2 -> multiplicitive */ - -/* returns the [original, not compacted] entry number or -1 on eof *********/ -long vorbis_book_decode(codebook *book, oggpack_buffer *b){ - long packed_entry=decode_packed_entry_number(book,b); - if(packed_entry>=0) - return(book->dec_index[packed_entry]); - - /* if there's no dec_index, the codebook unpacking isn't collapsed */ - return(packed_entry); -} - -/* returns 0 on OK or -1 on eof *************************************/ -long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){ - int step=n/book->dim; - long *entry = alloca(sizeof(*entry)*step); - float **t = alloca(sizeof(*t)*step); - int i,j,o; - - for (i = 0; i < step; i++) { - entry[i]=decode_packed_entry_number(book,b); - if(entry[i]==-1)return(-1); - t[i] = book->valuelist+entry[i]*book->dim; - } - for(i=0,o=0;idim;i++,o+=step) - for (j=0;jdim>8){ - for(i=0;ivaluelist+entry*book->dim; - for (j=0;jdim;) - a[i++]+=t[j++]; - } - }else{ - for(i=0;ivaluelist+entry*book->dim; - j=0; - switch((int)book->dim){ - case 8: - a[i++]+=t[j++]; - case 7: - a[i++]+=t[j++]; - case 6: - a[i++]+=t[j++]; - case 5: - a[i++]+=t[j++]; - case 4: - a[i++]+=t[j++]; - case 3: - a[i++]+=t[j++]; - case 2: - a[i++]+=t[j++]; - case 1: - a[i++]+=t[j++]; - case 0: - break; - } - } - } - return(0); -} - -long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){ - int i,j,entry; - float *t; - - for(i=0;ivaluelist+entry*book->dim; - for (j=0;jdim;) - a[i++]=t[j++]; - } - return(0); -} - -long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch, - oggpack_buffer *b,int n){ - long i,j,entry; - int chptr=0; - - for(i=offset/ch;i<(offset+n)/ch;){ - entry = decode_packed_entry_number(book,b); - if(entry==-1)return(-1); - { - const float *t = book->valuelist+entry*book->dim; - for (j=0;jdim;j++){ - a[chptr++][i]+=t[j]; - if(chptr==ch){ - chptr=0; - i++; - } - } - } - } - return(0); -} - -#ifdef _V_SELFTEST -/* Simple enough; pack a few candidate codebooks, unpack them. Code a - number of vectors through (keeping track of the quantized values), - and decode using the unpacked book. quantized version of in should - exactly equal out */ - -#include - -#include "vorbis/book/lsp20_0.vqh" -#include "vorbis/book/res0a_13.vqh" -#define TESTSIZE 40 - -float test1[TESTSIZE]={ - 0.105939f, - 0.215373f, - 0.429117f, - 0.587974f, - - 0.181173f, - 0.296583f, - 0.515707f, - 0.715261f, - - 0.162327f, - 0.263834f, - 0.342876f, - 0.406025f, - - 0.103571f, - 0.223561f, - 0.368513f, - 0.540313f, - - 0.136672f, - 0.395882f, - 0.587183f, - 0.652476f, - - 0.114338f, - 0.417300f, - 0.525486f, - 0.698679f, - - 0.147492f, - 0.324481f, - 0.643089f, - 0.757582f, - - 0.139556f, - 0.215795f, - 0.324559f, - 0.399387f, - - 0.120236f, - 0.267420f, - 0.446940f, - 0.608760f, - - 0.115587f, - 0.287234f, - 0.571081f, - 0.708603f, -}; - -float test3[TESTSIZE]={ - 0,1,-2,3,4,-5,6,7,8,9, - 8,-2,7,-1,4,6,8,3,1,-9, - 10,11,12,13,14,15,26,17,18,19, - 30,-25,-30,-1,-5,-32,4,3,-2,0}; - -static_codebook *testlist[]={&_vq_book_lsp20_0, - &_vq_book_res0a_13,NULL}; -float *testvec[]={test1,test3}; - -int main(){ - oggpack_buffer write; - oggpack_buffer read; - long ptr=0,i; - oggpack_writeinit(&write); - - fprintf(stderr,"Testing codebook abstraction...:\n"); - - while(testlist[ptr]){ - codebook c; - static_codebook s; - float *qv=alloca(sizeof(*qv)*TESTSIZE); - float *iv=alloca(sizeof(*iv)*TESTSIZE); - memcpy(qv,testvec[ptr],sizeof(*qv)*TESTSIZE); - memset(iv,0,sizeof(*iv)*TESTSIZE); - - fprintf(stderr,"\tpacking/coding %ld... ",ptr); - - /* pack the codebook, write the testvector */ - oggpack_reset(&write); - vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory - we can write */ - vorbis_staticbook_pack(testlist[ptr],&write); - fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write)); - for(i=0;i.000001){ - fprintf(stderr,"read (%g) != written (%g) at position (%ld)\n", - iv[i],qv[i],i); - exit(1); - } - - fprintf(stderr,"OK\n"); - ptr++; - } - - /* The above is the trivial stuff; now try unquantizing a log scale codebook */ - - exit(0); -} - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/codebook.h b/src/add-ons/media/plugins/vorbis/libvorbis/codebook.h deleted file mode 100644 index 43ce38a6e7..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/codebook.h +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: basic shared codebook operations - last mod: $Id: codebook.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_CODEBOOK_H_ -#define _V_CODEBOOK_H_ - -#include - -/* This structure encapsulates huffman and VQ style encoding books; it - doesn't do anything specific to either. - - valuelist/quantlist are nonNULL (and q_* significant) only if - there's entry->value mapping to be done. - - If encode-side mapping must be done (and thus the entry needs to be - hunted), the auxiliary encode pointer will point to a decision - tree. This is true of both VQ and huffman, but is mostly useful - with VQ. - -*/ - -typedef struct static_codebook{ - long dim; /* codebook dimensions (elements per vector) */ - long entries; /* codebook entries */ - long *lengthlist; /* codeword lengths in bits */ - - /* mapping ***************************************************************/ - int maptype; /* 0=none - 1=implicitly populated values from map column - 2=listed arbitrary values */ - - /* The below does a linear, single monotonic sequence mapping. */ - long q_min; /* packed 32 bit float; quant value 0 maps to minval */ - long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ - int q_quant; /* bits: 0 < quant <= 16 */ - int q_sequencep; /* bitflag */ - - long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map - map == 2: list of dim*entries quantized entry vals - */ - - /* encode helpers ********************************************************/ - struct encode_aux_nearestmatch *nearest_tree; - struct encode_aux_threshmatch *thresh_tree; - struct encode_aux_pigeonhole *pigeon_tree; - - int allocedp; -} static_codebook; - -/* this structures an arbitrary trained book to quickly find the - nearest cell match */ -typedef struct encode_aux_nearestmatch{ - /* pre-calculated partitioning tree */ - long *ptr0; - long *ptr1; - - long *p; /* decision points (each is an entry) */ - long *q; /* decision points (each is an entry) */ - long aux; /* number of tree entries */ - long alloc; -} encode_aux_nearestmatch; - -/* assumes a maptype of 1; encode side only, so that's OK */ -typedef struct encode_aux_threshmatch{ - float *quantthresh; - long *quantmap; - int quantvals; - int threshvals; -} encode_aux_threshmatch; - -typedef struct encode_aux_pigeonhole{ - float min; - float del; - - int mapentries; - int quantvals; - long *pigeonmap; - - long fittotal; - long *fitlist; - long *fitmap; - long *fitlength; -} encode_aux_pigeonhole; - -typedef struct codebook{ - long dim; /* codebook dimensions (elements per vector) */ - long entries; /* codebook entries */ - long used_entries; /* populated codebook entries */ - const static_codebook *c; - - /* for encode, the below are entry-ordered, fully populated */ - /* for decode, the below are ordered by bitreversed codeword and only - used entries are populated */ - float *valuelist; /* list of dim*entries actual entry values */ - ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */ - - int *dec_index; /* only used if sparseness collapsed */ - char *dec_codelengths; - ogg_uint32_t *dec_firsttable; - int dec_firsttablen; - int dec_maxlength; - -} codebook; - -extern void vorbis_staticbook_clear(static_codebook *b); -extern void vorbis_staticbook_destroy(static_codebook *b); -extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source); -extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source); -extern void vorbis_book_clear(codebook *b); - -extern float *_book_unquantize(const static_codebook *b,int n,int *map); -extern float *_book_logdist(const static_codebook *b,float *vals); -extern float _float32_unpack(long val); -extern long _float32_pack(float val); -extern int _best(codebook *book, float *a, int step); -extern int _ilog(unsigned int v); -extern long _book_maptype1_quantvals(const static_codebook *b); - -extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul); -extern long vorbis_book_codeword(codebook *book,int entry); -extern long vorbis_book_codelen(codebook *book,int entry); - - - -extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b); -extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c); - -extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b); -extern int vorbis_book_errorv(codebook *book, float *a); -extern int vorbis_book_encodev(codebook *book, int best,float *a, - oggpack_buffer *b); - -extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); -extern long vorbis_book_decodevs_add(codebook *book, float *a, - oggpack_buffer *b,int n); -extern long vorbis_book_decodev_set(codebook *book, float *a, - oggpack_buffer *b,int n); -extern long vorbis_book_decodev_add(codebook *book, float *a, - oggpack_buffer *b,int n); -extern long vorbis_book_decodevv_add(codebook *book, float **a, - long off,int ch, - oggpack_buffer *b,int n); - - - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/codec_internal.h b/src/add-ons/media/plugins/vorbis/libvorbis/codec_internal.h deleted file mode 100644 index 1b40a11fab..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/codec_internal.h +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: libvorbis codec headers - last mod: $Id: codec_internal.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_CODECI_H_ -#define _V_CODECI_H_ - -#include "envelope.h" -#include "codebook.h" - -#define BLOCKTYPE_IMPULSE 0 -#define BLOCKTYPE_PADDING 1 -#define BLOCKTYPE_TRANSITION 0 -#define BLOCKTYPE_LONG 1 - -#define PACKETBLOBS 15 - -typedef struct vorbis_block_internal{ - float **pcmdelay; /* this is a pointer into local storage */ - float ampmax; - int blocktype; - - ogg_uint32_t packetblob_markers[PACKETBLOBS]; -} vorbis_block_internal; - -typedef void vorbis_look_floor; -typedef void vorbis_look_residue; -typedef void vorbis_look_transform; - -/* mode ************************************************************/ -typedef struct { - int blockflag; - int windowtype; - int transformtype; - int mapping; -} vorbis_info_mode; - -typedef void vorbis_info_floor; -typedef void vorbis_info_residue; -typedef void vorbis_info_mapping; - -#include "psy.h" -#include "bitrate.h" - -typedef struct backend_lookup_state { - /* local lookup storage */ - envelope_lookup *ve; /* envelope lookup */ - float *window[2]; - vorbis_look_transform **transform[2]; /* block, type */ - drft_lookup fft_look[2]; - - int modebits; - vorbis_look_floor **flr; - vorbis_look_residue **residue; - vorbis_look_psy *psy; - vorbis_look_psy_global *psy_g_look; - - /* local storage, only used on the encoding side. This way the - application does not need to worry about freeing some packets' - memory and not others'; packet storage is always tracked. - Cleared next call to a _dsp_ function */ - unsigned char *header; - unsigned char *header1; - unsigned char *header2; - - bitrate_manager_state bms; - -} backend_lookup_state; - -/* codec_setup_info contains all the setup information specific to the - specific compression/decompression mode in progress (eg, - psychoacoustic settings, channel setup, options, codebook - etc). -*********************************************************************/ - -#include "highlevel.h" -typedef struct codec_setup_info { - - /* Vorbis supports only short and long blocks, but allows the - encoder to choose the sizes */ - - long blocksizes[2]; - - /* modes are the primary means of supporting on-the-fly different - blocksizes, different channel mappings (LR or M/A), - different residue backends, etc. Each mode consists of a - blocksize flag and a mapping (along with the mapping setup */ - - int modes; - int maps; - int floors; - int residues; - int books; - int psys; /* encode only */ - - vorbis_info_mode *mode_param[64]; - int map_type[64]; - vorbis_info_mapping *map_param[64]; - int floor_type[64]; - vorbis_info_floor *floor_param[64]; - int residue_type[64]; - vorbis_info_residue *residue_param[64]; - static_codebook *book_param[256]; - codebook *fullbooks; - - vorbis_info_psy *psy_param[4]; /* encode only */ - vorbis_info_psy_global psy_g_param; - - bitrate_manager_info bi; - highlevel_encode_setup hi; /* used only by vorbisenc.c. It's a - highly redundant structure, but - improves clarity of program flow. */ - -} codec_setup_info; - -extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi); -extern void _vp_global_free(vorbis_look_psy_global *look); - -#endif - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/envelope.c b/src/add-ons/media/plugins/vorbis/libvorbis/envelope.c deleted file mode 100644 index 125264eef6..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/envelope.c +++ /dev/null @@ -1,383 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: PCM data envelope analysis - last mod: $Id: envelope.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" - -#include "os.h" -#include "scales.h" -#include "envelope.h" -#include "mdct.h" -#include "misc.h" - -void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *gi=&ci->psy_g_param; - int ch=vi->channels; - int i,j; - int n=e->winlength=128; - e->searchstep=64; /* not random */ - - e->minenergy=gi->preecho_minenergy; - e->ch=ch; - e->storage=128; - e->cursor=ci->blocksizes[1]/2; - e->mdct_win=_ogg_calloc(n,sizeof(*e->mdct_win)); - mdct_init(&e->mdct,n); - - for(i=0;imdct_win[i]=sin(i/(n-1.)*M_PI); - e->mdct_win[i]*=e->mdct_win[i]; - } - - /* magic follows */ - e->band[0].begin=2; e->band[0].end=4; - e->band[1].begin=4; e->band[1].end=5; - e->band[2].begin=6; e->band[2].end=6; - e->band[3].begin=9; e->band[3].end=8; - e->band[4].begin=13; e->band[4].end=8; - e->band[5].begin=17; e->band[5].end=8; - e->band[6].begin=22; e->band[6].end=8; - - for(j=0;jband[j].end; - e->band[j].window=_ogg_malloc(n*sizeof(*e->band[0].window)); - for(i=0;iband[j].window[i]=sin((i+.5)/n*M_PI); - e->band[j].total+=e->band[j].window[i]; - } - e->band[j].total=1./e->band[j].total; - } - - e->filter=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter)); - e->mark=_ogg_calloc(e->storage,sizeof(*e->mark)); - -} - -void _ve_envelope_clear(envelope_lookup *e){ - int i; - mdct_clear(&e->mdct); - for(i=0;iband[i].window); - _ogg_free(e->mdct_win); - _ogg_free(e->filter); - _ogg_free(e->mark); - memset(e,0,sizeof(*e)); -} - -/* fairly straight threshhold-by-band based until we find something - that works better and isn't patented. */ - -static int _ve_amp(envelope_lookup *ve, - vorbis_info_psy_global *gi, - float *data, - envelope_band *bands, - envelope_filter_state *filters, - long pos){ - long n=ve->winlength; - int ret=0; - long i,j; - float decay; - - /* we want to have a 'minimum bar' for energy, else we're just - basing blocks on quantization noise that outweighs the signal - itself (for low power signals) */ - - float minV=ve->minenergy; - float *vec=alloca(n*sizeof(*vec)); - - /* stretch is used to gradually lengthen the number of windows - considered prevoius-to-potential-trigger */ - int stretch=max(VE_MINSTRETCH,ve->stretch/2); - float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH); - if(penalty<0.f)penalty=0.f; - if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty; - - /*_analysis_output_always("lpcm",seq2,data,n,0,0, - totalshift+pos*ve->searchstep);*/ - - /* window and transform */ - for(i=0;imdct_win[i]; - mdct_forward(&ve->mdct,vec,vec); - - /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */ - - /* near-DC spreading function; this has nothing to do with - psychoacoustics, just sidelobe leakage and window size */ - { - float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2]; - int ptr=filters->nearptr; - - /* the accumulation is regularly refreshed from scratch to avoid - floating point creep */ - if(ptr==0){ - decay=filters->nearDC_acc=filters->nearDC_partialacc+temp; - filters->nearDC_partialacc=temp; - }else{ - decay=filters->nearDC_acc+=temp; - filters->nearDC_partialacc+=temp; - } - filters->nearDC_acc-=filters->nearDC[ptr]; - filters->nearDC[ptr]=temp; - - decay*=(1./(VE_NEARDC+1)); - filters->nearptr++; - if(filters->nearptr>=VE_NEARDC)filters->nearptr=0; - decay=todB(&decay)*.5-15.f; - } - - /* perform spreading and limiting, also smooth the spectrum. yes, - the MDCT results in all real coefficients, but it still *behaves* - like real/imaginary pairs */ - for(i=0;i>1]=val; - decay-=8.; - } - - /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/ - - /* perform preecho/postecho triggering by band */ - for(j=0;j=VE_AMP)filters[j].ampptr=0; - } - - /* look at min/max, decide trigger */ - if(valmax>gi->preecho_thresh[j]+penalty){ - ret|=1; - ret|=4; - } - if(valminpostecho_thresh[j]-penalty)ret|=2; - } - - return(ret); -} - -#if 0 -static int seq=0; -static ogg_int64_t totalshift=-1024; -#endif - -long _ve_envelope_search(vorbis_dsp_state *v){ - vorbis_info *vi=v->vi; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *gi=&ci->psy_g_param; - envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve; - long i,j; - - int first=ve->current/ve->searchstep; - int last=v->pcm_current/ve->searchstep-VE_WIN; - if(first<0)first=0; - - /* make sure we have enough storage to match the PCM */ - if(last+VE_WIN+VE_POST>ve->storage){ - ve->storage=last+VE_WIN+VE_POST; /* be sure */ - ve->mark=_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark)); - } - - for(j=first;jstretch++; - if(ve->stretch>VE_MAXSTRETCH*2) - ve->stretch=VE_MAXSTRETCH*2; - - for(i=0;ich;i++){ - float *pcm=v->pcm[i]+ve->searchstep*(j); - ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS,j); - } - - ve->mark[j+VE_POST]=0; - if(ret&1){ - ve->mark[j]=1; - ve->mark[j+1]=1; - } - - if(ret&2){ - ve->mark[j]=1; - if(j>0)ve->mark[j-1]=1; - } - - if(ret&4)ve->stretch=-1; - } - - ve->current=last*ve->searchstep; - - { - long centerW=v->centerW; - long testW= - centerW+ - ci->blocksizes[v->W]/4+ - ci->blocksizes[1]/2+ - ci->blocksizes[0]/4; - - j=ve->cursor; - - while(jcurrent-(ve->searchstep)){/* account for postecho - working back one window */ - if(j>=testW)return(1); - - ve->cursor=j; - - if(ve->mark[j/ve->searchstep]){ - if(j>centerW){ - - #if 0 - if(j>ve->curmark){ - float *marker=alloca(v->pcm_current*sizeof(*marker)); - int l,m; - memset(marker,0,sizeof(*marker)*v->pcm_current); - fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n", - seq, - (totalshift+ve->cursor)/44100., - (totalshift+j)/44100.); - _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift); - _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift); - - _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift); - _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift); - - for(m=0;msearchstep]=ve->filter[m].markers[l]*.1; - _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); - } - - for(m=0;msearchstep]=ve->filter[m+VE_BANDS].markers[l]*.1; - _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); - } - - for(l=0;lsearchstep]=ve->mark[l]*.4; - _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift); - - - seq++; - - } -#endif - - ve->curmark=j; - if(j>=testW)return(1); - return(0); - } - } - j+=ve->searchstep; - } - } - - return(-1); -} - -int _ve_envelope_mark(vorbis_dsp_state *v){ - envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve; - vorbis_info *vi=v->vi; - codec_setup_info *ci=vi->codec_setup; - long centerW=v->centerW; - long beginW=centerW-ci->blocksizes[v->W]/4; - long endW=centerW+ci->blocksizes[v->W]/4; - if(v->W){ - beginW-=ci->blocksizes[v->lW]/4; - endW+=ci->blocksizes[v->nW]/4; - }else{ - beginW-=ci->blocksizes[0]/4; - endW+=ci->blocksizes[0]/4; - } - - if(ve->curmark>=beginW && ve->curmarksearchstep; - long last=endW/ve->searchstep; - long i; - for(i=first;imark[i])return(1); - } - return(0); -} - -void _ve_envelope_shift(envelope_lookup *e,long shift){ - int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks - ahead of ve->current */ - int smallshift=shift/e->searchstep; - int i; - - memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark)); - - #if 0 - for(i=0;ich;i++) - memmove(e->filter[i].markers, - e->filter[i].markers+smallshift, - (1024-smallshift)*sizeof(*(*e->filter).markers)); - totalshift+=shift; - #endif - - e->current-=shift; - if(e->curmark>=0) - e->curmark-=shift; - e->cursor-=shift; -} - - - - - - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/envelope.h b/src/add-ons/media/plugins/vorbis/libvorbis/envelope.h deleted file mode 100644 index c2e0696d39..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/envelope.h +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: PCM data envelope analysis and manipulation - last mod: $Id: envelope.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_ENVELOPE_ -#define _V_ENVELOPE_ - -#include "mdct.h" - -#define VE_PRE 16 -#define VE_WIN 4 -#define VE_POST 2 -#define VE_AMP (VE_PRE+VE_POST-1) - -#define VE_BANDS 7 -#define VE_NEARDC 15 - -#define VE_MINSTRETCH 2 /* a bit less than short block */ -#define VE_MAXSTRETCH 12 /* one-third full block */ - -typedef struct { - float ampbuf[VE_AMP]; - int ampptr; - - float nearDC[VE_NEARDC]; - float nearDC_acc; - float nearDC_partialacc; - int nearptr; - -} envelope_filter_state; - -typedef struct { - int begin; - int end; - float *window; - float total; -} envelope_band; - -typedef struct { - int ch; - int winlength; - int searchstep; - float minenergy; - - mdct_lookup mdct; - float *mdct_win; - - envelope_band band[VE_BANDS]; - envelope_filter_state *filter; - int stretch; - - int *mark; - - long storage; - long current; - long curmark; - long cursor; -} envelope_lookup; - -extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi); -extern void _ve_envelope_clear(envelope_lookup *e); -extern long _ve_envelope_search(vorbis_dsp_state *v); -extern void _ve_envelope_shift(envelope_lookup *e,long shift); -extern int _ve_envelope_mark(vorbis_dsp_state *v); - - -#endif - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/floor0.c b/src/add-ons/media/plugins/vorbis/libvorbis/floor0.c deleted file mode 100644 index 30f7c7125d..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/floor0.c +++ /dev/null @@ -1,235 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: floor backend 0 implementation - last mod: $Id: floor0.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "registry.h" -#include "lpc.h" -#include "lsp.h" -#include "codebook.h" -#include "scales.h" -#include "misc.h" -#include "os.h" - -#include "misc.h" -#include - -typedef struct { - int ln; - int m; - int **linearmap; - int n[2]; - - vorbis_info_floor0 *vi; - lpc_lookup lpclook; - float *lsp_look; - - long bits; - long frames; -} vorbis_look_floor0; - - -/***********************************************/ - -static void floor0_free_info(vorbis_info_floor *i){ - vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; - if(info){ - memset(info,0,sizeof(*info)); - _ogg_free(info); - } -} - -static void floor0_free_look(vorbis_look_floor *i){ - vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; - if(look){ - - if(look->linearmap){ - - if(look->linearmap[0])_ogg_free(look->linearmap[0]); - if(look->linearmap[1])_ogg_free(look->linearmap[1]); - - _ogg_free(look->linearmap); - } - if(look->lsp_look)_ogg_free(look->lsp_look); - lpc_clear(&look->lpclook); - memset(look,0,sizeof(*look)); - _ogg_free(look); - } -} - -static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ - codec_setup_info *ci=vi->codec_setup; - int j; - - vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info)); - info->order=oggpack_read(opb,8); - info->rate=oggpack_read(opb,16); - info->barkmap=oggpack_read(opb,16); - info->ampbits=oggpack_read(opb,6); - info->ampdB=oggpack_read(opb,8); - info->numbooks=oggpack_read(opb,4)+1; - - if(info->order<1)goto err_out; - if(info->rate<1)goto err_out; - if(info->barkmap<1)goto err_out; - if(info->numbooks<1)goto err_out; - - for(j=0;jnumbooks;j++){ - info->books[j]=oggpack_read(opb,8); - if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; - } - return(info); - - err_out: - floor0_free_info(info); - return(NULL); -} - -/* initialize Bark scale and normalization lookups. We could do this - with static tables, but Vorbis allows a number of possible - combinations, so it's best to do it computationally. - - The below is authoritative in terms of defining scale mapping. - Note that the scale depends on the sampling rate as well as the - linear block and mapping sizes */ - -static void floor0_map_lazy_init(vorbis_block *vb, - vorbis_info_floor *infoX, - vorbis_look_floor0 *look){ - if(!look->linearmap[vb->W]){ - vorbis_dsp_state *vd=vb->vd; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; - int W=vb->W; - int n=ci->blocksizes[W]/2,j; - - /* we choose a scaling constant so that: - floor(bark(rate/2-1)*C)=mapped-1 - floor(bark(rate/2)*C)=mapped */ - float scale=look->ln/toBARK(info->rate/2.f); - - /* the mapping from a linear scale to a smaller bark scale is - straightforward. We do *not* make sure that the linear mapping - does not skip bark-scale bins; the decoder simply skips them and - the encoder may do what it wishes in filling them. They're - necessary in some mapping combinations to keep the scale spacing - accurate */ - look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap)); - for(j=0;jrate/2.f)/n*j) - *scale); /* bark numbers represent band edges */ - if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ - look->linearmap[W][j]=val; - } - look->linearmap[W][j]=-1; - look->n[W]=n; - } -} - -static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd, - vorbis_info_floor *i){ - int j; - vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; - vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look)); - look->m=info->order; - look->ln=info->barkmap; - look->vi=info; - - if(vd->analysisp) - lpc_init(&look->lpclook,look->ln,look->m); - - look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap)); - - look->lsp_look=_ogg_malloc(look->ln*sizeof(*look->lsp_look)); - for(j=0;jln;j++) - look->lsp_look[j]=2*cos(M_PI/look->ln*j); - - return look; -} - -static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ - vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; - vorbis_info_floor0 *info=look->vi; - int j,k; - - int ampraw=oggpack_read(&vb->opb,info->ampbits); - if(ampraw>0){ /* also handles the -1 out of data case */ - long maxval=(1<ampbits)-1; - float amp=(float)ampraw/maxval*info->ampdB; - int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); - - if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ - codec_setup_info *ci=vb->vd->vi->codec_setup; - codebook *b=ci->fullbooks+info->books[booknum]; - float last=0.f; - - /* the additional b->dim is a guard against any possible stack - smash; b->dim is provably more than we can overflow the - vector */ - float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); - - for(j=0;jm;j+=b->dim) - if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop; - for(j=0;jm;){ - for(k=0;kdim;k++,j++)lsp[j]+=last; - last=lsp[j-1]; - } - - lsp[look->m]=amp; - return(lsp); - } - } - eop: - return(NULL); -} - -static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, - void *memo,float *out){ - vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; - vorbis_info_floor0 *info=look->vi; - - floor0_map_lazy_init(vb,info,look); - - if(memo){ - float *lsp=(float *)memo; - float amp=lsp[look->m]; - - /* take the coefficients back to a spectral envelope curve */ - vorbis_lsp_to_curve(out, - look->linearmap[vb->W], - look->n[vb->W], - look->ln, - lsp,look->m,amp,(float)info->ampdB); - return(1); - } - memset(out,0,sizeof(*out)*look->n[vb->W]); - return(0); -} - -/* export hooks */ -vorbis_func_floor floor0_exportbundle={ - NULL,&floor0_unpack,&floor0_look,&floor0_free_info, - &floor0_free_look,&floor0_inverse1,&floor0_inverse2 -}; - - - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/floor1.c b/src/add-ons/media/plugins/vorbis/libvorbis/floor1.c deleted file mode 100644 index 59bb91aae2..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/floor1.c +++ /dev/null @@ -1,1087 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: floor backend 1 implementation - last mod: $Id: floor1.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "registry.h" -#include "codebook.h" -#include "misc.h" -#include "scales.h" - -#include - -#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ - -typedef struct { - int sorted_index[VIF_POSIT+2]; - int forward_index[VIF_POSIT+2]; - int reverse_index[VIF_POSIT+2]; - - int hineighbor[VIF_POSIT]; - int loneighbor[VIF_POSIT]; - int posts; - - int n; - int quant_q; - vorbis_info_floor1 *vi; - - long phrasebits; - long postbits; - long frames; -} vorbis_look_floor1; - -typedef struct lsfit_acc{ - long x0; - long x1; - - long xa; - long ya; - long x2a; - long y2a; - long xya; - long n; - long an; -} lsfit_acc; - -/***********************************************/ - -static void floor1_free_info(vorbis_info_floor *i){ - vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; - if(info){ - memset(info,0,sizeof(*info)); - _ogg_free(info); - } -} - -static void floor1_free_look(vorbis_look_floor *i){ - vorbis_look_floor1 *look=(vorbis_look_floor1 *)i; - if(look){ - /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n", - (float)look->phrasebits/look->frames, - (float)look->postbits/look->frames, - (float)(look->postbits+look->phrasebits)/look->frames);*/ - - memset(look,0,sizeof(*look)); - _ogg_free(look); - } -} - -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static int ilog2(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){ - vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; - int j,k; - int count=0; - int rangebits; - int maxposit=info->postlist[1]; - int maxclass=-1; - - /* save out partitions */ - oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */ - for(j=0;jpartitions;j++){ - oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */ - if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; - } - - /* save out partition classes */ - for(j=0;jclass_dim[j]-1,3); /* 1 to 8 */ - oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */ - if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8); - for(k=0;k<(1<class_subs[j]);k++) - oggpack_write(opb,info->class_subbook[j][k]+1,8); - } - - /* save out the post list */ - oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */ - oggpack_write(opb,ilog2(maxposit),4); - rangebits=ilog2(maxposit); - - for(j=0,k=0;jpartitions;j++){ - count+=info->class_dim[info->partitionclass[j]]; - for(;kpostlist[k+2],rangebits); - } -} - - -static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){ - codec_setup_info *ci=vi->codec_setup; - int j,k,count=0,maxclass=-1,rangebits; - - vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info)); - /* read partitions */ - info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */ - for(j=0;jpartitions;j++){ - info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */ - if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; - } - - /* read partition classes */ - for(j=0;jclass_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */ - info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */ - if(info->class_subs[j]<0) - goto err_out; - if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8); - if(info->class_book[j]<0 || info->class_book[j]>=ci->books) - goto err_out; - for(k=0;k<(1<class_subs[j]);k++){ - info->class_subbook[j][k]=oggpack_read(opb,8)-1; - if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books) - goto err_out; - } - } - - /* read the post list */ - info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ - rangebits=oggpack_read(opb,4); - - for(j=0,k=0;jpartitions;j++){ - count+=info->class_dim[info->partitionclass[j]]; - for(;kpostlist[k+2]=oggpack_read(opb,rangebits); - if(t<0 || t>=(1<postlist[0]=0; - info->postlist[1]=1<vi=info; - look->n=info->postlist[1]; - - /* we drop each position value in-between already decoded values, - and use linear interpolation to predict each new value past the - edges. The positions are read in the order of the position - list... we precompute the bounding positions in the lookup. Of - course, the neighbors can change (if a position is declined), but - this is an initial mapping */ - - for(i=0;ipartitions;i++)n+=info->class_dim[info->partitionclass[i]]; - n+=2; - look->posts=n; - - /* also store a sorted position index */ - for(i=0;ipostlist+i; - qsort(sortpointer,n,sizeof(*sortpointer),icomp); - - /* points from sort order back to range number */ - for(i=0;iforward_index[i]=sortpointer[i]-info->postlist; - /* points from range order to sorted position */ - for(i=0;ireverse_index[look->forward_index[i]]=i; - /* we actually need the post values too */ - for(i=0;isorted_index[i]=info->postlist[look->forward_index[i]]; - - /* quantize values to multiplier spec */ - switch(info->mult){ - case 1: /* 1024 -> 256 */ - look->quant_q=256; - break; - case 2: /* 1024 -> 128 */ - look->quant_q=128; - break; - case 3: /* 1024 -> 86 */ - look->quant_q=86; - break; - case 4: /* 1024 -> 64 */ - look->quant_q=64; - break; - } - - /* discover our neighbors for decode where we don't use fit flags - (that would push the neighbors outward) */ - for(i=0;in; - int currentx=info->postlist[i+2]; - for(j=0;jpostlist[j]; - if(x>lx && xcurrentx){ - hi=j; - hx=x; - } - } - look->loneighbor[i]=lo; - look->hineighbor[i]=hi; - } - - return(look); -} - -static int render_point(int x0,int x1,int y0,int y1,int x){ - y0&=0x7fff; /* mask off flag */ - y1&=0x7fff; - - { - int dy=y1-y0; - int adx=x1-x0; - int ady=abs(dy); - int err=ady*(x-x0); - - int off=err/adx; - if(dy<0)return(y0-off); - return(y0+off); - } -} - -static int vorbis_dBquant(const float *x){ - int i= *x*7.3142857f+1023.5f; - if(i>1023)return(1023); - if(i<0)return(0); - return i; -} - -static float FLOOR1_fromdB_LOOKUP[256]={ - 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, - 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, - 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, - 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, - 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, - 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, - 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, - 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, - 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, - 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, - 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, - 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, - 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, - 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, - 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, - 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, - 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, - 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, - 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, - 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, - 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, - 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, - 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, - 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, - 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, - 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, - 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, - 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, - 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, - 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, - 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, - 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, - 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, - 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, - 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, - 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, - 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, - 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, - 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, - 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, - 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, - 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, - 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, - 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, - 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, - 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, - 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, - 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, - 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, - 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, - 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, - 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, - 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, - 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, - 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, - 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, - 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, - 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, - 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, - 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, - 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, - 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, - 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, - 0.82788260F, 0.88168307F, 0.9389798F, 1.F, -}; - -static void render_line(int x0,int x1,int y0,int y1,float *d){ - int dy=y1-y0; - int adx=x1-x0; - int ady=abs(dy); - int base=dy/adx; - int sy=(dy<0?base-1:base+1); - int x=x0; - int y=y0; - int err=0; - - ady-=abs(base*adx); - - d[x]*=FLOOR1_fromdB_LOOKUP[y]; - while(++x=adx){ - err-=adx; - y+=sy; - }else{ - y+=base; - } - d[x]*=FLOOR1_fromdB_LOOKUP[y]; - } -} - -static void render_line0(int x0,int x1,int y0,int y1,int *d){ - int dy=y1-y0; - int adx=x1-x0; - int ady=abs(dy); - int base=dy/adx; - int sy=(dy<0?base-1:base+1); - int x=x0; - int y=y0; - int err=0; - - ady-=abs(base*adx); - - d[x]=y; - while(++x=adx){ - err-=adx; - y+=sy; - }else{ - y+=base; - } - d[x]=y; - } -} - -/* the floor has already been filtered to only include relevant sections */ -static int accumulate_fit(const float *flr,const float *mdct, - int x0, int x1,lsfit_acc *a, - int n,vorbis_info_floor1 *info){ - long i; - int quantized=vorbis_dBquant(flr+x0); - - long xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0; - - memset(a,0,sizeof(*a)); - a->x0=x0; - a->x1=x1; - if(x1>=n)x1=n-1; - - for(i=x0;i<=x1;i++){ - int quantized=vorbis_dBquant(flr+i); - if(quantized){ - if(mdct[i]+info->twofitatten>=flr[i]){ - xa += i; - ya += quantized; - x2a += i*i; - y2a += quantized*quantized; - xya += i*quantized; - na++; - }else{ - xb += i; - yb += quantized; - x2b += i*i; - y2b += quantized*quantized; - xyb += i*quantized; - nb++; - } - } - } - - xb+=xa; - yb+=ya; - x2b+=x2a; - y2b+=y2a; - xyb+=xya; - nb+=na; - - /* weight toward the actually used frequencies if we meet the threshhold */ - { - int weight=nb*info->twofitweight/(na+1); - - a->xa=xa*weight+xb; - a->ya=ya*weight+yb; - a->x2a=x2a*weight+x2b; - a->y2a=y2a*weight+y2b; - a->xya=xya*weight+xyb; - a->an=na*weight+nb; - a->n=nb; - } - - return(na); -} - -static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){ - long x=0,y=0,x2=0,y2=0,xy=0,n=0,an=0,i; - long x0=a[0].x0; - long x1=a[fits-1].x1; - - for(i=0;i=0){ - x+= x0; - y+= *y0; - x2+= x0 * x0; - y2+= *y0 * *y0; - xy+= *y0 * x0; - n++; - an++; - } - - if(*y1>=0){ - x+= x1; - y+= *y1; - x2+= x1 * x1; - y2+= *y1 * *y1; - xy+= *y1 * x1; - n++; - an++; - } - - { - /* need 64 bit multiplies, which C doesn't give portably as int */ - double fx=x; - double fy=y; - double fx2=x2; - double fxy=xy; - double denom=1./(an*fx2-fx*fx); - double a=(fy*fx2-fxy*fx)*denom; - double b=(an*fxy-fx*fy)*denom; - *y0=rint(a+b*x0); - *y1=rint(a+b*x1); - - /* limit to our range! */ - if(*y0>1023)*y0=1023; - if(*y1>1023)*y1=1023; - if(*y0<0)*y0=0; - if(*y1<0)*y1=0; - - } -} - -/*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){ - long y=0; - int i; - - for(i=0;itwofitatten>=mask[x]){ - if(y+info->maxovermaxunder>val)return(1); - } - - while(++x=adx){ - err-=adx; - y+=sy; - }else{ - y+=base; - } - - val=vorbis_dBquant(mask+x); - mse+=((y-val)*(y-val)); - n++; - if(mdct[x]+info->twofitatten>=mask[x]){ - if(val){ - if(y+info->maxovermaxunder>val)return(1); - } - } - } - - if(info->maxover*info->maxover/n>info->maxerr)return(0); - if(info->maxunder*info->maxunder/n>info->maxerr)return(0); - if(mse/n>info->maxerr)return(1); - return(0); -} - -static int post_Y(int *A,int *B,int pos){ - if(A[pos]<0) - return B[pos]; - if(B[pos]<0) - return A[pos]; - - return (A[pos]+B[pos])>>1; -} - -static int seq=0; - -int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look, - const float *logmdct, /* in */ - const float *logmask){ - long i,j; - vorbis_info_floor1 *info=look->vi; - long n=look->n; - long posts=look->posts; - long nonzero=0; - lsfit_acc fits[VIF_POSIT+1]; - int fit_valueA[VIF_POSIT+2]; /* index by range list position */ - int fit_valueB[VIF_POSIT+2]; /* index by range list position */ - - int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */ - int hineighbor[VIF_POSIT+2]; - int *output=NULL; - int memo[VIF_POSIT+2]; - - for(i=0;isorted_index[i], - look->sorted_index[i+1],fits+i, - n,info); - } - - if(nonzero){ - /* start by fitting the implicit base case.... */ - int y0=-200; - int y1=-200; - fit_line(fits,posts-1,&y0,&y1); - - fit_valueA[0]=y0; - fit_valueB[0]=y0; - fit_valueB[1]=y1; - fit_valueA[1]=y1; - - /* Non degenerate case */ - /* start progressive splitting. This is a greedy, non-optimal - algorithm, but simple and close enough to the best - answer. */ - for(i=2;ireverse_index[i]; - int ln=loneighbor[sortpos]; - int hn=hineighbor[sortpos]; - - /* eliminate repeat searches of a particular range with a memo */ - if(memo[ln]!=hn){ - /* haven't performed this error search yet */ - int lsortpos=look->reverse_index[ln]; - int hsortpos=look->reverse_index[hn]; - memo[ln]=hn; - - { - /* A note: we want to bound/minimize *local*, not global, error */ - int lx=info->postlist[ln]; - int hx=info->postlist[hn]; - int ly=post_Y(fit_valueA,fit_valueB,ln); - int hy=post_Y(fit_valueA,fit_valueB,hn); - - if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){ - /* outside error bounds/begin search area. Split it. */ - int ly0=-200; - int ly1=-200; - int hy0=-200; - int hy1=-200; - fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1); - fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1); - - /* store new edge values */ - fit_valueB[ln]=ly0; - if(ln==0)fit_valueA[ln]=ly0; - fit_valueA[i]=ly1; - fit_valueB[i]=hy0; - fit_valueA[hn]=hy1; - if(hn==1)fit_valueB[hn]=hy1; - - if(ly1>=0 || hy0>=0){ - /* store new neighbor values */ - for(j=sortpos-1;j>=0;j--) - if(hineighbor[j]==hn) - hineighbor[j]=i; - else - break; - for(j=sortpos+1;jloneighbor[i-2]; - int hn=look->hineighbor[i-2]; - int x0=info->postlist[ln]; - int x1=info->postlist[hn]; - int y0=output[ln]; - int y1=output[hn]; - - int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); - int vx=post_Y(fit_valueA,fit_valueB,i); - - if(vx>=0 && predicted!=vx){ - output[i]=vx; - }else{ - output[i]= predicted|0x8000; - } - } - } - - return(output); - -} - -int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look, - int *A,int *B, - int del){ - - long i; - long posts=look->posts; - int *output=NULL; - - if(A && B){ - output=_vorbis_block_alloc(vb,sizeof(*output)*posts); - - for(i=0;i>16; - if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000; - } - } - - return(output); -} - - -int floor1_encode(vorbis_block *vb,vorbis_look_floor1 *look, - int *post,int *ilogmask){ - - long i,j; - vorbis_info_floor1 *info=look->vi; - long n=look->n; - long posts=look->posts; - codec_setup_info *ci=vb->vd->vi->codec_setup; - int out[VIF_POSIT+2]; - static_codebook **sbooks=ci->book_param; - codebook *books=ci->fullbooks; - static long seq=0; - - /* quantize values to multiplier spec */ - if(post){ - for(i=0;imult){ - case 1: /* 1024 -> 256 */ - val>>=2; - break; - case 2: /* 1024 -> 128 */ - val>>=3; - break; - case 3: /* 1024 -> 86 */ - val/=12; - break; - case 4: /* 1024 -> 64 */ - val>>=4; - break; - } - post[i]=val | (post[i]&0x8000); - } - - out[0]=post[0]; - out[1]=post[1]; - - /* find prediction values for each post and subtract them */ - for(i=2;iloneighbor[i-2]; - int hn=look->hineighbor[i-2]; - int x0=info->postlist[ln]; - int x1=info->postlist[hn]; - int y0=post[ln]; - int y1=post[hn]; - - int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); - - if((post[i]&0x8000) || (predicted==post[i])){ - post[i]=predicted|0x8000; /* in case there was roundoff jitter - in interpolation */ - out[i]=0; - }else{ - int headroom=(look->quant_q-predictedquant_q-predicted:predicted); - - int val=post[i]-predicted; - - /* at this point the 'deviation' value is in the range +/- max - range, but the real, unique range can always be mapped to - only [0-maxrange). So we want to wrap the deviation into - this limited range, but do it in the way that least screws - an essentially gaussian probability distribution. */ - - if(val<0) - if(val<-headroom) - val=headroom-val-1; - else - val=-1-(val<<1); - else - if(val>=headroom) - val= val+headroom; - else - val<<=1; - - out[i]=val; - post[ln]&=0x7fff; - post[hn]&=0x7fff; - } - } - - /* we have everything we need. pack it out */ - /* mark nontrivial floor */ - oggpack_write(&vb->opb,1,1); - - /* beginning/end post */ - look->frames++; - look->postbits+=ilog(look->quant_q-1)*2; - oggpack_write(&vb->opb,out[0],ilog(look->quant_q-1)); - oggpack_write(&vb->opb,out[1],ilog(look->quant_q-1)); - - - /* partition by partition */ - for(i=0,j=2;ipartitions;i++){ - int class=info->partitionclass[i]; - int cdim=info->class_dim[class]; - int csubbits=info->class_subs[class]; - int csub=1<class_subbook[class][k]; - if(booknum<0){ - maxval[k]=1; - }else{ - maxval[k]=sbooks[info->class_subbook[class][k]]->entries; - } - } - for(k=0;kphrasebits+= - vorbis_book_encode(books+info->class_book[class],cval,&vb->opb); - -#ifdef TRAIN_FLOOR1 - { - FILE *of; - char buffer[80]; - sprintf(buffer,"line_%dx%ld_class%d.vqd", - vb->pcmend/2,posts-2,class); - of=fopen(buffer,"a"); - fprintf(of,"%d\n",cval); - fclose(of); - } -#endif - } - - /* write post values */ - for(k=0;kclass_subbook[class][bookas[k]]; - if(book>=0){ - /* hack to allow training with 'bad' books */ - if(out[j+k]<(books+book)->entries) - look->postbits+=vorbis_book_encode(books+book, - out[j+k],&vb->opb); - /*else - fprintf(stderr,"+!");*/ - -#ifdef TRAIN_FLOOR1 - { - FILE *of; - char buffer[80]; - sprintf(buffer,"line_%dx%ld_%dsub%d.vqd", - vb->pcmend/2,posts-2,class,bookas[k]); - of=fopen(buffer,"a"); - fprintf(of,"%d\n",out[j+k]); - fclose(of); - } -#endif - } - } - j+=cdim; - } - - { - /* generate quantized floor equivalent to what we'd unpack in decode */ - /* render the lines */ - int hx=0; - int lx=0; - int ly=post[0]*info->mult; - for(j=1;jposts;j++){ - int current=look->forward_index[j]; - int hy=post[current]&0x7fff; - if(hy==post[current]){ - - hy*=info->mult; - hx=info->postlist[current]; - - render_line0(lx,hx,ly,hy,ilogmask); - - lx=hx; - ly=hy; - } - } - for(j=hx;jpcmend/2;j++)ilogmask[j]=ly; /* be certain */ - seq++; - return(1); - } - }else{ - oggpack_write(&vb->opb,0,1); - memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask)); - seq++; - return(0); - } -} - -static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){ - vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; - vorbis_info_floor1 *info=look->vi; - codec_setup_info *ci=vb->vd->vi->codec_setup; - - int i,j,k; - codebook *books=ci->fullbooks; - - /* unpack wrapped/predicted values from stream */ - if(oggpack_read(&vb->opb,1)==1){ - int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value)); - - fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); - fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); - - /* partition by partition */ - for(i=0,j=2;ipartitions;i++){ - int class=info->partitionclass[i]; - int cdim=info->class_dim[class]; - int csubbits=info->class_subs[class]; - int csub=1<class_book[class],&vb->opb); - - if(cval==-1)goto eop; - } - - for(k=0;kclass_subbook[class][cval&(csub-1)]; - cval>>=csubbits; - if(book>=0){ - if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) - goto eop; - }else{ - fit_value[j+k]=0; - } - } - j+=cdim; - } - - /* unwrap positive values and reconsitute via linear interpolation */ - for(i=2;iposts;i++){ - int predicted=render_point(info->postlist[look->loneighbor[i-2]], - info->postlist[look->hineighbor[i-2]], - fit_value[look->loneighbor[i-2]], - fit_value[look->hineighbor[i-2]], - info->postlist[i]); - int hiroom=look->quant_q-predicted; - int loroom=predicted; - int room=(hiroom=room){ - if(hiroom>loroom){ - val = val-loroom; - }else{ - val = -1-(val-hiroom); - } - }else{ - if(val&1){ - val= -((val+1)>>1); - }else{ - val>>=1; - } - } - - fit_value[i]=val+predicted; - fit_value[look->loneighbor[i-2]]&=0x7fff; - fit_value[look->hineighbor[i-2]]&=0x7fff; - - }else{ - fit_value[i]=predicted|0x8000; - } - - } - - return(fit_value); - } - eop: - return(NULL); -} - -static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, - float *out){ - vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; - vorbis_info_floor1 *info=look->vi; - - codec_setup_info *ci=vb->vd->vi->codec_setup; - int n=ci->blocksizes[vb->W]/2; - int j; - - if(memo){ - /* render the lines */ - int *fit_value=(int *)memo; - int hx=0; - int lx=0; - int ly=fit_value[0]*info->mult; - for(j=1;jposts;j++){ - int current=look->forward_index[j]; - int hy=fit_value[current]&0x7fff; - if(hy==fit_value[current]){ - - hy*=info->mult; - hx=info->postlist[current]; - - render_line(lx,hx,ly,hy,out); - - lx=hx; - ly=hy; - } - } - for(j=hx;j header packets - last mod: $Id: info.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -/* general handling of the header and the vorbis_info structure (and - substructures) */ - -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "codebook.h" -#include "registry.h" -#include "window.h" -#include "psy.h" -#include "misc.h" -#include "os.h" - -/* helpers */ -static int ilog2(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static void _v_writestring(oggpack_buffer *o,char *s, int bytes){ - - while(bytes--){ - oggpack_write(o,*s++,8); - } -} - -static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ - while(bytes--){ - *buf++=oggpack_read(o,8); - } -} - -void vorbis_comment_init(vorbis_comment *vc){ - memset(vc,0,sizeof(*vc)); -} - -void vorbis_comment_add(vorbis_comment *vc,char *comment){ - vc->user_comments=_ogg_realloc(vc->user_comments, - (vc->comments+2)*sizeof(*vc->user_comments)); - vc->comment_lengths=_ogg_realloc(vc->comment_lengths, - (vc->comments+2)*sizeof(*vc->comment_lengths)); - vc->comment_lengths[vc->comments]=strlen(comment); - vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1); - strcpy(vc->user_comments[vc->comments], comment); - vc->comments++; - vc->user_comments[vc->comments]=NULL; -} - -void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){ - char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */ - strcpy(comment, tag); - strcat(comment, "="); - strcat(comment, contents); - vorbis_comment_add(vc, comment); -} - -/* This is more or less the same as strncasecmp - but that doesn't exist - * everywhere, and this is a fairly trivial function, so we include it */ -static int tagcompare(const char *s1, const char *s2, int n){ - int c=0; - while(c < n){ - if(toupper(s1[c]) != toupper(s2[c])) - return !0; - c++; - } - return 0; -} - -char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ - long i; - int found = 0; - int taglen = strlen(tag)+1; /* +1 for the = we append */ - char *fulltag = alloca(taglen+ 1); - - strcpy(fulltag, tag); - strcat(fulltag, "="); - - for(i=0;icomments;i++){ - if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ - if(count == found) - /* We return a pointer to the data, not a copy */ - return vc->user_comments[i] + taglen; - else - found++; - } - } - return NULL; /* didn't find anything */ -} - -int vorbis_comment_query_count(vorbis_comment *vc, char *tag){ - int i,count=0; - int taglen = strlen(tag)+1; /* +1 for the = we append */ - char *fulltag = alloca(taglen+1); - strcpy(fulltag,tag); - strcat(fulltag, "="); - - for(i=0;icomments;i++){ - if(!tagcompare(vc->user_comments[i], fulltag, taglen)) - count++; - } - - return count; -} - -void vorbis_comment_clear(vorbis_comment *vc){ - if(vc){ - long i; - for(i=0;icomments;i++) - if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); - if(vc->user_comments)_ogg_free(vc->user_comments); - if(vc->comment_lengths)_ogg_free(vc->comment_lengths); - if(vc->vendor)_ogg_free(vc->vendor); - } - memset(vc,0,sizeof(*vc)); -} - -/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. - They may be equal, but short will never ge greater than long */ -int vorbis_info_blocksize(vorbis_info *vi,int zo){ - codec_setup_info *ci = vi->codec_setup; - return ci ? ci->blocksizes[zo] : -1; -} - -/* used by synthesis, which has a full, alloced vi */ -void vorbis_info_init(vorbis_info *vi){ - memset(vi,0,sizeof(*vi)); - vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info)); -} - -void vorbis_info_clear(vorbis_info *vi){ - codec_setup_info *ci=vi->codec_setup; - int i; - - if(ci){ - - for(i=0;imodes;i++) - if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); - - for(i=0;imaps;i++) /* unpack does the range checking */ - _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); - - for(i=0;ifloors;i++) /* unpack does the range checking */ - _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); - - for(i=0;iresidues;i++) /* unpack does the range checking */ - _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); - - for(i=0;ibooks;i++){ - if(ci->book_param[i]){ - /* knows if the book was not alloced */ - vorbis_staticbook_destroy(ci->book_param[i]); - } - if(ci->fullbooks) - vorbis_book_clear(ci->fullbooks+i); - } - if(ci->fullbooks) - _ogg_free(ci->fullbooks); - - for(i=0;ipsys;i++) - _vi_psy_free(ci->psy_param[i]); - - _ogg_free(ci); - } - - memset(vi,0,sizeof(*vi)); -} - -/* Header packing/unpacking ********************************************/ - -static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ - codec_setup_info *ci=vi->codec_setup; - if(!ci)return(OV_EFAULT); - - vi->version=oggpack_read(opb,32); - if(vi->version!=0)return(OV_EVERSION); - - vi->channels=oggpack_read(opb,8); - vi->rate=oggpack_read(opb,32); - - vi->bitrate_upper=oggpack_read(opb,32); - vi->bitrate_nominal=oggpack_read(opb,32); - vi->bitrate_lower=oggpack_read(opb,32); - - ci->blocksizes[0]=1<blocksizes[1]=1<rate<1)goto err_out; - if(vi->channels<1)goto err_out; - if(ci->blocksizes[0]<8)goto err_out; - if(ci->blocksizes[1]blocksizes[0])goto err_out; - - if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ - - return(0); - err_out: - vorbis_info_clear(vi); - return(OV_EBADHEADER); -} - -static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ - int i; - int vendorlen=oggpack_read(opb,32); - if(vendorlen<0)goto err_out; - vc->vendor=_ogg_calloc(vendorlen+1,1); - _v_readstring(opb,vc->vendor,vendorlen); - vc->comments=oggpack_read(opb,32); - if(vc->comments<0)goto err_out; - vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); - vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); - - for(i=0;icomments;i++){ - int len=oggpack_read(opb,32); - if(len<0)goto err_out; - vc->comment_lengths[i]=len; - vc->user_comments[i]=_ogg_calloc(len+1,1); - _v_readstring(opb,vc->user_comments[i],len); - } - if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ - - return(0); - err_out: - vorbis_comment_clear(vc); - return(OV_EBADHEADER); -} - -/* all of the real encoding details are here. The modes, books, - everything */ -static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ - codec_setup_info *ci=vi->codec_setup; - int i; - if(!ci)return(OV_EFAULT); - - /* codebooks */ - ci->books=oggpack_read(opb,8)+1; - /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ - for(i=0;ibooks;i++){ - ci->book_param[i]=_ogg_calloc(1,sizeof(*ci->book_param[i])); - if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; - } - - /* time backend settings; hooks are unused */ - { - int times=oggpack_read(opb,6)+1; - for(i=0;i=VI_TIMEB)goto err_out; - } - } - - /* floor backend settings */ - ci->floors=oggpack_read(opb,6)+1; - /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ - /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ - for(i=0;ifloors;i++){ - ci->floor_type[i]=oggpack_read(opb,16); - if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; - ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); - if(!ci->floor_param[i])goto err_out; - } - - /* residue backend settings */ - ci->residues=oggpack_read(opb,6)+1; - /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ - /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ - for(i=0;iresidues;i++){ - ci->residue_type[i]=oggpack_read(opb,16); - if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; - ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); - if(!ci->residue_param[i])goto err_out; - } - - /* map backend settings */ - ci->maps=oggpack_read(opb,6)+1; - /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ - /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ - for(i=0;imaps;i++){ - ci->map_type[i]=oggpack_read(opb,16); - if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; - ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); - if(!ci->map_param[i])goto err_out; - } - - /* mode settings */ - ci->modes=oggpack_read(opb,6)+1; - /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ - for(i=0;imodes;i++){ - ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i])); - ci->mode_param[i]->blockflag=oggpack_read(opb,1); - ci->mode_param[i]->windowtype=oggpack_read(opb,16); - ci->mode_param[i]->transformtype=oggpack_read(opb,16); - ci->mode_param[i]->mapping=oggpack_read(opb,8); - - if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; - if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; - if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; - } - - if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ - - return(0); - err_out: - vorbis_info_clear(vi); - return(OV_EBADHEADER); -} - -/* The Vorbis header is in three packets; the initial small packet in - the first page that identifies basic parameters, a second packet - with bitstream comments and a third packet that holds the - codebook. */ - -int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ - oggpack_buffer opb; - - if(op){ - oggpack_readinit(&opb,op->packet,op->bytes); - - /* Which of the three types of header is this? */ - /* Also verify header-ness, vorbis */ - { - char buffer[6]; - int packtype=oggpack_read(&opb,8); - memset(buffer,0,6); - _v_readstring(&opb,buffer,6); - if(memcmp(buffer,"vorbis",6)){ - /* not a vorbis header */ - return(OV_ENOTVORBIS); - } - switch(packtype){ - case 0x01: /* least significant *bit* is read first */ - if(!op->b_o_s){ - /* Not the initial packet */ - return(OV_EBADHEADER); - } - if(vi->rate!=0){ - /* previously initialized info header */ - return(OV_EBADHEADER); - } - - return(_vorbis_unpack_info(vi,&opb)); - - case 0x03: /* least significant *bit* is read first */ - if(vi->rate==0){ - /* um... we didn't get the initial header */ - return(OV_EBADHEADER); - } - - return(_vorbis_unpack_comment(vc,&opb)); - - case 0x05: /* least significant *bit* is read first */ - if(vi->rate==0 || vc->vendor==NULL){ - /* um... we didn;t get the initial header or comments yet */ - return(OV_EBADHEADER); - } - - return(_vorbis_unpack_books(vi,&opb)); - - default: - /* Not a valid vorbis header type */ - return(OV_EBADHEADER); - break; - } - } - } - return(OV_EBADHEADER); -} - -/* pack side **********************************************************/ - -static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){ - codec_setup_info *ci=vi->codec_setup; - if(!ci)return(OV_EFAULT); - - /* preamble */ - oggpack_write(opb,0x01,8); - _v_writestring(opb,"vorbis", 6); - - /* basic information about the stream */ - oggpack_write(opb,0x00,32); - oggpack_write(opb,vi->channels,8); - oggpack_write(opb,vi->rate,32); - - oggpack_write(opb,vi->bitrate_upper,32); - oggpack_write(opb,vi->bitrate_nominal,32); - oggpack_write(opb,vi->bitrate_lower,32); - - oggpack_write(opb,ilog2(ci->blocksizes[0]),4); - oggpack_write(opb,ilog2(ci->blocksizes[1]),4); - oggpack_write(opb,1,1); - - return(0); -} - -static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){ - char temp[]="Xiph.Org libVorbis I 20020717"; - int bytes = strlen(temp); - - /* preamble */ - oggpack_write(opb,0x03,8); - _v_writestring(opb,"vorbis", 6); - - /* vendor */ - oggpack_write(opb,bytes,32); - _v_writestring(opb,temp, bytes); - - /* comments */ - - oggpack_write(opb,vc->comments,32); - if(vc->comments){ - int i; - for(i=0;icomments;i++){ - if(vc->user_comments[i]){ - oggpack_write(opb,vc->comment_lengths[i],32); - _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]); - }else{ - oggpack_write(opb,0,32); - } - } - } - oggpack_write(opb,1,1); - - return(0); -} - -static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){ - codec_setup_info *ci=vi->codec_setup; - int i; - if(!ci)return(OV_EFAULT); - - oggpack_write(opb,0x05,8); - _v_writestring(opb,"vorbis", 6); - - /* books */ - oggpack_write(opb,ci->books-1,8); - for(i=0;ibooks;i++) - if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out; - - /* times; hook placeholders */ - oggpack_write(opb,0,6); - oggpack_write(opb,0,16); - - /* floors */ - oggpack_write(opb,ci->floors-1,6); - for(i=0;ifloors;i++){ - oggpack_write(opb,ci->floor_type[i],16); - if(_floor_P[ci->floor_type[i]]->pack) - _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb); - else - goto err_out; - } - - /* residues */ - oggpack_write(opb,ci->residues-1,6); - for(i=0;iresidues;i++){ - oggpack_write(opb,ci->residue_type[i],16); - _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb); - } - - /* maps */ - oggpack_write(opb,ci->maps-1,6); - for(i=0;imaps;i++){ - oggpack_write(opb,ci->map_type[i],16); - _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb); - } - - /* modes */ - oggpack_write(opb,ci->modes-1,6); - for(i=0;imodes;i++){ - oggpack_write(opb,ci->mode_param[i]->blockflag,1); - oggpack_write(opb,ci->mode_param[i]->windowtype,16); - oggpack_write(opb,ci->mode_param[i]->transformtype,16); - oggpack_write(opb,ci->mode_param[i]->mapping,8); - } - oggpack_write(opb,1,1); - - return(0); -err_out: - return(-1); -} - -int vorbis_commentheader_out(vorbis_comment *vc, - ogg_packet *op){ - - oggpack_buffer opb; - - oggpack_writeinit(&opb); - if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; - - op->packet = _ogg_malloc(oggpack_bytes(&opb)); - memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); - - op->bytes=oggpack_bytes(&opb); - op->b_o_s=0; - op->e_o_s=0; - op->granulepos=0; - - return 0; -} - -int vorbis_analysis_headerout(vorbis_dsp_state *v, - vorbis_comment *vc, - ogg_packet *op, - ogg_packet *op_comm, - ogg_packet *op_code){ - int ret=OV_EIMPL; - vorbis_info *vi=v->vi; - oggpack_buffer opb; - backend_lookup_state *b=v->backend_state; - - if(!b){ - ret=OV_EFAULT; - goto err_out; - } - - /* first header packet **********************************************/ - - oggpack_writeinit(&opb); - if(_vorbis_pack_info(&opb,vi))goto err_out; - - /* build the packet */ - if(b->header)_ogg_free(b->header); - b->header=_ogg_malloc(oggpack_bytes(&opb)); - memcpy(b->header,opb.buffer,oggpack_bytes(&opb)); - op->packet=b->header; - op->bytes=oggpack_bytes(&opb); - op->b_o_s=1; - op->e_o_s=0; - op->granulepos=0; - - /* second header packet (comments) **********************************/ - - oggpack_reset(&opb); - if(_vorbis_pack_comment(&opb,vc))goto err_out; - - if(b->header1)_ogg_free(b->header1); - b->header1=_ogg_malloc(oggpack_bytes(&opb)); - memcpy(b->header1,opb.buffer,oggpack_bytes(&opb)); - op_comm->packet=b->header1; - op_comm->bytes=oggpack_bytes(&opb); - op_comm->b_o_s=0; - op_comm->e_o_s=0; - op_comm->granulepos=0; - - /* third header packet (modes/codebooks) ****************************/ - - oggpack_reset(&opb); - if(_vorbis_pack_books(&opb,vi))goto err_out; - - if(b->header2)_ogg_free(b->header2); - b->header2=_ogg_malloc(oggpack_bytes(&opb)); - memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); - op_code->packet=b->header2; - op_code->bytes=oggpack_bytes(&opb); - op_code->b_o_s=0; - op_code->e_o_s=0; - op_code->granulepos=0; - - oggpack_writeclear(&opb); - return(0); - err_out: - oggpack_writeclear(&opb); - memset(op,0,sizeof(*op)); - memset(op_comm,0,sizeof(*op_comm)); - memset(op_code,0,sizeof(*op_code)); - - if(b->header)_ogg_free(b->header); - if(b->header1)_ogg_free(b->header1); - if(b->header2)_ogg_free(b->header2); - b->header=NULL; - b->header1=NULL; - b->header2=NULL; - return(ret); -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/lookup.c b/src/add-ons/media/plugins/vorbis/libvorbis/lookup.c deleted file mode 100644 index 4e073dc9d1..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/lookup.c +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: lookup based functions - last mod: $Id: lookup.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include "lookup.h" -#include "lookup_data.h" -#include "os.h" -#include "misc.h" - -#ifdef FLOAT_LOOKUP - -/* interpolated lookup based cos function, domain 0 to PI only */ -float vorbis_coslook(float a){ - double d=a*(.31830989*(float)COS_LOOKUP_SZ); - int i=vorbis_ftoi(d-.5); - - return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]); -} - -/* interpolated 1./sqrt(p) where .5 <= p < 1. */ -float vorbis_invsqlook(float a){ - double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ; - int i=vorbis_ftoi(d-.5f); - return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]); -} - -/* interpolated 1./sqrt(p) where .5 <= p < 1. */ -float vorbis_invsq2explook(int a){ - return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN]; -} - -#include -/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ -float vorbis_fromdBlook(float a){ - int i=vorbis_ftoi(a*((float)(-(1<=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); -} - -#endif - -#ifdef INT_LOOKUP -/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in - 16.16 format - - returns in m.8 format */ -long vorbis_invsqlook_i(long a,long e){ - long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); - long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /* 0.16 */ - long val=INVSQ_LOOKUP_I[i]- /* 1.16 */ - (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])* /* 0.16 */ - d)>>16); /* result 1.16 */ - - e+=32; - if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */ - e=(e>>1)-8; - - return(val>>e); -} - -/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ -/* a is in n.12 format */ -float vorbis_fromdBlook_i(long a){ - int i=(-a)>>(12-FROMdB2_SHIFT); - return (i<0)?1.f: - ((i>=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); -} - -/* interpolated lookup based cos function, domain 0 to PI only */ -/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */ -long vorbis_coslook_i(long a){ - int i=a>>COS_LOOKUP_I_SHIFT; - int d=a&COS_LOOKUP_I_MASK; - return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>> - COS_LOOKUP_I_SHIFT); -} - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/lookup.h b/src/add-ons/media/plugins/vorbis/libvorbis/lookup.h deleted file mode 100644 index 5980ce8fe4..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/lookup.h +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: lookup based functions - last mod: $Id: lookup.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_LOOKUP_H_ - -#ifdef FLOAT_LOOKUP -extern float vorbis_coslook(float a); -extern float vorbis_invsqlook(float a); -extern float vorbis_invsq2explook(int a); -extern float vorbis_fromdBlook(float a); -#endif -#ifdef INT_LOOKUP -extern long vorbis_invsqlook_i(long a,long e); -extern long vorbis_coslook_i(long a); -extern float vorbis_fromdBlook_i(long a); -#endif - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/lookup_data.h b/src/add-ons/media/plugins/vorbis/libvorbis/lookup_data.h deleted file mode 100644 index 4674b296c7..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/lookup_data.h +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: lookup data; generated by lookups.pl; edit there - last mod: $Id: lookup_data.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_LOOKUP_DATA_H_ - -#ifdef FLOAT_LOOKUP -#define COS_LOOKUP_SZ 128 -static float COS_LOOKUP[COS_LOOKUP_SZ+1]={ - +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f, - +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f, - +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f, - +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f, - +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f, - +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f, - +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f, - +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f, - +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f, - +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f, - +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f, - +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f, - +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f, - +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f, - +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f, - +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f, - +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f, - -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f, - -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f, - -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f, - -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f, - -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f, - -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f, - -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f, - -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f, - -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f, - -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f, - -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f, - -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f, - -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f, - -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f, - -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f, - -1.0000000000000f, -}; - -#define INVSQ_LOOKUP_SZ 32 -static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={ - 1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f, - 1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f, - 1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f, - 1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f, - 1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f, - 1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f, - 1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f, - 1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f, - 1.000000000000f, -}; - -#define INVSQ2EXP_LOOKUP_MIN -32 -#define INVSQ2EXP_LOOKUP_MAX 32 -static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\ - INVSQ2EXP_LOOKUP_MIN+1]={ - 65536.f, 46340.95001f, 32768.f, 23170.47501f, - 16384.f, 11585.2375f, 8192.f, 5792.618751f, - 4096.f, 2896.309376f, 2048.f, 1448.154688f, - 1024.f, 724.0773439f, 512.f, 362.038672f, - 256.f, 181.019336f, 128.f, 90.50966799f, - 64.f, 45.254834f, 32.f, 22.627417f, - 16.f, 11.3137085f, 8.f, 5.656854249f, - 4.f, 2.828427125f, 2.f, 1.414213562f, - 1.f, 0.7071067812f, 0.5f, 0.3535533906f, - 0.25f, 0.1767766953f, 0.125f, 0.08838834765f, - 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f, - 0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f, - 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f, - 0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f, - 0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f, - 6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f, - 1.525878906e-05f, -}; - -#endif - -#define FROMdB_LOOKUP_SZ 35 -#define FROMdB2_LOOKUP_SZ 32 -#define FROMdB_SHIFT 5 -#define FROMdB2_SHIFT 3 -#define FROMdB2_MASK 31 -static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={ - 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f, - 0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f, - 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f, - 0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f, - 0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f, - 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f, - 1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f, - 2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f, - 3.981071706e-07f,2.511886432e-07f,1.584893192e-07f, -}; - -static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={ - 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f, - 0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f, - 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f, - 0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f, - 0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f, - 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f, - 0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f, - 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f, -}; - -#ifdef INT_LOOKUP - -#define INVSQ_LOOKUP_I_SHIFT 10 -#define INVSQ_LOOKUP_I_MASK 1023 -static long INVSQ_LOOKUP_I[64+1]={ - 92682l, 91966l, 91267l, 90583l, - 89915l, 89261l, 88621l, 87995l, - 87381l, 86781l, 86192l, 85616l, - 85051l, 84497l, 83953l, 83420l, - 82897l, 82384l, 81880l, 81385l, - 80899l, 80422l, 79953l, 79492l, - 79039l, 78594l, 78156l, 77726l, - 77302l, 76885l, 76475l, 76072l, - 75674l, 75283l, 74898l, 74519l, - 74146l, 73778l, 73415l, 73058l, - 72706l, 72359l, 72016l, 71679l, - 71347l, 71019l, 70695l, 70376l, - 70061l, 69750l, 69444l, 69141l, - 68842l, 68548l, 68256l, 67969l, - 67685l, 67405l, 67128l, 66855l, - 66585l, 66318l, 66054l, 65794l, - 65536l, -}; - -#define COS_LOOKUP_I_SHIFT 9 -#define COS_LOOKUP_I_MASK 511 -#define COS_LOOKUP_I_SZ 128 -static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={ - 16384l, 16379l, 16364l, 16340l, - 16305l, 16261l, 16207l, 16143l, - 16069l, 15986l, 15893l, 15791l, - 15679l, 15557l, 15426l, 15286l, - 15137l, 14978l, 14811l, 14635l, - 14449l, 14256l, 14053l, 13842l, - 13623l, 13395l, 13160l, 12916l, - 12665l, 12406l, 12140l, 11866l, - 11585l, 11297l, 11003l, 10702l, - 10394l, 10080l, 9760l, 9434l, - 9102l, 8765l, 8423l, 8076l, - 7723l, 7366l, 7005l, 6639l, - 6270l, 5897l, 5520l, 5139l, - 4756l, 4370l, 3981l, 3590l, - 3196l, 2801l, 2404l, 2006l, - 1606l, 1205l, 804l, 402l, - 0l, -401l, -803l, -1204l, - -1605l, -2005l, -2403l, -2800l, - -3195l, -3589l, -3980l, -4369l, - -4755l, -5138l, -5519l, -5896l, - -6269l, -6638l, -7004l, -7365l, - -7722l, -8075l, -8422l, -8764l, - -9101l, -9433l, -9759l, -10079l, - -10393l, -10701l, -11002l, -11296l, - -11584l, -11865l, -12139l, -12405l, - -12664l, -12915l, -13159l, -13394l, - -13622l, -13841l, -14052l, -14255l, - -14448l, -14634l, -14810l, -14977l, - -15136l, -15285l, -15425l, -15556l, - -15678l, -15790l, -15892l, -15985l, - -16068l, -16142l, -16206l, -16260l, - -16304l, -16339l, -16363l, -16378l, - -16383l, -}; - -#endif - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/lpc.c b/src/add-ons/media/plugins/vorbis/libvorbis/lpc.c deleted file mode 100644 index 9df9e1cda8..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/lpc.c +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: LPC low level routines - last mod: $Id: lpc.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -/* Some of these routines (autocorrelator, LPC coefficient estimator) - are derived from code written by Jutta Degener and Carsten Bormann; - thus we include their copyright below. The entirety of this file - is freely redistributable on the condition that both of these - copyright notices are preserved without modification. */ - -/* Preserved Copyright: *********************************************/ - -/* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universita"t Berlin - -Any use of this software is permitted provided that this notice is not -removed and that neither the authors nor the Technische Universita"t -Berlin are deemed to have made any representations as to the -suitability of this software for any purpose nor are held responsible -for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR -THIS SOFTWARE. - -As a matter of courtesy, the authors request to be informed about uses -this software has found, about bugs in this software, and about any -improvements that may be of general interest. - -Berlin, 28.11.1994 -Jutta Degener -Carsten Bormann - -*********************************************************************/ - -#include -#include -#include -#include "os.h" -#include "smallft.h" -#include "lpc.h" -#include "scales.h" -#include "misc.h" - -/* Autocorrelation LPC coeff generation algorithm invented by - N. Levinson in 1947, modified by J. Durbin in 1959. */ - -/* Input : n elements of time doamin data - Output: m lpc coefficients, excitation energy */ - -float vorbis_lpc_from_data(float *data,float *lpc,int n,int m){ - float *aut=alloca(sizeof(*aut)*(m+1)); - float error; - int i,j; - - /* autocorrelation, p+1 lag coefficients */ - - j=m+1; - while(j--){ - double d=0; /* double needed for accumulator depth */ - for(i=j;iln; - int m=l->m; - float *work=alloca(sizeof(*work)*(n+n)); - float fscale=.5f/n; - int i,j; - - /* input is a real curve. make it complex-real */ - /* This mixes phase, but the LPC generation doesn't care. */ - for(i=0;ifft,work); - - /* The autocorrelation will not be circular. Shift, else we lose - most of the power in the edges. */ - - for(i=0,j=n/2;iln=mapped; - l->m=m; - - /* we cheat decoding the LPC spectrum via FFTs */ - drft_init(&l->fft,mapped*2); - -} - -void lpc_clear(lpc_lookup *l){ - if(l){ - drft_clear(&l->fft); - } -} - -void vorbis_lpc_predict(float *coeff,float *prime,int m, - float *data,long n){ - - /* in: coeff[0...m-1] LPC coefficients - prime[0...m-1] initial values (allocated size of n+m-1) - out: data[0...n-1] data samples */ - - long i,j,o,p; - float y; - float *work=alloca(sizeof(*work)*(m+n)); - - if(!prime) - for(i=0;i, available at: - - http://www2.xtdl.com/~rothwlr/lsfpaper/lsfpage.html - - ********************************************************************/ - -/* Note that the lpc-lsp conversion finds the roots of polynomial with - an iterative root polisher (CACM algorithm 283). It *is* possible - to confuse this algorithm into not converging; that should only - happen with absurdly closely spaced roots (very sharp peaks in the - LPC f response) which in turn should be impossible in our use of - the code. If this *does* happen anyway, it's a bug in the floor - finder; find the cause of the confusion (probably a single bin - spike or accidental near-float-limit resolution problems) and - correct it. */ - -#include -#include -#include -#include "lsp.h" -#include "os.h" -#include "misc.h" -#include "lookup.h" -#include "scales.h" - -/* three possible LSP to f curve functions; the exact computation - (float), a lookup based float implementation, and an integer - implementation. The float lookup is likely the optimal choice on - any machine with an FPU. The integer implementation is *not* fixed - point (due to the need for a large dynamic range and thus a - seperately tracked exponent) and thus much more complex than the - relatively simple float implementations. It's mostly for future - work on a fully fixed point implementation for processors like the - ARM family. */ - -/* undefine both for the 'old' but more precise implementation */ -#define FLOAT_LOOKUP -#undef INT_LOOKUP - -#ifdef FLOAT_LOOKUP -#include "lookup.c" /* catch this in the build system; we #include for - compilers (like gcc) that can't inline across - modules */ - -/* side effect: changes *lsp to cosines of lsp */ -void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, - float amp,float ampoffset){ - int i; - float wdel=M_PI/ln; - vorbis_fpu_control fpu; - - vorbis_fpu_setround(&fpu); - for(i=0;i>1; - - do{ - q*=ftmp[0]-w; - p*=ftmp[1]-w; - ftmp+=2; - }while(--c); - - if(m&1){ - /* odd order filter; slightly assymetric */ - /* the last coefficient */ - q*=ftmp[0]-w; - q*=q; - p*=p*(1.f-w*w); - }else{ - /* even order filter; still symmetric */ - q*=q*(1.f+w); - p*=p*(1.f-w); - } - - q=frexp(p+q,&qexp); - q=vorbis_fromdBlook(amp* - vorbis_invsqlook(q)* - vorbis_invsq2explook(qexp+m)- - ampoffset); - - do{ - curve[i++]*=q; - }while(map[i]==k); - } - vorbis_fpu_restore(fpu); -} - -#else - -#ifdef INT_LOOKUP -#include "lookup.c" /* catch this in the build system; we #include for - compilers (like gcc) that can't inline across - modules */ - -static int MLOOP_1[64]={ - 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13, - 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, -}; - -static int MLOOP_2[64]={ - 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7, - 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8, - 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, - 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, -}; - -static int MLOOP_3[8]={0,1,2,2,3,3,3,3}; - - -/* side effect: changes *lsp to cosines of lsp */ -void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, - float amp,float ampoffset){ - - /* 0 <= m < 256 */ - - /* set up for using all int later */ - int i; - int ampoffseti=rint(ampoffset*4096.f); - int ampi=rint(amp*16.f); - long *ilsp=alloca(m*sizeof(*ilsp)); - for(i=0;i>25])) - if(!(shift=MLOOP_2[(pi|qi)>>19])) - shift=MLOOP_3[(pi|qi)>>16]; - qi=(qi>>shift)*labs(ilsp[j-1]-wi); - pi=(pi>>shift)*labs(ilsp[j]-wi); - qexp+=shift; - } - if(!(shift=MLOOP_1[(pi|qi)>>25])) - if(!(shift=MLOOP_2[(pi|qi)>>19])) - shift=MLOOP_3[(pi|qi)>>16]; - - /* pi,qi normalized collectively, both tracked using qexp */ - - if(m&1){ - /* odd order filter; slightly assymetric */ - /* the last coefficient */ - qi=(qi>>shift)*labs(ilsp[j-1]-wi); - pi=(pi>>shift)<<14; - qexp+=shift; - - if(!(shift=MLOOP_1[(pi|qi)>>25])) - if(!(shift=MLOOP_2[(pi|qi)>>19])) - shift=MLOOP_3[(pi|qi)>>16]; - - pi>>=shift; - qi>>=shift; - qexp+=shift-14*((m+1)>>1); - - pi=((pi*pi)>>16); - qi=((qi*qi)>>16); - qexp=qexp*2+m; - - pi*=(1<<14)-((wi*wi)>>14); - qi+=pi>>14; - - }else{ - /* even order filter; still symmetric */ - - /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't - worth tracking step by step */ - - pi>>=shift; - qi>>=shift; - qexp+=shift-7*m; - - pi=((pi*pi)>>16); - qi=((qi*qi)>>16); - qexp=qexp*2+m; - - pi*=(1<<14)-wi; - qi*=(1<<14)+wi; - qi=(qi+pi)>>14; - - } - - - /* we've let the normalization drift because it wasn't important; - however, for the lookup, things must be normalized again. We - need at most one right shift or a number of left shifts */ - - if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */ - qi>>=1; qexp++; - }else - while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/ - qi<<=1; qexp--; - } - - amp=vorbis_fromdBlook_i(ampi* /* n.4 */ - vorbis_invsqlook_i(qi,qexp)- - /* m.8, m+n<=8 */ - ampoffseti); /* 8.12[0] */ - - curve[i]*=amp; - while(map[++i]==k)curve[i]*=amp; - } -} - -#else - -/* old, nonoptimized but simple version for any poor sap who needs to - figure out what the hell this code does, or wants the other - fraction of a dB precision */ - -/* side effect: changes *lsp to cosines of lsp */ -void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, - float amp,float ampoffset){ - int i; - float wdel=M_PI/ln; - for(i=0;i= i; j--) { - g[j-2] -= g[j]; - g[j] += g[j]; - } - } -} - -static int comp(const void *a,const void *b){ - if(*(float *)a<*(float *)b) - return(1); - else - return(-1); -} - -/* Newton-Raphson-Maehly actually functioned as a decent root finder, - but there are root sets for which it gets into limit cycles - (exacerbated by zero suppression) and fails. We can't afford to - fail, even if the failure is 1 in 100,000,000, so we now use - Laguerre and later polish with Newton-Raphson (which can then - afford to fail) */ - -#define EPSILON 10e-7 -static int Laguerre_With_Deflation(float *a,int ord,float *r){ - int i,m; - double lastdelta=0.f; - double *defl=alloca(sizeof(*defl)*(ord+1)); - for(i=0;i<=ord;i++)defl[i]=a[i]; - - for(m=ord;m>0;m--){ - double new=0.f,delta; - - /* iterate a root */ - while(1){ - double p=defl[m],pp=0.f,ppp=0.f,denom; - - /* eval the polynomial and its first two derivatives */ - for(i=m;i>0;i--){ - ppp = new*ppp + pp; - pp = new*pp + p; - p = new*p + defl[i-1]; - } - - /* Laguerre's method */ - denom=(m-1) * ((m-1)*pp*pp - m*p*ppp); - if(denom<0) - return(-1); /* complex root! The LPC generator handed us a bad filter */ - - if(pp>0){ - denom = pp + sqrt(denom); - if(denom-(EPSILON))denom=-(EPSILON); - } - - delta = m*p/denom; - new -= delta; - - if(delta<0.f)delta*=-1; - - if(fabs(delta/new)<10e-12)break; - lastdelta=delta; - } - - r[m-1]=new; - - /* forward deflation */ - - for(i=m;i>0;i--) - defl[i-1]+=new*defl[i]; - defl++; - - } - return(0); -} - - -/* for spit-and-polish only */ -static int Newton_Raphson(float *a,int ord,float *r){ - int i, k, count=0; - double error=1.f; - double *root=alloca(ord*sizeof(*root)); - - for(i=0; i1e-20){ - error=0; - - for(i=0; i= 0; k--) { - - pp= pp* rooti + p; - p = p * rooti + a[k]; - } - - delta = p/pp; - root[i] -= delta; - error+= delta*delta; - } - - if(count>40)return(-1); - - count++; - } - - /* Replaced the original bubble sort with a real sort. With your - help, we can eliminate the bubble sort in our lifetime. --Monty */ - - for(i=0; i>1; - int g1_order,g2_order; - float *g1=alloca(sizeof(*g1)*(order2+1)); - float *g2=alloca(sizeof(*g2)*(order2+1)); - float *g1r=alloca(sizeof(*g1r)*(order2+1)); - float *g2r=alloca(sizeof(*g2r)*(order2+1)); - int i; - - /* even and odd are slightly different base cases */ - g1_order=(m+1)>>1; - g2_order=(m) >>1; - - /* Compute the lengths of the x polynomials. */ - /* Compute the first half of K & R F1 & F2 polynomials. */ - /* Compute half of the symmetric and antisymmetric polynomials. */ - /* Remove the roots at +1 and -1. */ - - g1[g1_order] = 1.f; - for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i]; - g2[g2_order] = 1.f; - for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i]; - - if(g1_order>g2_order){ - for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2]; - }else{ - for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1]; - for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1]; - } - - /* Convert into polynomials in cos(alpha) */ - cheby(g1,g1_order); - cheby(g2,g2_order); - - /* Find the roots of the 2 even polynomials.*/ - if(Laguerre_With_Deflation(g1,g1_order,g1r) || - Laguerre_With_Deflation(g2,g2_order,g2r)) - return(-1); - - Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */ - Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */ - - qsort(g1r,g1_order,sizeof(*g1r),comp); - qsort(g2r,g2_order,sizeof(*g2r),comp); - - for(i=0;i -#include -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "codebook.h" -#include "window.h" -#include "registry.h" -#include "psy.h" -#include "misc.h" - -/* simplistic, wasteful way of doing this (unique lookup for each - mode/submapping); there should be a central repository for - identical lookups. That will require minor work, so I'm putting it - off as low priority. - - Why a lookup for each backend in a given mode? Because the - blocksize is set by the mode, and low backend lookups may require - parameters from other areas of the mode/mapping */ - -static void mapping0_free_info(vorbis_info_mapping *i){ - vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i; - if(info){ - memset(info,0,sizeof(*info)); - _ogg_free(info); - } -} - -static int ilog(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm, - oggpack_buffer *opb){ - int i; - vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm; - - /* another 'we meant to do it this way' hack... up to beta 4, we - packed 4 binary zeros here to signify one submapping in use. We - now redefine that to mean four bitflags that indicate use of - deeper features; bit0:submappings, bit1:coupling, - bit2,3:reserved. This is backward compatable with all actual uses - of the beta code. */ - - if(info->submaps>1){ - oggpack_write(opb,1,1); - oggpack_write(opb,info->submaps-1,4); - }else - oggpack_write(opb,0,1); - - if(info->coupling_steps>0){ - oggpack_write(opb,1,1); - oggpack_write(opb,info->coupling_steps-1,8); - - for(i=0;icoupling_steps;i++){ - oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels)); - oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels)); - } - }else - oggpack_write(opb,0,1); - - oggpack_write(opb,0,2); /* 2,3:reserved */ - - /* we don't write the channel submappings if we only have one... */ - if(info->submaps>1){ - for(i=0;ichannels;i++) - oggpack_write(opb,info->chmuxlist[i],4); - } - for(i=0;isubmaps;i++){ - oggpack_write(opb,0,8); /* time submap unused */ - oggpack_write(opb,info->floorsubmap[i],8); - oggpack_write(opb,info->residuesubmap[i],8); - } -} - -/* also responsible for range checking */ -static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ - int i; - vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info)); - codec_setup_info *ci=vi->codec_setup; - memset(info,0,sizeof(*info)); - - if(oggpack_read(opb,1)) - info->submaps=oggpack_read(opb,4)+1; - else - info->submaps=1; - - if(oggpack_read(opb,1)){ - info->coupling_steps=oggpack_read(opb,8)+1; - - for(i=0;icoupling_steps;i++){ - int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); - int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels)); - - if(testM<0 || - testA<0 || - testM==testA || - testM>=vi->channels || - testA>=vi->channels) goto err_out; - } - - } - - if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */ - - if(info->submaps>1){ - for(i=0;ichannels;i++){ - info->chmuxlist[i]=oggpack_read(opb,4); - if(info->chmuxlist[i]>=info->submaps)goto err_out; - } - } - for(i=0;isubmaps;i++){ - oggpack_read(opb,8); /* time submap unused */ - info->floorsubmap[i]=oggpack_read(opb,8); - if(info->floorsubmap[i]>=ci->floors)goto err_out; - info->residuesubmap[i]=oggpack_read(opb,8); - if(info->residuesubmap[i]>=ci->residues)goto err_out; - } - - return info; - - err_out: - mapping0_free_info(info); - return(NULL); -} - -#include "os.h" -#include "lpc.h" -#include "lsp.h" -#include "envelope.h" -#include "mdct.h" -#include "psy.h" -#include "scales.h" - -#if 0 -static long seq=0; -static ogg_int64_t total=0; -static float FLOOR1_fromdB_LOOKUP[256]={ - 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, - 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, - 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, - 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, - 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, - 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, - 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, - 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, - 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, - 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, - 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, - 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, - 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, - 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, - 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, - 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, - 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, - 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, - 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, - 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, - 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, - 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, - 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, - 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, - 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, - 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, - 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, - 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, - 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, - 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, - 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, - 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, - 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, - 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, - 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, - 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, - 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, - 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, - 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, - 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, - 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, - 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, - 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, - 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, - 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, - 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, - 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, - 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, - 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, - 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, - 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, - 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, - 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, - 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, - 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, - 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, - 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, - 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, - 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, - 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, - 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, - 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, - 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, - 0.82788260F, 0.88168307F, 0.9389798F, 1.F, -}; - -#endif - -extern int *floor1_fit(vorbis_block *vb,vorbis_look_floor *look, - const float *logmdct, /* in */ - const float *logmask); -extern int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor *look, - int *A,int *B, - int del); -extern int floor1_encode(vorbis_block *vb,vorbis_look_floor *look, - int *post,int *ilogmask); - - -static int mapping0_forward(vorbis_block *vb){ - vorbis_dsp_state *vd=vb->vd; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - backend_lookup_state *b=vb->vd->backend_state; - vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; - int n=vb->pcmend; - int i,j,k; - - int *nonzero = alloca(sizeof(*nonzero)*vi->channels); - float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct)); - int **ilogmaskch= _vorbis_block_alloc(vb,vi->channels*sizeof(*ilogmaskch)); - int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts)); - - float global_ampmax=vbi->ampmax; - float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels); - int blocktype=vbi->blocktype; - - int modenumber=vb->W; - vorbis_info_mapping0 *info=ci->map_param[modenumber]; - vorbis_look_psy *psy_look= - b->psy+blocktype+(vb->W?2:0); - - vb->mode=modenumber; - - for(i=0;ichannels;i++){ - float scale=4.f/n; - float scale_dB; - - float *pcm =vb->pcm[i]; - float *logfft =pcm; - - gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); - - scale_dB=todB(&scale); - -#if 0 - if(vi->channels==2) - if(i==0) - _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2); - else - _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2); -#endif - - /* window the PCM data */ - _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); - -#if 0 - if(vi->channels==2) - if(i==0) - _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2); - else - _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2); -#endif - - /* transform the PCM data */ - /* only MDCT right now.... */ - mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]); - - /* FFT yields more accurate tonal estimation (not phase sensitive) */ - drft_forward(&b->fft_look[vb->W],pcm); - logfft[0]=scale_dB+todB(pcm); - local_ampmax[i]=logfft[0]; - for(j=1;j>1]=scale_dB+.5f*todB(&temp); - if(temp>local_ampmax[i])local_ampmax[i]=temp; - } - - if(local_ampmax[i]>0.f)local_ampmax[i]=0.f; - if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i]; - -#if 0 - if(vi->channels==2) - if(i==0) - _analysis_output("fftL",seq,logfft,n/2,1,0,0); - else - _analysis_output("fftR",seq,logfft,n/2,1,0,0); -#endif - - } - - { - float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise)); - float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone)); - - for(i=0;ichannels;i++){ - /* the encoder setup assumes that all the modes used by any - specific bitrate tweaking use the same floor */ - - int submap=info->chmuxlist[i]; - - /* the following makes things clearer to *me* anyway */ - float *mdct =gmdct[i]; - float *logfft =vb->pcm[i]; - - float *logmdct =logfft+n/2; - float *logmask =logfft; - - vb->mode=modenumber; - - floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts)); - memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS); - - for(j=0;jchannels==2){ - if(i==0) - _analysis_output("mdctL",seq,logmdct,n/2,1,0,0); - else - _analysis_output("mdctR",seq,logmdct,n/2,1,0,0); - }else{ - _analysis_output("mdct",seq,logmdct,n/2,1,0,0); - } -#endif - - /* first step; noise masking. Not only does 'noise masking' - give us curves from which we can decide how much resolution - to give noise parts of the spectrum, it also implicitly hands - us a tonality estimate (the larger the value in the - 'noise_depth' vector, the more tonal that area is) */ - - _vp_noisemask(psy_look, - logmdct, - noise); /* noise does not have by-frequency offset - bias applied yet */ -#if 0 - if(vi->channels==2){ - if(i==0) - _analysis_output("noiseL",seq,noise,n/2,1,0,0); - else - _analysis_output("noiseR",seq,noise,n/2,1,0,0); - } -#endif - - /* second step: 'all the other crap'; all the stuff that isn't - computed/fit for bitrate management goes in the second psy - vector. This includes tone masking, peak limiting and ATH */ - - _vp_tonemask(psy_look, - logfft, - tone, - global_ampmax, - local_ampmax[i]); - -#if 0 - if(vi->channels==2){ - if(i==0) - _analysis_output("toneL",seq,tone,n/2,1,0,0); - else - _analysis_output("toneR",seq,tone,n/2,1,0,0); - } -#endif - - /* third step; we offset the noise vectors, overlay tone - masking. We then do a floor1-specific line fit. If we're - performing bitrate management, the line fit is performed - multiple times for up/down tweakage on demand. */ - - _vp_offset_and_mix(psy_look, - noise, - tone, - 1, - logmask); - -#if 0 - if(vi->channels==2){ - if(i==0) - _analysis_output("mask1L",seq,logmask,n/2,1,0,0); - else - _analysis_output("mask1R",seq,logmask,n/2,1,0,0); - } -#endif - - /* this algorithm is hardwired to floor 1 for now; abort out if - we're *not* floor1. This won't happen unless someone has - broken the encode setup lib. Guard it anyway. */ - if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); - - floor_posts[i][PACKETBLOBS/2]= - floor1_fit(vb,b->flr[info->floorsubmap[submap]], - logmdct, - logmask); - - /* are we managing bitrate? If so, perform two more fits for - later rate tweaking (fits represent hi/lo) */ - if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ - /* higher rate by way of lower noise curve */ - - _vp_offset_and_mix(psy_look, - noise, - tone, - 2, - logmask); - -#if 0 - if(vi->channels==2){ - if(i==0) - _analysis_output("mask2L",seq,logmask,n/2,1,0,0); - else - _analysis_output("mask2R",seq,logmask,n/2,1,0,0); - } -#endif - - floor_posts[i][PACKETBLOBS-1]= - floor1_fit(vb,b->flr[info->floorsubmap[submap]], - logmdct, - logmask); - - /* lower rate by way of higher noise curve */ - _vp_offset_and_mix(psy_look, - noise, - tone, - 0, - logmask); - -#if 0 - if(vi->channels==2) - if(i==0) - _analysis_output("mask0L",seq,logmask,n/2,1,0,0); - else - _analysis_output("mask0R",seq,logmask,n/2,1,0,0); -#endif - - floor_posts[i][0]= - floor1_fit(vb,b->flr[info->floorsubmap[submap]], - logmdct, - logmask); - - /* we also interpolate a range of intermediate curves for - intermediate rates */ - for(k=1;kflr[info->floorsubmap[submap]], - floor_posts[i][0], - floor_posts[i][PACKETBLOBS/2], - k*65536/(PACKETBLOBS/2)); - for(k=PACKETBLOBS/2+1;kflr[info->floorsubmap[submap]], - floor_posts[i][PACKETBLOBS/2], - floor_posts[i][PACKETBLOBS-1], - (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2)); - } - } - } - vbi->ampmax=global_ampmax; - - /* - the next phases are performed once for vbr-only and PACKETBLOB - times for bitrate managed modes. - - 1) encode actual mode being used - 2) encode the floor for each channel, compute coded mask curve/res - 3) normalize and couple. - 4) encode residue - 5) save packet bytes to the packetblob vector - - */ - - /* iterate over the many masking curve fits we've created */ - - { - float **res_bundle=alloca(sizeof(*res_bundle)*vi->channels); - float **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); - int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); - int **sortindex=alloca(sizeof(*sortindex)*vi->channels); - float **mag_memo; - int **mag_sort; - - if(info->coupling_steps){ - mag_memo=_vp_quantize_couple_memo(vb, - &ci->psy_g_param, - psy_look, - info, - gmdct); - - mag_sort=_vp_quantize_couple_sort(vb, - psy_look, - info, - mag_memo); - } - - memset(sortindex,0,sizeof(*sortindex)*vi->channels); - if(psy_look->vi->normal_channel_p){ - for(i=0;ichannels;i++){ - float *mdct =gmdct[i]; - sortindex[i]=alloca(sizeof(**sortindex)*n/2); - _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]); - } - } - - for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); - k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); - k++){ - - /* start out our new packet blob with packet type and mode */ - /* Encode the packet type */ - oggpack_write(&vb->opb,0,1); - /* Encode the modenumber */ - /* Encode frame mode, pre,post windowsize, then dispatch */ - oggpack_write(&vb->opb,modenumber,b->modebits); - if(vb->W){ - oggpack_write(&vb->opb,vb->lW,1); - oggpack_write(&vb->opb,vb->nW,1); - } - - /* encode floor, compute masking curve, sep out residue */ - for(i=0;ichannels;i++){ - int submap=info->chmuxlist[i]; - float *mdct =gmdct[i]; - float *res =vb->pcm[i]; - int *ilogmask=ilogmaskch[i]= - _vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); - - nonzero[i]=floor1_encode(vb,b->flr[info->floorsubmap[submap]], - floor_posts[i][k], - ilogmask); -#if 0 - { - char buf[80]; - sprintf(buf,"maskI%c%d",i?'R':'L',k); - float work[n/2]; - for(j=0;jpsy_g_param.sliding_lowpass[vb->W][k]); - - _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]); - - -#if 0 - { - char buf[80]; - float work[n/2]; - for(j=0;jcoupling_steps){ - _vp_couple(k, - &ci->psy_g_param, - psy_look, - info, - vb->pcm, - mag_memo, - mag_sort, - ilogmaskch, - nonzero, - ci->psy_g_param.sliding_lowpass[vb->W][k]); - } - - /* classify and encode by submap */ - for(i=0;isubmaps;i++){ - int ch_in_bundle=0; - long **classifications; - int resnum=info->residuesubmap[i]; - - for(j=0;jchannels;j++){ - if(info->chmuxlist[j]==i){ - zerobundle[ch_in_bundle]=0; - if(nonzero[j])zerobundle[ch_in_bundle]=1; - res_bundle[ch_in_bundle]=vb->pcm[j]; - couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2; - } - } - - classifications=_residue_P[ci->residue_type[resnum]]-> - class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle); - - _residue_P[ci->residue_type[resnum]]-> - forward(vb,b->residue[resnum], - couple_bundle,NULL,zerobundle,ch_in_bundle,classifications); - } - - /* ok, done encoding. Mark this protopacket and prepare next. */ - oggpack_writealign(&vb->opb); - vbi->packetblob_markers[k]=oggpack_bytes(&vb->opb); - - } - - } - -#if 0 - seq++; - total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; -#endif - return(0); -} - -static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ - vorbis_dsp_state *vd=vb->vd; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - backend_lookup_state *b=vd->backend_state; - vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l; - - int i,j; - long n=vb->pcmend=ci->blocksizes[vb->W]; - - float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels); - int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); - - int *nonzero =alloca(sizeof(*nonzero)*vi->channels); - void **floormemo=alloca(sizeof(*floormemo)*vi->channels); - - /* recover the spectral envelope; store it in the PCM vector for now */ - for(i=0;ichannels;i++){ - int submap=info->chmuxlist[i]; - floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]-> - inverse1(vb,b->flr[info->floorsubmap[submap]]); - if(floormemo[i]) - nonzero[i]=1; - else - nonzero[i]=0; - memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); - } - - /* channel coupling can 'dirty' the nonzero listing */ - for(i=0;icoupling_steps;i++){ - if(nonzero[info->coupling_mag[i]] || - nonzero[info->coupling_ang[i]]){ - nonzero[info->coupling_mag[i]]=1; - nonzero[info->coupling_ang[i]]=1; - } - } - - /* recover the residue into our working vectors */ - for(i=0;isubmaps;i++){ - int ch_in_bundle=0; - for(j=0;jchannels;j++){ - if(info->chmuxlist[j]==i){ - if(nonzero[j]) - zerobundle[ch_in_bundle]=1; - else - zerobundle[ch_in_bundle]=0; - pcmbundle[ch_in_bundle++]=vb->pcm[j]; - } - } - - _residue_P[ci->residue_type[info->residuesubmap[i]]]-> - inverse(vb,b->residue[info->residuesubmap[i]], - pcmbundle,zerobundle,ch_in_bundle); - } - - /* channel coupling */ - for(i=info->coupling_steps-1;i>=0;i--){ - float *pcmM=vb->pcm[info->coupling_mag[i]]; - float *pcmA=vb->pcm[info->coupling_ang[i]]; - - for(j=0;j0) - if(ang>0){ - pcmM[j]=mag; - pcmA[j]=mag-ang; - }else{ - pcmA[j]=mag; - pcmM[j]=mag+ang; - } - else - if(ang>0){ - pcmM[j]=mag; - pcmA[j]=mag+ang; - }else{ - pcmA[j]=mag; - pcmM[j]=mag-ang; - } - } - } - - /* compute and apply spectral envelope */ - for(i=0;ichannels;i++){ - float *pcm=vb->pcm[i]; - int submap=info->chmuxlist[i]; - _floor_P[ci->floor_type[info->floorsubmap[submap]]]-> - inverse2(vb,b->flr[info->floorsubmap[submap]], - floormemo[i],pcm); - } - - /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ - /* only MDCT right now.... */ - for(i=0;ichannels;i++){ - float *pcm=vb->pcm[i]; - mdct_backward(b->transform[vb->W][0],pcm,pcm); - } - - /* window the data */ - for(i=0;ichannels;i++){ - float *pcm=vb->pcm[i]; - if(nonzero[i]) - _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); - else - for(j=0;j -#include -#include -#include -#include "vorbis/codec.h" -#include "mdct.h" -#include "os.h" -#include "misc.h" - -/* build lookups for trig functions; also pre-figure scaling and - some window function algebra. */ - -void mdct_init(mdct_lookup *lookup,int n){ - int *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4)); - DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4)); - - int i; - int n2=n>>1; - int log2n=lookup->log2n=rint(log((float)n)/log(2.f)); - lookup->n=n; - lookup->trig=T; - lookup->bitrev=bitrev; - -/* trig lookups... */ - - for(i=0;i>j;j++) - if((msb>>j)&i)acc|=1<scale=FLOAT_CONV(4.f/n); -} - -/* 8 point butterfly (in place, 4 register) */ -STIN void mdct_butterfly_8(DATA_TYPE *x){ - REG_TYPE r0 = x[6] + x[2]; - REG_TYPE r1 = x[6] - x[2]; - REG_TYPE r2 = x[4] + x[0]; - REG_TYPE r3 = x[4] - x[0]; - - x[6] = r0 + r2; - x[4] = r0 - r2; - - r0 = x[5] - x[1]; - r2 = x[7] - x[3]; - x[0] = r1 + r0; - x[2] = r1 - r0; - - r0 = x[5] + x[1]; - r1 = x[7] + x[3]; - x[3] = r2 + r3; - x[1] = r2 - r3; - x[7] = r1 + r0; - x[5] = r1 - r0; - -} - -/* 16 point butterfly (in place, 4 register) */ -STIN void mdct_butterfly_16(DATA_TYPE *x){ - REG_TYPE r0 = x[1] - x[9]; - REG_TYPE r1 = x[0] - x[8]; - - x[8] += x[0]; - x[9] += x[1]; - x[0] = MULT_NORM((r0 + r1) * cPI2_8); - x[1] = MULT_NORM((r0 - r1) * cPI2_8); - - r0 = x[3] - x[11]; - r1 = x[10] - x[2]; - x[10] += x[2]; - x[11] += x[3]; - x[2] = r0; - x[3] = r1; - - r0 = x[12] - x[4]; - r1 = x[13] - x[5]; - x[12] += x[4]; - x[13] += x[5]; - x[4] = MULT_NORM((r0 - r1) * cPI2_8); - x[5] = MULT_NORM((r0 + r1) * cPI2_8); - - r0 = x[14] - x[6]; - r1 = x[15] - x[7]; - x[14] += x[6]; - x[15] += x[7]; - x[6] = r0; - x[7] = r1; - - mdct_butterfly_8(x); - mdct_butterfly_8(x+8); -} - -/* 32 point butterfly (in place, 4 register) */ -STIN void mdct_butterfly_32(DATA_TYPE *x){ - REG_TYPE r0 = x[30] - x[14]; - REG_TYPE r1 = x[31] - x[15]; - - x[30] += x[14]; - x[31] += x[15]; - x[14] = r0; - x[15] = r1; - - r0 = x[28] - x[12]; - r1 = x[29] - x[13]; - x[28] += x[12]; - x[29] += x[13]; - x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 ); - x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 ); - - r0 = x[26] - x[10]; - r1 = x[27] - x[11]; - x[26] += x[10]; - x[27] += x[11]; - x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8); - x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8); - - r0 = x[24] - x[8]; - r1 = x[25] - x[9]; - x[24] += x[8]; - x[25] += x[9]; - x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 ); - x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); - - r0 = x[22] - x[6]; - r1 = x[7] - x[23]; - x[22] += x[6]; - x[23] += x[7]; - x[6] = r1; - x[7] = r0; - - r0 = x[4] - x[20]; - r1 = x[5] - x[21]; - x[20] += x[4]; - x[21] += x[5]; - x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 ); - x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 ); - - r0 = x[2] - x[18]; - r1 = x[3] - x[19]; - x[18] += x[2]; - x[19] += x[3]; - x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8); - x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8); - - r0 = x[0] - x[16]; - r1 = x[1] - x[17]; - x[16] += x[0]; - x[17] += x[1]; - x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); - x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 ); - - mdct_butterfly_16(x); - mdct_butterfly_16(x+16); - -} - -/* N point first stage butterfly (in place, 2 register) */ -STIN void mdct_butterfly_first(DATA_TYPE *T, - DATA_TYPE *x, - int points){ - - DATA_TYPE *x1 = x + points - 8; - DATA_TYPE *x2 = x + (points>>1) - 8; - REG_TYPE r0; - REG_TYPE r1; - - do{ - - r0 = x1[6] - x2[6]; - r1 = x1[7] - x2[7]; - x1[6] += x2[6]; - x1[7] += x2[7]; - x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); - x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); - - r0 = x1[4] - x2[4]; - r1 = x1[5] - x2[5]; - x1[4] += x2[4]; - x1[5] += x2[5]; - x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]); - x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]); - - r0 = x1[2] - x2[2]; - r1 = x1[3] - x2[3]; - x1[2] += x2[2]; - x1[3] += x2[3]; - x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]); - x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]); - - r0 = x1[0] - x2[0]; - r1 = x1[1] - x2[1]; - x1[0] += x2[0]; - x1[1] += x2[1]; - x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]); - x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]); - - x1-=8; - x2-=8; - T+=16; - - }while(x2>=x); -} - -/* N/stage point generic N stage butterfly (in place, 2 register) */ -STIN void mdct_butterfly_generic(DATA_TYPE *T, - DATA_TYPE *x, - int points, - int trigint){ - - DATA_TYPE *x1 = x + points - 8; - DATA_TYPE *x2 = x + (points>>1) - 8; - REG_TYPE r0; - REG_TYPE r1; - - do{ - - r0 = x1[6] - x2[6]; - r1 = x1[7] - x2[7]; - x1[6] += x2[6]; - x1[7] += x2[7]; - x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); - x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); - - T+=trigint; - - r0 = x1[4] - x2[4]; - r1 = x1[5] - x2[5]; - x1[4] += x2[4]; - x1[5] += x2[5]; - x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]); - x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]); - - T+=trigint; - - r0 = x1[2] - x2[2]; - r1 = x1[3] - x2[3]; - x1[2] += x2[2]; - x1[3] += x2[3]; - x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]); - x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]); - - T+=trigint; - - r0 = x1[0] - x2[0]; - r1 = x1[1] - x2[1]; - x1[0] += x2[0]; - x1[1] += x2[1]; - x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]); - x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]); - - T+=trigint; - x1-=8; - x2-=8; - - }while(x2>=x); -} - -STIN void mdct_butterflies(mdct_lookup *init, - DATA_TYPE *x, - int points){ - - DATA_TYPE *T=init->trig; - int stages=init->log2n-5; - int i,j; - - if(--stages>0){ - mdct_butterfly_first(T,x,points); - } - - for(i=1;--stages>0;i++){ - for(j=0;j<(1<>i)*j,points>>i,4<trig)_ogg_free(l->trig); - if(l->bitrev)_ogg_free(l->bitrev); - memset(l,0,sizeof(*l)); - } -} - -STIN void mdct_bitreverse(mdct_lookup *init, - DATA_TYPE *x){ - int n = init->n; - int *bit = init->bitrev; - DATA_TYPE *w0 = x; - DATA_TYPE *w1 = x = w0+(n>>1); - DATA_TYPE *T = init->trig+n; - - do{ - DATA_TYPE *x0 = x+bit[0]; - DATA_TYPE *x1 = x+bit[1]; - - REG_TYPE r0 = x0[1] - x1[1]; - REG_TYPE r1 = x0[0] + x1[0]; - REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]); - REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]); - - w1 -= 4; - - r0 = HALVE(x0[1] + x1[1]); - r1 = HALVE(x0[0] - x1[0]); - - w0[0] = r0 + r2; - w1[2] = r0 - r2; - w0[1] = r1 + r3; - w1[3] = r3 - r1; - - x0 = x+bit[2]; - x1 = x+bit[3]; - - r0 = x0[1] - x1[1]; - r1 = x0[0] + x1[0]; - r2 = MULT_NORM(r1 * T[2] + r0 * T[3]); - r3 = MULT_NORM(r1 * T[3] - r0 * T[2]); - - r0 = HALVE(x0[1] + x1[1]); - r1 = HALVE(x0[0] - x1[0]); - - w0[2] = r0 + r2; - w1[0] = r0 - r2; - w0[3] = r1 + r3; - w1[1] = r3 - r1; - - T += 4; - bit += 4; - w0 += 4; - - }while(w0n; - int n2=n>>1; - int n4=n>>2; - - /* rotate */ - - DATA_TYPE *iX = in+n2-7; - DATA_TYPE *oX = out+n2+n4; - DATA_TYPE *T = init->trig+n4; - - do{ - oX -= 4; - oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]); - oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]); - oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]); - oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]); - iX -= 8; - T += 4; - }while(iX>=in); - - iX = in+n2-8; - oX = out+n2+n4; - T = init->trig+n4; - - do{ - T -= 4; - oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]); - oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]); - oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]); - oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]); - iX -= 8; - oX += 4; - }while(iX>=in); - - mdct_butterflies(init,out+n2,n2); - mdct_bitreverse(init,out); - - /* roatate + window */ - - { - DATA_TYPE *oX1=out+n2+n4; - DATA_TYPE *oX2=out+n2+n4; - DATA_TYPE *iX =out; - T =init->trig+n2; - - do{ - oX1-=4; - - oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]); - oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]); - - oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]); - oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]); - - oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]); - oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]); - - oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]); - oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]); - - oX2+=4; - iX += 8; - T += 8; - }while(iXoX2); - } -} - -void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){ - int n=init->n; - int n2=n>>1; - int n4=n>>2; - int n8=n>>3; - DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */ - DATA_TYPE *w2=w+n2; - - /* rotate */ - - /* window + rotate + step 1 */ - - REG_TYPE r0; - REG_TYPE r1; - DATA_TYPE *x0=in+n2+n4; - DATA_TYPE *x1=x0+1; - DATA_TYPE *T=init->trig+n2; - - int i=0; - - for(i=0;itrig+n2; - x0=out+n2; - - for(i=0;iscale); - x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale); - w+=2; - T+=2; - } -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/mdct.h b/src/add-ons/media/plugins/vorbis/libvorbis/mdct.h deleted file mode 100644 index 2f4426fa2c..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/mdct.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: modified discrete cosine transform prototypes - last mod: $Id: mdct.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _OGG_mdct_H_ -#define _OGG_mdct_H_ - -#include "vorbis/codec.h" - - - - - -/*#define MDCT_INTEGERIZED <- be warned there could be some hurt left here*/ -#ifdef MDCT_INTEGERIZED - -#define DATA_TYPE int -#define REG_TYPE register int -#define TRIGBITS 14 -#define cPI3_8 6270 -#define cPI2_8 11585 -#define cPI1_8 15137 - -#define FLOAT_CONV(x) ((int)((x)*(1<>TRIGBITS) -#define HALVE(x) ((x)>>1) - -#else - -#define DATA_TYPE float -#define REG_TYPE float -#define cPI3_8 .38268343236508977175F -#define cPI2_8 .70710678118654752441F -#define cPI1_8 .92387953251128675613F - -#define FLOAT_CONV(x) (x) -#define MULT_NORM(x) (x) -#define HALVE(x) ((x)*.5f) - -#endif - - -typedef struct { - int n; - int log2n; - - DATA_TYPE *trig; - int *bitrev; - - DATA_TYPE scale; -} mdct_lookup; - -extern void mdct_init(mdct_lookup *lookup,int n); -extern void mdct_clear(mdct_lookup *l); -extern void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out); -extern void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out); - -#endif - - - - - - - - - - - - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/misc.h b/src/add-ons/media/plugins/vorbis/libvorbis/misc.h deleted file mode 100644 index cb1146713c..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/misc.h +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: miscellaneous prototypes - last mod: $Id: misc.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_RANDOM_H_ -#define _V_RANDOM_H_ -#include "vorbis/codec.h" - -extern int analysis_noisy; - -extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); -extern void _vorbis_block_ripcord(vorbis_block *vb); -extern void _analysis_output(char *base,int i,float *v,int n,int bark,int dB, - ogg_int64_t off); - -#ifdef DEBUG_MALLOC - -#define _VDBG_GRAPHFILE "malloc.m" -extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line); -extern void _VDBG_free(void *ptr,char *file,long line); - -#ifndef MISC_C -#undef _ogg_malloc -#undef _ogg_calloc -#undef _ogg_realloc -#undef _ogg_free - -#define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__) -#define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__) -#define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__) -#define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__) -#endif -#endif - -#endif - - - - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/os.h b/src/add-ons/media/plugins/vorbis/libvorbis/os.h deleted file mode 100644 index 5110a04774..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/os.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef _OS_H -#define _OS_H -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: #ifdef jail to whip a few platforms into the UNIX ideal. - last mod: $Id: os.h 28305 2008-10-23 21:46:26Z bonefish $ - - ********************************************************************/ - -#include -#include - -#include "misc.h" - -#ifndef _V_IFDEFJAIL_H_ -# define _V_IFDEFJAIL_H_ - -# ifdef __GNUC__ -# define STIN static __inline__ -# elif _WIN32 -# define STIN static __inline -#else -# define STIN static -#endif - -#ifndef M_PI -# define M_PI (3.1415926536f) -#endif - -#ifdef _WIN32 -# include -# define rint(x) (floor((x)+0.5f)) -# define NO_FLOAT_MATH_LIB -# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b)) -#endif - -#ifndef FAST_HYPOT -# define FAST_HYPOT hypot -#endif - -#endif - -#ifdef HAVE_ALLOCA_H -# include -#endif - -#ifdef USE_MEMORY_H -# include -#endif - -#ifndef min -# define min(x,y) ((x)>(y)?(y):(x)) -#endif - -#ifndef max -# define max(x,y) ((x)<(y)?(y):(x)) -#endif - -#if defined(__i386__) && defined(__GNUC__) && !(defined(__BEOS__) || defined(__HAIKU__)) -# define VORBIS_FPU_CONTROL -/* both GCC and MSVC are kinda stupid about rounding/casting to int. - Because of encapsulation constraints (GCC can't see inside the asm - block and so we end up doing stupid things like a store/load that - is collectively a noop), we do it this way */ - -/* we must set up the fpu before this works!! */ - -typedef ogg_int16_t vorbis_fpu_control; - -static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ - ogg_int16_t ret; - ogg_int16_t temp; - __asm__ __volatile__("fnstcw %0\n\t" - "movw %0,%%dx\n\t" - "orw $62463,%%dx\n\t" - "movw %%dx,%1\n\t" - "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx"); - *fpu=ret; -} - -static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ - __asm__ __volatile__("fldcw %0":: "m"(fpu)); -} - -/* assumes the FPU is in round mode! */ -static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise, - we get extra fst/fld to - truncate precision */ - int i; - __asm__("fistl %0": "=m"(i) : "t"(f)); - return(i); -} -#endif - - -#if defined(_WIN32) && !defined(__GNUC__) && !defined(__BORLANDC__) -# define VORBIS_FPU_CONTROL - -typedef ogg_int16_t vorbis_fpu_control; - -static __inline int vorbis_ftoi(double f){ - int i; - __asm{ - fld f - fistp i - } - return i; -} - -static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ -} - -static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ -} - -#endif - - -#ifndef VORBIS_FPU_CONTROL - -typedef int vorbis_fpu_control; - -static int vorbis_ftoi(double f){ - return (int)(f+.5); -} - -/* We don't have special code for this compiler/arch, so do it the slow way */ -# define vorbis_fpu_setround(vorbis_fpu_control) {} -# define vorbis_fpu_restore(vorbis_fpu_control) {} - -#endif - -#endif /* _OS_H */ diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/psy.c b/src/add-ons/media/plugins/vorbis/libvorbis/psy.c deleted file mode 100644 index 8541ce9f32..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/psy.c +++ /dev/null @@ -1,1131 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: psychoacoustics not including preecho - last mod: $Id: psy.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" - -#include "masking.h" -#include "psy.h" -#include "os.h" -#include "lpc.h" -#include "smallft.h" -#include "scales.h" -#include "misc.h" - -#define NEGINF -9999.f -static double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10}; - -vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){ - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *gi=&ci->psy_g_param; - vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look)); - - look->channels=vi->channels; - - look->ampmax=-9999.; - look->gi=gi; - return(look); -} - -void _vp_global_free(vorbis_look_psy_global *look){ - if(look){ - memset(look,0,sizeof(*look)); - _ogg_free(look); - } -} - -void _vi_gpsy_free(vorbis_info_psy_global *i){ - if(i){ - memset(i,0,sizeof(*i)); - _ogg_free(i); - } -} - -void _vi_psy_free(vorbis_info_psy *i){ - if(i){ - memset(i,0,sizeof(*i)); - _ogg_free(i); - } -} - -static void min_curve(float *c, - float *c2){ - int i; - for(i=0;ic[i])c[i]=c2[i]; -} - -static void attenuate_curve(float *c,float att){ - int i; - for(i=0;iATH[j+k+ath_offset])min=ATH[j+k+ath_offset]; - }else{ - if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1]; - } - ath[j]=min; - } - - /* copy curves into working space, replicate the 50dB curve to 30 - and 40, replicate the 100dB curve to 110 */ - for(j=0;j<6;j++) - memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j])); - memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); - memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); - - /* apply centered curve boost/decay */ - for(j=0;j0)adj=0.; - if(adj>0. && center_boost<0)adj=0.; - workc[i][j][k]+=adj; - } - } - - /* normalize curves so the driving amplitude is 0dB */ - /* make temp curves with the ATH overlayed */ - for(j=0;j an eighth of an octave and that the eighth - octave values may also be composited. */ - - /* which octave curves will we be compositing? */ - bin=floor(fromOC(i*.5)/binHz); - lo_curve= ceil(toOC(bin*binHz+1)*2); - hi_curve= floor(toOC((bin+1)*binHz)*2); - if(lo_curve>i)lo_curve=i; - if(lo_curve<0)lo_curve=0; - if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1; - - for(m=0;mn)lo_bin=n; - if(lo_binn)hi_bin=n; - - for(;lworkc[k][m][j]) - brute_buffer[l]=workc[k][m][j]; - } - - for(;lworkc[k][m][EHMER_MAX-1]) - brute_buffer[l]=workc[k][m][EHMER_MAX-1]; - - } - - /* be equally paranoid about being valid up to next half ocatve */ - if(i+1n)lo_bin=n; - if(lo_binn)hi_bin=n; - - for(;lworkc[k][m][j]) - brute_buffer[l]=workc[k][m][j]; - } - - for(;lworkc[k][m][EHMER_MAX-1]) - brute_buffer[l]=workc[k][m][EHMER_MAX-1]; - - } - - - for(j=0;j=n){ - ret[i][m][j+2]=-999.; - }else{ - ret[i][m][j+2]=brute_buffer[bin]; - } - } - } - - /* add fenceposts */ - for(j=0;j-200.f)break; - ret[i][m][0]=j; - - for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--) - if(ret[i][m][j+2]>-200.f) - break; - ret[i][m][1]=j; - - } - } - - return(ret); -} - -void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, - vorbis_info_psy_global *gi,int n,long rate){ - long i,j,lo=-99,hi=0; - long maxoc; - memset(p,0,sizeof(*p)); - - p->eighth_octave_lines=gi->eighth_octave_lines; - p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1; - - p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines; - maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f; - p->total_octave_lines=maxoc-p->firstoc+1; - p->ath=_ogg_malloc(n*sizeof(*p->ath)); - - p->octave=_ogg_malloc(n*sizeof(*p->octave)); - p->bark=_ogg_malloc(n*sizeof(*p->bark)); - p->vi=vi; - p->n=n; - p->rate=rate; - - /* set up the lookups for a given blocksize and sample rate */ - - for(i=0,j=0;iath[j]=base+100.; - base+=delta; - } - } - } - - for(i=0;inoisewindowlominnoisewindowlo);lo++); - - for(;hinoisewindowhimin || - toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++); - - p->bark[i]=(lo<<16)+hi; - - } - - for(i=0;ioctave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f; - - p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n, - vi->tone_centerboost,vi->tone_decay); - - /* set up rolling noise median */ - p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset)); - for(i=0;inoiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset)); - - for(i=0;i=P_BANDS-1)halfoc=P_BANDS-1; - inthalfoc=(int)halfoc; - del=halfoc-inthalfoc; - - for(j=0;jnoiseoffset[j][i]= - p->vi->noiseoff[j][inthalfoc]*(1.-del) + - p->vi->noiseoff[j][inthalfoc+1]*del; - - } -#if 0 - { - static int ls=0; - _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0); - _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0); - _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0); - } -#endif -} - -void _vp_psy_clear(vorbis_look_psy *p){ - int i,j; - if(p){ - if(p->ath)_ogg_free(p->ath); - if(p->octave)_ogg_free(p->octave); - if(p->bark)_ogg_free(p->bark); - if(p->tonecurves){ - for(i=0;itonecurves[i][j]); - } - _ogg_free(p->tonecurves[i]); - } - _ogg_free(p->tonecurves); - } - if(p->noiseoffset){ - for(i=0;inoiseoffset[i]); - } - _ogg_free(p->noiseoffset); - } - memset(p,0,sizeof(*p)); - } -} - -/* octave/(8*eighth_octave_lines) x scale and dB y scale */ -static void seed_curve(float *seed, - const float **curves, - float amp, - int oc, int n, - int linesper,float dBoffset){ - int i,post1; - int seedptr; - const float *posts,*curve; - - int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f); - choice=max(choice,0); - choice=min(choice,P_LEVELS-1); - posts=curves[choice]; - curve=posts+2; - post1=(int)posts[1]; - seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1); - - for(i=posts[0];i0){ - float lin=amp+curve[i]; - if(seed[seedptr]=n)break; - } -} - -static void seed_loop(vorbis_look_psy *p, - const float ***curves, - const float *f, - const float *flr, - float *seed, - float specmax){ - vorbis_info_psy *vi=p->vi; - long n=p->n,i; - float dBoffset=vi->max_curve_dB-specmax; - - /* prime the working vector with peak values */ - - for(i=0;ioctave[i]; - while(i+1octave[i+1]==oc){ - i++; - if(f[i]>max)max=f[i]; - } - - if(max+6.f>flr[i]){ - oc=oc>>p->shiftoc; - - if(oc>=P_BANDS)oc=P_BANDS-1; - if(oc<0)oc=0; - - seed_curve(seed, - curves[oc], - max, - p->octave[i]-p->firstoc, - p->total_octave_lines, - p->eighth_octave_lines, - dBoffset); - } - } -} - -static void seed_chase(float *seeds, int linesper, long n){ - long *posstack=alloca(n*sizeof(*posstack)); - float *ampstack=alloca(n*sizeof(*ampstack)); - long stack=0; - long pos=0; - long i; - - for(i=0;i1 && ampstack[stack-1]<=ampstack[stack-2] && - iampstack[i]){ - endpos=posstack[i+1]; - }else{ - endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is - discarded in short frames */ - } - if(endpos>n)endpos=n; - for(;pos -static void max_seeds(vorbis_look_psy *p, - float *seed, - float *flr){ - long n=p->total_octave_lines; - int linesper=p->eighth_octave_lines; - long linpos=0; - long pos; - - seed_chase(seed,linesper,n); /* for masking */ - - pos=p->octave[0]-p->firstoc-(linesper>>1); - - while(linpos+1n){ - float minV=seed[pos]; - long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc; - if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit; - while(pos+1<=end){ - pos++; - if((seed[pos]>NEGINF && seed[pos]firstoc; - for(;linposn && p->octave[linpos]<=end;linpos++) - if(flr[linpos]total_octave_lines-1]; - for(;linposn;linpos++) - if(flr[linpos]> 16; - if( lo>=0 ) break; - hi = b[i] & 0xffff; - - tN = N[hi] + N[-lo]; - tX = X[hi] - X[-lo]; - tXX = XX[hi] + XX[-lo]; - tY = Y[hi] + Y[-lo]; - tXY = XY[hi] - XY[-lo]; - - A = tY * tXX - tX * tXY; - B = tN * tXY - tX * tY; - D = tN * tXX - tX * tX; - R = (A + fi * B) / D; - if (R < 0.f) - R = 0.f; - - noise[i] = R - offset; - } - - for ( ; hi < n; i++, fi += 1.f) { - - lo = b[i] >> 16; - hi = b[i] & 0xffff; - - tN = N[hi] - N[lo]; - tX = X[hi] - X[lo]; - tXX = XX[hi] - XX[lo]; - tY = Y[hi] - Y[lo]; - tXY = XY[hi] - XY[lo]; - - A = tY * tXX - tX * tXY; - B = tN * tXY - tX * tY; - D = tN * tXX - tX * tX; - R = (A + fi * B) / D; - if (R < 0.f) R = 0.f; - - noise[i] = R - offset; - } - for ( ; i < n; i++, fi += 1.f) { - - R = (A + fi * B) / D; - if (R < 0.f) R = 0.f; - - noise[i] = R - offset; - } - - if (fixed <= 0) return; - - for (i = 0, fi = 0.f; i < (fixed + 1) / 2; i++, fi += 1.f) { - hi = i + fixed / 2; - lo = hi - fixed; - - tN = N[hi] + N[-lo]; - tX = X[hi] - X[-lo]; - tXX = XX[hi] + XX[-lo]; - tY = Y[hi] + Y[-lo]; - tXY = XY[hi] - XY[-lo]; - - - A = tY * tXX - tX * tXY; - B = tN * tXY - tX * tY; - D = tN * tXX - tX * tX; - R = (A + fi * B) / D; - - if (R > 0.f && R - offset < noise[i]) noise[i] = R - offset; - } - for ( ; hi < n; i++, fi += 1.f) { - - hi = i + fixed / 2; - lo = hi - fixed; - - tN = N[hi] - N[lo]; - tX = X[hi] - X[lo]; - tXX = XX[hi] - XX[lo]; - tY = Y[hi] - Y[lo]; - tXY = XY[hi] - XY[lo]; - - A = tY * tXX - tX * tXY; - B = tN * tXY - tX * tY; - D = tN * tXX - tX * tX; - R = (A + fi * B) / D; - - if (R > 0.f && R - offset < noise[i]) noise[i] = R - offset; - } - for ( ; i < n; i++, fi += 1.f) { - R = (A + fi * B) / D; - if (R > 0.f && R - offset < noise[i]) noise[i] = R - offset; - } -} - -static float FLOOR1_fromdB_INV_LOOKUP[256]={ - 0.F, 8.81683e+06F, 8.27882e+06F, 7.77365e+06F, - 7.29930e+06F, 6.85389e+06F, 6.43567e+06F, 6.04296e+06F, - 5.67422e+06F, 5.32798e+06F, 5.00286e+06F, 4.69759e+06F, - 4.41094e+06F, 4.14178e+06F, 3.88905e+06F, 3.65174e+06F, - 3.42891e+06F, 3.21968e+06F, 3.02321e+06F, 2.83873e+06F, - 2.66551e+06F, 2.50286e+06F, 2.35014e+06F, 2.20673e+06F, - 2.07208e+06F, 1.94564e+06F, 1.82692e+06F, 1.71544e+06F, - 1.61076e+06F, 1.51247e+06F, 1.42018e+06F, 1.33352e+06F, - 1.25215e+06F, 1.17574e+06F, 1.10400e+06F, 1.03663e+06F, - 973377.F, 913981.F, 858210.F, 805842.F, - 756669.F, 710497.F, 667142.F, 626433.F, - 588208.F, 552316.F, 518613.F, 486967.F, - 457252.F, 429351.F, 403152.F, 378551.F, - 355452.F, 333762.F, 313396.F, 294273.F, - 276316.F, 259455.F, 243623.F, 228757.F, - 214798.F, 201691.F, 189384.F, 177828.F, - 166977.F, 156788.F, 147221.F, 138237.F, - 129802.F, 121881.F, 114444.F, 107461.F, - 100903.F, 94746.3F, 88964.9F, 83536.2F, - 78438.8F, 73652.5F, 69158.2F, 64938.1F, - 60975.6F, 57254.9F, 53761.2F, 50480.6F, - 47400.3F, 44507.9F, 41792.0F, 39241.9F, - 36847.3F, 34598.9F, 32487.7F, 30505.3F, - 28643.8F, 26896.0F, 25254.8F, 23713.7F, - 22266.7F, 20908.0F, 19632.2F, 18434.2F, - 17309.4F, 16253.1F, 15261.4F, 14330.1F, - 13455.7F, 12634.6F, 11863.7F, 11139.7F, - 10460.0F, 9821.72F, 9222.39F, 8659.64F, - 8131.23F, 7635.06F, 7169.17F, 6731.70F, - 6320.93F, 5935.23F, 5573.06F, 5232.99F, - 4913.67F, 4613.84F, 4332.30F, 4067.94F, - 3819.72F, 3586.64F, 3367.78F, 3162.28F, - 2969.31F, 2788.13F, 2617.99F, 2458.24F, - 2308.24F, 2167.39F, 2035.14F, 1910.95F, - 1794.35F, 1684.85F, 1582.04F, 1485.51F, - 1394.86F, 1309.75F, 1229.83F, 1154.78F, - 1084.32F, 1018.15F, 956.024F, 897.687F, - 842.910F, 791.475F, 743.179F, 697.830F, - 655.249F, 615.265F, 577.722F, 542.469F, - 509.367F, 478.286F, 449.101F, 421.696F, - 395.964F, 371.803F, 349.115F, 327.812F, - 307.809F, 289.026F, 271.390F, 254.830F, - 239.280F, 224.679F, 210.969F, 198.096F, - 186.008F, 174.658F, 164.000F, 153.993F, - 144.596F, 135.773F, 127.488F, 119.708F, - 112.404F, 105.545F, 99.1046F, 93.0572F, - 87.3788F, 82.0469F, 77.0404F, 72.3394F, - 67.9252F, 63.7804F, 59.8885F, 56.2341F, - 52.8027F, 49.5807F, 46.5553F, 43.7144F, - 41.0470F, 38.5423F, 36.1904F, 33.9821F, - 31.9085F, 29.9614F, 28.1332F, 26.4165F, - 24.8045F, 23.2910F, 21.8697F, 20.5352F, - 19.2822F, 18.1056F, 17.0008F, 15.9634F, - 14.9893F, 14.0746F, 13.2158F, 12.4094F, - 11.6522F, 10.9411F, 10.2735F, 9.64662F, - 9.05798F, 8.50526F, 7.98626F, 7.49894F, - 7.04135F, 6.61169F, 6.20824F, 5.82941F, - 5.47370F, 5.13970F, 4.82607F, 4.53158F, - 4.25507F, 3.99542F, 3.75162F, 3.52269F, - 3.30774F, 3.10590F, 2.91638F, 2.73842F, - 2.57132F, 2.41442F, 2.26709F, 2.12875F, - 1.99885F, 1.87688F, 1.76236F, 1.65482F, - 1.55384F, 1.45902F, 1.36999F, 1.28640F, - 1.20790F, 1.13419F, 1.06499F, 1.F -}; - -void _vp_remove_floor(vorbis_look_psy *p, - float *mdct, - int *codedflr, - float *residue, - int sliding_lowpass){ - - int i,n=p->n; - - if(sliding_lowpass>n)sliding_lowpass=n; - - for(i=0;in; - float *work=alloca(n*sizeof(*work)); - - bark_noise_hybridmp(n,p->bark,logmdct,logmask, - 140.,-1); - - for(i=0;ibark,work,logmask,0., - p->vi->noisewindowfixed); - - for(i=0;i=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1; - logmask[i]= work[i]+p->vi->noisecompand[dB]; - } - -} - -void _vp_tonemask(vorbis_look_psy *p, - float *logfft, - float *logmask, - float global_specmax, - float local_specmax){ - - int i,n=p->n; - - float *seed=alloca(sizeof(*seed)*p->total_octave_lines); - float att=local_specmax+p->vi->ath_adjatt; - for(i=0;itotal_octave_lines;i++)seed[i]=NEGINF; - - /* set the ATH (floating below localmax, not global max by a - specified att) */ - if(attvi->ath_maxatt)att=p->vi->ath_maxatt; - - for(i=0;iath[i]+att; - - /* tone masking */ - seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax); - max_seeds(p,seed,logmask); - -} - -void _vp_offset_and_mix(vorbis_look_psy *p, - float *noise, - float *tone, - int offset_select, - float *logmask){ - int i,n=p->n; - float toneatt=p->vi->tone_masteratt[offset_select]; - - for(i=0;inoiseoffset[offset_select][i]; - if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp; - logmask[i]=max(val,tone[i]+toneatt); - } -} - -float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){ - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *gi=&ci->psy_g_param; - - int n=ci->blocksizes[vd->W]/2; - float secs=(float)n/vi->rate; - - amp+=secs*gi->ampmax_att_per_sec; - if(amp<-9999)amp=-9999; - return(amp); -} - -static void couple_lossless(float A, float B, - float *qA, float *qB){ - int test1=fabs(*qA)>fabs(*qB); - test1-= fabs(*qA)fabs(B))<<1)-1; - if(test1==1){ - *qB=(*qA>0.f?*qA-*qB:*qB-*qA); - }else{ - float temp=*qB; - *qB=(*qB>0.f?*qA-*qB:*qB-*qA); - *qA=temp; - } - - if(*qB>fabs(*qA)*1.9999f){ - *qB= -fabs(*qA)*2.f; - *qA= -*qA; - } -} - -static float hypot_lookup[32]={ - -0.009935, -0.011245, -0.012726, -0.014397, - -0.016282, -0.018407, -0.020800, -0.023494, - -0.026522, -0.029923, -0.033737, -0.038010, - -0.042787, -0.048121, -0.054064, -0.060671, - -0.068000, -0.076109, -0.085054, -0.094892, - -0.105675, -0.117451, -0.130260, -0.144134, - -0.159093, -0.175146, -0.192286, -0.210490, - -0.229718, -0.249913, -0.271001, -0.292893}; - -static void precomputed_couple_point(float premag, - int floorA,int floorB, - float *mag, float *ang){ - - int test=(floorA>floorB)-1; - int offset=31-abs(floorA-floorB); - float floormag=hypot_lookup[((offset<0)-1)&offset]+1.f; - - floormag*=FLOOR1_fromdB_INV_LOOKUP[(floorB&test)|(floorA&(~test))]; - - *mag=premag*floormag; - *ang=0.f; -} - -/* just like below, this is currently set up to only do - single-step-depth coupling. Otherwise, we'd have to do more - copying (which will be inevitable later) */ - -/* doing the real circular magnitude calculation is audibly superior - to (A+B)/sqrt(2) */ -static float dipole_hypot(float a, float b){ - if(a>0.){ - if(b>0.)return sqrt(a*a+b*b); - if(a>-b)return sqrt(a*a-b*b); - return -sqrt(b*b-a*a); - } - if(b<0.)return -sqrt(a*a+b*b); - if(-a>b)return -sqrt(a*a-b*b); - return sqrt(b*b-a*a); -} -static float round_hypot(float a, float b){ - if(a>0.){ - if(b>0.)return sqrt(a*a+b*b); - if(a>-b)return sqrt(a*a+b*b); - return -sqrt(b*b+a*a); - } - if(b<0.)return -sqrt(a*a+b*b); - if(-a>b)return -sqrt(a*a+b*b); - return sqrt(b*b+a*a); -} - -/* revert to round hypot for now */ -float **_vp_quantize_couple_memo(vorbis_block *vb, - vorbis_info_psy_global *g, - vorbis_look_psy *p, - vorbis_info_mapping0 *vi, - float **mdct){ - - int i,j,n=p->n; - float **ret=_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret)); - int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2]; - - for(i=0;icoupling_steps;i++){ - float *mdctM=mdct[vi->coupling_mag[i]]; - float *mdctA=mdct[vi->coupling_ang[i]]; - ret[i]=_vorbis_block_alloc(vb,n*sizeof(**ret)); - for(j=0;jfabs(**(float **)b))return -1; - return 1; -} - -int **_vp_quantize_couple_sort(vorbis_block *vb, - vorbis_look_psy *p, - vorbis_info_mapping0 *vi, - float **mags){ - - - if(p->vi->normal_point_p){ - int i,j,k,n=p->n; - int **ret=_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret)); - int partition=p->vi->normal_partition; - float **work=alloca(sizeof(*work)*partition); - - for(i=0;icoupling_steps;i++){ - ret[i]=_vorbis_block_alloc(vb,n*sizeof(**ret)); - - for(j=0;jn; - vorbis_info_psy *vi=p->vi; - int partition=vi->normal_partition; - float **work=alloca(sizeof(*work)*partition); - int start=vi->normal_start; - - for(j=start;jn)partition=n-j; - for(i=0;in; - vorbis_info_psy *vi=p->vi; - int partition=vi->normal_partition; - int start=vi->normal_start; - - if(start>n)start=n; - - if(vi->normal_channel_p){ - for(;j=.25f){ - out[k]=rint(in[k]); - acc-=in[k]*in[k]; - flag=1; - }else{ - if(accnormal_thresh)break; - out[k]=unitnorm(in[k]); - acc-=1.; - } - } - - for(;in; - - /* perform any requested channel coupling */ - /* point stereo can only be used in a first stage (in this encoder) - because of the dependency on floor lookups */ - for(i=0;icoupling_steps;i++){ - - /* once we're doing multistage coupling in which a channel goes - through more than one coupling step, the floor vector - magnitudes will also have to be recalculated an propogated - along with PCM. Right now, we're not (that will wait until 5.1 - most likely), so the code isn't here yet. The memory management - here is all assuming single depth couplings anyway. */ - - /* make sure coupling a zero and a nonzero channel results in two - nonzero channels. */ - if(nonzero[vi->coupling_mag[i]] || - nonzero[vi->coupling_ang[i]]){ - - - float *rM=res[vi->coupling_mag[i]]; - float *rA=res[vi->coupling_ang[i]]; - float *qM=rM+n; - float *qA=rA+n; - int *floorM=ifloor[vi->coupling_mag[i]]; - int *floorA=ifloor[vi->coupling_ang[i]]; - float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]]; - float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]]; - int partition=(p->vi->normal_point_p?p->vi->normal_partition:p->n); - int limit=g->coupling_pointlimit[p->vi->blockflag][blobno]; - int pointlimit=limit; - - nonzero[vi->coupling_mag[i]]=1; - nonzero[vi->coupling_ang[i]]=1; - - for(j=0;jn;j+=partition){ - float acc=0.f; - - for(k=0;k=limit && fabs(rM[l])vi->normal_point_p){ - for(k=0;k=p->vi->normal_thresh;k++){ - int l=mag_sort[i][j+k]; - if(l=pointlimit && rint(qM[l])==0.f){ - qM[l]=unitnorm(qM[l]); - acc-=1.f; - } - } - } - } - } - } -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/psy.h b/src/add-ons/media/plugins/vorbis/libvorbis/psy.h deleted file mode 100644 index 777278d732..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/psy.h +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: random psychoacoustics (not including preecho) - last mod: $Id: psy.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_PSY_H_ -#define _V_PSY_H_ -#include "smallft.h" - -#include "backends.h" -#include "envelope.h" - -#ifndef EHMER_MAX -#define EHMER_MAX 56 -#endif - -/* psychoacoustic setup ********************************************/ -#define P_BANDS 17 /* 62Hz to 16kHz */ -#define P_LEVELS 8 /* 30dB to 100dB */ -#define P_LEVEL_0 30. /* 30 dB */ -#define P_NOISECURVES 3 - -#define NOISE_COMPAND_LEVELS 40 -typedef struct vorbis_info_psy{ - int blockflag; - - float ath_adjatt; - float ath_maxatt; - - float tone_masteratt[P_NOISECURVES]; - float tone_centerboost; - float tone_decay; - float tone_abs_limit; - float toneatt[P_BANDS]; - - int noisemaskp; - float noisemaxsupp; - float noisewindowlo; - float noisewindowhi; - int noisewindowlomin; - int noisewindowhimin; - int noisewindowfixed; - float noiseoff[P_NOISECURVES][P_BANDS]; - float noisecompand[NOISE_COMPAND_LEVELS]; - - float max_curve_dB; - - int normal_channel_p; - int normal_point_p; - int normal_start; - int normal_partition; - double normal_thresh; -} vorbis_info_psy; - -typedef struct{ - int eighth_octave_lines; - - /* for block long/short tuning; encode only */ - float preecho_thresh[VE_BANDS]; - float postecho_thresh[VE_BANDS]; - float stretch_penalty; - float preecho_minenergy; - - float ampmax_att_per_sec; - - /* channel coupling config */ - int coupling_pkHz[PACKETBLOBS]; - int coupling_pointlimit[2][PACKETBLOBS]; - int coupling_prepointamp[PACKETBLOBS]; - int coupling_postpointamp[PACKETBLOBS]; - int sliding_lowpass[2][PACKETBLOBS]; - -} vorbis_info_psy_global; - -typedef struct { - float ampmax; - int channels; - - vorbis_info_psy_global *gi; - int coupling_pointlimit[2][P_NOISECURVES]; -} vorbis_look_psy_global; - - -typedef struct { - int n; - struct vorbis_info_psy *vi; - - float ***tonecurves; - float **noiseoffset; - - float *ath; - long *octave; /* in n.ocshift format */ - long *bark; - - long firstoc; - long shiftoc; - int eighth_octave_lines; /* power of two, please */ - int total_octave_lines; - long rate; /* cache it */ -} vorbis_look_psy; - -extern void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, - vorbis_info_psy_global *gi,int n,long rate); -extern void _vp_psy_clear(vorbis_look_psy *p); -extern void *_vi_psy_dup(void *source); - -extern void _vi_psy_free(vorbis_info_psy *i); -extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i); - -extern void _vp_remove_floor(vorbis_look_psy *p, - float *mdct, - int *icodedflr, - float *residue, - int sliding_lowpass); - -extern void _vp_noisemask(vorbis_look_psy *p, - float *logmdct, - float *logmask); - -extern void _vp_tonemask(vorbis_look_psy *p, - float *logfft, - float *logmask, - float global_specmax, - float local_specmax); - -extern void _vp_offset_and_mix(vorbis_look_psy *p, - float *noise, - float *tone, - int offset_select, - float *logmask); - -extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd); - -extern float **_vp_quantize_couple_memo(vorbis_block *vb, - vorbis_info_psy_global *g, - vorbis_look_psy *p, - vorbis_info_mapping0 *vi, - float **mdct); - -extern void _vp_couple(int blobno, - vorbis_info_psy_global *g, - vorbis_look_psy *p, - vorbis_info_mapping0 *vi, - float **res, - float **mag_memo, - int **mag_sort, - int **ifloor, - int *nonzero, - int sliding_lowpass); - -extern void _vp_noise_normalize(vorbis_look_psy *p, - float *in,float *out,int *sortedindex); - -extern void _vp_noise_normalize_sort(vorbis_look_psy *p, - float *magnitudes,int *sortedindex); - -extern int **_vp_quantize_couple_sort(vorbis_block *vb, - vorbis_look_psy *p, - vorbis_info_mapping0 *vi, - float **mags); - -#endif - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/psytune.c b/src/add-ons/media/plugins/vorbis/libvorbis/psytune.c deleted file mode 100644 index a61929364e..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/psytune.c +++ /dev/null @@ -1,521 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: simple utility that runs audio through the psychoacoustics - without encoding - last mod: $Id: psytune.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include - -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "os.h" -#include "misc.h" -#include "psy.h" -#include "mdct.h" -#include "smallft.h" -#include "window.h" -#include "scales.h" -#include "lpc.h" -#include "lsp.h" -#include "masking.h" -#include "registry.h" - -static vorbis_info_psy_global _psy_set0G={ - 0, /* decaydBpms */ - 8, /* lines per eighth octave */ - - /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ - 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, - -6.f, - - 0, - - 0., - 0., -}; - -static vp_part _vp_part0[]={ - { 1,9e10f, 9e10f, 1.f,9999.f}, - { 9999, .75f, 9e10f, .5f,9999.f}, -/*{ 9999, 1.5f, 9e10f, .5f,9999.f},*/ - { 18,9e10f, 9e10f, .5f, 30.f}, - { 9999,9e10f, 9e10f, .5f, 30.f} -}; - -static vp_couple _vp_couple0[]={ - { 1, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}}, - { 18, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}}, - { 9999, {9e10f,9e10f,0}, { 0.f, 9e10f,0}, { 0.f,22.f,1}, {0.f,0.f,0}} -}; - -static vorbis_info_psy _psy_set0={ - ATH_Bark_dB_lineaggressive, - - -100.f, - -140.f, - 6.f, /* floor master att */ - - /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */ - /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */ - /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */ - 1, /* tonemaskp */ - 0.f, /* tone master att */ - /* 0 10 20 30 40 50 60 70 80 90 100 */ - { - {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/ - {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/ - {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/ - - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/ - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/ - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/ - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/ - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/ - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/ - {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/ - {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/ - {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/ - {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/ - - {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/ - - {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/ - {-30.f,-30.f,-33.f,-35.f,-40.f,-45.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*11500*/ - {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*16000*/ - - }, - - 1,/* peakattp */ - {{-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*63*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*88*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*125*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*175*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*250*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*350*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*500*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*700*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1000*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1400*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2000*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2800*/ - {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*4000*/ - {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*5600*/ - {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*8000*/ - {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*11500*/ - {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*16000*/ - }, - - 1,/*noisemaskp */ - -10.f, /* suppress any noise curve over maxspec+n */ - .5f, /* low window */ - .5f, /* high window */ - 10, - 10, - 25, - {.000f, 0.f, /*63*/ - .000f, 0.f, /*88*/ - .000f, 0.f, /*125*/ - .000f, 0.f, /*175*/ - .000f, 0.f, /*250*/ - .000f, 0.f, /*350*/ - .000f, 0.f, /*500*/ - .000f, 0.f, /*700*/ - .000f, 0.f, /*1000*/ - .300f, 0.f, /*1400*/ - .300f, 0.f, /*2000*/ - .300f, 0.f, /*2800*/ - .500f, 0.f, /*4000*/ - .700f, 0.f, /*5600*/ - .850f, 0.f, /*8000*/ - .900f, 0.f, /*11500*/ - .900f, 1.f, /*16000*/ - }, - - 95.f, /* even decade + 5 is important; saves an rint() later in a - tight loop) */ - -44., - - 32, - _vp_part0,_vp_couple0 -}; - -static vorbis_info_floor1 _floor_set0={1, - {0}, - - {32}, - {0}, - {0}, - {{-1}}, - - 2, - {0,1024, - - 88,31,243, - - 14,54,143,460, - - 6,3,10, 22,18,26, 41,36,47, - 69,61,78, 112,99,126, 185,162,211, - 329,282,387, 672,553,825 - }, - - 60,30,400, - 20,8,1,18., - 20,600, - 960}; - - -static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}}; -static codec_setup_info codec_setup0={ {0,0}, - 1,1,1,1,1,0,1, - {NULL}, - {0},{&mapping_info}, - {0},{NULL}, - {1},{&_floor_set0}, - {2},{NULL}, - {NULL}, - {&_psy_set0}, - &_psy_set0G}; - -static int noisy=0; -void analysis(char *base,int i,float *v,int n,int bark,int dB){ - if(noisy){ - int j; - FILE *of; - char buffer[80]; - sprintf(buffer,"%s_%d.m",base,i); - of=fopen(buffer,"w"); - - for(j=0;jlook(NULL,NULL,&_floor_set0); - - /* we cheat on the WAV header; we just bypass 44 bytes and never - verify that it matches 16bit/stereo/44.1kHz. */ - - fread(buffer,1,44,stdin); - fwrite(buffer,1,44,stdout); - memset(buffer,0,framesize*2); - - analysis("window",0,window,framesize,0,0); - - fprintf(stderr,"Processing for frame size %d...\n",framesize); - - while(!eos){ - long bytes=fread(buffer2,1,framesize*2,stdin); - if(bytes>1]=todB(&temp); - if(temp>local_ampmax[i])local_ampmax[i]=temp; - } - if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i]; - - mdct_forward(&m_look,pcm[i],mdct); - for(j=0;jforward(&vb,floor_look, - mdct, - logmdct, - mask, - logmax, - - flr[i]); - } - - _vp_remove_floor(&p_look, - pg_look, - logmdct, - mdct, - flr[i], - pcm[i], - local_ampmax[i]); - - for(j=0;j1500) - fprintf(stderr,"%ld ",frameno+i); - - analysis("res",frameno+i,pcm[i],framesize/2,1,0); - analysis("codedflr",frameno+i,flr[i],framesize/2,1,1); - } - - /* residue prequantization */ - _vp_partition_prequant(&p_look, - &vi, - pcm, - nonzero); - - for(i=0;i<2;i++) - analysis("quant",frameno+i,pcm[i],framesize/2,1,0); - - /* channel coupling / stereo quantization */ - - _vp_couple(&p_look, - &mapping_info, - pcm, - nonzero); - - for(i=0;i<2;i++) - analysis("coupled",frameno+i,pcm[i],framesize/2,1,0); - - /* decoupling */ - for(i=mapping_info.coupling_steps-1;i>=0;i--){ - float *pcmM=pcm[mapping_info.coupling_mag[i]]; - float *pcmA=pcm[mapping_info.coupling_ang[i]]; - - for(j=0;j0) - if(ang>0){ - pcmM[j]=mag; - pcmA[j]=mag-ang; - }else{ - pcmA[j]=mag; - pcmM[j]=mag+ang; - } - else - if(ang>0){ - pcmM[j]=mag; - pcmA[j]=mag+ang; - }else{ - pcmA[j]=mag; - pcmM[j]=mag-ang; - } - } - } - - for(i=0;i<2;i++) - analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0); - - for(i=0;i<2;i++){ - float amp; - - for(j=0;j32767){ - if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); - flag=1; - val=32767; - } - if(val<-32768){ - if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); - flag=1; - val=-32768; - } - ptr[0]=val&0xff; - ptr[1]=(val>>8)&0xff; - ptr+=4; - } - } - - fprintf(stderr,"*"); - fwrite(buffer,1,framesize*2,stdout); - memmove(buffer,buffer2,framesize*2); - - for(i=0;i<2;i++){ - for(j=0,k=framesize/2;j -#include -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "registry.h" -#include "codebook.h" -#include "misc.h" -#include "os.h" - -#ifdef TRAIN_RES -#include -#endif - -typedef struct { - vorbis_info_residue0 *info; - - int parts; - int stages; - codebook *fullbooks; - codebook *phrasebook; - codebook ***partbooks; - - int partvals; - int **decodemap; - - long postbits; - long phrasebits; - long frames; - -#ifdef TRAIN_RES - int train_seq; - long *training_data[8][64]; - float training_max[8][64]; - float training_min[8][64]; - float tmin; - float tmax; -#endif - -} vorbis_look_residue0; - -void res0_free_info(vorbis_info_residue *i){ - vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; - if(info){ - memset(info,0,sizeof(*info)); - _ogg_free(info); - } -} - -void res0_free_look(vorbis_look_residue *i){ - int j; - if(i){ - - vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; - -#ifdef TRAIN_RES - { - int j,k,l; - for(j=0;jparts;j++){ - /*fprintf(stderr,"partition %d: ",j);*/ - for(k=0;k<8;k++) - if(look->training_data[k][j]){ - char buffer[80]; - FILE *of; - codebook *statebook=look->partbooks[j][k]; - - /* long and short into the same bucket by current convention */ - sprintf(buffer,"res_part%d_pass%d.vqd",j,k); - of=fopen(buffer,"a"); - - for(l=0;lentries;l++) - fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]); - - fclose(of); - - /*fprintf(stderr,"%d(%.2f|%.2f) ",k, - look->training_min[k][j],look->training_max[k][j]);*/ - - _ogg_free(look->training_data[k][j]); - } - /*fprintf(stderr,"\n");*/ - } - } - fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax); - - /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n", - (float)look->phrasebits/look->frames, - (float)look->postbits/look->frames, - (float)(look->postbits+look->phrasebits)/look->frames);*/ -#endif - - - /*vorbis_info_residue0 *info=look->info; - - fprintf(stderr, - "%ld frames encoded in %ld phrasebits and %ld residue bits " - "(%g/frame) \n",look->frames,look->phrasebits, - look->resbitsflat, - (look->phrasebits+look->resbitsflat)/(float)look->frames); - - for(j=0;jparts;j++){ - long acc=0; - fprintf(stderr,"\t[%d] == ",j); - for(k=0;kstages;k++) - if((info->secondstages[j]>>k)&1){ - fprintf(stderr,"%ld,",look->resbits[j][k]); - acc+=look->resbits[j][k]; - } - - fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], - acc?(float)acc/(look->resvals[j]*info->grouping):0); - } - fprintf(stderr,"\n");*/ - - for(j=0;jparts;j++) - if(look->partbooks[j])_ogg_free(look->partbooks[j]); - _ogg_free(look->partbooks); - for(j=0;jpartvals;j++) - _ogg_free(look->decodemap[j]); - _ogg_free(look->decodemap); - - memset(look,0,sizeof(*look)); - _ogg_free(look); - } -} - -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static int icount(unsigned int v){ - int ret=0; - while(v){ - ret+=v&1; - v>>=1; - } - return(ret); -} - - -void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ - vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; - int j,acc=0; - oggpack_write(opb,info->begin,24); - oggpack_write(opb,info->end,24); - - oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and - code with a partitioned book */ - oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ - oggpack_write(opb,info->groupbook,8); /* group huffman book */ - - /* secondstages is a bitmask; as encoding progresses pass by pass, a - bitmask of one indicates this partition class has bits to write - this pass */ - for(j=0;jpartitions;j++){ - if(ilog(info->secondstages[j])>3){ - /* yes, this is a minor hack due to not thinking ahead */ - oggpack_write(opb,info->secondstages[j],3); - oggpack_write(opb,1,1); - oggpack_write(opb,info->secondstages[j]>>3,5); - }else - oggpack_write(opb,info->secondstages[j],4); /* trailing zero */ - acc+=icount(info->secondstages[j]); - } - for(j=0;jbooklist[j],8); - -} - -/* vorbis_info is for range checking */ -vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ - int j,acc=0; - vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info)); - codec_setup_info *ci=vi->codec_setup; - - info->begin=oggpack_read(opb,24); - info->end=oggpack_read(opb,24); - info->grouping=oggpack_read(opb,24)+1; - info->partitions=oggpack_read(opb,6)+1; - info->groupbook=oggpack_read(opb,8); - - for(j=0;jpartitions;j++){ - int cascade=oggpack_read(opb,3); - if(oggpack_read(opb,1)) - cascade|=(oggpack_read(opb,5)<<3); - info->secondstages[j]=cascade; - - acc+=icount(cascade); - } - for(j=0;jbooklist[j]=oggpack_read(opb,8); - - if(info->groupbook>=ci->books)goto errout; - for(j=0;jbooklist[j]>=ci->books)goto errout; - - return(info); - errout: - res0_free_info(info); - return(NULL); -} - -vorbis_look_residue *res0_look(vorbis_dsp_state *vd, - vorbis_info_residue *vr){ - vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; - vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look)); - codec_setup_info *ci=vd->vi->codec_setup; - - int j,k,acc=0; - int dim; - int maxstage=0; - look->info=info; - - look->parts=info->partitions; - look->fullbooks=ci->fullbooks; - look->phrasebook=ci->fullbooks+info->groupbook; - dim=look->phrasebook->dim; - - look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); - - for(j=0;jparts;j++){ - int stages=ilog(info->secondstages[j]); - if(stages){ - if(stages>maxstage)maxstage=stages; - look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); - for(k=0;ksecondstages[j]&(1<partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; -#ifdef TRAIN_RES - look->training_data[k][j]=calloc(look->partbooks[j][k]->entries, - sizeof(***look->training_data)); -#endif - } - } - } - - look->partvals=rint(pow((float)look->parts,(float)dim)); - look->stages=maxstage; - look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); - for(j=0;jpartvals;j++){ - long val=j; - long mult=look->partvals/look->parts; - look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j])); - for(k=0;kparts; - look->decodemap[j][k]=deco; - } - } -#ifdef TRAIN_RES - { - static int train_seq=0; - look->train_seq=train_seq++; - } -#endif - return(look); -} - -/* break an abstraction and copy some code for performance purposes */ -static int local_book_besterror(codebook *book,float *a){ - int dim=book->dim,i,k,o; - int best=0; - encode_aux_threshmatch *tt=book->c->thresh_tree; - - /* find the quant val of each scalar */ - for(k=0,o=dim;kthreshvals>>1; - - if(valquantthresh[i]){ - if(valquantthresh[i-1]){ - for(--i;i>0;--i) - if(val>=tt->quantthresh[i-1]) - break; - } - }else{ - - for(++i;ithreshvals-1;++i) - if(valquantthresh[i])break; - - } - - best=(best*tt->quantvals)+tt->quantmap[i]; - } - /* regular lattices are easy :-) */ - - if(book->c->lengthlist[best]<=0){ - const static_codebook *c=book->c; - int i,j; - float bestf=0.f; - float *e=book->valuelist; - best=-1; - for(i=0;ientries;i++){ - if(c->lengthlist[i]>0){ - float this=0.f; - for(j=0;jvaluelist+best*dim; - for(i=0;idim; - int step=n/dim; - - for(i=0;iinfo; - vorbis_info *vi=vb->vd->vi; - codec_setup_info *ci=vi->codec_setup; - - /* move all this setup out later */ - int samples_per_partition=info->grouping; - int possible_partitions=info->partitions; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword)); - float scale=100./samples_per_partition; - - /* we find the partition type for each partition of each - channel. We'll go back and do the interleaved encoding in a - bit. For now, clarity */ - - for(i=0;ibegin; - for(j=0;jmax)max=fabs(in[j][offset+k]); - ent+=fabs(rint(in[j][offset+k])); - } - ent*=scale; - - for(k=0;kclassmetric1[k] && - (info->classmetric2[k]<0 || (int)entclassmetric2[k])) - break; - - partword[j][i]=k; - } - } - -#ifdef TRAIN_RESAUX - { - FILE *of; - char buffer[80]; - - for(i=0;itrain_seq); - of=fopen(buffer,"a"); - for(j=0;jframes++; - - return(partword); -} - -/* designed for stereo or other modes where the partition size is an - integer multiple of the number of channels encoded in the current - submap */ -static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in, - int ch){ - long i,j,k,l; - vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; - vorbis_info_residue0 *info=look->info; - - /* move all this setup out later */ - int samples_per_partition=info->grouping; - int possible_partitions=info->partitions; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - long **partword=_vorbis_block_alloc(vb,sizeof(*partword)); - -#ifdef TRAIN_RES - FILE *of; - char buffer[80]; -#endif - - partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(*partword[0])); - memset(partword[0],0,n*ch/samples_per_partition*sizeof(*partword[0])); - - for(i=0,l=info->begin/ch;imagmax)magmax=fabs(in[0][l]); - for(k=1;kangmax)angmax=fabs(in[k][l]); - l++; - } - - for(j=0;jclassmetric1[j] && - angmax<=info->classmetric2[j]) - break; - - partword[0][i]=j; - - } - -#ifdef TRAIN_RESAUX - sprintf(buffer,"resaux_%d.vqd",look->train_seq); - of=fopen(buffer,"a"); - for(i=0;iframes++; - - return(partword); -} - -static int _01forward(vorbis_block *vb,vorbis_look_residue *vl, - float **in,int ch, - long **partword, - int (*encode)(oggpack_buffer *,float *,int, - codebook *,long *)){ - long i,j,k,s; - vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; - vorbis_info_residue0 *info=look->info; - - vorbis_dsp_state *vd=vb->vd; - - /* move all this setup out later */ - int samples_per_partition=info->grouping; - int possible_partitions=info->partitions; - int partitions_per_word=look->phrasebook->dim; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - long resbits[128]; - long resvals[128]; - -#ifdef TRAIN_RES - for(i=0;ibegin;jend;j++){ - if(in[i][j]>look->tmax)look->tmax=in[i][j]; - if(in[i][j]tmin)look->tmin=in[i][j]; - } -#endif - - memset(resbits,0,sizeof(resbits)); - memset(resvals,0,sizeof(resvals)); - - /* we code the partition words for each channel, then the residual - words for a partition per channel until we've written all the - residual words for that partition word. Then write the next - partition channel words... */ - - for(s=0;sstages;s++){ - - for(i=0;iphrasebook->entries) - look->phrasebits+=vorbis_book_encode(look->phrasebook,val,&vb->opb); -#if 0 /*def TRAIN_RES*/ - else - fprintf(stderr,"!"); -#endif - - } - } - - /* now we encode interleaved residual values for the partitions */ - for(k=0;kbegin; - - for(j=0;jsecondstages[partword[j][i]]&(1<partbooks[partword[j][i]][s]; - if(statebook){ - int ret; - long *accumulator=NULL; - -#ifdef TRAIN_RES - accumulator=look->training_data[s][partword[j][i]]; - { - int l; - float *samples=in[j]+offset; - for(l=0;ltraining_min[s][partword[j][i]]) - look->training_min[s][partword[j][i]]=samples[l]; - if(samples[l]>look->training_max[s][partword[j][i]]) - look->training_max[s][partword[j][i]]=samples[l]; - } - } -#endif - - ret=encode(&vb->opb,in[j]+offset,samples_per_partition, - statebook,accumulator); - - look->postbits+=ret; - resbits[partword[j][i]]+=ret; - } - } - } - } - } - } - - /*{ - long total=0; - long totalbits=0; - fprintf(stderr,"%d :: ",vb->mode); - for(k=0;kinfo; - - /* move all this setup out later */ - int samples_per_partition=info->grouping; - int partitions_per_word=look->phrasebook->dim; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int ***partword=alloca(ch*sizeof(*partword)); - - for(j=0;jstages;s++){ - - /* each loop decodes on partition codeword containing - partitions_pre_word partitions */ - for(i=0,l=0;iphrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[j][l]=look->decodemap[temp]; - if(partword[j][l]==NULL)goto errout; - } - } - - /* now we decode residual values for the partitions */ - for(k=0;kbegin+i*samples_per_partition; - if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; - if(stagebook){ - if(decodepart(stagebook,in[j]+offset,&vb->opb, - samples_per_partition)==-1)goto eopbreak; - } - } - } - } - } - - errout: - eopbreak: - return(0); -} - -#if 0 -/* residue 0 and 1 are just slight variants of one another. 0 is - interleaved, 1 is not */ -long **res0_class(vorbis_block *vb,vorbis_look_residue *vl, - float **in,int *nonzero,int ch){ - /* we encode only the nonzero parts of a bundle */ - int i,used=0; - for(i=0;ipcmend/2; - for(i=0;ipcmend/2; - for(i=0;ipcmend/2,used=0; - - /* don't duplicate the code; use a working vector hack for now and - reshape ourselves into a single channel res1 */ - /* ugly; reallocs for each coupling pass :-( */ - float *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work)); - for(i=0;iinfo; - - /* move all this setup out later */ - int samples_per_partition=info->grouping; - int partitions_per_word=look->phrasebook->dim; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword)); - - for(i=0;istages;s++){ - for(i=0,l=0;iphrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[l]=look->decodemap[temp]; - if(partword[l]==NULL)goto errout; - } - - /* now we decode residual values for the partitions */ - for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; - - if(stagebook){ - if(vorbis_book_decodevv_add(stagebook,in, - i*samples_per_partition+info->begin,ch, - &vb->opb,samples_per_partition)==-1) - goto eopbreak; - } - } - } - } - - errout: - eopbreak: - return(0); -} - - -vorbis_func_residue residue0_exportbundle={ - NULL, - &res0_unpack, - &res0_look, - &res0_free_info, - &res0_free_look, - NULL, - NULL, - &res0_inverse -}; - -vorbis_func_residue residue1_exportbundle={ - &res0_pack, - &res0_unpack, - &res0_look, - &res0_free_info, - &res0_free_look, - &res1_class, - &res1_forward, - &res1_inverse -}; - -vorbis_func_residue residue2_exportbundle={ - &res0_pack, - &res0_unpack, - &res0_look, - &res0_free_info, - &res0_free_look, - &res2_class, - &res2_forward, - &res2_inverse -}; - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/scales.h b/src/add-ons/media/plugins/vorbis/libvorbis/scales.h deleted file mode 100644 index 436e52c925..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/scales.h +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: linear scale -> dB, Bark and Mel scales - last mod: $Id: scales.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_SCALES_H_ -#define _V_SCALES_H_ - -#include -#include "os.h" - -/* 20log10(x) */ -#define VORBIS_IEEE_FLOAT32 1 -#ifdef VORBIS_IEEE_FLOAT32 - -static float unitnorm(float x){ - ogg_uint32_t *ix=(ogg_uint32_t *)&x; - *ix=(*ix&0x80000000UL)|(0x3f800000UL); - return(x); -} - -static float FABS(float *x){ - ogg_uint32_t *ix=(ogg_uint32_t *)x; - *ix&=0x7fffffffUL; - return(*x); -} - -static float todB(const float *x){ - float calc; - ogg_int32_t *i=(ogg_int32_t *)x; - calc = ((*i) & 0x7fffffff); - calc *= 7.1771144e-7f; - calc += -764.27118f; - return calc; -} - -#define todB_nn(x) todB(x) - -#else - -static float unitnorm(float x){ - if(x<0)return(-1.f); - return(1.f); -} - -#define FABS(x) fabs(*(x)) - -#define todB(x) (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f) -#define todB_nn(x) (*(x)==0.f?-400.f:log(*(x))*8.6858896f) - -#endif - -#define fromdB(x) (exp((x)*.11512925f)) - -/* The bark scale equations are approximations, since the original - table was somewhat hand rolled. The below are chosen to have the - best possible fit to the rolled tables, thus their somewhat odd - appearance (these are more accurate and over a longer range than - the oft-quoted bark equations found in the texts I have). The - approximations are valid from 0 - 30kHz (nyquist) or so. - - all f in Hz, z in Bark */ - -#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) -#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f) -#define toMEL(n) (log(1.f+(n)*.001f)*1442.695f) -#define fromMEL(m) (1000.f*exp((m)/1442.695f)-1000.f) - -/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave - 0.0 */ - -#define toOC(n) (log(n)*1.442695f-5.965784f) -#define fromOC(o) (exp(((o)+5.965784f)*.693147f)) - -#endif - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/sharedbook.c b/src/add-ons/media/plugins/vorbis/libvorbis/sharedbook.c deleted file mode 100644 index 1797c06033..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/sharedbook.c +++ /dev/null @@ -1,733 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: basic shared codebook operations - last mod: $Id: sharedbook.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include "os.h" -#include "misc.h" -#include "vorbis/codec.h" -#include "codebook.h" -#include "scales.h" - -/**** pack/unpack helpers ******************************************/ -int _ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -/* 32 bit float (not IEEE; nonnormalized mantissa + - biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm - Why not IEEE? It's just not that important here. */ - -#define VQ_FEXP 10 -#define VQ_FMAN 21 -#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */ - -/* doesn't currently guard under/overflow */ -long _float32_pack(float val){ - int sign=0; - long exp; - long mant; - if(val<0){ - sign=0x80000000; - val= -val; - } - exp= floor(log(val)/log(2.f)); - mant=rint(ldexp(val,(VQ_FMAN-1)-exp)); - exp=(exp+VQ_FEXP_BIAS)<>VQ_FMAN; - if(sign)mant= -mant; - return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS)); -} - -/* given a list of word lengths, generate a list of codewords. Works - for length ordered or unordered, always assigns the lowest valued - codewords first. Extended to handle unused entries (length 0) */ -ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ - long i,j,count=0; - ogg_uint32_t marker[33]; - ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); - memset(marker,0,sizeof(marker)); - - for(i=0;i0){ - ogg_uint32_t entry=marker[length]; - - /* when we claim a node for an entry, we also claim the nodes - below it (pruning off the imagined tree that may have dangled - from it) as well as blocking the use of any nodes directly - above for leaves */ - - /* update ourself */ - if(length<32 && (entry>>length)){ - /* error condition; the lengths must specify an overpopulated tree */ - _ogg_free(r); - return(NULL); - } - r[count++]=entry; - - /* Look to see if the next shorter marker points to the node - above. if so, update it and repeat. */ - { - for(j=length;j>0;j--){ - - if(marker[j]&1){ - /* have to jump branches */ - if(j==1) - marker[1]++; - else - marker[j]=marker[j-1]<<1; - break; /* invariant says next upper marker would already - have been moved if it was on the same path */ - } - marker[j]++; - } - } - - /* prune the tree; the implicit invariant says all the longer - markers were dangling from our just-taken node. Dangle them - from our *new* node. */ - for(j=length+1;j<33;j++) - if((marker[j]>>1) == entry){ - entry=marker[j]; - marker[j]=marker[j-1]<<1; - }else - break; - }else - if(sparsecount==0)count++; - } - - /* bitreverse the words because our bitwise packer/unpacker is LSb - endian */ - for(i=0,count=0;i>j)&1; - } - - if(sparsecount){ - if(l[i]) - r[count++]=temp; - }else - r[count++]=temp; - } - - return(r); -} - -/* there might be a straightforward one-line way to do the below - that's portable and totally safe against roundoff, but I haven't - thought of it. Therefore, we opt on the side of caution */ -long _book_maptype1_quantvals(const static_codebook *b){ - long vals=floor(pow((float)b->entries,1.f/b->dim)); - - /* the above *should* be reliable, but we'll not assume that FP is - ever reliable when bitstream sync is at stake; verify via integer - means that vals really is the greatest value of dim for which - vals^b->bim <= b->entries */ - /* treat the above as an initial guess */ - while(1){ - long acc=1; - long acc1=1; - int i; - for(i=0;idim;i++){ - acc*=vals; - acc1*=vals+1; - } - if(acc<=b->entries && acc1>b->entries){ - return(vals); - }else{ - if(acc>b->entries){ - vals--; - }else{ - vals++; - } - } - } -} - -/* unpack the quantized list of values for encode/decode ***********/ -/* we need to deal with two map types: in map type 1, the values are - generated algorithmically (each column of the vector counts through - the values in the quant vector). in map type 2, all the values came - in in an explicit list. Both value lists must be unpacked */ -float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){ - long j,k,count=0; - if(b->maptype==1 || b->maptype==2){ - int quantvals; - float mindel=_float32_unpack(b->q_min); - float delta=_float32_unpack(b->q_delta); - float *r=_ogg_calloc(n*b->dim,sizeof(*r)); - - /* maptype 1 and 2 both use a quantized value vector, but - different sizes */ - switch(b->maptype){ - case 1: - /* most of the time, entries%dimensions == 0, but we need to be - well defined. We define that the possible vales at each - scalar is values == entries/dim. If entries%dim != 0, we'll - have 'too few' values (values*dimentries;j++){ - if((sparsemap && b->lengthlist[j]) || !sparsemap){ - float last=0.f; - int indexdiv=1; - for(k=0;kdim;k++){ - int index= (j/indexdiv)%quantvals; - float val=b->quantlist[index]; - val=fabs(val)*delta+mindel+last; - if(b->q_sequencep)last=val; - if(sparsemap) - r[sparsemap[count]*b->dim+k]=val; - else - r[count*b->dim+k]=val; - indexdiv*=quantvals; - } - count++; - } - - } - break; - case 2: - for(j=0;jentries;j++){ - if((sparsemap && b->lengthlist[j]) || !sparsemap){ - float last=0.f; - - for(k=0;kdim;k++){ - float val=b->quantlist[j*b->dim+k]; - val=fabs(val)*delta+mindel+last; - if(b->q_sequencep)last=val; - if(sparsemap) - r[sparsemap[count]*b->dim+k]=val; - else - r[count*b->dim+k]=val; - } - count++; - } - } - break; - } - - return(r); - } - return(NULL); -} - -void vorbis_staticbook_clear(static_codebook *b){ - if(b->allocedp){ - if(b->quantlist)_ogg_free(b->quantlist); - if(b->lengthlist)_ogg_free(b->lengthlist); - if(b->nearest_tree){ - _ogg_free(b->nearest_tree->ptr0); - _ogg_free(b->nearest_tree->ptr1); - _ogg_free(b->nearest_tree->p); - _ogg_free(b->nearest_tree->q); - memset(b->nearest_tree,0,sizeof(*b->nearest_tree)); - _ogg_free(b->nearest_tree); - } - if(b->thresh_tree){ - _ogg_free(b->thresh_tree->quantthresh); - _ogg_free(b->thresh_tree->quantmap); - memset(b->thresh_tree,0,sizeof(*b->thresh_tree)); - _ogg_free(b->thresh_tree); - } - - memset(b,0,sizeof(*b)); - } -} - -void vorbis_staticbook_destroy(static_codebook *b){ - if(b->allocedp){ - vorbis_staticbook_clear(b); - _ogg_free(b); - } -} - -void vorbis_book_clear(codebook *b){ - /* static book is not cleared; we're likely called on the lookup and - the static codebook belongs to the info struct */ - if(b->valuelist)_ogg_free(b->valuelist); - if(b->codelist)_ogg_free(b->codelist); - - if(b->dec_index)_ogg_free(b->dec_index); - if(b->dec_codelengths)_ogg_free(b->dec_codelengths); - if(b->dec_firsttable)_ogg_free(b->dec_firsttable); - - memset(b,0,sizeof(*b)); -} - -int vorbis_book_init_encode(codebook *c,const static_codebook *s){ - - memset(c,0,sizeof(*c)); - c->c=s; - c->entries=s->entries; - c->used_entries=s->entries; - c->dim=s->dim; - c->codelist=_make_words(s->lengthlist,s->entries,0); - c->valuelist=_book_unquantize(s,s->entries,NULL); - - return(0); -} - -static ogg_uint32_t bitreverse(ogg_uint32_t x){ - x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL); - x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL); - x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL); - x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL); - return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL); -} - -static int sort32a(const void *a,const void *b){ - return ( (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)<<1)-1; -} - -/* decode codebook arrangement is more heavily optimized than encode */ -int vorbis_book_init_decode(codebook *c,const static_codebook *s){ - int i,j,n=0,tabn; - int *sortindex; - memset(c,0,sizeof(*c)); - - /* count actually used entries */ - for(i=0;ientries;i++) - if(s->lengthlist[i]>0) - n++; - - c->entries=s->entries; - c->used_entries=n; - c->dim=s->dim; - - /* two different remappings go on here. - - First, we collapse the likely sparse codebook down only to - actually represented values/words. This collapsing needs to be - indexed as map-valueless books are used to encode original entry - positions as integers. - - Second, we reorder all vectors, including the entry index above, - by sorted bitreversed codeword to allow treeless decode. */ - - { - /* perform sort */ - ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); - ogg_uint32_t **codep=alloca(sizeof(*codep)*n); - - if(codes==NULL)goto err_out; - - for(i=0;icodelist=_ogg_malloc(n*sizeof(*c->codelist)); - /* the index is a reverse index */ - for(i=0;icodelist[sortindex[i]]=codes[i]; - _ogg_free(codes); - } - - c->valuelist=_book_unquantize(s,n,sortindex); - c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index)); - - for(n=0,i=0;ientries;i++) - if(s->lengthlist[i]>0) - c->dec_index[sortindex[n++]]=i; - - c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths)); - for(n=0,i=0;ientries;i++) - if(s->lengthlist[i]>0) - c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; - - c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ - if(c->dec_firsttablen<5)c->dec_firsttablen=5; - if(c->dec_firsttablen>8)c->dec_firsttablen=8; - - tabn=1<dec_firsttablen; - c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); - c->dec_maxlength=0; - - for(i=0;idec_maxlengthdec_codelengths[i]) - c->dec_maxlength=c->dec_codelengths[i]; - if(c->dec_codelengths[i]<=c->dec_firsttablen){ - ogg_uint32_t orig=bitreverse(c->codelist[i]); - for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) - c->dec_firsttable[orig|(j<dec_codelengths[i])]=i+1; - } - } - - /* now fill in 'unused' entries in the firsttable with hi/lo search - hints for the non-direct-hits */ - { - ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); - long lo=0,hi=0; - - for(i=0;idec_firsttablen); - if(c->dec_firsttable[bitreverse(word)]==0){ - while((lo+1)codelist[lo+1]<=word)lo++; - while( hi=(c->codelist[hi]&mask))hi++; - - /* we only actually have 15 bits per hint to play with here. - In order to overflow gracefully (nothing breaks, efficiency - just drops), encode as the difference from the extremes. */ - { - unsigned long loval=lo; - unsigned long hival=n-hi; - - if(loval>0x7fff)loval=0x7fff; - if(hival>0x7fff)hival=0x7fff; - c->dec_firsttable[bitreverse(word)]= - 0x80000000UL | (loval<<15) | hival; - } - } - } - } - - - return(0); - err_out: - vorbis_book_clear(c); - return(-1); -} - -static float _dist(int el,float *ref, float *b,int step){ - int i; - float acc=0.f; - for(i=0;ic->thresh_tree; - -#if 0 - encode_aux_nearestmatch *nt=book->c->nearest_tree; - encode_aux_pigeonhole *pt=book->c->pigeon_tree; -#endif - int dim=book->dim; - int k,o; - /*int savebest=-1; - float saverr;*/ - - /* do we have a threshhold encode hint? */ - if(tt){ - int index=0,i; - /* find the quant val of each scalar */ - for(k=0,o=step*(dim-1);kthreshvals>>1; - if(a[o]quantthresh[i]){ - - for(;i>0;i--) - if(a[o]>=tt->quantthresh[i-1]) - break; - - }else{ - - for(i++;ithreshvals-1;i++) - if(a[o]quantthresh[i])break; - - } - - index=(index*tt->quantvals)+tt->quantmap[i]; - } - /* regular lattices are easy :-) */ - if(book->c->lengthlist[index]>0) /* is this unused? If so, we'll - use a decision tree after all - and fall through*/ - return(index); - } - -#if 0 - /* do we have a pigeonhole encode hint? */ - if(pt){ - const static_codebook *c=book->c; - int i,besti=-1; - float best=0.f; - int entry=0; - - /* dealing with sequentialness is a pain in the ass */ - if(c->q_sequencep){ - int pv; - long mul=1; - float qlast=0; - for(k=0,o=0;kmin)/pt->del); - if(pv<0 || pv>=pt->mapentries)break; - entry+=pt->pigeonmap[pv]*mul; - mul*=pt->quantvals; - qlast+=pv*pt->del+pt->min; - } - }else{ - for(k=0,o=step*(dim-1);kmin)/pt->del); - if(pv<0 || pv>=pt->mapentries)break; - entry=entry*pt->quantvals+pt->pigeonmap[pv]; - } - } - - /* must be within the pigeonholable range; if we quant outside (or - in an entry that we define no list for), brute force it */ - if(k==dim && pt->fitlength[entry]){ - /* search the abbreviated list */ - long *list=pt->fitlist+pt->fitmap[entry]; - for(i=0;ifitlength[entry];i++){ - float this=_dist(dim,book->valuelist+list[i]*dim,a,step); - if(besti==-1 || thisvaluelist+nt->p[ptr]; - float *q=book->valuelist+nt->q[ptr]; - - for(k=0,o=0;k0.f) /* in A */ - ptr= -nt->ptr0[ptr]; - else /* in B */ - ptr= -nt->ptr1[ptr]; - if(ptr<=0)break; - } - return(-ptr); - } -#endif - - /* brute force it! */ - { - const static_codebook *c=book->c; - int i,besti=-1; - float best=0.f; - float *e=book->valuelist; - for(i=0;ientries;i++){ - if(c->lengthlist[i]>0){ - float this=_dist(dim,e,a,step); - if(besti==-1 || thisvaluelist+savebest*dim)[i]); - fprintf(stderr,"\n" - "bruteforce (entry %d, err %g):",besti,best); - for(i=0;ivaluelist+besti*dim)[i]); - fprintf(stderr,"\n"); - }*/ - return(besti); - } -} - -long vorbis_book_codeword(codebook *book,int entry){ - if(book->c) /* only use with encode; decode optimizations are - allowed to break this */ - return book->codelist[entry]; - return -1; -} - -long vorbis_book_codelen(codebook *book,int entry){ - if(book->c) /* only use with encode; decode optimizations are - allowed to break this */ - return book->c->lengthlist[entry]; - return -1; -} - -#ifdef _V_SELFTEST - -/* Unit tests of the dequantizer; this stuff will be OK - cross-platform, I simply want to be sure that special mapping cases - actually work properly; a bug could go unnoticed for a while */ - -#include - -/* cases: - - no mapping - full, explicit mapping - algorithmic mapping - - nonsequential - sequential -*/ - -static long full_quantlist1[]={0,1,2,3, 4,5,6,7, 8,3,6,1}; -static long partial_quantlist1[]={0,7,2}; - -/* no mapping */ -static_codebook test1={ - 4,16, - NULL, - 0, - 0,0,0,0, - NULL, - NULL,NULL -}; -static float *test1_result=NULL; - -/* linear, full mapping, nonsequential */ -static_codebook test2={ - 4,3, - NULL, - 2, - -533200896,1611661312,4,0, - full_quantlist1, - NULL,NULL -}; -static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2}; - -/* linear, full mapping, sequential */ -static_codebook test3={ - 4,3, - NULL, - 2, - -533200896,1611661312,4,1, - full_quantlist1, - NULL,NULL -}; -static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6}; - -/* linear, algorithmic mapping, nonsequential */ -static_codebook test4={ - 3,27, - NULL, - 1, - -533200896,1611661312,4,0, - partial_quantlist1, - NULL,NULL -}; -static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3, - -3, 4,-3, 4, 4,-3, -1, 4,-3, - -3,-1,-3, 4,-1,-3, -1,-1,-3, - -3,-3, 4, 4,-3, 4, -1,-3, 4, - -3, 4, 4, 4, 4, 4, -1, 4, 4, - -3,-1, 4, 4,-1, 4, -1,-1, 4, - -3,-3,-1, 4,-3,-1, -1,-3,-1, - -3, 4,-1, 4, 4,-1, -1, 4,-1, - -3,-1,-1, 4,-1,-1, -1,-1,-1}; - -/* linear, algorithmic mapping, sequential */ -static_codebook test5={ - 3,27, - NULL, - 1, - -533200896,1611661312,4,1, - partial_quantlist1, - NULL,NULL -}; -static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7, - -3, 1,-2, 4, 8, 5, -1, 3, 0, - -3,-4,-7, 4, 3, 0, -1,-2,-5, - -3,-6,-2, 4, 1, 5, -1,-4, 0, - -3, 1, 5, 4, 8,12, -1, 3, 7, - -3,-4, 0, 4, 3, 7, -1,-2, 2, - -3,-6,-7, 4, 1, 0, -1,-4,-5, - -3, 1, 0, 4, 8, 7, -1, 3, 2, - -3,-4,-5, 4, 3, 2, -1,-2,-3}; - -void run_test(static_codebook *b,float *comp){ - float *out=_book_unquantize(b,b->entries,NULL); - int i; - - if(comp){ - if(!out){ - fprintf(stderr,"_book_unquantize incorrectly returned NULL\n"); - exit(1); - } - - for(i=0;ientries*b->dim;i++) - if(fabs(out[i]-comp[i])>.0001){ - fprintf(stderr,"disagreement in unquantized and reference data:\n" - "position %d, %g != %g\n",i,out[i],comp[i]); - exit(1); - } - - }else{ - if(out){ - fprintf(stderr,"_book_unquantize returned a value array: \n" - " correct result should have been NULL\n"); - exit(1); - } - } -} - -int main(){ - /* run the nine dequant tests, and compare to the hand-rolled results */ - fprintf(stderr,"Dequant test 1... "); - run_test(&test1,test1_result); - fprintf(stderr,"OK\nDequant test 2... "); - run_test(&test2,test2_result); - fprintf(stderr,"OK\nDequant test 3... "); - run_test(&test3,test3_result); - fprintf(stderr,"OK\nDequant test 4... "); - run_test(&test4,test4_result); - fprintf(stderr,"OK\nDequant test 5... "); - run_test(&test5,test5_result); - fprintf(stderr,"OK\n\n"); - - return(0); -} - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/smallft.c b/src/add-ons/media/plugins/vorbis/libvorbis/smallft.c deleted file mode 100644 index abb829685d..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/smallft.c +++ /dev/null @@ -1,1254 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: *unnormalized* fft transform - last mod: $Id: smallft.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -/* FFT implementation from OggSquish, minus cosine transforms, - * minus all but radix 2/4 case. In Vorbis we only need this - * cut-down version. - * - * To do more than just power-of-two sized vectors, see the full - * version I wrote for NetLib. - * - * Note that the packing is a little strange; rather than the FFT r/i - * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, - * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the - * FORTRAN version - */ - -#include -#include -#include -#include "smallft.h" -#include "misc.h" - -static void drfti1(int n, float *wa, int *ifac){ - static int ntryh[4] = { 4,2,3,5 }; - static float tpi = 6.28318530717958648f; - float arg,argh,argld,fi; - int ntry=0,i,j=-1; - int k1, l1, l2, ib; - int ld, ii, ip, is, nq, nr; - int ido, ipm, nfm1; - int nl=n; - int nf=0; - - L101: - j++; - if (j < 4) - ntry=ntryh[j]; - else - ntry+=2; - - L104: - nq=nl/ntry; - nr=nl-ntry*nq; - if (nr!=0) goto L101; - - nf++; - ifac[nf+1]=ntry; - nl=nq; - if(ntry!=2)goto L107; - if(nf==1)goto L107; - - for (i=1;i>1; - ipp2=ip; - idp2=ido; - nbd=(ido-1)>>1; - t0=l1*ido; - t10=ip*ido; - - if(ido==1)goto L119; - for(ik=0;ikl1){ - for(j=1;j>1; - ipp2=ip; - ipph=(ip+1)>>1; - if(idol1)goto L139; - - is= -ido-1; - t1=0; - for(j=1;jn==1)return; - drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); -} - -void drft_backward(drft_lookup *l,float *data){ - if (l->n==1)return; - drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); -} - -void drft_init(drft_lookup *l,int n){ - l->n=n; - l->trigcache=_ogg_calloc(3*n,sizeof(*l->trigcache)); - l->splitcache=_ogg_calloc(32,sizeof(*l->splitcache)); - fdrffti(n, l->trigcache, l->splitcache); -} - -void drft_clear(drft_lookup *l){ - if(l){ - if(l->trigcache)_ogg_free(l->trigcache); - if(l->splitcache)_ogg_free(l->splitcache); - memset(l,0,sizeof(*l)); - } -} diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/smallft.h b/src/add-ons/media/plugins/vorbis/libvorbis/smallft.h deleted file mode 100644 index 0c39bad2e6..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/smallft.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: fft transform - last mod: $Id: smallft.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _V_SMFT_H_ -#define _V_SMFT_H_ - -#include "vorbis/codec.h" - -typedef struct { - int n; - float *trigcache; - int *splitcache; -} drft_lookup; - -extern void drft_forward(drft_lookup *l,float *data); -extern void drft_backward(drft_lookup *l,float *data); -extern void drft_init(drft_lookup *l,int n); -extern void drft_clear(drft_lookup *l); - -#endif diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/synthesis.c b/src/add-ons/media/plugins/vorbis/libvorbis/synthesis.c deleted file mode 100644 index c469812635..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/synthesis.c +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: single-block PCM synthesis - last mod: $Id: synthesis.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include "vorbis/codec.h" -#include "codec_internal.h" -#include "registry.h" -#include "misc.h" -#include "os.h" - -int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ - vorbis_dsp_state *vd=vb->vd; - backend_lookup_state *b=vd->backend_state; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - oggpack_buffer *opb=&vb->opb; - int type,mode,i; - - /* first things first. Make sure decode is ready */ - _vorbis_block_ripcord(vb); - oggpack_readinit(opb,op->packet,op->bytes); - - /* Check the packet type */ - if(oggpack_read(opb,1)!=0){ - /* Oops. This is not an audio data packet */ - return(OV_ENOTAUDIO); - } - - /* read our mode and pre/post windowsize */ - mode=oggpack_read(opb,b->modebits); - if(mode==-1)return(OV_EBADPACKET); - - vb->mode=mode; - vb->W=ci->mode_param[mode]->blockflag; - if(vb->W){ - - /* this doesn;t get mapped through mode selection as it's used - only for window selection */ - vb->lW=oggpack_read(opb,1); - vb->nW=oggpack_read(opb,1); - if(vb->nW==-1) return(OV_EBADPACKET); - }else{ - vb->lW=0; - vb->nW=0; - } - - /* more setup */ - vb->granulepos=op->granulepos; - vb->sequence=op->packetno-3; /* first block is third packet */ - vb->eofflag=op->e_o_s; - - /* alloc pcm passback storage */ - vb->pcmend=ci->blocksizes[vb->W]; - vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); - for(i=0;ichannels;i++) - vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); - - /* unpack_header enforces range checking */ - type=ci->map_type[ci->mode_param[mode]->mapping]; - - return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]-> - mapping])); -} - -/* used to track pcm position without actually performing decode. - Useful for sequential 'fast forward' */ -int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){ - vorbis_dsp_state *vd=vb->vd; - backend_lookup_state *b=vd->backend_state; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=vi->codec_setup; - oggpack_buffer *opb=&vb->opb; - int mode; - - /* first things first. Make sure decode is ready */ - _vorbis_block_ripcord(vb); - oggpack_readinit(opb,op->packet,op->bytes); - - /* Check the packet type */ - if(oggpack_read(opb,1)!=0){ - /* Oops. This is not an audio data packet */ - return(OV_ENOTAUDIO); - } - - /* read our mode and pre/post windowsize */ - mode=oggpack_read(opb,b->modebits); - if(mode==-1)return(OV_EBADPACKET); - - vb->mode=mode; - vb->W=ci->mode_param[mode]->blockflag; - if(vb->W){ - vb->lW=oggpack_read(opb,1); - vb->nW=oggpack_read(opb,1); - if(vb->nW==-1) return(OV_EBADPACKET); - }else{ - vb->lW=0; - vb->nW=0; - } - - /* more setup */ - vb->granulepos=op->granulepos; - vb->sequence=op->packetno-3; /* first block is third packet */ - vb->eofflag=op->e_o_s; - - /* no pcm */ - vb->pcmend=0; - vb->pcm=NULL; - - return(0); -} - -long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ - codec_setup_info *ci=vi->codec_setup; - oggpack_buffer opb; - int mode; - - oggpack_readinit(&opb,op->packet,op->bytes); - - /* Check the packet type */ - if(oggpack_read(&opb,1)!=0){ - /* Oops. This is not an audio data packet */ - return(OV_ENOTAUDIO); - } - - { - int modebits=0; - int v=ci->modes; - while(v>1){ - modebits++; - v>>=1; - } - - /* read our mode and pre/post windowsize */ - mode=oggpack_read(&opb,modebits); - } - if(mode==-1)return(OV_EBADPACKET); - return(ci->blocksizes[ci->mode_param[mode]->blockflag]); -} - - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/tone.c b/src/add-ons/media/plugins/vorbis/libvorbis/tone.c deleted file mode 100644 index daf2f93137..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/tone.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include - -void usage(){ - fprintf(stderr,"tone ,[] [,[]...]\n"); - exit(1); -} - -int main (int argc,char *argv[]){ - int i,j; - double *f; - double *amp; - - if(argc<2)usage(); - - f=alloca(sizeof(*f)*(argc-1)); - amp=alloca(sizeof(*amp)*(argc-1)); - - i=0; - while(argv[i+1]){ - char *pos=strchr(argv[i+1],','); - - f[i]=atof(argv[i+1]); - if(pos) - amp[i]=atof(pos+1)*32767.f; - else - amp[i]=32767.f; - - fprintf(stderr,"%g Hz, %g amp\n",f[i],amp[i]); - - i++; - } - - for(i=0;i<44100*10;i++){ - float val=0; - int ival; - for(j=0;j32767.f)ival=32767.f; - if(ival<-32768.f)ival=-32768.f; - - fprintf(stdout,"%c%c%c%c", - (char)(ival&0xff), - (char)((ival>>8)&0xff), - (char)(ival&0xff), - (char)((ival>>8)&0xff)); - } - return(0); -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/vorbis/codec.h b/src/add-ons/media/plugins/vorbis/libvorbis/vorbis/codec.h deleted file mode 100644 index a8f2952469..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/vorbis/codec.h +++ /dev/null @@ -1,233 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - - ******************************************************************** - - function: libvorbis codec headers - last mod: $Id: codec.h 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#ifndef _vorbis_codec_h_ -#define _vorbis_codec_h_ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#include - -typedef struct vorbis_info{ - int version; - int channels; - long rate; - - /* The below bitrate declarations are *hints*. - Combinations of the three values carry the following implications: - - all three set to the same value: - implies a fixed rate bitstream - only nominal set: - implies a VBR stream that averages the nominal bitrate. No hard - upper/lower limit - upper and or lower set: - implies a VBR bitstream that obeys the bitrate limits. nominal - may also be set to give a nominal rate. - none set: - the coder does not care to speculate. - */ - - long bitrate_upper; - long bitrate_nominal; - long bitrate_lower; - long bitrate_window; - - void *codec_setup; -} vorbis_info; - -/* vorbis_dsp_state buffers the current vorbis audio - analysis/synthesis state. The DSP state belongs to a specific - logical bitstream ****************************************************/ -typedef struct vorbis_dsp_state{ - int analysisp; - vorbis_info *vi; - - float **pcm; - float **pcmret; - int pcm_storage; - int pcm_current; - int pcm_returned; - - int preextrapolate; - int eofflag; - - long lW; - long W; - long nW; - long centerW; - - ogg_int64_t granulepos; - ogg_int64_t sequence; - - ogg_int64_t glue_bits; - ogg_int64_t time_bits; - ogg_int64_t floor_bits; - ogg_int64_t res_bits; - - void *backend_state; -} vorbis_dsp_state; - -typedef struct vorbis_block{ - /* necessary stream state for linking to the framing abstraction */ - float **pcm; /* this is a pointer into local storage */ - oggpack_buffer opb; - - long lW; - long W; - long nW; - int pcmend; - int mode; - - int eofflag; - ogg_int64_t granulepos; - ogg_int64_t sequence; - vorbis_dsp_state *vd; /* For read-only access of configuration */ - - /* local storage to avoid remallocing; it's up to the mapping to - structure it */ - void *localstore; - long localtop; - long localalloc; - long totaluse; - struct alloc_chain *reap; - - /* bitmetrics for the frame */ - long glue_bits; - long time_bits; - long floor_bits; - long res_bits; - - void *internal; - -} vorbis_block; - -/* vorbis_block is a single block of data to be processed as part of -the analysis/synthesis stream; it belongs to a specific logical -bitstream, but is independant from other vorbis_blocks belonging to -that logical bitstream. *************************************************/ - -struct alloc_chain{ - void *ptr; - struct alloc_chain *next; -}; - -/* vorbis_info contains all the setup information specific to the - specific compression/decompression mode in progress (eg, - psychoacoustic settings, channel setup, options, codebook - etc). vorbis_info and substructures are in backends.h. -*********************************************************************/ - -/* the comments are not part of vorbis_info so that vorbis_info can be - static storage */ -typedef struct vorbis_comment{ - /* unlimited user comment fields. libvorbis writes 'libvorbis' - whatever vendor is set to in encode */ - char **user_comments; - int *comment_lengths; - int comments; - char *vendor; - -} vorbis_comment; - - -/* libvorbis encodes in two abstraction layers; first we perform DSP - and produce a packet (see docs/analysis.txt). The packet is then - coded into a framed OggSquish bitstream by the second layer (see - docs/framing.txt). Decode is the reverse process; we sync/frame - the bitstream and extract individual packets, then decode the - packet back into PCM audio. - - The extra framing/packetizing is used in streaming formats, such as - files. Over the net (such as with UDP), the framing and - packetization aren't necessary as they're provided by the transport - and the streaming layer is not used */ - -/* Vorbis PRIMITIVES: general ***************************************/ - -extern void vorbis_info_init(vorbis_info *vi); -extern void vorbis_info_clear(vorbis_info *vi); -extern int vorbis_info_blocksize(vorbis_info *vi,int zo); -extern void vorbis_comment_init(vorbis_comment *vc); -extern void vorbis_comment_add(vorbis_comment *vc, char *comment); -extern void vorbis_comment_add_tag(vorbis_comment *vc, - char *tag, char *contents); -extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); -extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); -extern void vorbis_comment_clear(vorbis_comment *vc); - -extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); -extern int vorbis_block_clear(vorbis_block *vb); -extern void vorbis_dsp_clear(vorbis_dsp_state *v); - -/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ - -extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); -extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); -extern int vorbis_analysis_headerout(vorbis_dsp_state *v, - vorbis_comment *vc, - ogg_packet *op, - ogg_packet *op_comm, - ogg_packet *op_code); -extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); -extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); -extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); -extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); - -extern int vorbis_bitrate_addblock(vorbis_block *vb); -extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, - ogg_packet *op); - -/* Vorbis PRIMITIVES: synthesis layer *******************************/ -extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, - ogg_packet *op); - -extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); -extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); -extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); -extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); -extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); -extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); -extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); - -/* Vorbis ERRORS and return codes ***********************************/ - -#define OV_FALSE -1 -#define OV_EOF -2 -#define OV_HOLE -3 - -#define OV_EREAD -128 -#define OV_EFAULT -129 -#define OV_EIMPL -130 -#define OV_EINVAL -131 -#define OV_ENOTVORBIS -132 -#define OV_EBADHEADER -133 -#define OV_EVERSION -134 -#define OV_ENOTAUDIO -135 -#define OV_EBADPACKET -136 -#define OV_EBADLINK -137 -#define OV_ENOSEEK -138 - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/vorbisenc.c b/src/add-ons/media/plugins/vorbis/libvorbis/vorbisenc.c deleted file mode 100644 index ed16e34cef..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/vorbisenc.c +++ /dev/null @@ -1,1134 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: simple programmatic interface for encoder mode setup - last mod: $Id: vorbisenc.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include - -#include "vorbis/codec.h" -#include "vorbis/vorbisenc.h" - -#include "codec_internal.h" - -#include "os.h" -#include "misc.h" - -/* careful with this; it's using static array sizing to make managing - all the modes a little less annoying. If we use a residue backend - with > 12 partition types, or a different division of iteration, - this needs to be updated. */ -typedef struct { - static_codebook *books[12][3]; -} static_bookblock; - -typedef struct { - int res_type; - int limit_type; /* 0 lowpass limited, 1 point stereo limited */ - vorbis_info_residue0 *res; - static_codebook *book_aux; - static_codebook *book_aux_managed; - static_bookblock *books_base; - static_bookblock *books_base_managed; -} vorbis_residue_template; - -typedef struct { - vorbis_info_mapping0 *map; - vorbis_residue_template *res; -} vorbis_mapping_template; - -typedef struct vp_adjblock{ - int block[P_BANDS]; -} vp_adjblock; - -typedef struct { - int data[NOISE_COMPAND_LEVELS]; -} compandblock; - -/* high level configuration information for setting things up - step-by-step with the detailed vorbis_encode_ctl interface. - There's a fair amount of redundancy such that interactive setup - does not directly deal with any vorbis_info or codec_setup_info - initialization; it's all stored (until full init) in this highlevel - setup, then flushed out to the real codec setup structs later. */ - -typedef struct { - int att[P_NOISECURVES]; - float boost; - float decay; -} att3; -typedef struct { int data[P_NOISECURVES]; } adj3; - -typedef struct { - int pre[PACKETBLOBS]; - int post[PACKETBLOBS]; - float kHz[PACKETBLOBS]; - float lowpasskHz[PACKETBLOBS]; -} adj_stereo; - -typedef struct { - int lo; - int hi; - int fixed; -} noiseguard; -typedef struct { - int data[P_NOISECURVES][17]; -} noise3; - -typedef struct { - int mappings; - double *rate_mapping; - double *quality_mapping; - int coupling_restriction; - long samplerate_min_restriction; - long samplerate_max_restriction; - - - int *blocksize_short; - int *blocksize_long; - - att3 *psy_tone_masteratt; - int *psy_tone_0dB; - int *psy_tone_dBsuppress; - - vp_adjblock *psy_tone_adj_impulse; - vp_adjblock *psy_tone_adj_long; - vp_adjblock *psy_tone_adj_other; - - noiseguard *psy_noiseguards; - noise3 *psy_noise_bias_impulse; - noise3 *psy_noise_bias_padding; - noise3 *psy_noise_bias_trans; - noise3 *psy_noise_bias_long; - int *psy_noise_dBsuppress; - - compandblock *psy_noise_compand; - double *psy_noise_compand_short_mapping; - double *psy_noise_compand_long_mapping; - - int *psy_noise_normal_start[2]; - int *psy_noise_normal_partition[2]; - double *psy_noise_normal_thresh; - - int *psy_ath_float; - int *psy_ath_abs; - - double *psy_lowpass; - - vorbis_info_psy_global *global_params; - double *global_mapping; - adj_stereo *stereo_modes; - - static_codebook ***floor_books; - vorbis_info_floor1 *floor_params; - int *floor_short_mapping; - int *floor_long_mapping; - - vorbis_mapping_template *maps; -} ve_setup_data_template; - -/* a few static coder conventions */ -static vorbis_info_mode _mode_template[2]={ - {0,0,0,0}, - {1,0,0,1} -}; - -static vorbis_info_mapping0 _map_nominal[2]={ - {1, {0,0}, {0}, {0}, 1,{0},{1}}, - {1, {0,0}, {1}, {1}, 1,{0},{1}} -}; - -#include "modes/setup_44.h" -#include "modes/setup_44u.h" -#include "modes/setup_32.h" -#include "modes/setup_8.h" -#include "modes/setup_11.h" -#include "modes/setup_16.h" -#include "modes/setup_22.h" -#include "modes/setup_X.h" - -static ve_setup_data_template *setup_list[]={ - &ve_setup_44_stereo, - &ve_setup_44_stereo_low, - &ve_setup_44_uncoupled, - &ve_setup_44_uncoupled_low, - - &ve_setup_32_stereo, - &ve_setup_32_stereo_low, - &ve_setup_32_uncoupled, - &ve_setup_32_uncoupled_low, - - &ve_setup_22_stereo, - &ve_setup_22_uncoupled, - &ve_setup_16_stereo, - &ve_setup_16_uncoupled, - - &ve_setup_11_stereo, - &ve_setup_11_uncoupled, - &ve_setup_8_stereo, - &ve_setup_8_uncoupled, - - &ve_setup_X_stereo, - &ve_setup_X_uncoupled, - &ve_setup_X_stereo_low, - &ve_setup_X_uncoupled_low, - &ve_setup_XX_stereo, - &ve_setup_XX_uncoupled, - 0 -}; - -static int vorbis_encode_toplevel_setup(vorbis_info *vi,int ch,long rate){ - if(vi && vi->codec_setup){ - - vi->version=0; - vi->channels=ch; - vi->rate=rate; - - return(0); - } - return(OV_EINVAL); -} - -static void vorbis_encode_floor_setup(vorbis_info *vi,double s,int block, - static_codebook ***books, - vorbis_info_floor1 *in, - int *x){ - int i,k,is=s; - vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f)); - codec_setup_info *ci=vi->codec_setup; - - memcpy(f,in+x[is],sizeof(*f)); - /* fill in the lowpass field, even if it's temporary */ - f->n=ci->blocksizes[block]>>1; - - /* books */ - { - int partitions=f->partitions; - int maxclass=-1; - int maxbook=-1; - for(i=0;ipartitionclass[i]>maxclass)maxclass=f->partitionclass[i]; - for(i=0;i<=maxclass;i++){ - if(f->class_book[i]>maxbook)maxbook=f->class_book[i]; - f->class_book[i]+=ci->books; - for(k=0;k<(1<class_subs[i]);k++){ - if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k]; - if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books; - } - } - - for(i=0;i<=maxbook;i++) - ci->book_param[ci->books++]=books[x[is]][i]; - } - - /* for now, we're only using floor 1 */ - ci->floor_type[ci->floors]=1; - ci->floor_param[ci->floors]=f; - ci->floors++; - - return; -} - -static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s, - vorbis_info_psy_global *in, - double *x){ - int i,is=s; - double ds=s-is; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *g=&ci->psy_g_param; - - memcpy(g,in+(int)x[is],sizeof(*g)); - - ds=x[is]*(1.-ds)+x[is+1]*ds; - is=(int)ds; - ds-=is; - if(ds==0 && is>0){ - is--; - ds=1.; - } - - /* interpolate the trigger threshholds */ - for(i=0;i<4;i++){ - g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds; - g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds; - } - g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec; - return; -} - -static void vorbis_encode_global_stereo(vorbis_info *vi, - highlevel_encode_setup *hi, - adj_stereo *p){ - float s=hi->stereo_point_setting; - int i,is=s; - double ds=s-is; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy_global *g=&ci->psy_g_param; - - if(p){ - memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS); - memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS); - - if(hi->managed){ - /* interpolate the kHz threshholds */ - for(i=0;icoupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; - g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; - g->coupling_pkHz[i]=kHz; - - kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds; - g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; - g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; - - } - }else{ - float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds; - for(i=0;icoupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; - g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; - g->coupling_pkHz[i]=kHz; - } - - kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds; - for(i=0;isliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; - g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; - } - } - }else{ - for(i=0;isliding_lowpass[0][i]=ci->blocksizes[0]; - g->sliding_lowpass[1][i]=ci->blocksizes[1]; - } - } - return; -} - -static void vorbis_encode_psyset_setup(vorbis_info *vi,double s, - int *nn_start, - int *nn_partition, - double *nn_thresh, - int block){ - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy *p=ci->psy_param[block]; - highlevel_encode_setup *hi=&ci->hi; - int is=s; - - if(block>=ci->psys) - ci->psys=block+1; - if(!p){ - p=_ogg_calloc(1,sizeof(*p)); - ci->psy_param[block]=p; - } - - memcpy(p,&_psy_info_template,sizeof(*p)); - p->blockflag=block>>1; - - if(hi->noise_normalize_p){ - p->normal_channel_p=1; - p->normal_point_p=1; - p->normal_start=nn_start[is]; - p->normal_partition=nn_partition[is]; - p->normal_thresh=nn_thresh[is]; - } - - return; -} - -static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block, - att3 *att, - int *max, - vp_adjblock *in){ - int i,is=s; - double ds=s-is; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy *p=ci->psy_param[block]; - - /* 0 and 2 are only used by bitmanagement, but there's no harm to always - filling the values in here */ - p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds; - p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds; - p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds; - p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds; - p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds; - - p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds; - - for(i=0;itoneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds; - return; -} - - -static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block, - compandblock *in, double *x){ - int i,is=s; - double ds=s-is; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy *p=ci->psy_param[block]; - - ds=x[is]*(1.-ds)+x[is+1]*ds; - is=(int)ds; - ds-=is; - if(ds==0 && is>0){ - is--; - ds=1.; - } - - /* interpolate the compander settings */ - for(i=0;inoisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds; - return; -} - -static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block, - int *suppress){ - int is=s; - double ds=s-is; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy *p=ci->psy_param[block]; - - p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds; - - return; -} - -static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block, - int *suppress, - noise3 *in, - noiseguard *guard, - double userbias){ - int i,is=s,j; - double ds=s-is; - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy *p=ci->psy_param[block]; - - p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds; - p->noisewindowlomin=guard[block].lo; - p->noisewindowhimin=guard[block].hi; - p->noisewindowfixed=guard[block].fixed; - - for(j=0;jnoiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds; - - /* impulse blocks may take a user specified bias to boost the - nominal/high noise encoding depth */ - for(j=0;jnoiseoff[j][0]+6; /* the lowest it can go */ - for(i=0;inoiseoff[j][i]+=userbias; - if(p->noiseoff[j][i]noiseoff[j][i]=min; - } - } - - return; -} - -static void vorbis_encode_ath_setup(vorbis_info *vi,int block){ - codec_setup_info *ci=vi->codec_setup; - vorbis_info_psy *p=ci->psy_param[block]; - - p->ath_adjatt=ci->hi.ath_floating_dB; - p->ath_maxatt=ci->hi.ath_absolute_dB; - return; -} - - -static int book_dup_or_new(codec_setup_info *ci,static_codebook *book){ - int i; - for(i=0;ibooks;i++) - if(ci->book_param[i]==book)return(i); - - return(ci->books++); -} - -static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s, - int *shortb,int *longb){ - - codec_setup_info *ci=vi->codec_setup; - int is=s; - - int blockshort=shortb[is]; - int blocklong=longb[is]; - ci->blocksizes[0]=blockshort; - ci->blocksizes[1]=blocklong; - -} - -static void vorbis_encode_residue_setup(vorbis_info *vi, - int number, int block, - vorbis_residue_template *res){ - - codec_setup_info *ci=vi->codec_setup; - int i,n; - - vorbis_info_residue0 *r=ci->residue_param[number]= - _ogg_malloc(sizeof(*r)); - - memcpy(r,res->res,sizeof(*r)); - if(ci->residues<=number)ci->residues=number+1; - - switch(ci->blocksizes[block]){ - case 64:case 128:case 256: - r->grouping=16; - break; - default: - r->grouping=32; - break; - } - ci->residue_type[number]=res->res_type; - - /* to be adjusted by lowpass/pointlimit later */ - n=r->end=ci->blocksizes[block]>>1; - if(res->res_type==2) - n=r->end*=vi->channels; - - /* fill in all the books */ - { - int booklist=0,k; - - if(ci->hi.managed){ - for(i=0;ipartitions;i++) - for(k=0;k<3;k++) - if(res->books_base_managed->books[i][k]) - r->secondstages[i]|=(1<groupbook=book_dup_or_new(ci,res->book_aux_managed); - ci->book_param[r->groupbook]=res->book_aux_managed; - - for(i=0;ipartitions;i++){ - for(k=0;k<3;k++){ - if(res->books_base_managed->books[i][k]){ - int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]); - r->booklist[booklist++]=bookid; - ci->book_param[bookid]=res->books_base_managed->books[i][k]; - } - } - } - - }else{ - - for(i=0;ipartitions;i++) - for(k=0;k<3;k++) - if(res->books_base->books[i][k]) - r->secondstages[i]|=(1<groupbook=book_dup_or_new(ci,res->book_aux); - ci->book_param[r->groupbook]=res->book_aux; - - for(i=0;ipartitions;i++){ - for(k=0;k<3;k++){ - if(res->books_base->books[i][k]){ - int bookid=book_dup_or_new(ci,res->books_base->books[i][k]); - r->booklist[booklist++]=bookid; - ci->book_param[bookid]=res->books_base->books[i][k]; - } - } - } - } - } - - /* lowpass setup/pointlimit */ - { - double freq=ci->hi.lowpass_kHz*1000.; - vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */ - double nyq=vi->rate/2.; - long blocksize=ci->blocksizes[block]>>1; - - /* lowpass needs to be set in the floor and the residue. */ - if(freq>nyq)freq=nyq; - /* in the floor, the granularity can be very fine; it doesn't alter - the encoding structure, only the samples used to fit the floor - approximation */ - f->n=freq/nyq*blocksize; - - /* this res may by limited by the maximum pointlimit of the mode, - not the lowpass. the floor is always lowpass limited. */ - if(res->limit_type){ - if(ci->hi.managed) - freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.; - else - freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.; - if(freq>nyq)freq=nyq; - } - - /* in the residue, we're constrained, physically, by partition - boundaries. We still lowpass 'wherever', but we have to round up - here to next boundary, or the vorbis spec will round it *down* to - previous boundary in encode/decode */ - if(ci->residue_type[block]==2) - r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */ - r->grouping; - else - r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ - r->grouping; - } -} - -/* we assume two maps in this encoder */ -static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s, - vorbis_mapping_template *maps){ - - codec_setup_info *ci=vi->codec_setup; - int i,j,is=s,modes=2; - vorbis_info_mapping0 *map=maps[is].map; - vorbis_info_mode *mode=_mode_template; - vorbis_residue_template *res=maps[is].res; - - if(ci->blocksizes[0]==ci->blocksizes[1])modes=1; - - for(i=0;imap_param[i]=_ogg_calloc(1,sizeof(*map)); - ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode)); - - memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template)); - if(i>=ci->modes)ci->modes=i+1; - - ci->map_type[i]=0; - memcpy(ci->map_param[i],map+i,sizeof(*map)); - if(i>=ci->maps)ci->maps=i+1; - - for(j=0;jcodec_setup; - highlevel_encode_setup *hi=&ci->hi; - ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup; - int is=hi->base_setting; - double ds=hi->base_setting-is; - int ch=vi->channels; - double *r=setup->rate_mapping; - - if(r==NULL) - return(-1); - - return((r[is]*(1.-ds)+r[is+1]*ds)*ch); -} - -static void get_setup_template(vorbis_info *vi, - long ch,long srate, - double req,int q_or_bitrate){ - int i=0,j; - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; - if(q_or_bitrate)req/=ch; - - while(setup_list[i]){ - if(setup_list[i]->coupling_restriction==-1 || - setup_list[i]->coupling_restriction==ch){ - if(srate>=setup_list[i]->samplerate_min_restriction && - srate<=setup_list[i]->samplerate_max_restriction){ - int mappings=setup_list[i]->mappings; - double *map=(q_or_bitrate? - setup_list[i]->rate_mapping: - setup_list[i]->quality_mapping); - - /* the template matches. Does the requested quality mode - fall within this template's modes? */ - if(reqmap[setup_list[i]->mappings]){++i;continue;} - for(j=0;j=map[j] && reqsetup=setup_list[i]; - if(j==mappings) - hi->base_setting=j-.001; - else{ - float low=map[j]; - float high=map[j+1]; - float del=(req-low)/(high-low); - hi->base_setting=j+del; - } - return; - } - } - i++; - } - - hi->setup=NULL; -} - -/* encoders will need to use vorbis_info_init beforehand and call - vorbis_info clear when all done */ - -/* two interfaces; this, more detailed one, and later a convenience - layer on top */ - -/* the final setup call */ -int vorbis_encode_setup_init(vorbis_info *vi){ - int i0=0,singleblock=0; - codec_setup_info *ci=vi->codec_setup; - ve_setup_data_template *setup=NULL; - highlevel_encode_setup *hi=&ci->hi; - - if(ci==NULL)return(OV_EINVAL); - if(!hi->impulse_block_p)i0=1; - - /* too low/high an ATH floater is nonsensical, but doesn't break anything */ - if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80; - if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200; - - /* again, bound this to avoid the app shooting itself int he foot - too badly */ - if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.; - if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.; - - /* get the appropriate setup template; matches the fetch in previous - stages */ - setup=(ve_setup_data_template *)hi->setup; - if(setup==NULL)return(OV_EINVAL); - - hi->set_in_stone=1; - /* choose block sizes from configured sizes as well as paying - attention to long_block_p and short_block_p. If the configured - short and long blocks are the same length, we set long_block_p - and unset short_block_p */ - vorbis_encode_blocksize_setup(vi,hi->base_setting, - setup->blocksize_short, - setup->blocksize_long); - if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1; - - /* floor setup; choose proper floor params. Allocated on the floor - stack in order; if we alloc only long floor, it's 0 */ - vorbis_encode_floor_setup(vi,hi->short_setting,0, - setup->floor_books, - setup->floor_params, - setup->floor_short_mapping); - if(!singleblock) - vorbis_encode_floor_setup(vi,hi->long_setting,1, - setup->floor_books, - setup->floor_params, - setup->floor_long_mapping); - - /* setup of [mostly] short block detection and stereo*/ - vorbis_encode_global_psych_setup(vi,hi->trigger_setting, - setup->global_params, - setup->global_mapping); - vorbis_encode_global_stereo(vi,hi,setup->stereo_modes); - - /* basic psych setup and noise normalization */ - vorbis_encode_psyset_setup(vi,hi->short_setting, - setup->psy_noise_normal_start[0], - setup->psy_noise_normal_partition[0], - setup->psy_noise_normal_thresh, - 0); - vorbis_encode_psyset_setup(vi,hi->short_setting, - setup->psy_noise_normal_start[0], - setup->psy_noise_normal_partition[0], - setup->psy_noise_normal_thresh, - 1); - if(!singleblock){ - vorbis_encode_psyset_setup(vi,hi->long_setting, - setup->psy_noise_normal_start[1], - setup->psy_noise_normal_partition[1], - setup->psy_noise_normal_thresh, - 2); - vorbis_encode_psyset_setup(vi,hi->long_setting, - setup->psy_noise_normal_start[1], - setup->psy_noise_normal_partition[1], - setup->psy_noise_normal_thresh, - 3); - } - - /* tone masking setup */ - vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0, - setup->psy_tone_masteratt, - setup->psy_tone_0dB, - setup->psy_tone_adj_impulse); - vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1, - setup->psy_tone_masteratt, - setup->psy_tone_0dB, - setup->psy_tone_adj_other); - if(!singleblock){ - vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2, - setup->psy_tone_masteratt, - setup->psy_tone_0dB, - setup->psy_tone_adj_other); - vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3, - setup->psy_tone_masteratt, - setup->psy_tone_0dB, - setup->psy_tone_adj_long); - } - - /* noise companding setup */ - vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0, - setup->psy_noise_compand, - setup->psy_noise_compand_short_mapping); - vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1, - setup->psy_noise_compand, - setup->psy_noise_compand_short_mapping); - if(!singleblock){ - vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2, - setup->psy_noise_compand, - setup->psy_noise_compand_long_mapping); - vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3, - setup->psy_noise_compand, - setup->psy_noise_compand_long_mapping); - } - - /* peak guarding setup */ - vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0, - setup->psy_tone_dBsuppress); - vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1, - setup->psy_tone_dBsuppress); - if(!singleblock){ - vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2, - setup->psy_tone_dBsuppress); - vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3, - setup->psy_tone_dBsuppress); - } - - /* noise bias setup */ - vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0, - setup->psy_noise_dBsuppress, - setup->psy_noise_bias_impulse, - setup->psy_noiseguards, - (i0==0?hi->impulse_noisetune:0.)); - vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1, - setup->psy_noise_dBsuppress, - setup->psy_noise_bias_padding, - setup->psy_noiseguards,0.); - if(!singleblock){ - vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2, - setup->psy_noise_dBsuppress, - setup->psy_noise_bias_trans, - setup->psy_noiseguards,0.); - vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3, - setup->psy_noise_dBsuppress, - setup->psy_noise_bias_long, - setup->psy_noiseguards,0.); - } - - vorbis_encode_ath_setup(vi,0); - vorbis_encode_ath_setup(vi,1); - if(!singleblock){ - vorbis_encode_ath_setup(vi,2); - vorbis_encode_ath_setup(vi,3); - } - - vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps); - - /* set bitrate readonlies and management */ - vi->bitrate_nominal=setting_to_approx_bitrate(vi); - vi->bitrate_lower=hi->bitrate_min; - vi->bitrate_upper=hi->bitrate_max; - vi->bitrate_window=hi->bitrate_limit_window; - - if(hi->managed){ - ci->bi.queue_avg_time=hi->bitrate_av_window; - ci->bi.queue_avg_center=hi->bitrate_av_window_center; - ci->bi.queue_minmax_time=hi->bitrate_limit_window; - ci->bi.queue_hardmin=hi->bitrate_min; - ci->bi.queue_hardmax=hi->bitrate_max; - ci->bi.queue_avgmin=hi->bitrate_av_lo; - ci->bi.queue_avgmax=hi->bitrate_av_hi; - ci->bi.avgfloat_downslew_max=-999999.f; - ci->bi.avgfloat_upslew_max=999999.f; - } - - return(0); - -} - -static int vorbis_encode_setup_setting(vorbis_info *vi, - long channels, - long rate){ - int ret=0,i,is; - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; - ve_setup_data_template *setup=hi->setup; - double ds; - - ret=vorbis_encode_toplevel_setup(vi,channels,rate); - if(ret)return(ret); - - is=hi->base_setting; - ds=hi->base_setting-is; - - hi->short_setting=hi->base_setting; - hi->long_setting=hi->base_setting; - - hi->managed=0; - - hi->impulse_block_p=1; - hi->noise_normalize_p=1; - - hi->stereo_point_setting=hi->base_setting; - hi->lowpass_kHz= - setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds; - - hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+ - setup->psy_ath_float[is+1]*ds; - hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+ - setup->psy_ath_abs[is+1]*ds; - - hi->amplitude_track_dBpersec=-6.; - hi->trigger_setting=hi->base_setting; - - for(i=0;i<4;i++){ - hi->block[i].tone_mask_setting=hi->base_setting; - hi->block[i].tone_peaklimit_setting=hi->base_setting; - hi->block[i].noise_bias_setting=hi->base_setting; - hi->block[i].noise_compand_setting=hi->base_setting; - } - - return(ret); -} - -int vorbis_encode_setup_vbr(vorbis_info *vi, - long channels, - long rate, - float quality){ - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; - - quality+=.00001; - if(quality>=1.)quality=.9999; - - get_setup_template(vi,channels,rate,quality,0); - if(!hi->setup)return OV_EIMPL; - - return vorbis_encode_setup_setting(vi,channels,rate); -} - -int vorbis_encode_init_vbr(vorbis_info *vi, - long channels, - long rate, - - float base_quality /* 0. to 1. */ - ){ - int ret=0; - - ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality); - - if(ret){ - vorbis_info_clear(vi); - return ret; - } - ret=vorbis_encode_setup_init(vi); - if(ret) - vorbis_info_clear(vi); - return(ret); -} - -int vorbis_encode_setup_managed(vorbis_info *vi, - long channels, - long rate, - - long max_bitrate, - long nominal_bitrate, - long min_bitrate){ - - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; - double tnominal=nominal_bitrate; - int ret=0; - - if(nominal_bitrate<=0.){ - if(max_bitrate>0.){ - nominal_bitrate=max_bitrate*.875; - }else{ - if(min_bitrate>0.){ - nominal_bitrate=min_bitrate; - }else{ - return(OV_EINVAL); - } - } - } - - get_setup_template(vi,channels,rate,nominal_bitrate,1); - if(!hi->setup)return OV_EIMPL; - - ret=vorbis_encode_setup_setting(vi,channels,rate); - if(ret){ - vorbis_info_clear(vi); - return ret; - } - - /* initialize management with sane defaults */ - /* initialize management with sane defaults */ - hi->managed=1; - hi->bitrate_av_window=4.; - hi->bitrate_av_window_center=.5; - hi->bitrate_limit_window=2.; - hi->bitrate_min=min_bitrate; - hi->bitrate_max=max_bitrate; - hi->bitrate_av_lo=tnominal; - hi->bitrate_av_hi=tnominal; - - return(ret); - -} - -int vorbis_encode_init(vorbis_info *vi, - long channels, - long rate, - - long max_bitrate, - long nominal_bitrate, - long min_bitrate){ - - int ret=vorbis_encode_setup_managed(vi,channels,rate, - max_bitrate, - nominal_bitrate, - min_bitrate); - if(ret){ - vorbis_info_clear(vi); - return(ret); - } - - ret=vorbis_encode_setup_init(vi); - if(ret) - vorbis_info_clear(vi); - return(ret); -} - -int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ - if(vi){ - codec_setup_info *ci=vi->codec_setup; - highlevel_encode_setup *hi=&ci->hi; - int setp=(number&0xf); /* a read request has a low nibble of 0 */ - - if(setp && hi->set_in_stone)return(OV_EINVAL); - - switch(number){ - case OV_ECTL_RATEMANAGE_GET: - { - - struct ovectl_ratemanage_arg *ai= - (struct ovectl_ratemanage_arg *)arg; - - ai->management_active=hi->managed; - ai->bitrate_av_window=hi->bitrate_av_window; - ai->bitrate_av_window_center=hi->bitrate_av_window_center; - ai->bitrate_hard_window=hi->bitrate_limit_window; - ai->bitrate_hard_min=hi->bitrate_min; - ai->bitrate_hard_max=hi->bitrate_max; - ai->bitrate_av_lo=hi->bitrate_av_lo; - ai->bitrate_av_hi=hi->bitrate_av_hi; - - } - return(0); - - case OV_ECTL_RATEMANAGE_SET: - { - struct ovectl_ratemanage_arg *ai= - (struct ovectl_ratemanage_arg *)arg; - if(ai==NULL){ - hi->managed=0; - }else{ - hi->managed=ai->management_active; - vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg); - vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg); - } - } - return 0; - - case OV_ECTL_RATEMANAGE_AVG: - { - struct ovectl_ratemanage_arg *ai= - (struct ovectl_ratemanage_arg *)arg; - if(ai==NULL){ - hi->bitrate_av_lo=0; - hi->bitrate_av_hi=0; - hi->bitrate_av_window=0; - }else{ - hi->bitrate_av_window=ai->bitrate_av_window; - hi->bitrate_av_window_center=ai->bitrate_av_window_center; - hi->bitrate_av_lo=ai->bitrate_av_lo; - hi->bitrate_av_hi=ai->bitrate_av_hi; - } - - if(hi->bitrate_av_window<.25)hi->bitrate_av_window=.25; - if(hi->bitrate_av_window>10.)hi->bitrate_av_window=10.; - if(hi->bitrate_av_window_center<0.)hi->bitrate_av_window=0.; - if(hi->bitrate_av_window_center>1.)hi->bitrate_av_window=1.; - - if( ( (hi->bitrate_av_lo<=0 && hi->bitrate_av_hi<=0)|| - (hi->bitrate_av_window<=0) ) && - ( (hi->bitrate_min<=0 && hi->bitrate_max<=0)|| - (hi->bitrate_limit_window<=0) )) - hi->managed=0; - } - return(0); - case OV_ECTL_RATEMANAGE_HARD: - { - struct ovectl_ratemanage_arg *ai= - (struct ovectl_ratemanage_arg *)arg; - if(ai==NULL){ - hi->bitrate_min=0; - hi->bitrate_max=0; - hi->bitrate_limit_window=0; - }else{ - hi->bitrate_limit_window=ai->bitrate_hard_window; - hi->bitrate_min=ai->bitrate_hard_min; - hi->bitrate_max=ai->bitrate_hard_max; - } - if(hi->bitrate_limit_window<0.)hi->bitrate_limit_window=0.; - if(hi->bitrate_limit_window>10.)hi->bitrate_limit_window=10.; - - if( ( (hi->bitrate_av_lo<=0 && hi->bitrate_av_hi<=0)|| - (hi->bitrate_av_window<=0) ) && - ( (hi->bitrate_min<=0 && hi->bitrate_max<=0)|| - (hi->bitrate_limit_window<=0) )) - hi->managed=0; - } - return(0); - - case OV_ECTL_LOWPASS_GET: - { - double *farg=(double *)arg; - *farg=hi->lowpass_kHz; - } - return(0); - case OV_ECTL_LOWPASS_SET: - { - double *farg=(double *)arg; - hi->lowpass_kHz=*farg; - - if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.; - if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.; - } - return(0); - case OV_ECTL_IBLOCK_GET: - { - double *farg=(double *)arg; - *farg=hi->impulse_noisetune; - } - return(0); - case OV_ECTL_IBLOCK_SET: - { - double *farg=(double *)arg; - hi->impulse_noisetune=*farg; - - if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.; - if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.; - } - return(0); - } - - - return(OV_EIMPL); - } - return(OV_EINVAL); -} diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/vorbisfile.c b/src/add-ons/media/plugins/vorbis/libvorbis/vorbisfile.c deleted file mode 100644 index e19d955567..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/vorbisfile.c +++ /dev/null @@ -1,1619 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include -#include -#include - -#include "vorbis/codec.h" -#include "vorbis/vorbisfile.h" - -#include "os.h" -#include "misc.h" - -/* A 'chained bitstream' is a Vorbis bitstream that contains more than - one logical bitstream arranged end to end (the only form of Ogg - multiplexing allowed in a Vorbis bitstream; grouping [parallel - multiplexing] is not allowed in Vorbis) */ - -/* A Vorbis file can be played beginning to end (streamed) without - worrying ahead of time about chaining (see decoder_example.c). If - we have the whole file, however, and want random access - (seeking/scrubbing) or desire to know the total length/time of a - file, we need to account for the possibility of chaining. */ - -/* We can handle things a number of ways; we can determine the entire - bitstream structure right off the bat, or find pieces on demand. - This example determines and caches structure for the entire - bitstream, but builds a virtual decoder on the fly when moving - between links in the chain. */ - -/* There are also different ways to implement seeking. Enough - information exists in an Ogg bitstream to seek to - sample-granularity positions in the output. Or, one can seek by - picking some portion of the stream roughly in the desired area if - we only want coarse navigation through the stream. */ - -/************************************************************************* - * Many, many internal helpers. The intention is not to be confusing; - * rampant duplication and monolithic function implementation would be - * harder to understand anyway. The high level functions are last. Begin - * grokking near the end of the file */ - -/* read a little more data from the file/pipe into the ogg_sync framer -*/ -#define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well - over 8k gets what they deserve */ -static long _get_data(OggVorbis_File *vf){ - errno=0; - if(vf->datasource){ - char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE); - long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); - if(bytes>0)ogg_sync_wrote(&vf->oy,bytes); - if(bytes==0 && errno)return(-1); - return(bytes); - }else - return(0); -} - -/* save a tiny smidge of verbosity to make the code more readable */ -static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){ - if(vf->datasource){ - (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET); - vf->offset=offset; - ogg_sync_reset(&vf->oy); - }else{ - /* shouldn't happen unless someone writes a broken callback */ - return; - } -} - -/* The read/seek functions track absolute position within the stream */ - -/* from the head of the stream, get the next page. boundary specifies - if the function is allowed to fetch more data from the stream (and - how much) or only use internally buffered data. - - boundary: -1) unbounded search - 0) read no additional data; use cached only - n) search for a new page beginning for n bytes - - return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD) - n) found a page at absolute offset n */ - -static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, - ogg_int64_t boundary){ - if(boundary>0)boundary+=vf->offset; - while(1){ - long more; - - if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); - more=ogg_sync_pageseek(&vf->oy,og); - - if(more<0){ - /* skipped n bytes */ - vf->offset-=more; - }else{ - if(more==0){ - /* send more paramedics */ - if(!boundary)return(OV_FALSE); - { - long ret=_get_data(vf); - if(ret==0)return(OV_EOF); - if(ret<0)return(OV_EREAD); - } - }else{ - /* got a page. Return the offset at the page beginning, - advance the internal offset past the page end */ - ogg_int64_t ret=vf->offset; - vf->offset+=more; - return(ret); - - } - } - } -} - -/* find the latest page beginning before the current stream cursor - position. Much dirtier than the above as Ogg doesn't have any - backward search linkage. no 'readp' as it will certainly have to - read. */ -/* returns offset or OV_EREAD, OV_FAULT */ -static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){ - ogg_int64_t begin=vf->offset; - ogg_int64_t end=begin; - ogg_int64_t ret; - ogg_int64_t offset=-1; - - while(offset==-1){ - begin-=CHUNKSIZE; - if(begin<0) - begin=0; - _seek_helper(vf,begin); - while(vf->offsetoffset); - if(ret==OV_EREAD)return(OV_EREAD); - if(ret<0){ - break; - }else{ - offset=ret; - } - } - } - - /* we have the offset. Actually snork and hold the page now */ - _seek_helper(vf,offset); - ret=_get_next_page(vf,og,CHUNKSIZE); - if(ret<0) - /* this shouldn't be possible */ - return(OV_EFAULT); - - return(offset); -} - -/* finds each bitstream link one at a time using a bisection search - (has to begin by knowing the offset of the lb's initial page). - Recurses for each link so it can alloc the link storage after - finding them all, then unroll and fill the cache at the same time */ -static int _bisect_forward_serialno(OggVorbis_File *vf, - ogg_int64_t begin, - ogg_int64_t searched, - ogg_int64_t end, - long currentno, - long m){ - ogg_int64_t endsearched=end; - ogg_int64_t next=end; - ogg_page og; - ogg_int64_t ret; - - /* the below guards against garbage seperating the last and - first pages of two links. */ - while(searched=0)next=ret; - }else{ - searched=ret+og.header_len+og.body_len; - } - } - - _seek_helper(vf,next); - ret=_get_next_page(vf,&og,-1); - if(ret==OV_EREAD)return(OV_EREAD); - - if(searched>=end || ret<0){ - vf->links=m+1; - vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); - vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); - vf->offsets[m+1]=searched; - }else{ - ret=_bisect_forward_serialno(vf,next,vf->offset, - end,ogg_page_serialno(&og),m+1); - if(ret==OV_EREAD)return(OV_EREAD); - } - - vf->offsets[m]=begin; - vf->serialnos[m]=currentno; - return(0); -} - -/* uses the local ogg_stream storage in vf; this is important for - non-streaming input sources */ -static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, - long *serialno,ogg_page *og_ptr){ - ogg_page og; - ogg_packet op; - int i,ret; - - if(!og_ptr){ - ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE); - if(llret==OV_EREAD)return(OV_EREAD); - if(llret<0)return OV_ENOTVORBIS; - og_ptr=&og; - } - - ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); - if(serialno)*serialno=vf->os.serialno; - vf->ready_state=STREAMSET; - - /* extract the initial header from the first page and verify that the - Ogg bitstream is in fact Vorbis data */ - - vorbis_info_init(vi); - vorbis_comment_init(vc); - - i=0; - while(i<3){ - ogg_stream_pagein(&vf->os,og_ptr); - while(i<3){ - int result=ogg_stream_packetout(&vf->os,&op); - if(result==0)break; - if(result==-1){ - ret=OV_EBADHEADER; - goto bail_header; - } - if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ - goto bail_header; - } - i++; - } - if(i<3) - if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){ - ret=OV_EBADHEADER; - goto bail_header; - } - } - return 0; - - bail_header: - vorbis_info_clear(vi); - vorbis_comment_clear(vc); - vf->ready_state=OPENED; - - return ret; -} - -/* last step of the OggVorbis_File initialization; get all the - vorbis_info structs and PCM positions. Only called by the seekable - initialization (local stream storage is hacked slightly; pay - attention to how that's done) */ - -/* this is void and does not propogate errors up because we want to be - able to open and use damaged bitstreams as well as we can. Just - watch out for missing information for links in the OggVorbis_File - struct */ -static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){ - ogg_page og; - int i; - ogg_int64_t ret; - - vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); - vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); - vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); - vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); - - for(i=0;ilinks;i++){ - if(i==0){ - /* we already grabbed the initial header earlier. Just set the offset */ - vf->dataoffsets[i]=dataoffset; - _seek_helper(vf,dataoffset); - - }else{ - - /* seek to the location of the initial header */ - - _seek_helper(vf,vf->offsets[i]); - if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){ - vf->dataoffsets[i]=-1; - }else{ - vf->dataoffsets[i]=vf->offset; - } - } - - /* fetch beginning PCM offset */ - - if(vf->dataoffsets[i]!=-1){ - ogg_int64_t accumulated=0; - long lastblock=-1; - int result; - - ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]); - - while(1){ - ogg_packet op; - - ret=_get_next_page(vf,&og,-1); - if(ret<0) - /* this should not be possible unless the file is - truncated/mangled */ - break; - - if(ogg_page_serialno(&og)!=vf->serialnos[i]) - break; - - /* count blocksizes of all frames in the page */ - ogg_stream_pagein(&vf->os,&og); - while((result=ogg_stream_packetout(&vf->os,&op))){ - if(result>0){ /* ignore holes */ - long thisblock=vorbis_packet_blocksize(vf->vi+i,&op); - if(lastblock!=-1) - accumulated+=(lastblock+thisblock)>>2; - lastblock=thisblock; - } - } - - if(ogg_page_granulepos(&og)!=-1){ - /* pcm offset of last packet on the first audio page */ - accumulated= ogg_page_granulepos(&og)-accumulated; - break; - } - } - - /* less than zero? This is a stream with samples trimmed off - the beginning, a normal occurrence; set the offset to zero */ - if(accumulated<0)accumulated=0; - - vf->pcmlengths[i*2]=accumulated; - } - - /* get the PCM length of this link. To do this, - get the last page of the stream */ - { - ogg_int64_t end=vf->offsets[i+1]; - _seek_helper(vf,end); - - while(1){ - ret=_get_prev_page(vf,&og); - if(ret<0){ - /* this should not be possible */ - vorbis_info_clear(vf->vi+i); - vorbis_comment_clear(vf->vc+i); - break; - } - if(ogg_page_granulepos(&og)!=-1){ - vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2]; - break; - } - vf->offset=ret; - } - } - } -} - -static void _make_decode_ready(OggVorbis_File *vf){ - if(vf->ready_state!=STREAMSET)return; - if(vf->seekable){ - vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link); - }else{ - vorbis_synthesis_init(&vf->vd,vf->vi); - } - vorbis_block_init(&vf->vd,&vf->vb); - vf->ready_state=INITSET; - return; -} - -static int _open_seekable2(OggVorbis_File *vf){ - long serialno=vf->current_serialno; - ogg_int64_t dataoffset=vf->offset, end; - ogg_page og; - - /* we're partially open and have a first link header state in - storage in vf */ - /* we can seek, so set out learning all about this file */ - (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END); - vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource); - - /* We get the offset for the last page of the physical bitstream. - Most OggVorbis files will contain a single logical bitstream */ - end=_get_prev_page(vf,&og); - if(end<0)return(end); - - /* more than one logical bitstream? */ - if(ogg_page_serialno(&og)!=serialno){ - - /* Chained bitstream. Bisect-search each logical bitstream - section. Do so based on serial number only */ - if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD); - - }else{ - - /* Only one logical bitstream */ - if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD); - - } - - /* the initial header memory is referenced by vf after; don't free it */ - _prefetch_all_headers(vf,dataoffset); - return(ov_raw_seek(vf,0)); -} - -/* clear out the current logical bitstream decoder */ -static void _decode_clear(OggVorbis_File *vf){ - vorbis_dsp_clear(&vf->vd); - vorbis_block_clear(&vf->vb); - vf->ready_state=OPENED; - - vf->bittrack=0.f; - vf->samptrack=0.f; -} - -/* fetch and process a packet. Handles the case where we're at a - bitstream boundary and dumps the decoding machine. If the decoding - machine is unloaded, it loads it. It also keeps pcm_offset up to - date (seek and read both use this. seek uses a special hack with - readp). - - return: <0) error, OV_HOLE (lost packet) or OV_EOF - 0) need more data (only if readp==0) - 1) got a packet -*/ - -static int _fetch_and_process_packet(OggVorbis_File *vf, - ogg_packet *op_in, - int readp){ - ogg_page og; - - /* handle one packet. Try to fetch it from current stream state */ - /* extract packets from page */ - while(1){ - - /* process a packet if we can. If the machine isn't loaded, - neither is a page */ - if(vf->ready_state==INITSET){ - while(1) { - ogg_packet op; - ogg_packet *op_ptr=(op_in?op_in:&op); - int result=ogg_stream_packetout(&vf->os,op_ptr); - ogg_int64_t granulepos; - - op_in=NULL; - if(result==-1)return(OV_HOLE); /* hole in the data. */ - if(result>0){ - /* got a packet. process it */ - granulepos=op_ptr->granulepos; - if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy - header handling. The - header packets aren't - audio, so if/when we - submit them, - vorbis_synthesis will - reject them */ - - /* suck in the synthesis data and track bitrate */ - { - int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL); - /* for proper use of libvorbis within libvorbisfile, - oldsamples will always be zero. */ - if(oldsamples)return(OV_EFAULT); - - vorbis_synthesis_blockin(&vf->vd,&vf->vb); - vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; - vf->bittrack+=op_ptr->bytes*8; - } - - /* update the pcm offset. */ - if(granulepos!=-1 && !op_ptr->e_o_s){ - int link=(vf->seekable?vf->current_link:0); - int i,samples; - - /* this packet has a pcm_offset on it (the last packet - completed on a page carries the offset) After processing - (above), we know the pcm position of the *last* sample - ready to be returned. Find the offset of the *first* - - As an aside, this trick is inaccurate if we begin - reading anew right at the last page; the end-of-stream - granulepos declares the last frame in the stream, and the - last packet of the last page may be a partial frame. - So, we need a previous granulepos from an in-sequence page - to have a reference point. Thus the !op_ptr->e_o_s clause - above */ - - if(vf->seekable && link>0) - granulepos-=vf->pcmlengths[link*2]; - if(granulepos<0)granulepos=0; /* actually, this - shouldn't be possible - here unless the stream - is very broken */ - - samples=vorbis_synthesis_pcmout(&vf->vd,NULL); - - granulepos-=samples; - for(i=0;ipcmlengths[i*2+1]; - vf->pcm_offset=granulepos; - } - return(1); - } - } - else - break; - } - } - - if(vf->ready_state>=OPENED){ - if(!readp)return(0); - if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. - leave unitialized */ - /* bitrate tracking; add the header's bytes here, the body bytes - are done by packet above */ - vf->bittrack+=og.header_len*8; - - /* has our decoding just traversed a bitstream boundary? */ - if(vf->ready_state==INITSET){ - if(vf->current_serialno!=ogg_page_serialno(&og)){ - _decode_clear(vf); - - if(!vf->seekable){ - vorbis_info_clear(vf->vi); - vorbis_comment_clear(vf->vc); - } - } - } - } - - /* Do we need to load a new machine before submitting the page? */ - /* This is different in the seekable and non-seekable cases. - - In the seekable case, we already have all the header - information loaded and cached; we just initialize the machine - with it and continue on our merry way. - - In the non-seekable (streaming) case, we'll only be at a - boundary if we just left the previous logical bitstream and - we're now nominally at the header of the next bitstream - */ - - if(vf->ready_state!=INITSET){ - int link; - - if(vf->ready_stateseekable){ - vf->current_serialno=ogg_page_serialno(&og); - - /* match the serialno to bitstream section. We use this rather than - offset positions to avoid problems near logical bitstream - boundaries */ - for(link=0;linklinks;link++) - if(vf->serialnos[link]==vf->current_serialno)break; - if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus - stream. error out, - leave machine - uninitialized */ - - vf->current_link=link; - - ogg_stream_reset_serialno(&vf->os,vf->current_serialno); - vf->ready_state=STREAMSET; - - }else{ - /* we're streaming */ - /* fetch the three header packets, build the info struct */ - - int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og); - if(ret)return(ret); - vf->current_link++; - link=0; - } - } - - _make_decode_ready(vf); - } - ogg_stream_pagein(&vf->os,&og); - } -} - -/* if, eg, 64 bit stdio is configured by default, this will build with - fseek64 */ -static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){ - if(f==NULL)return(-1); - return fseek(f,off,whence); -} - -static int _ov_open1(void *f,OggVorbis_File *vf,char *initial, - long ibytes, ov_callbacks callbacks){ - int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1); - int ret; - - memset(vf,0,sizeof(*vf)); - vf->datasource=f; - vf->callbacks = callbacks; - - /* init the framing state */ - ogg_sync_init(&vf->oy); - - /* perhaps some data was previously read into a buffer for testing - against other stream types. Allow initialization from this - previously read data (as we may be reading from a non-seekable - stream) */ - if(initial){ - char *buffer=ogg_sync_buffer(&vf->oy,ibytes); - memcpy(buffer,initial,ibytes); - ogg_sync_wrote(&vf->oy,ibytes); - } - - /* can we seek? Stevens suggests the seek test was portable */ - if(offsettest!=-1)vf->seekable=1; - - /* No seeking yet; Set up a 'single' (current) logical bitstream - entry for partial open */ - vf->links=1; - vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); - vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); - ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ - - /* Try to fetch the headers, maintaining all the storage */ - if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){ - vf->datasource=NULL; - ov_clear(vf); - }else if(vf->ready_state < PARTOPEN) - vf->ready_state=PARTOPEN; - return(ret); -} - -static int _ov_open2(OggVorbis_File *vf){ - if(vf->ready_state < OPENED) - vf->ready_state=OPENED; - if(vf->seekable){ - int ret=_open_seekable2(vf); - if(ret){ - vf->datasource=NULL; - ov_clear(vf); - } - return(ret); - } - return 0; -} - - -/* clear out the OggVorbis_File struct */ -int ov_clear(OggVorbis_File *vf){ - if(vf){ - vorbis_block_clear(&vf->vb); - vorbis_dsp_clear(&vf->vd); - ogg_stream_clear(&vf->os); - - if(vf->vi && vf->links){ - int i; - for(i=0;ilinks;i++){ - vorbis_info_clear(vf->vi+i); - vorbis_comment_clear(vf->vc+i); - } - _ogg_free(vf->vi); - _ogg_free(vf->vc); - } - if(vf->dataoffsets)_ogg_free(vf->dataoffsets); - if(vf->pcmlengths)_ogg_free(vf->pcmlengths); - if(vf->serialnos)_ogg_free(vf->serialnos); - if(vf->offsets)_ogg_free(vf->offsets); - ogg_sync_clear(&vf->oy); - if(vf->datasource)(vf->callbacks.close_func)(vf->datasource); - memset(vf,0,sizeof(*vf)); - } -#ifdef DEBUG_LEAKS - _VDBG_dump(); -#endif - return(0); -} - -/* inspects the OggVorbis file and finds/documents all the logical - bitstreams contained in it. Tries to be tolerant of logical - bitstream sections that are truncated/woogie. - - return: -1) error - 0) OK -*/ - -int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, - ov_callbacks callbacks){ - int ret=_ov_open1(f,vf,initial,ibytes,callbacks); - if(ret)return ret; - return _ov_open2(vf); -} - -int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ - ov_callbacks callbacks = { - (size_t (*)(void *, size_t, size_t, void *)) fread, - (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, - (int (*)(void *)) fclose, - (long (*)(void *)) ftell - }; - - return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks); -} - -/* Only partially open the vorbis file; test for Vorbisness, and load - the headers for the first chain. Do not seek (although test for - seekability). Use ov_test_open to finish opening the file, else - ov_clear to close/free it. Same return codes as open. */ - -int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, - ov_callbacks callbacks) -{ - return _ov_open1(f,vf,initial,ibytes,callbacks); -} - -int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ - ov_callbacks callbacks = { - (size_t (*)(void *, size_t, size_t, void *)) fread, - (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, - (int (*)(void *)) fclose, - (long (*)(void *)) ftell - }; - - return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks); -} - -int ov_test_open(OggVorbis_File *vf){ - if(vf->ready_state!=PARTOPEN)return(OV_EINVAL); - return _ov_open2(vf); -} - -/* How many logical bitstreams in this physical bitstream? */ -long ov_streams(OggVorbis_File *vf){ - return vf->links; -} - -/* Is the FILE * associated with vf seekable? */ -long ov_seekable(OggVorbis_File *vf){ - return vf->seekable; -} - -/* returns the bitrate for a given logical bitstream or the entire - physical bitstream. If the file is open for random access, it will - find the *actual* average bitrate. If the file is streaming, it - returns the nominal bitrate (if set) else the average of the - upper/lower bounds (if set) else -1 (unset). - - If you want the actual bitrate field settings, get them from the - vorbis_info structs */ - -long ov_bitrate(OggVorbis_File *vf,int i){ - if(vf->ready_state=vf->links)return(OV_EINVAL); - if(!vf->seekable && i!=0)return(ov_bitrate(vf,0)); - if(i<0){ - ogg_int64_t bits=0; - int i; - for(i=0;ilinks;i++) - bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8; - return(rint(bits/ov_time_total(vf,-1))); - }else{ - if(vf->seekable){ - /* return the actual bitrate */ - return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i))); - }else{ - /* return nominal if set */ - if(vf->vi[i].bitrate_nominal>0){ - return vf->vi[i].bitrate_nominal; - }else{ - if(vf->vi[i].bitrate_upper>0){ - if(vf->vi[i].bitrate_lower>0){ - return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2; - }else{ - return vf->vi[i].bitrate_upper; - } - } - return(OV_FALSE); - } - } - } -} - -/* returns the actual bitrate since last call. returns -1 if no - additional data to offer since last call (or at beginning of stream), - EINVAL if stream is only partially open -*/ -long ov_bitrate_instant(OggVorbis_File *vf){ - int link=(vf->seekable?vf->current_link:0); - long ret; - if(vf->ready_statesamptrack==0)return(OV_FALSE); - ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5; - vf->bittrack=0.f; - vf->samptrack=0.f; - return(ret); -} - -/* Guess */ -long ov_serialnumber(OggVorbis_File *vf,int i){ - if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1)); - if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1)); - if(i<0){ - return(vf->current_serialno); - }else{ - return(vf->serialnos[i]); - } -} - -/* returns: total raw (compressed) length of content if i==-1 - raw (compressed) length of that logical bitstream for i==0 to n - OV_EINVAL if the stream is not seekable (we can't know the length) - or if stream is only partially open -*/ -ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){ - if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); - if(i<0){ - ogg_int64_t acc=0; - int i; - for(i=0;ilinks;i++) - acc+=ov_raw_total(vf,i); - return(acc); - }else{ - return(vf->offsets[i+1]-vf->offsets[i]); - } -} - -/* returns: total PCM length (samples) of content if i==-1 PCM length - (samples) of that logical bitstream for i==0 to n - OV_EINVAL if the stream is not seekable (we can't know the - length) or only partially open -*/ -ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){ - if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); - if(i<0){ - ogg_int64_t acc=0; - int i; - for(i=0;ilinks;i++) - acc+=ov_pcm_total(vf,i); - return(acc); - }else{ - return(vf->pcmlengths[i*2+1]); - } -} - -/* returns: total seconds of content if i==-1 - seconds in that logical bitstream for i==0 to n - OV_EINVAL if the stream is not seekable (we can't know the - length) or only partially open -*/ -double ov_time_total(OggVorbis_File *vf,int i){ - if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); - if(i<0){ - double acc=0; - int i; - for(i=0;ilinks;i++) - acc+=ov_time_total(vf,i); - return(acc); - }else{ - return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate); - } -} - -/* seek to an offset relative to the *compressed* data. This also - scans packets to update the PCM cursor. It will cross a logical - bitstream boundary, but only if it can't get any packets out of the - tail of the bitstream we seek to (so no surprises). - - returns zero on success, nonzero on failure */ - -int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ - ogg_stream_state work_os; - - if(vf->ready_stateseekable) - return(OV_ENOSEEK); /* don't dump machine if we can't seek */ - - if(pos<0 || pos>vf->end)return(OV_EINVAL); - - /* clear out decoding machine state */ - vf->pcm_offset=-1; - _decode_clear(vf); - - _seek_helper(vf,pos); - - /* we need to make sure the pcm_offset is set, but we don't want to - advance the raw cursor past good packets just to get to the first - with a granulepos. That's not equivalent behavior to beginning - decoding as immediately after the seek position as possible. - - So, a hack. We use two stream states; a local scratch state and - a the shared vf->os stream state. We use the local state to - scan, and the shared state as a buffer for later decode. - - Unfortuantely, on the last page we still advance to last packet - because the granulepos on the last page is not necessarily on a - packet boundary, and we need to make sure the granpos is - correct. - */ - - { - ogg_page og; - ogg_packet op; - int lastblock=0; - int accblock=0; - int thisblock; - int eosflag; - - ogg_stream_init(&work_os,-1); /* get the memory ready */ - - while(1){ - if(vf->ready_state==STREAMSET){ - /* snarf/scan a packet if we can */ - int result=ogg_stream_packetout(&work_os,&op); - - if(result>0){ - - if(vf->vi[vf->current_link].codec_setup) - thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); - if(eosflag) - ogg_stream_packetout(&vf->os,NULL); - else - if(lastblock)accblock+=(lastblock+thisblock)>>2; - - if(op.granulepos!=-1){ - int i,link=vf->current_link; - ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2]; - if(granulepos<0)granulepos=0; - - for(i=0;ipcmlengths[i*2+1]; - vf->pcm_offset=granulepos-accblock; - break; - } - lastblock=thisblock; - continue; - } - } - - if(!lastblock){ - if(_get_next_page(vf,&og,-1)<0){ - vf->pcm_offset=ov_pcm_total(vf,-1); - break; - } - }else{ - /* huh? Bogus stream with packets but no granulepos */ - vf->pcm_offset=-1; - break; - } - - /* has our decoding just traversed a bitstream boundary? */ - if(vf->ready_state==STREAMSET) - if(vf->current_serialno!=ogg_page_serialno(&og)){ - _decode_clear(vf); /* clear out stream state */ - ogg_stream_clear(&work_os); - } - - if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); - for(link=0;linklinks;link++) - if(vf->serialnos[link]==vf->current_serialno)break; - if(link==vf->links)goto seek_error; /* sign of a bogus stream. - error out, leave - machine uninitialized */ - vf->current_link=link; - - ogg_stream_reset_serialno(&vf->os,vf->current_serialno); - ogg_stream_reset_serialno(&work_os,vf->current_serialno); - vf->ready_state=STREAMSET; - - } - - ogg_stream_pagein(&vf->os,&og); - ogg_stream_pagein(&work_os,&og); - eosflag=ogg_page_eos(&og); - } - } - - ogg_stream_clear(&work_os); - return(0); - - seek_error: - /* dump the machine so we're in a known state */ - vf->pcm_offset=-1; - ogg_stream_clear(&work_os); - _decode_clear(vf); - return OV_EBADLINK; -} - -/* Page granularity seek (faster than sample granularity because we - don't do the last bit of decode to find a specific sample). - - Seek to the last [granule marked] page preceeding the specified pos - location, such that decoding past the returned point will quickly - arrive at the requested position. */ -int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ - int link=-1; - ogg_int64_t result=0; - ogg_int64_t total=ov_pcm_total(vf,-1); - - if(vf->ready_stateseekable)return(OV_ENOSEEK); - - if(pos<0 || pos>total)return(OV_EINVAL); - - /* which bitstream section does this pcm offset occur in? */ - for(link=vf->links-1;link>=0;link--){ - total-=vf->pcmlengths[link*2+1]; - if(pos>=total)break; - } - - /* search within the logical bitstream for the page with the highest - pcm_pos preceeding (or equal to) pos. There is a danger here; - missing pages or incorrect frame number information in the - bitstream could make our task impossible. Account for that (it - would be an error condition) */ - - /* new search algorithm by HB (Nicholas Vinen) */ - { - ogg_int64_t end=vf->offsets[link+1]; - ogg_int64_t begin=vf->offsets[link]; - ogg_int64_t begintime = vf->pcmlengths[link*2]; - ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime; - ogg_int64_t target=pos-total+begintime; - ogg_int64_t best=begin; - - ogg_page og; - while(beginoffset); - if(result==OV_EREAD) goto seek_error; - if(result<0){ - if(bisect<=begin+1) - end=begin; /* found it */ - else{ - if(bisect==0) goto seek_error; - bisect-=CHUNKSIZE; - if(bisect<=begin)bisect=begin+1; - _seek_helper(vf,bisect); - } - }else{ - ogg_int64_t granulepos=ogg_page_granulepos(&og); - if(granulepos==-1)continue; - if(granuleposoffset; /* raw offset of next page */ - begintime=granulepos; - - if(target-begintime>44100)break; - bisect=begin; /* *not* begin + 1 */ - }else{ - if(bisect<=begin+1) - end=begin; /* found it */ - else{ - if(end==vf->offset){ /* we're pretty close - we'd be stuck in */ - end=result; - bisect-=CHUNKSIZE; /* an endless loop otherwise. */ - if(bisect<=begin)bisect=begin+1; - _seek_helper(vf,bisect); - }else{ - end=result; - endtime=granulepos; - break; - } - } - } - } - } - } - - /* found our page. seek to it, update pcm offset. Easier case than - raw_seek, don't keep packets preceeding granulepos. */ - { - ogg_page og; - ogg_packet op; - /* clear out decoding machine state */ - _decode_clear(vf); - /* seek */ - _seek_helper(vf,best); - - if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */ - vf->current_serialno=ogg_page_serialno(&og); - vf->current_link=link; - - ogg_stream_reset_serialno(&vf->os,vf->current_serialno); - vf->ready_state=STREAMSET; - ogg_stream_pagein(&vf->os,&og); - - /* pull out all but last packet; the one with granulepos */ - while(1){ - result=ogg_stream_packetpeek(&vf->os,&op); - if(result==0){ - /* !!! the packet finishing this page originated on a - preceeding page. Keep fetching previous pages until we - get one with a granulepos or without the 'continued' flag - set. Then just use raw_seek for simplicity. */ - - _decode_clear(vf); - _seek_helper(vf,best); - - while(1){ - result=_get_prev_page(vf,&og); - if(result<0) goto seek_error; - if(ogg_page_granulepos(&og)>-1 || - !ogg_page_continued(&og)){ - return ov_raw_seek(vf,result); - } - vf->offset=result; - } - } - if(result<0){ - result = OV_EBADPACKET; - goto seek_error; - } - if(op.granulepos!=-1){ - vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; - if(vf->pcm_offset<0)vf->pcm_offset=0; - vf->pcm_offset+=total; - break; - }else - result=ogg_stream_packetout(&vf->os,NULL); - } - } - } - - /* verify result */ - if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){ - result=OV_EFAULT; - goto seek_error; - } - return(0); - - seek_error: - /* dump machine so we're in a known state */ - vf->pcm_offset=-1; - _decode_clear(vf); - return (int)result; -} - -/* seek to a sample offset relative to the decompressed pcm stream - returns zero on success, nonzero on failure */ - -int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ - int thisblock,lastblock=0; - int ret=ov_pcm_seek_page(vf,pos); - if(ret<0)return(ret); - _make_decode_ready(vf); - - /* discard leading packets we don't need for the lapping of the - position we want; don't decode them */ - - while(1){ - ogg_packet op; - ogg_page og; - - int ret=ogg_stream_packetpeek(&vf->os,&op); - if(ret>0){ - thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); - if(thisblock<0)thisblock=0; /* non audio packet */ - if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2; - - if(vf->pcm_offset+((thisblock+ - vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break; - - /* remove the packet from packet queue and track its granulepos */ - ogg_stream_packetout(&vf->os,NULL); - vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with - only tracking, no - pcm_decode */ - vorbis_synthesis_blockin(&vf->vd,&vf->vb); - - /* end of logical stream case is hard, especially with exact - length positioning. */ - - if(op.granulepos>-1){ - int i; - /* always believe the stream markers */ - vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; - if(vf->pcm_offset<0)vf->pcm_offset=0; - for(i=0;icurrent_link;i++) - vf->pcm_offset+=vf->pcmlengths[i*2+1]; - } - - lastblock=thisblock; - - }else{ - if(ret<0 && ret!=OV_HOLE)break; - - /* suck in a new page */ - if(_get_next_page(vf,&og,-1)<0)break; - if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf); - - if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); - for(link=0;linklinks;link++) - if(vf->serialnos[link]==vf->current_serialno)break; - if(link==vf->links)return(OV_EBADLINK); - vf->current_link=link; - - ogg_stream_reset_serialno(&vf->os,vf->current_serialno); - vf->ready_state=STREAMSET; - _make_decode_ready(vf); - lastblock=0; - } - - ogg_stream_pagein(&vf->os,&og); - } - } - - /* discard samples until we reach the desired position. Crossing a - logical bitstream boundary with abandon is OK. */ - while(vf->pcm_offsetpcm_offset; - long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); - - if(samples>target)samples=target; - vorbis_synthesis_read(&vf->vd,samples); - vf->pcm_offset+=samples; - - if(samplespcm_offset=ov_pcm_total(vf,-1); /* eof */ - } - return 0; -} - -/* seek to a playback time relative to the decompressed pcm stream - returns zero on success, nonzero on failure */ -int ov_time_seek(OggVorbis_File *vf,double seconds){ - /* translate time to PCM position and call ov_pcm_seek */ - - int link=-1; - ogg_int64_t pcm_total=ov_pcm_total(vf,-1); - double time_total=ov_time_total(vf,-1); - - if(vf->ready_stateseekable)return(OV_ENOSEEK); - if(seconds<0 || seconds>time_total)return(OV_EINVAL); - - /* which bitstream section does this time offset occur in? */ - for(link=vf->links-1;link>=0;link--){ - pcm_total-=vf->pcmlengths[link*2+1]; - time_total-=ov_time_total(vf,link); - if(seconds>=time_total)break; - } - - /* enough information to convert time offset to pcm offset */ - { - ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate; - return(ov_pcm_seek(vf,target)); - } -} - -/* page-granularity version of ov_time_seek - returns zero on success, nonzero on failure */ -int ov_time_seek_page(OggVorbis_File *vf,double seconds){ - /* translate time to PCM position and call ov_pcm_seek */ - - int link=-1; - ogg_int64_t pcm_total=ov_pcm_total(vf,-1); - double time_total=ov_time_total(vf,-1); - - if(vf->ready_stateseekable)return(OV_ENOSEEK); - if(seconds<0 || seconds>time_total)return(OV_EINVAL); - - /* which bitstream section does this time offset occur in? */ - for(link=vf->links-1;link>=0;link--){ - pcm_total-=vf->pcmlengths[link*2+1]; - time_total-=ov_time_total(vf,link); - if(seconds>=time_total)break; - } - - /* enough information to convert time offset to pcm offset */ - { - ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate; - return(ov_pcm_seek_page(vf,target)); - } -} - -/* tell the current stream offset cursor. Note that seek followed by - tell will likely not give the set offset due to caching */ -ogg_int64_t ov_raw_tell(OggVorbis_File *vf){ - if(vf->ready_stateoffset); -} - -/* return PCM offset (sample) of next PCM sample to be read */ -ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){ - if(vf->ready_statepcm_offset); -} - -/* return time offset (seconds) of next PCM sample to be read */ -double ov_time_tell(OggVorbis_File *vf){ - /* translate time to PCM position and call ov_pcm_seek */ - - int link=-1; - ogg_int64_t pcm_total=0; - double time_total=0.f; - - if(vf->ready_stateseekable){ - pcm_total=ov_pcm_total(vf,-1); - time_total=ov_time_total(vf,-1); - - /* which bitstream section does this time offset occur in? */ - for(link=vf->links-1;link>=0;link--){ - pcm_total-=vf->pcmlengths[link*2+1]; - time_total-=ov_time_total(vf,link); - if(vf->pcm_offset>=pcm_total)break; - } - } - - return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate); -} - -/* link: -1) return the vorbis_info struct for the bitstream section - currently being decoded - 0-n) to request information for a specific bitstream section - - In the case of a non-seekable bitstream, any call returns the - current bitstream. NULL in the case that the machine is not - initialized */ - -vorbis_info *ov_info(OggVorbis_File *vf,int link){ - if(vf->seekable){ - if(link<0) - if(vf->ready_state>=STREAMSET) - return vf->vi+vf->current_link; - else - return vf->vi; - else - if(link>=vf->links) - return NULL; - else - return vf->vi+link; - }else{ - return vf->vi; - } -} - -/* grr, strong typing, grr, no templates/inheritence, grr */ -vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ - if(vf->seekable){ - if(link<0) - if(vf->ready_state>=STREAMSET) - return vf->vc+vf->current_link; - else - return vf->vc; - else - if(link>=vf->links) - return NULL; - else - return vf->vc+link; - }else{ - return vf->vc; - } -} - -static int host_is_big_endian() { - ogg_int32_t pattern = 0xfeedface; /* deadbeef */ - unsigned char *bytewise = (unsigned char *)&pattern; - if (bytewise[0] == 0xfe) return 1; - return 0; -} - -/* up to this point, everything could more or less hide the multiple - logical bitstream nature of chaining from the toplevel application - if the toplevel application didn't particularly care. However, at - the point that we actually read audio back, the multiple-section - nature must surface: Multiple bitstream sections do not necessarily - have to have the same number of channels or sampling rate. - - ov_read returns the sequential logical bitstream number currently - being decoded along with the PCM data in order that the toplevel - application can take action on channel/sample rate changes. This - number will be incremented even for streamed (non-seekable) streams - (for seekable streams, it represents the actual logical bitstream - index within the physical bitstream. Note that the accessor - functions above are aware of this dichotomy). - - input values: buffer) a buffer to hold packed PCM data for return - length) the byte length requested to be placed into buffer - bigendianp) should the data be packed LSB first (0) or - MSB first (1) - word) word size for output. currently 1 (byte) or - 2 (16 bit short) - - return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) - 0) EOF - n) number of bytes of PCM actually returned. The - below works on a packet-by-packet basis, so the - return length is not related to the 'length' passed - in, just guaranteed to fit. - - *section) set to the logical bitstream number */ - -long ov_read(OggVorbis_File *vf,char *buffer,int length, - int bigendianp,int word,int sgned,int *bitstream){ - int i,j; - int host_endian = host_is_big_endian(); - - float **pcm; - long samples; - - if(vf->ready_stateready_state>=STREAMSET){ - samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); - if(samples)break; - } - - /* suck in another packet */ - { - int ret=_fetch_and_process_packet(vf,NULL,1); - if(ret==OV_EOF)return(0); - if(ret<=0)return(ret); - } - - } - - if(samples>0){ - - /* yay! proceed to pack data into the byte buffer */ - - long channels=ov_info(vf,-1)->channels; - long bytespersample=word * channels; - vorbis_fpu_control fpu; - if(samples>length/bytespersample)samples=length/bytespersample; - - if(samples <= 0) - return OV_EINVAL; - - /* a tight loop to pack each size */ - { - int val; - if(word==1){ - int off=(sgned?0:128); - vorbis_fpu_setround(&fpu); - for(j=0;j127)val=127; - else if(val<-128)val=-128; - *buffer++=val+off; - } - vorbis_fpu_restore(fpu); - }else{ - int off=(sgned?0:32768); - - if(host_endian==bigendianp){ - if(sgned){ - - vorbis_fpu_setround(&fpu); - for(i=0;i32767)val=32767; - else if(val<-32768)val=-32768; - *dest=val; - dest+=channels; - } - } - vorbis_fpu_restore(fpu); - - }else{ - - vorbis_fpu_setround(&fpu); - for(i=0;i32767)val=32767; - else if(val<-32768)val=-32768; - *dest=val+off; - dest+=channels; - } - } - vorbis_fpu_restore(fpu); - - } - }else if(bigendianp){ - - vorbis_fpu_setround(&fpu); - for(j=0;j32767)val=32767; - else if(val<-32768)val=-32768; - val+=off; - *buffer++=(val>>8); - *buffer++=(val&0xff); - } - vorbis_fpu_restore(fpu); - - }else{ - int val; - vorbis_fpu_setround(&fpu); - for(j=0;j32767)val=32767; - else if(val<-32768)val=-32768; - val+=off; - *buffer++=(val&0xff); - *buffer++=(val>>8); - } - vorbis_fpu_restore(fpu); - - } - } - } - - vorbis_synthesis_read(&vf->vd,samples); - vf->pcm_offset+=samples; - if(bitstream)*bitstream=vf->current_link; - return(samples*bytespersample); - }else{ - return(samples); - } -} - -/* input values: pcm_channels) a float vector per channel of output - length) the sample length being read by the app - - return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) - 0) EOF - n) number of samples of PCM actually returned. The - below works on a packet-by-packet basis, so the - return length is not related to the 'length' passed - in, just guaranteed to fit. - - *section) set to the logical bitstream number */ - - - -long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length, - int *bitstream){ - - if(vf->ready_stateready_state>=STREAMSET){ - float **pcm; - long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); - if(samples){ - if(pcm_channels)*pcm_channels=pcm; - if(samples>length)samples=length; - vorbis_synthesis_read(&vf->vd,samples); - vf->pcm_offset+=samples; - if(bitstream)*bitstream=vf->current_link; - return samples; - - } - } - - /* suck in another packet */ - { - int ret=_fetch_and_process_packet(vf,NULL,1); - if(ret==OV_EOF)return(0); - if(ret<=0)return(ret); - } - - } -} - diff --git a/src/add-ons/media/plugins/vorbis/libvorbis/window.c b/src/add-ons/media/plugins/vorbis/libvorbis/window.c deleted file mode 100644 index 22194cd507..0000000000 --- a/src/add-ons/media/plugins/vorbis/libvorbis/window.c +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: window functions - last mod: $Id: window.c 5664 2003-12-13 20:17:56Z shatty $ - - ********************************************************************/ - -#include -#include -#include "os.h" -#include "misc.h" - -float *_vorbis_window(int type, int left){ - float *ret=_ogg_calloc(left,sizeof(*ret)); - int i; - - switch(type){ - case 0: - /* The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi) */ - { - - for(i=0;i -#include -#include -#include -#include -#include -#include -#include "vorbisCodecPlugin.h" -#include "OggVorbisFormats.h" - -#define TRACE_THIS 0 -#if TRACE_THIS - #define TRACE printf -#else - #define TRACE(a...) -#endif - -#define DECODE_BUFFER_SIZE (32 * 1024) - - -inline void -AdjustBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */) -{ - size_t frame_size = (raf->format & 0xf) * raf->channel_count; - if (raf->buffer_size <= frame_size) { - raf->buffer_size = frame_size * (size_t)((raf->frame_rate * buffer_duration) / 1000000.0); - } else { - raf->buffer_size = (raf->buffer_size / frame_size) * frame_size; - } -} - - -static media_format -vorbis_decoded_media_format() -{ - media_format format; - format.type = B_MEDIA_RAW_AUDIO; - init_vorbis_media_raw_audio_format(&format.u.raw_audio); - return format; -} - - -/* - * VorbisDecoder - */ - - -VorbisDecoder::VorbisDecoder() -{ - TRACE("VorbisDecoder::VorbisDecoder\n"); - vorbis_info_init(&fInfo); - vorbis_comment_init(&fComment); - fStartTime = 0; - fFrameSize = 0; - fOutputBufferSize = 0; -} - - -VorbisDecoder::~VorbisDecoder() -{ - TRACE("VorbisDecoder::~VorbisDecoder\n"); - vorbis_info_clear(&fInfo); - vorbis_comment_clear(&fComment); -} - - -void -VorbisDecoder::GetCodecInfo(media_codec_info *info) -{ - strncpy(info->short_name, "vorbis-libvorbis", sizeof(info->short_name)); - strncpy(info->pretty_name, "vorbis decoder [libvorbis], by Andrew Bachmann", sizeof(info->pretty_name)); -} - - -status_t -VorbisDecoder::Setup(media_format *inputFormat, - const void *infoBuffer, size_t infoSize) -{ - TRACE("VorbisDecoder::Setup\n"); - if (!format_is_compatible(vorbis_encoded_media_format(),*inputFormat)) { - return B_MEDIA_BAD_FORMAT; - } - // grab header packets from meta data - if (inputFormat->MetaDataSize() != sizeof(std::vector)) { - TRACE("VorbisDecoder::Setup not called with ogg_packet meta data: not vorbis\n"); - return B_ERROR; - } - std::vector * packets = (std::vector *)inputFormat->MetaData(); - if (packets->size() != 3) { - TRACE("VorbisDecoder::Setup not called with three ogg_packets: not vorbis\n"); - return B_ERROR; - } - // parse header packet - if (vorbis_synthesis_headerin(&fInfo,&fComment,&(*packets)[0]) != 0) { - TRACE("VorbisDecoder::Setup: vorbis_synthesis_headerin failed: not vorbis header\n"); - return B_ERROR; - } - // parse comment packet - if (vorbis_synthesis_headerin(&fInfo,&fComment,&(*packets)[1]) != 0) { - TRACE("VorbisDecoder::Setup: vorbis_synthesis_headerin failed: not vorbis comment\n"); - return B_ERROR; - } - // parse codebook packet - if (vorbis_synthesis_headerin(&fInfo,&fComment,&(*packets)[2]) != 0) { - TRACE("VorbisDecoder::Setup: vorbis_synthesis_headerin failed: not vorbis codebook\n"); - return B_ERROR; - } - // initialize decoder - vorbis_synthesis_init(&fDspState,&fInfo); - vorbis_block_init(&fDspState,&fBlock); - // setup default output - media_format requested_format = vorbis_decoded_media_format(); - ((media_raw_audio_format)requested_format.u.raw_audio) = inputFormat->u.encoded_audio.output; - return NegotiateOutputFormat(&requested_format); -} - - -status_t -VorbisDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat) -{ - TRACE("VorbisDecoder::NegotiateOutputFormat\n"); - // BMediaTrack::DecodedFormat - // Pass in ioFormat the format that you want (with wildcards - // as applicable). The codec will find and return in ioFormat - // its best matching format. - // - // BMediaDecoder::SetOutputFormat - // sets the format the decoder should output. On return, - // the outputFormat is changed to match the actual format - // that will be output; this can be different if you - // specified any wildcards. - // - // Be R5 behavior seems to be that we can never fail. If we - // don't support the requested format, just return one we do. - media_format format = vorbis_decoded_media_format(); - format.u.raw_audio.frame_rate = (float)fInfo.rate; - format.u.raw_audio.channel_count = fInfo.channels; - format.u.raw_audio.channel_mask = B_CHANNEL_LEFT | (fInfo.channels != 1 ? B_CHANNEL_RIGHT : 0); - if (!format_is_compatible(format,*ioDecodedFormat)) { - *ioDecodedFormat = format; - } - ioDecodedFormat->SpecializeTo(&format); - AdjustBufferSize(&ioDecodedFormat->u.raw_audio); - // setup output variables - fFrameSize = ioDecodedFormat->AudioFrameSize(); - fOutputBufferSize = ioDecodedFormat->u.raw_audio.buffer_size; - return B_OK; -} - - -status_t -VorbisDecoder::Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time) -{ - TRACE("VorbisDecoder::Seek\n"); - float **pcm; - // throw the old samples away! - int samples = vorbis_synthesis_pcmout(&fDspState,&pcm); - vorbis_synthesis_read(&fDspState,samples); - return B_OK; -} - - -status_t -VorbisDecoder::Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info /* = 0 */) -{ -// TRACE("VorbisDecoder::Decode\n"); - uint8 * out_buffer = static_cast(buffer); - int32 out_bytes_needed = fOutputBufferSize; - - bool synced = false; - - int total_samples = 0; - while (out_bytes_needed > 0) { - int samples; - float **pcm; - while ((samples = vorbis_synthesis_pcmout(&fDspState,&pcm)) == 0) { - // get a new packet - const void *chunkBuffer; - size_t chunkSize; - media_header mh; - status_t status = GetNextChunk(&chunkBuffer, &chunkSize, &mh); - if (status == B_LAST_BUFFER_ERROR) { - goto done; - } - if (status != B_OK) { - TRACE("VorbisDecoder::Decode: GetNextChunk failed\n"); - return status; - } - ogg_packet packet; - if (mh.user_data_type == OGG_PACKET_DATA_TYPE) { - memcpy(&packet, mh.user_data, sizeof(packet)); - } else { - // According to http://lists.xiph.org/pipermail/theora-dev/2004-May/002161.html - // this is invalid, but results from it are tolerable and better than nothing. - TRACE("VorbisDecoder::Decode: using compatibility chunk interpretation\n"); - packet.b_o_s = 0; - packet.e_o_s = 0; - packet.granulepos = -1; - packet.packetno = 7; - } - packet.packet = (unsigned char *)chunkBuffer; - packet.bytes = chunkSize; - if (!synced) { - if (mh.start_time > 0) { - mediaHeader->start_time = mh.start_time - (1000000LL * total_samples) / fInfo.rate; - synced = true; - } - } - if (vorbis_synthesis(&fBlock, &packet)==0) { - vorbis_synthesis_blockin(&fDspState,&fBlock); - } - } - // reduce samples to the amount of samples we will actually consume - samples = min_c(samples,out_bytes_needed/fFrameSize); - total_samples += samples; - for (int sample = 0; sample < samples ; sample++) { - for (int channel = 0; channel < fInfo.channels; channel++) { - *((float*)out_buffer) = pcm[channel][sample]; - out_buffer += sizeof(float); - } - } - out_bytes_needed -= samples * fFrameSize; - // report back how many samples we consumed - vorbis_synthesis_read(&fDspState,samples); - - } - -done: - if (!synced) { - mediaHeader->start_time = fStartTime; - } - fStartTime = mediaHeader->start_time + (1000000LL * total_samples) / fInfo.rate; - - *frameCount = (fOutputBufferSize - out_bytes_needed) / fFrameSize; - - if (out_buffer != buffer) { - return B_OK; - } - return B_LAST_BUFFER_ERROR; -} - - -/* - * VorbisDecoderPlugin - */ - - -Decoder * -VorbisDecoderPlugin::NewDecoder(uint index) -{ - static BLocker locker; - static bool initdone = false; - BAutolock lock(locker); - if (!initdone) { - initdone = true; - } - return new VorbisDecoder; -} - -static media_format vorbis_formats[1]; - -status_t -VorbisDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count) -{ - media_format_description description = vorbis_description(); - media_format format = vorbis_encoded_media_format(); - - BMediaFormats mediaFormats; - status_t result = mediaFormats.InitCheck(); - if (result != B_OK) { - return result; - } - result = mediaFormats.MakeFormatFor(&description, 1, &format); - if (result != B_OK) { - return result; - } - vorbis_formats[0] = format; - - *formats = vorbis_formats; - *count = 1; - - return result; -} - - -/* - * instantiate_plugin - */ - - -MediaPlugin *instantiate_plugin() -{ - return new VorbisDecoderPlugin; -} diff --git a/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.h b/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.h deleted file mode 100644 index 157cf9cefa..0000000000 --- a/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _VORBIS_CODEC_PLUGIN_H_ -#define _VORBIS_CODEC_PLUGIN_H_ - -#include "DecoderPlugin.h" - -#include "libvorbis/vorbis/codec.h" - -class VorbisDecoder : public Decoder -{ -public: - VorbisDecoder(); - ~VorbisDecoder(); - - void GetCodecInfo(media_codec_info *info); - status_t Setup(media_format *inputFormat, - const void *infoBuffer, size_t infoSize); - - status_t NegotiateOutputFormat(media_format *ioDecodedFormat); - - status_t Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time); - - - status_t Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info); - -private: - vorbis_info fInfo; - vorbis_comment fComment; - vorbis_dsp_state fDspState; - vorbis_block fBlock; - bigtime_t fStartTime; - int fFrameSize; - int fOutputBufferSize; -}; - - -class VorbisDecoderPlugin : public DecoderPlugin -{ -public: - Decoder * NewDecoder(uint index); - status_t GetSupportedFormats(media_format ** formats, size_t * count); -}; - -#endif //_VORBIS_CODEC_PLUGIN_H_