[xiph-cvs] cvs commit: vorbis-plugins/realplayer/render/make linux-2.0-libc6-i386.mak
Jack Moffitt
jack at xiph.org
Tue Jan 30 20:58:52 PST 2001
jack 01/01/30 20:58:52
Added: realplayer README
realplayer/filefmt fvorbis.cpp fvorbis.h
realplayer/filefmt/make linux-2.0-libc6-i386.mak
realplayer/render fivemque.cpp fivemque.h rvorbis.cpp
rvorbis.h
realplayer/render/make linux-2.0-libc6-i386.mak
Log:
first cut at a realplayer plugin
Revision Changes Path
1.1 vorbis-plugins/realplayer/README
Index: README
===================================================================
You'll need the RMA SDK to compile these. You can find it at
www.realnetworks.com in the DevZone.
These currently work but don't support chaining or seeking. Also
only stereo 44.1kHz files are supported.
Streaming doesn't seem to work but should soon.
Since the RMA SDK is hard to find at realnetworks.com, you can find it here:
http://i.cantcode.com/~jack/rsg2sdk_r4.tar.gz
You can find RealPlayer8 at www.real.com or www.realnetworks.com, although
this plugin should work any g2 player i think.
jack.
1.1 vorbis-plugins/realplayer/filefmt/fvorbis.cpp
Index: fvorbis.cpp
===================================================================
#define INITGUID
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include "pntypes.h"
#include "pncom.h"
#include "rmacomm.h"
#include "rmapckts.h"
#include "rmaplugn.h"
#include "rmafiles.h"
#include "rmaformt.h"
#include "fvorbis.h"
// static variables
const char *CVorbisFileFormat::zm_pDescription = DESCRIPTION;
const char *CVorbisFileFormat::zm_pCopyright = COPYRIGHT;
const char *CVorbisFileFormat::zm_pMoreInfoURL = MORE_INFO_URL;
const char *CVorbisFileFormat::zm_pFileMimeTypes[] = FILE_MIME_TYPES;
const char *CVorbisFileFormat::zm_pFileExtensions[] = FILE_EXTENSIONS;
const char *CVorbisFileFormat::zm_pFileOpenNames[] = FILE_OPEN_NAMES;
int CVorbisFileFormat::instno = 0;
STDAPI RMACreateInstance(IUnknown **ppExFileFormatObj)
{
//printf("RMACreateInstance() called\n");
*ppExFileFormatObj = (IUnknown *)(IRMAPlugin *)new CVorbisFileFormat();
if (*ppExFileFormatObj != NULL) {
(*ppExFileFormatObj)->AddRef();
return PNR_OK;
}
return PNR_OUTOFMEMORY;
}
// constructor
CVorbisFileFormat::CVorbisFileFormat(void)
: m_RefCount(0),
m_pClassFactory(NULL),
m_pFileObj(NULL),
m_pStatus(NULL),
m_State(Ready),
m_NextPacketDeliveryTime(0),
m_ogg_inited(0)
{
//printf("Entering CVorbisFileFormat()\n");
m_instno = instno++;
//printf("Exiting CVorbisFileFormat(%d)\n", m_instno);
}
STDMETHODIMP CVorbisFileFormat::GetPluginInfo(
REF(BOOL) bLoadMultiple,
REF(const char *) pDescription,
REF(const char *) pCopyright,
REF(const char *) pMoreInfoURL,
REF(UINT32) versionNumber
)
{
//printf("Entering GetPluginInfo(%d)\n", m_instno);
// File Format plugins must be able to be multiply instantiated
bLoadMultiple = TRUE;
pDescription = zm_pDescription;
pCopyright = zm_pCopyright;
pMoreInfoURL = zm_pMoreInfoURL;
versionNumber = PLUGIN_VERSION;
//printf("Exiting GetPluginInfo(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::GetFileFormatInfo(
REF(const char **) pFileMimeTypes,
REF(const char **) pFileExtensions,
REF(const char **) pFileOpenNames
)
{
//printf("Entering GetFileFormatInfo(%d)\n", m_instno);
pFileMimeTypes = zm_pFileMimeTypes;
pFileExtensions = zm_pFileExtensions;
pFileOpenNames = zm_pFileOpenNames;
//printf("Exiting GetFileFormatInfo(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::InitPlugin(IUnknown *pRMACore)
{
//printf("Entering InitPlugin(%d)\n", m_instno);
// store a reference to the IRMACommonClassFactory interface
pRMACore->QueryInterface(IID_IRMACommonClassFactory, (void **)&m_pClassFactory);
if (m_pClassFactory == NULL) return PNR_NOTIMPL;
// queryinterface adds a reference for us, we are responsible
// for release the reference when we're done
//printf("Exiting InitPlugin(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::InitFileFormat(
IRMARequest *pRequest,
IRMAFormatResponse *pFormatResponse,
IRMAFileObject *pFileObject
)
{
//printf("Entering InitFileFormat(%d)\n", m_instno);
// the format response object is used to notify rma core of our status
m_pStatus = pFormatResponse;
if (m_pStatus != NULL)
m_pStatus->AddRef();
// the file object is used to handle file i/o
m_pFileObj = pFileObject;
if (m_pFileObj != NULL) {
m_pFileObj->AddRef();
// init and check file, then associate file with response object
m_State = InitPending;
m_pFileObj->Init(PN_FILE_READ | PN_FILE_BINARY, this);
}
ogg_sync_init(&m_oy);
vorbis_info_init(&m_initial_i);
vorbis_comment_init(&m_initial_c);
m_granulepos = 0;
m_ogg_inited = 1;
//printf("Exiting InitFileFormat(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::InitDone(PN_RESULT status)
{
//printf("Entering InitDone(%d)\n", m_instno);
if (m_State != InitPending) return PNR_UNEXPECTED;
// notify RMA core that init started in InitFileFormat is done
m_State = Ready;
m_pStatus->InitDone(status);
//printf("Exiting InitDone(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::GetFileHeader(void)
{
IRMAFileStat *pFileStatObj;
//printf("Entering GetFileHeader(%d)\n", m_instno);
if (m_State != Ready) return PNR_UNEXPECTED;
// async stuff makes this muddy, but here's the steps
// 1) stat the file to get the length
// 2) in StatDone,
m_State = GetFileHeaderStatPending;
m_pFileObj->QueryInterface(IID_IRMAFileStat, (void **)&pFileStatObj);
if (pFileStatObj != NULL) {
pFileStatObj->Stat(this);
pFileStatObj->Release();
}
//printf("Exiting GetFileHeader(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::StatDone(PN_RESULT status, UINT32 ulSize, UINT32 ulCreationTime, UINT32 ulAccessTime,
UINT32 ulModificationTime, UINT32 ulMode)
{
//printf("Entering StatDone(%d)\n", m_instno);
if (m_State != GetFileHeaderStatPending) return PNR_UNEXPECTED;
m_State = GFHInitialHeaderReadPending;
m_FileSize = ulSize;
//printf("Filesize of this ogg file is %ld\n", m_FileSize);
m_pFileObj->Read(READ_LENGTH);
//printf("Exiting StatDone(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::ReadDone(PN_RESULT status, IRMABuffer *pBuffer)
{
char *buffer;
ogg_page og;
ogg_packet op;
int result;
int falling_through = 0;
//printf("Enterint ReadDone(%d)\n", m_instno);
switch (m_State) {
case GFHInitialHeaderReadPending:
//printf("state = GFHInitialHeadReadPending\n");
if (pBuffer == NULL) {
m_State = Ready;
return PNR_INVALID_FILE;
}
// submit what we read to libvorbis
buffer = ogg_sync_buffer(&m_oy, pBuffer->GetSize());
memcpy(buffer, pBuffer->GetBuffer(), pBuffer->GetSize());
ogg_sync_wrote(&m_oy, pBuffer->GetSize());
//printf("GFHIHRP: submitted %d bytes to ogg\n", pBuffer->GetSize());
// if we didn't read enough, read some more
if (ogg_sync_pageout(&m_oy, &og) != 1) {
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
m_initial_serialno = ogg_page_serialno(&og);
ogg_stream_init(&m_os, ogg_page_serialno(&og));
//printf("serial number is %ld\n", m_initial_serialno);
if (ogg_stream_pagein(&m_os, &og) < 0) {
//printf("GFHIHRP: ogg_stream_pagein failed...\n");
// error
m_State = Ready;
return PNR_INVALID_FILE;
}
if (ogg_stream_packetout(&m_os, &op) != 1) {
//printf("couldn't read initial packet\n");
// must not be vorbis
return PNR_INVALID_FILE;
}
if (vorbis_synthesis_headerin(&m_initial_i, &m_initial_c, &op) < 0) {
//printf("GFHIHRP: vorbis_synthesis headerin failed\n");
// error: not a vorbis header
m_State = Ready;
return PNR_INVALID_FILE;
}
// we're sure we're vorbis. need to read the comments and the codebooks
m_State = GFHInitialHeaderCommentReadPending;
falling_through = 1;
// pass through intentional
case GFHInitialHeaderCommentReadPending:
//printf("state = GFHInitialHeaderCommentReadPending\n");
if (!falling_through) {
if (pBuffer == NULL) {
m_State = Ready;
return PNR_INVALID_FILE;
}
// submit what we read to libvorbis
buffer = ogg_sync_buffer(&m_oy, pBuffer->GetSize());
memcpy(buffer, pBuffer->GetBuffer(), pBuffer->GetSize());
ogg_sync_wrote(&m_oy, pBuffer->GetSize());
}
if (ogg_sync_pageout(&m_oy, &og) != 1) {
// not enough data
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
//printf("GFHIHCRP: we got a page...\n");
ogg_stream_pagein(&m_os, &og); // we can ignore these errors, they'll show up later
result = ogg_stream_packetout(&m_os, &op);
// do we need more data
if (result == 0) {
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
// was there an error
if (result < 0) {
m_State = Ready;
return PNR_INVALID_FILE;
}
vorbis_synthesis_headerin(&m_initial_i, &m_initial_c, &op);
// got the comments
m_State = GFHInitialHeaderCodebookReadPending;
falling_through = 1;
// fall through intentional
case GFHInitialHeaderCodebookReadPending:
//printf("state = GFHInitialHeaderCodebookReadPending\n");
if (!falling_through) {
if (pBuffer == NULL) {
m_State = Ready;
return PNR_INVALID_FILE;
}
// submit what we read to libvorbis
buffer = ogg_sync_buffer(&m_oy, pBuffer->GetSize());
memcpy(buffer, pBuffer->GetBuffer(), pBuffer->GetSize());
ogg_sync_wrote(&m_oy, pBuffer->GetSize());
}
if (ogg_sync_pageout(&m_oy, &og) != 1) {
// not enough data
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
ogg_stream_pagein(&m_os, &og);
result = ogg_stream_packetout(&m_os, &op);
// do we need more data?
if (result == 0) {
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
// was there an error?
if (result < 0) {
m_State = Ready;
return PNR_INVALID_FILE;
}
vorbis_synthesis_headerin(&m_initial_i, &m_initial_c, &op);
// we know it's vorbis. that's good enough. reset the stream state.
ogg_stream_clear(&m_os);
// and the sync state
ogg_sync_reset(&m_oy);
// now we need to seek to the end and see if we're the only logical stream
m_State = GFHSeekEndPending;
m_offset = m_FileSize;
m_begin = m_FileSize;
m_pFileObj->Seek(m_FileSize, FALSE);
return PNR_OK;
case GFHReadEndSearching:
//printf("state = GFHReadEndSearching\n");
// we're looking for a page
// if we couldn't read anymore data, seek back some more.
if (pBuffer == NULL) {
m_State = GFHSeekEndSearching;
m_begin -= READ_LENGTH;
m_pFileObj->Seek(m_begin, FALSE);
return PNR_OK;
}
// add the new data
buffer = ogg_sync_buffer(&m_oy, pBuffer->GetSize());
memcpy(buffer, pBuffer->GetBuffer(), pBuffer->GetSize());
ogg_sync_wrote(&m_oy, pBuffer->GetSize());
if (ogg_sync_pageout(&m_oy, &og) != 1) {
// more data please
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
// yay we found a page
// is there more than one logical bitstream?
if (ogg_page_serialno(&og) != m_initial_serialno) {
// this is a chained bitstream
// this is NOT currently implemented.
m_State = Ready;
return PNR_INVALID_FILE;
} else {
// now we can get the length of the song
m_FileTime = (UINT32)((float)(ogg_page_granulepos(&og) / m_initial_i.rate) * 1000.0);
m_State = GFHSeekBeginPending;
m_pFileObj->Seek(0, FALSE);
return PNR_OK;
}
break;
case GetPacketReadPending:
//printf("state = GetPacketReadPending\n");
if (pBuffer == NULL) {
m_State = Ready;
return PNR_UNEXPECTED;
}
// send the data to the ogg layer
buffer = ogg_sync_buffer(&m_oy, pBuffer->GetSize());
memcpy(buffer, pBuffer->GetBuffer(), pBuffer->GetSize());
ogg_sync_wrote(&m_oy, pBuffer->GetSize());
// do we have a page yet?
if (ogg_sync_pageout(&m_oy, &og) != 1) {
// get more data
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
}
CreatePacketObj(&og, m_granulepos);
m_granulepos = ogg_page_granulepos(&og);
return PNR_OK;
default:
return PNR_UNEXPECTED;
}
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::SeekDone(PN_RESULT status)
{
//printf("Entering SeekDone(%d)\n", m_instno);
switch (m_State) {
case GFHSeekEndPending:
//printf("state = GFHSeekEndPending\n");
// now we need to read the last page in this file
// start searching
m_State = GFHSeekEndSearching;
m_begin -= READ_LENGTH;
m_pFileObj->Seek(m_begin, FALSE);
return PNR_OK;
case GFHSeekEndSearching:
//printf("state = GFHSeekEndSearching\n");
// find a page
m_State = GFHReadEndSearching;
m_pFileObj->Read(READ_LENGTH);
return PNR_OK;
case GFHSeekBeginPending:
//printf("state = GFHSeekBeginPending\n");
m_State = Ready;
// let's reset the stream/sync states
ogg_sync_reset(&m_oy);
CreateFileHeaderObj();
return PNR_OK;
default:
return PNR_UNEXPECTED;
}
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::GetStreamHeader(UINT16 streamNo)
{
//printf("Entering GetStreamHeader(%d)\n", m_instno);
if (m_State != Ready) return PNR_UNEXPECTED;
CreateStreamHeaderObj();
//printf("Exiting GetStreamHeader(%d)\n", m_instno);
return PNR_OK;
}
void CVorbisFileFormat::CreateFileHeaderObj(void)
{
//printf("Entering CreateFileHeaderObj(%d)\n", m_instno);
m_State = Ready;
// Step 5: create new object containing header data
IRMAValues *pHeaderObj = NULL;
m_pClassFactory->CreateInstance(CLSID_IRMAValues, (void **)&pHeaderObj);
if (pHeaderObj != NULL) {
// required property: StreamCount
pHeaderObj->SetPropertyULONG32("StreamCount", 1);
// step 6: notify rma core that header object is ready
m_pStatus->FileHeaderReady(PN_STATUS_OK, pHeaderObj);
// release object since we're done with it
pHeaderObj->Release();
}
//printf("Exiting CreateFileHeaderObj(%d)\n", m_instno);
}
void CVorbisFileFormat::CreateStreamHeaderObj(void)
{
UINT32 avgBitRate;
//printf("Entering CreateStreamHeaderObj(%d)\n", m_instno);
m_State = Ready;
IRMAValues *pStreamHeaderObj = NULL;
m_pClassFactory->CreateInstance(CLSID_IRMAValues, (void **)&pStreamHeaderObj);
if (pStreamHeaderObj != NULL) {
// these properties are required
// "StreamNumber" the stream number
pStreamHeaderObj->SetPropertyULONG32("StreamNumber", STREAM_NO);
// "AvgBitRate" the average bitrate of this stream
avgBitRate = (UINT32)((float)((m_FileSize * 8) / (m_FileTime / 1000)));
pStreamHeaderObj->SetPropertyULONG32("AvgBitRate", avgBitRate);
//printf("AvgBitRate = %ld\n", avgBitRate);
// preroll might not be required
// "Preroll" the amount to prebuffer
//pStreamHeaderObj->SetPropertyULONG32("Preroll", 0);
// "Duration" length in milliseconds
pStreamHeaderObj->SetPropertyULONG32("Duration", m_FileTime);
//printf("Duration = %ld\n", m_FileTime);
// "MimeType" the mime-type
IRMABuffer *pStringObj = NULL;
m_pClassFactory->CreateInstance(CLSID_IRMABuffer, (void **)&pStringObj);
if (pStringObj != NULL) {
char *streamMimeType = STREAM_MIME_TYPE;
pStringObj->Set((const BYTE *)streamMimeType, strlen(streamMimeType) + 1);
pStreamHeaderObj->SetPropertyCString("MimeType", pStringObj);
pStringObj->Release();
}
// notify RMA core
m_pStatus->StreamHeaderReady(PN_STATUS_OK, pStreamHeaderObj);
// release the object
pStreamHeaderObj->Release();
}
//printf("Exiting CreateStreamHeaderObj(%d)\n", m_instno);
}
STDMETHODIMP CVorbisFileFormat::GetPacket(UINT16 streamNo)
{
//printf("Entering GetPacket(%d)\n", m_instno);
if (m_State != Ready) return PNR_UNEXPECTED;
m_State = GetPacketReadPending;
m_pFileObj->Read(READ_LENGTH);
//printf("Exiting GetPacket(%d)\n", m_instno);
return PNR_OK;
}
void CVorbisFileFormat::CreatePacketObj(ogg_page *og, ogg_int64_t granulepos)
{
char *buffer;
//printf("Entering CreatePacketObj(%d)\n", m_instno);
m_State = Ready;
IRMAPacket *pPacketObj = NULL;
m_pClassFactory->CreateInstance(CLSID_IRMAPacket, (void **)&pPacketObj);
if (pPacketObj != NULL) {
float deliveryTime = (float)granulepos / 44100.0 * 1000.0;
UINT16 streamNo = 0;
printf("granulepos = %lld deliverytime = %f\n", granulepos, deliveryTime);
IRMABuffer *pBuffer = NULL;
m_pClassFactory->CreateInstance(CLSID_IRMABuffer, (void **)&pBuffer);
if (pBuffer != NULL) {
pBuffer->SetSize(og->header_len + og->body_len);
buffer = (char *)pBuffer->GetBuffer();
memcpy(buffer, og->header, og->header_len);
memcpy(&buffer[og->header_len], og->body, og->body_len);
pPacketObj->Set(pBuffer, (UINT32)deliveryTime, streamNo, 0, 0);
m_pStatus->PacketReady(PN_STATUS_OK, pPacketObj);
pPacketObj->Release();
} else {
printf("OH SHIT111!\n");
}
} else {
printf("OH SHIT222!\n");
}
//printf("Exiting CreatePacketObj(%d)\n", m_instno);
}
STDMETHODIMP CVorbisFileFormat::Seek(UINT32 requestedTime)
{
//printf("Entering Seek(%d)\n", m_instno);
// not implemented
//printf("Exiting Seek(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::Close(void)
{
//printf("Entering Close(%d)\n", m_instno);
if (m_ogg_inited) {
vorbis_comment_clear(&m_initial_c);
vorbis_info_clear(&m_initial_i);
ogg_sync_clear(&m_oy);
}
if (m_pFileObj != NULL) {
m_pFileObj->Close();
m_pFileObj->Release();
m_pFileObj = NULL;
}
if (m_pStatus != NULL) {
m_pStatus->Release();
m_pStatus = NULL;
}
if (m_pClassFactory != NULL) {
m_pClassFactory->Release();
m_pClassFactory = NULL;
}
//printf("Exiting Close(%d)\n", m_instno);
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::CloseDone(PN_RESULT result)
{
//printf("CloseDone() not implemented\n");
return PNR_OK;
}
STDMETHODIMP CVorbisFileFormat::WriteDone(PN_RESULT result)
{
//printf("WriteDone() not implemented\n");
return PNR_OK;
}
CVorbisFileFormat::~CVorbisFileFormat(void)
{
//printf("Entering ~CVorbisFileFormat(%d)\n", m_instno);
Close();
//printf("Exiting ~CVorbisFileFormat(%d)\n", m_instno);
}
STDMETHODIMP_(UINT32) CVorbisFileFormat::AddRef(void)
{
return InterlockedIncrement(&m_RefCount);
}
STDMETHODIMP_(UINT32) CVorbisFileFormat::Release(void)
{
if (InterlockedDecrement(&m_RefCount) > 0)
return m_RefCount;
delete this;
return 0;
}
STDMETHODIMP CVorbisFileFormat::QueryInterface(REFIID interfaceID, void **ppInterfaceObj)
{
if (IsEqualIID(interfaceID, IID_IUnknown)) {
AddRef();
*ppInterfaceObj = (IUnknown *)(IRMAPlugin *)this;
return PNR_OK;
} else if (IsEqualIID(interfaceID, IID_IRMAPlugin)) {
AddRef();
*ppInterfaceObj = (IRMAPlugin *)this;
return PNR_OK;
} else if (IsEqualIID(interfaceID, IID_IRMAFileResponse)) {
AddRef();
*ppInterfaceObj = (IRMAFileResponse *)this;
return PNR_OK;
} else if (IsEqualIID(interfaceID, IID_IRMAFileFormatObject)) {
AddRef();
*ppInterfaceObj = (IRMAFileFormatObject *)this;
return PNR_OK;
} else if (IsEqualIID(interfaceID, IID_IRMAFileStatResponse)) {
AddRef();
*ppInterfaceObj = (IRMAFileStatResponse *)this;
return PNR_OK;
}
*ppInterfaceObj = NULL;
return PNR_NOINTERFACE;
}
1.1 vorbis-plugins/realplayer/filefmt/fvorbis.h
Index: fvorbis.h
===================================================================
#ifndef __FVORBIS_H__
#define __FVORBIS_H__
#define PLUGIN_VERSION 0
#define DESCRIPTION "Ogg Vorbis File Format Plugin"
#define COPYRIGHT "(c) 2001 Xiphophorus, All rights reserved."
#define MORE_INFO_URL "http://www.xiph.org"
#define FILE_MIME_TYPES {"application/x-ogg", NULL}
#define FILE_EXTENSIONS {"ogg", NULL}
#define FILE_OPEN_NAMES {"Ogg Vorbis (*.ogg)", NULL}
#define STREAM_NO 0
#define STREAM_MIME_TYPE "application/x-ogg"
#define READ_LENGTH 4096
typedef enum
{
Ready,
InitPending,
GetFileHeaderStatPending,
GFHInitialHeaderReadPending,
GFHInitialHeaderCommentReadPending,
GFHInitialHeaderCodebookReadPending,
GFHSeekEndPending,
GFHSeekEndSearching,
GFHReadEndSearching,
GFHSeekBeginPending,
GetPacketSeekPending,
GetPacketReadPending,
SeekSeekPending
} PluginState;
class CVorbisFileFormat : public IRMAFileFormatObject,
public IRMAFileResponse,
public IRMAFileStatResponse,
public IRMAPlugin
{
public:
CVorbisFileFormat(void);
// IRMAFileFormatObject interface
STDMETHOD(GetFileFormatInfo)
(THIS_
REF(const char **)pFileMimeTypes,
REF(const char **)pFileExtensions,
REF(const char **)pFileOpenNames
);
STDMETHOD(InitFileFormat)
(THIS_
IRMARequest *pRequest,
IRMAFormatResponse *pFormatResponse,
IRMAFileObject *pFileObject
);
STDMETHOD(GetFileHeader) (THIS);
STDMETHOD(GetStreamHeader) (THIS_ UINT16 streamNo);
STDMETHOD(GetPacket) (THIS_ UINT16 streamNo);
STDMETHOD(Seek) (THIS_ UINT32 requestedTime);
STDMETHOD(Close) (THIS);
// IRMAFileResponse Interface
STDMETHOD(InitDone) (THIS_ PN_RESULT status);
STDMETHOD(SeekDone) (THIS_ PN_RESULT status);
STDMETHOD(ReadDone) (THIS_ PN_RESULT status, IRMABuffer *pBuffer);
STDMETHOD(WriteDone) (THIS_ PN_RESULT status);
STDMETHOD(CloseDone) (THIS_ PN_RESULT status);
// IRMAFileStatResponse Interface
STDMETHOD(StatDone)
(THIS_
PN_RESULT status,
UINT32 ulSize,
UINT32 ulCreationTime,
UINT32 ulAccessTime,
UINT32 ulModificationTime,
UINT32 ulMode
);
// IRMAPlugin Interface
STDMETHOD(GetPluginInfo)
(THIS_
REF(BOOL) bLoadMultiple,
REF(const char *) pDescription,
REF(const char *) pCopyright,
REF(const char *) pMoreInfoURL,
REF(UINT32) versionNumber
);
STDMETHOD(InitPlugin) (THIS_ IUnknown *pRMACore);
// IUnknown COM Interface
STDMETHOD(QueryInterface) (THIS_ REFIID ID, void **ppInterfaceObj);
STDMETHOD_(UINT32, AddRef) (THIS);
STDMETHOD_(UINT32, Release) (THIS);
private:
// private class variables
UINT32 m_FileTime; // total time of the file in milliseconds
UINT32 m_FileSize; // file size of the current file
INT32 m_RefCount; // Objects reference count
IRMACommonClassFactory *m_pClassFactory; // creates common RMA classes
IRMAFileObject *m_pFileObj; // Used for file i/o
IRMAFormatResponse *m_pStatus; // Reports status to RMA core
PluginState m_State; // Status used for async calls
UINT32 m_NextPacketDeliveryTime; // Delivery time of next packet
// ogg vorbis stuff
int m_ogg_inited;
ogg_int64_t m_granulepos;
ogg_int64_t m_offset;
ogg_int64_t m_begin;
long m_initial_serialno;
ogg_sync_state m_oy;
//int m_links;
//ogg_int64_t *m_offsets;
//ogg_int64_t *m_dataoffsets;
//long *m_serialnos;
//ogg_int64_t *m_pcmlengths;
//vorbis_info *m_vi;
//vorbis_comment *m_vc;
vorbis_info m_initial_i;
vorbis_comment m_initial_c;
// vorbis working state
//ogg_int64_t m_pcmoffset;
//long m_current_serialno;
//int m_current_link;
ogg_stream_state m_os;
// private static class variables
int m_instno;
static int instno;
static const char *zm_pDescription;
static const char *zm_pCopyright;
static const char *zm_pMoreInfoURL;
static const char *zm_pFileMimeTypes[];
static const char *zm_pFileExtensions[];
static const char *zm_pFileOpenNames[];
// private class methods
~CVorbisFileFormat(void);
void CreateFileHeaderObj(void);
void CreateStreamHeaderObj(void);
void CreatePacketObj(ogg_page *og, ogg_int64_t granulepos);
PRIVATE_DESTRUCTORS_ARE_NOT_A_CRIME
};
#endif // __FVORBIS_H__
1.1 vorbis-plugins/realplayer/filefmt/make/linux-2.0-libc6-i386.mak
Index: linux-2.0-libc6-i386.mak
===================================================================
# UMAKE generated Makefile
# build choices: default,release
# platform: linux-2.0-libc6-i386
# Wed Feb 2 15:36:22 2000
.SUFFIXES: .cpp .so
.c.so:
$(CC) $(CCFLAGS) -fPIC -DPIC -o $@ -c $<
.cpp.so:
$(CXX) $(CXXFLAGS) -fPIC -DPIC -o $@ -c $<
RM = rm -f
RM_DIR = rm -rf
MAKE_DEP = makedep.py
MAKE_DEP_FLAGS = $(INCLUDES) $(DEFINES)
MAKE_LIB = ar cr
MAKE_LIB_FLAGS =
RANLIB = ranlib
CP = cp
MAKE = make
# Compilers
CC = gcc
CCFLAGS = -Wall -pipe -O2 $(INCLUDES) $(DEFINES)
CXX = g++
CXXFLAGS = -Wall -pipe -O2 $(INCLUDES) $(DEFINES)
# Linker
LD = g++
LDFLAGS = -shared -L/usr/X11R6/lib -L/usr/X11R6/lib
DEPLIBS =
DYNAMIC_LIBS = -logg -lvorbis
SRCS = \
../fvorbis.cpp
OBJS = $(COMPILED_OBJS) $(SOURCE_OBJS)
COMPILED_OBJS = \
rel/obj/fvorbis.so
SOURCE_OBJS =
INCLUDES = \
-I/usr/X11R6/include \
-I/usr/X11R6/include \
-I/home/jack/download/rmasdk_6_0/include \
-I.. \
-I./pub
DEFINES = \
-D_LINUX \
-D_REENTRANT \
-D_UNIX \
-D_RED_HAT_5_X_
SYSLIBS =
LOCAL_LIBS =
rel/fvorbis.so : rel/obj $(OBJS) $(DEPLIBS)
if test -d rel; then echo; else mkdir rel; fi
$(LD) $(LDFLAGS) -o rel/fvorbis.so $(OBJS) $(DYNAMIC_LIBS) $(DEPLIBS) $(LOCAL_LIBS) $(SYSLIBS) -lgcc
clean::
$(RM) rel/fvorbis.so $(COMPILED_OBJS)
## OBJECT DEPENDANCIES
rel/obj:
if test -d rel; then echo; else mkdir rel; fi
if test -d rel/obj; then echo; else mkdir rel/obj; fi
rel/obj/fvorbis.so : ../fvorbis.cpp
$(CXX) $(CXXFLAGS) -fPIC -DPIC -o rel/obj/fvorbis.so -c ../fvorbis.cpp
copy:
if test -d ../release; then echo; else mkdir ../release; fi
cp rel/fvorbis.so ../release/fvorbis.so
depend:
$(MAKE_DEP) $(MAKE_DEP_FLAGS) rel/obj/ $(SRCS)
1.1 vorbis-plugins/realplayer/render/fivemque.cpp
Index: fivemque.cpp
===================================================================
/****************************************************************************
*
* $Id: fivemque.cpp,v 1.1 2001/01/31 04:58:50 jack Exp $
*
* Copyright (C) 1995,1996,1997 RealNetworks.
* All rights reserved.
*
* http://www.real.com/devzone
*
* This program contains proprietary information of RealNetworks, Inc.,
* and is licensed subject to restrictions on use and distribution.
*
* Very basic queue class.
*
*/
/****************************************************************************
* Includes
*/
#include <string.h>
#include "pntypes.h"
#include "fivemque.h"
/****************************************************************************
* FiveMinuteQueue::Add ref: fivemque.h
*
*/
void
FiveMinuteQueue::Add(void* pElement)
{
FiveMinuteElement* pElem = new FiveMinuteElement(pElement);
FiveMinuteElement* pPtr;
FiveMinuteElement** ppPtr;
for (ppPtr = &m_pElemList; (pPtr = *ppPtr) != 0; ppPtr = &pPtr->m_pNext)
;
*ppPtr = pElem;
}
/****************************************************************************
* FiveMinuteQueue::Remove ref: fivemque.h
*
*/
void*
FiveMinuteQueue::Remove()
{
if (!m_pElemList)
return 0;
FiveMinuteElement* pElem = m_pElemList;
void* pPtr = pElem->m_pPtr;
m_pElemList = m_pElemList->m_pNext;
delete pElem;
return pPtr;
}
1.1 vorbis-plugins/realplayer/render/fivemque.h
Index: fivemque.h
===================================================================
/****************************************************************************
*
* $Id: fivemque.h,v 1.1 2001/01/31 04:58:50 jack Exp $
*
* Copyright (C) 1995,1996,1997 RealNetworks, Inc.
* All rights reserved.
*
* http://www.real.com/devzone
*
* This program contains proprietary information of RealNetworks, Inc.,
* and is licensed subject to restrictions on use and distribution.
*
* Very basic queue class.
*
*/
#ifndef _FIVEMQUE_H_
#define _FIVEMQUE_H_
#ifndef _PNTYPES_H_
#error FiveMinuteQueue assumes pntypes.h.
#endif
/****************************************************************************
*
* FiveMinuteElement Class
*
*/
class FiveMinuteElement
{
friend class FiveMinuteQueue;
public:
FiveMinuteElement(void* pPtr)
{
m_pPtr = pPtr;
m_pNext = 0;
};
private:
void* m_pPtr;
FiveMinuteElement* m_pNext;
};
/****************************************************************************
*
* FiveMinuteQueue Class
*
*/
class FiveMinuteQueue
{
public:
FiveMinuteQueue()
: m_pElemList(NULL)
{};
void Add(void* pElement);
void* Remove();
private:
FiveMinuteElement* m_pElemList;
};
#endif /* _FIVEMQUE_H_ */
1.1 vorbis-plugins/realplayer/render/rvorbis.cpp
Index: rvorbis.cpp
===================================================================
#define INITGUID
#include <stdio.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include "pntypes.h"
#include "pncom.h"
#include "rmacore.h"
#include "rmacomm.h"
#include "rmapckts.h"
#include "rmaplugn.h"
#include "rmarendr.h"
#include "rmaausvc.h"
#include "fivemque.h"
#include "rvorbis.h"
STDAPI RMACreateInstance(IUnknown **ppRendererObj)
{
*ppRendererObj = (IUnknown *)(IRMAPlugin *)new CVorbisRenderer();
if (*ppRendererObj != NULL) {
(*ppRendererObj)->AddRef();
return PNR_OK;
}
return PNR_OUTOFMEMORY;
}
const char *CVorbisRenderer::zm_pDescription = DESCRIPTION;
const char *CVorbisRenderer::zm_pCopyright = COPYRIGHT;
const char *CVorbisRenderer::zm_pMoreInfoURL = MORE_INFO_URL;
const char *CVorbisRenderer::zm_pStreamMimeTypes[] = STREAM_MIME_TYPES;
CVorbisRenderer::CVorbisRenderer(void)
: m_RefCount(0),
m_pClassFactory(NULL),
m_bInSeekMode(FALSE),
m_bIsGapInStreaming(TRUE),
m_oldRealTime(0),
m_totalSamples(0)
{
}
STDMETHODIMP CVorbisRenderer::GetPluginInfo(
REF(BOOL) bLoadMultiple,
REF(const char *) pDescription,
REF(const char *) pCopyright,
REF(const char *) pMoreInfoURL,
REF(UINT32) versionNumber
)
{
bLoadMultiple = TRUE;
pDescription = zm_pDescription;
pCopyright = zm_pCopyright;
pMoreInfoURL = zm_pMoreInfoURL;
versionNumber = PLUGIN_VERSION;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::GetRendererInfo(
REF(const char **) pStreamMimeTypes,
REF(UINT32) initialGranularity
)
{
pStreamMimeTypes = zm_pStreamMimeTypes;
initialGranularity = TIME_SYNC_FREQ;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::InitPlugin(IUnknown *pRMACore)
{
pRMACore->QueryInterface(IID_IRMACommonClassFactory, (void **)&m_pClassFactory);
if (m_pClassFactory == NULL)
return PNR_NOTIMPL;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::StartStream(IRMAStream *pStream, IRMAPlayer *pPlayer)
{
m_OggState = OggInitialHeader;
ogg_sync_init(&m_oy);
m_pStream = pStream;
m_pPlayer = pPlayer;
if (m_pStream) m_pStream->AddRef();
if (m_pPlayer) m_pPlayer->AddRef();
// get interface to audio player
if (PNR_OK != m_pPlayer->QueryInterface(IID_IRMAAudioPlayer, (void **)&m_pAudioPlayer))
return !PNR_OK;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnHeader(IRMAValues *pStreamHeaderObj)
{
m_audioFmt.uChannels = 2;
m_audioFmt.uBitsPerSample = 16;
m_audioFmt.ulSamplesPerSec = 44100;
m_audioFmt.uMaxBlockSize = 4096;
m_pAudioPlayer->CreateAudioStream(&m_pAudioStream);
m_pAudioStream->Init(&m_audioFmt, pStreamHeaderObj);
m_pAudioStream->AddDryNotification(this);
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnBegin(UINT32 timeAfterBeing)
{
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::GetDisplayType(
REF(RMA_DISPLAY_TYPE) displayType,
REF(IRMABuffer *) pDisplayInfo
)
{
displayType = RMA_DISPLAY_NONE;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnPacket(IRMAPacket *pPacketObj, INT32 streamOffsetTime)
{
char *buffer;
ogg_page og;
ogg_packet op;
int result;
int falling_through = 0;
// ignore pre-seek packets
if (m_bInSeekMode) return PNR_OK;
// did we get a valid packet?
if (pPacketObj->IsLost()) {
printf("Lost a packet????\n");
m_bIsGapInStreaming = TRUE;
return PNR_OK;
}
LONG32 lRealTime = pPacketObj->GetTime();
if (streamOffsetTime > lRealTime)
lRealTime = 0;
else
// lRealTime -= streamOffsetTime;
;
printf("streamoffsettime = %d\n", streamOffsetTime);
// now correct m_oldRealTime
m_oldRealTime = lRealTime;
IRMABuffer *pPacketBuff = pPacketObj->GetBuffer();
if (pPacketBuff != NULL) {
UCHAR *pPacketData = pPacketBuff->GetBuffer();
if (pPacketData != NULL) {
//printf("RENDER: decoding ogg page\n");
// submit packet to ogg layer
buffer = ogg_sync_buffer(&m_oy, pPacketBuff->GetSize());
memcpy(buffer, pPacketData, pPacketBuff->GetSize());
ogg_sync_wrote(&m_oy, pPacketBuff->GetSize());
if (ogg_sync_pageout(&m_oy, &og) != 1) {
// not enough data yet
pPacketBuff->Release();
return PNR_OK;
}
switch (m_OggState) {
case OggInitialHeader:
ogg_stream_init(&m_os, ogg_page_serialno(&og));
vorbis_info_init(&m_vi);
vorbis_comment_init(&m_vc);
if (ogg_stream_pagein(&m_os, &og) < 0) {
pPacketBuff->Release();
return PNR_UNEXPECTED;
}
if (ogg_stream_packetout(&m_os, &op) != 1) {
pPacketBuff->Release();
return PNR_UNEXPECTED;
}
if (vorbis_synthesis_headerin(&m_vi, &m_vc, &op) < 0) {
pPacketBuff->Release();
return PNR_UNEXPECTED;
}
m_OggState = OggCommentHeader;
printf("Got Initial Header\n");
falling_through = 1;
// fall through intentional
case OggCommentHeader:
if (!falling_through) {
ogg_stream_pagein(&m_os, &og);
}
result = ogg_stream_packetout(&m_os, &op);
if (result < 0) {
pPacketBuff->Release();
return PNR_UNEXPECTED;
}
// need more data?
if (result == 0) break;
vorbis_synthesis_headerin(&m_vi, &m_vc, &op);
m_OggState = OggCodebookHeader;
printf("Got Comment Header\n");
falling_through = 1;
// fall through intentional
case OggCodebookHeader:
if (!falling_through) {
ogg_stream_pagein(&m_os, &og);
}
result = ogg_stream_packetout(&m_os, &op);
if (result < 0) {
pPacketBuff->Release();
return PNR_UNEXPECTED;
}
// need more data
if (result == 0) break;
vorbis_synthesis_headerin(&m_vi, &m_vc, &op);
vorbis_synthesis_init(&m_vd, &m_vi);
vorbis_block_init(&m_vd, &m_vb);
m_OggState = OggPlay;
printf("Got Codebooks\n");
falling_through = 1;
// fall through intentional
case OggPlay:
if (!falling_through) {
ogg_stream_pagein(&m_os, &og);
}
printf("OGG PAGE CAME IN\n");
while (ogg_stream_packetout(&m_os, &op) > 0) {
// we have a packet to decode
float **pcm;
int samples;
int convsize;
ogg_int16_t convbuffer[4096];
convsize = 4096 / m_vi.channels;
if (vorbis_synthesis(&m_vb, &op) == 0)
vorbis_synthesis_blockin(&m_vd, &m_vb);
else
printf("ERROR ? HMMMMMMM\n");
//printf("got a packet, get some samples\n");
while ((samples = vorbis_synthesis_pcmout(&m_vd, &pcm)) > 0) {
int i, j;
int clipflag = 0;
int bout = (samples < convsize ? samples : convsize);
// convert floats to 16bit signed ints (host order) and interleave
for (i = 0; i < m_vi.channels; i++) {
ogg_int16_t *ptr = convbuffer + i;
float *mono = pcm[i];
for (j = 0; j < bout; j++) {
int val = mono[j] * 32767.f;
// guard against clipping
if (val > 32767) {
val = 32767;
clipflag = 1;
}
if (val < -32768) {
val = -32768;
clipflag = 1;
}
*ptr = val;
ptr += 2;
}
}
// send to audio output
IRMABuffer *pBuffer = NULL;
char *tmp;
// create and fill a buffer
m_pClassFactory->CreateInstance(CLSID_IRMABuffer, (void **)&pBuffer);
if (pBuffer == NULL) {
printf("ERROR - no memory?\n");
return PNR_OUTOFMEMORY;
}
pBuffer->SetSize(bout * m_vi.channels * 2);
tmp = (char *)pBuffer->GetBuffer();
memcpy(tmp, convbuffer, bout * m_vi.channels * 2);
m_oldRealTime = CalcMs(m_totalSamples * 4);
m_totalSamples += bout;
RMAAudioData *pAudioData = new RMAAudioData;
pAudioData->pData = pBuffer;
pAudioData->ulAudioTime = m_oldRealTime;
printf("Sending %d samples (%ld ms) time = %d to audio out\n", bout, CalcMs(bout*4), m_oldRealTime);
//m_oldRealTime += CalcMs(bout * 4);
if (m_bIsGapInStreaming) {
pAudioData->uAudioStreamType = TIMED_AUDIO;
m_bIsGapInStreaming = FALSE;
} else {
pAudioData->uAudioStreamType = STREAMING_AUDIO;
}
m_PacketQueue.Add((void *)pAudioData);
//m_pAudioStream->Write(pAudioData);
//pAudioData->pData->Release();
//delete pAudioData;
// tell vorbis how many samples we consumed
vorbis_synthesis_read(&m_vd, bout);
}
//printf("done decoding packet\n");
}
//m_oldRealTime = lRealTime;
printf("old/real - %d/%d\n", m_oldRealTime, lRealTime);
printf("OGG PAGE DONE\n");
break;
default:
break;
}
}
pPacketBuff->Release();
}
return PNR_OK;
}
UINT32 CVorbisRenderer::CalcMs(UINT32 ulNumBytes)
{
return ((UINT32)((1000.0 / (m_audioFmt.uChannels * ((m_audioFmt.uBitsPerSample == 8) ? 1 : 2)
* m_audioFmt.ulSamplesPerSec)) * ulNumBytes));
}
STDMETHODIMP CVorbisRenderer::OnDryNotification(UINT32 ulCurrentStreamTime, UINT32 ulMinimumDurationRequired)
{
UINT32 ulNumMsWritten = 0;
RMAAudioData *pAudioData = (RMAAudioData *)m_PacketQueue.Remove();
while (pAudioData) {
m_pAudioStream->Write(pAudioData);
ulNumMsWritten += CalcMs(pAudioData->pData->GetSize());
pAudioData->pData->Release();
delete pAudioData;
if (ulNumMsWritten >= ulMinimumDurationRequired) break;
pAudioData = (RMAAudioData *)m_PacketQueue.Remove();
}
printf("needed %ldms sent %ldms...\n", ulMinimumDurationRequired, ulNumMsWritten);
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnTimeSync(UINT32 currentPlayBackTime)
{
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnPreSeek(UINT32 timeBeforeSeek, UINT32 timeAfterSeek)
{
m_bInSeekMode = TRUE;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnPostSeek(UINT32 timeBeforeSeek, UINT32 timeAfterSeek)
{
m_bInSeekMode = FALSE;
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnPause(UINT32 timeBeforePause)
{
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnBuffering(UINT32 reason, UINT16 percentComplete)
{
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::OnEndofPackets(void)
{
vorbis_comment_clear(&m_vc);
vorbis_info_clear(&m_vi);
ogg_stream_clear(&m_os);
ogg_sync_clear(&m_oy);
return PNR_OK;
}
STDMETHODIMP CVorbisRenderer::EndStream(void)
{
if (m_pClassFactory != NULL) {
m_pClassFactory->Release();
m_pClassFactory = NULL;
}
return PNR_OK;
}
CVorbisRenderer::~CVorbisRenderer(void)
{
EndStream();
}
STDMETHODIMP_(UINT32) CVorbisRenderer::AddRef(void)
{
return InterlockedIncrement(&m_RefCount);
}
STDMETHODIMP_(UINT32) CVorbisRenderer::Release(void)
{
if (InterlockedDecrement(&m_RefCount) > 0)
return m_RefCount;
delete this;
return 0;
}
STDMETHODIMP CVorbisRenderer::QueryInterface(REFIID interfaceID, void **ppInterfaceObj)
{
if (IsEqualIID(interfaceID, IID_IUnknown)) {
AddRef();
*ppInterfaceObj = (IUnknown *)(IRMAPlugin *)this;
return PNR_OK;
} else if (IsEqualIID(interfaceID, IID_IRMAPlugin)) {
AddRef();
*ppInterfaceObj = (IRMAPlugin *)this;
return PNR_OK;
} else if (IsEqualIID(interfaceID, IID_IRMARenderer)) {
AddRef();
*ppInterfaceObj = (IRMARenderer *)this;
return PNR_OK;
}
*ppInterfaceObj = NULL;
return PNR_NOINTERFACE;
}
1.1 vorbis-plugins/realplayer/render/rvorbis.h
Index: rvorbis.h
===================================================================
#ifndef __RVORBIS_H__
#define __RVORBIS_H__
#define PLUGIN_VERSION 0
#define DESCRIPTION "Ogg Vorbis Renderer Plugin"
#define COPYRIGHT "(c) 2001 Xiphophorus, All Rights Reserved"
#define MORE_INFO_URL "http://www.xiph.org"
#define STREAM_MIME_TYPES { "application/x-ogg", NULL }
#define TIME_SYNC_FREQ 100
typedef enum
{
OggInitialHeader,
OggCommentHeader,
OggCodebookHeader,
OggPlay
} OggState;
class CVorbisRenderer: public IRMARenderer,
public IRMAPlugin,
public IRMADryNotification
{
public:
CVorbisRenderer(void);
STDMETHOD(StartStream) (THIS_ IRMAStream *pStream, IRMAPlayer *pPlayer);
STDMETHOD(EndStream) (THIS);
STDMETHOD(OnHeader) (THIS_ IRMAValues *pStreamHeaderObj);
STDMETHOD(OnPacket) (THIS_ IRMAPacket *pPacketObj, INT32 timeOffset);
STDMETHOD(OnTimeSync) (THIS_ UINT32 currentPlayBackTime);
STDMETHOD(OnPreSeek) (THIS_ UINT32 timeBefore, UINT32 timeAfter);
STDMETHOD(OnPostSeek) (THIS_ UINT32 timeBefore, UINT32 timeAfter);
STDMETHOD(OnPause) (THIS_ UINT32 timeBeforePause);
STDMETHOD(OnBegin) (THIS_ UINT32 timeAfterBegin);
STDMETHOD(OnBuffering) (THIS_ UINT32 reason, UINT16 percentComplete);
STDMETHOD(GetRendererInfo)
(THIS_
REF(const char **) pStreamMimeTypes,
REF(UINT32) initialGranularity
);
STDMETHOD(GetDisplayType)
(THIS_
REF(RMA_DISPLAY_TYPE) displayType,
REF(IRMABuffer *) pDisplayInfo
);
STDMETHOD(OnEndofPackets) (THIS);
STDMETHOD(GetPluginInfo)
(THIS_
REF(BOOL) bLoadMultiple,
REF(const char *) pDescription,
REF(const char *) pCopyright,
REF(const char *) pMoreInfoURL,
REF(UINT32) versionNumber
);
STDMETHOD(InitPlugin) (THIS_ IUnknown *pRMACore);
// IRMADryNotification Interface
STDMETHOD(OnDryNotification)
(THIS_
UINT32 ulCurrentStreamTime,
UINT32 ulMinimumDurationRequired
);
STDMETHOD(QueryInterface) (THIS_ REFIID interfaceID, void **ppInterfaceObj);
STDMETHOD_(UINT32, AddRef) (THIS);
STDMETHOD_(UINT32, Release) (THIS);
private:
UINT32 CalcMs(UINT32 ulNumBytes);
~CVorbisRenderer(void);
INT32 m_RefCount;
IRMACommonClassFactory *m_pClassFactory;
BOOL m_bInSeekMode;
BOOL m_bIsGapInStreaming;
// vorbis decoding
OggState m_OggState;
ogg_sync_state m_oy;
ogg_stream_state m_os;
vorbis_info m_vi;
vorbis_comment m_vc;
vorbis_dsp_state m_vd;
vorbis_block m_vb;
// more stuff
ogg_int64_t m_totalSamples;
UINT32 m_oldRealTime;
IRMAStream *m_pStream;
IRMAPlayer *m_pPlayer;
IRMAAudioPlayer *m_pAudioPlayer;
IRMAAudioStream *m_pAudioStream;
RMAAudioFormat m_audioFmt;
FiveMinuteQueue m_PacketQueue;
static const char *zm_pDescription;
static const char *zm_pCopyright;
static const char *zm_pMoreInfoURL;
static const char *zm_pStreamMimeTypes[];
PRIVATE_DESTRUCTORS_ARE_NOT_A_CRIME
};
#endif // __RVORBIS_H__
1.1 vorbis-plugins/realplayer/render/make/linux-2.0-libc6-i386.mak
Index: linux-2.0-libc6-i386.mak
===================================================================
# UMAKE generated Makefile
# build choices: default,release
# platform: linux-2.0-libc6-i386
# Wed Feb 2 15:36:20 2000
.SUFFIXES: .cpp .so
.c.so:
$(CC) $(CCFLAGS) -fPIC -DPIC -o $@ -c $<
.cpp.so:
$(CXX) $(CXXFLAGS) -fPIC -DPIC -o $@ -c $<
RM = rm -f
RM_DIR = rm -rf
MAKE_DEP = makedep.py
MAKE_DEP_FLAGS = $(INCLUDES) $(DEFINES)
MAKE_LIB = ar cr
MAKE_LIB_FLAGS =
RANLIB = ranlib
CP = cp
MAKE = make
# Compilers
CC = gcc
CCFLAGS = -pipe -O2 $(INCLUDES) $(DEFINES)
CXX = g++
CXXFLAGS = -pipe -O2 $(INCLUDES) $(DEFINES)
# Linker
LD = g++
LDFLAGS = -shared -L/usr/X11R6/lib -L/usr/X11R6/lib
DEPLIBS =
DYNAMIC_LIBS = -logg -lvorbis
SRCS = \
../rvorbis.cpp \
../fivemque.cpp
OBJS = $(COMPILED_OBJS) $(SOURCE_OBJS)
COMPILED_OBJS = \
rel/obj/rvorbis.so \
rel/obj/fivemque.so
SOURCE_OBJS =
INCLUDES = \
-I/usr/X11R6/include \
-I/usr/X11R6/include \
-I/home/jack/download/rmasdk_6_0/include \
-I.. \
-I./pub
DEFINES = \
-D_LINUX \
-D_REENTRANT \
-D_UNIX \
-D_RED_HAT_5_X_
SYSLIBS =
LOCAL_LIBS =
rel/rvorbis.so : rel/obj $(OBJS) $(DEPLIBS)
if test -d rel; then echo; else mkdir rel; fi
$(LD) $(LDFLAGS) -o rel/rvorbis.so $(OBJS) $(DYNAMIC_LIBS) $(DEPLIBS) $(LOCAL_LIBS) $(SYSLIBS) -lgcc
clean::
$(RM) rel/rvorbis.so $(COMPILED_OBJS)
## OBJECT DEPENDANCIES
rel/obj:
if test -d rel; then echo; else mkdir rel; fi
if test -d rel/obj; then echo; else mkdir rel/obj; fi
rel/obj/rvorbis.so : ../rvorbis.cpp
$(CXX) $(CXXFLAGS) -fPIC -DPIC -o rel/obj/rvorbis.so -c ../rvorbis.cpp
rel/obj/fivemque.so : ../fivemque.cpp
$(CXX) $(CXXFLAGS) -fPIC -DPIC -o rel/obj/fivemque.so -c ../fivemque.cpp
copy:
if test -d ../release; then echo; else mkdir ../release; fi
cp rel/rvorbis.so ../release/rvorbis.so
depend:
$(MAKE_DEP) $(MAKE_DEP_FLAGS) rel/obj/ $(SRCS)
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list