compilable, missing seek, getnextchunk

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5757 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty
2003-12-26 04:42:41 +00:00
parent 3a9ada71c5
commit 8267371e90
3 changed files with 135 additions and 48 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ SubDir OBOS_TOP src add-ons media plugins ogg ;
UsePrivateHeaders media ;
SubDirHdrs $(SUBDIR) libogg ogg ;
SubDirHdrs [ FDirName $(SUBDIR) libogg ] ;
Addon ogg : media plugins :
OggReaderPlugin.cpp
+129 -42
View File
@@ -19,15 +19,13 @@
oggReader::oggReader()
{
TRACE("oggReader::oggReader\n");
ogg_stream_init(&fOggStreamState,(int)this);
ogg_sync_init(&fOggSyncState);
ogg_sync_init(&fSync);
}
oggReader::~oggReader()
{
ogg_stream_destroy(&fOggStreamState);
ogg_sync_destroy(&fOggSyncState);
ogg_sync_destroy(&fSync);
}
@@ -42,47 +40,116 @@ status_t
oggReader::Sniff(int32 *streamCount)
{
TRACE("oggReader::Sniff\n");
fSeekableSource = dynamic_cast<BPositionIO *>(Reader::Source());
if (!fSeekableSource) {
TRACE("oggReader::Sniff: not a BPositionIO\n");
return B_ERROR;
}
fSeekableSource->Seek(0,SEEK_SET);
ogg_sync_state sync;
ogg_sync_init(&sync);
char * buffer = 0;
ssize_t bytes = 0;
ogg_page page;
buffer = ogg_sync_buffer(&sync,4096);
bytes = fSeekableSource->Read(buffer,4096);
ogg_sync_pageout(&fSync,&page); // clear the buffer
char * buffer = ogg_sync_buffer(&fSync,4096);
ssize_t bytes = Source()->Read(buffer,4096);
if (bytes < 4096) {
TRACE("oggReader::Sniff: Read: not enough: not ogg\n");
ogg_sync_destroy(&sync);
return B_ERROR;
}
if (ogg_sync_wrote(&fSync,bytes) != 0) {
TRACE("oggReader::Sniff: ogg_sync_wrote failed?: bail\n");
return B_ERROR;
}
ogg_sync_wrote(&sync,bytes);
if (bytesogg_sync_pageout(&sync,&page) != 1) {
TRACE("oggReader::Sniff: ogg_sync_pageout error: not ogg\n");
ogg_sync_destroy(&sync);
switch ((int)ogg_sync_pageout(&fSync,&page)) {
case -1:
TRACE("oggReader::Sniff: ogg_sync_pageout: not synced: not ogg\n");
return B_ERROR;
case 0:
TRACE("oggReader::Sniff: ogg_sync_pageout: need more data: not ogg\n");
return B_ERROR;
case 1:
TRACE("oggReader::Sniff: looks like a valid ogg page\n");
break;
default:
TRACE("oggReader::Sniff: ogg_sync_pageout: unexpected result: bail\n");
return B_ERROR;
}
// page sanity checks
if (ogg_page_version(&page) != 0) {
TRACE("oggReader::Sniff: ogg_sync_version: error in page encoding: not ogg\n");
return B_ERROR;
}
if (ogg_page_continued(&page) != 0) {
TRACE("oggReader::Sniff: ogg_page_continued: continued page: not ogg\n");
return B_ERROR;
}
if (ogg_page_bos(&page) == 0) {
TRACE("oggReader::Sniff: ogg_page_bos: not beginning of a bitstream: not ogg\n");
return B_ERROR;
}
// seems like ogg
// TODO: count the streams
*streamCount = 1;
/* ogg_stream_state stream;
ogg_stream_init(&stream,ogg_page_serial_no(&page);
ogg_stream_pagein(&stream,&page);
ogg_packet packet;
ogg_stream_packetout(&stream,&packet);*/
ogg_stream_state stream;
if (ogg_stream_init(&stream,ogg_page_serialno(&page)) != 0) {
TRACE("oggReader::Sniff: ogg_stream_init: failed: bail\n");
return B_ERROR;
}
if (ogg_stream_pagein(&stream,&page) != 0) {
TRACE("oggReader::Sniff: ogg_stream_pagein: failed: bail\n");
return B_ERROR;
}
fStreams[ogg_page_serialno(&page)] = stream;
while (true) {
buffer = ogg_sync_buffer(&fSync,4096);
bytes = Source()->Read(buffer,4096);
if (bytes < 4096) {
TRACE("oggReader::Sniff: Read: not enough: not ogg\n");
return B_ERROR;
}
if (ogg_sync_wrote(&fSync,bytes) != 0) {
TRACE("oggReader::Sniff: ogg_sync_wrote failed?: bail\n");
return B_ERROR;
}
int result = ogg_sync_pageout(&fSync,&page);
if (result == -1) {
TRACE("oggReader::Sniff: ogg_sync_pageout: not synced: not ogg\n");
return B_ERROR;
} else if (result == 0) {
// need more data to complete an ogg page
} else if (result == 1) {
// valid ogg page
if (ogg_page_version(&page) != 0) {
TRACE("oggReader::Sniff: ogg_sync_version: error in page encoding: not ogg\n");
return B_ERROR;
}
if (ogg_page_bos(&page) == 0) {
// not start of stream
break;
}
// new stream
if (ogg_stream_init(&stream,ogg_page_serialno(&page)) != 0) {
TRACE("oggReader::Sniff: ogg_stream_init: failed: bail\n");
return B_ERROR;
}
if (ogg_stream_pagein(&stream,&page) != 0) {
TRACE("oggReader::Sniff: ogg_stream_pagein: failed: bail\n");
return B_ERROR;
}
// we don't check for unique-ness of start pages. we accept duplication.
fStreams[ogg_page_serialno(&page)] = stream;
} else {
TRACE("oggReader::Sniff: ogg_sync_pageout: unexpected result: bail\n");
return B_ERROR;
}
}
// last page needs to be put into the right stream
ogg_stream_map::iterator i = fStreams.find(ogg_page_serialno(&page));
if (i == fStreams.end()) {
// the next page doesn't belong to any existing stream?
return B_ERROR;
}
if (ogg_stream_pagein(&i->second,&page) != 0) {
TRACE("oggReader::Sniff: ogg_stream_pagein: failed: bail\n");
return B_ERROR;
}
*streamCount = fStreams.size();
return B_OK;
}
void
oggReader::GetFileFormatInfo(media_file_format *mff)
{
@@ -90,14 +157,11 @@ oggReader::GetFileFormatInfo(media_file_format *mff)
| media_file_format::B_KNOWS_ENCODED_VIDEO
| media_file_format::B_KNOWS_ENCODED_AUDIO
| media_file_format::B_IMPERFECTLY_SEEKABLE;
mff->family = B_OGG_FORMAT_FAMILY;
mff->family = B_MISC_FORMAT_FAMILY;
mff->version = 100;
strcpy(mff->mime_type, "application/ogg");
strcpy(mff->file_extension, "ogg");
// uint8 header[4];
// Source()->ReadAt(fDataStart, header, sizeof(header));
strcpy(mff->short_name, "Ogg");
strcpy(mff->short_name, "Ogg");
strcpy(mff->pretty_name, "Ogg bitstream");
}
@@ -106,9 +170,17 @@ status_t
oggReader::AllocateCookie(int32 streamNumber, void **cookie)
{
TRACE("oggReader::AllocateCookie\n");
ogg_stream_map::iterator i = fStreams.begin();
while (streamNumber > 0) {
if (i == fStreams.end()) {
TRACE("oggReader::AllocateCookie: invalid streamNumber: bail\n");
return B_ERROR;
}
i++;
streamNumber--;
}
// store the cookie
*cookie = data;
*cookie = (void*)(&i->second);
return B_OK;
}
@@ -125,6 +197,13 @@ status_t
oggReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
media_format *format, void **infoBuffer, int32 *infoSize)
{
TRACE("oggReader::GetStreamInfo\n");
ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie);
*frameCount = -1; // don't know
*duration = -1; // don't know
// no info
*infoBuffer = 0;
*infoSize = 0;
return B_OK;
}
@@ -134,10 +213,15 @@ oggReader::Seek(void *cookie,
uint32 seekTo,
int64 *frame, bigtime_t *time)
{
if (!fSeekableSource)
TRACE("oggReader::Seek\n");
BPositionIO * input = dynamic_cast<BPositionIO *>(Source());
if (input == 0) {
TRACE("oggReader::Seek: not a PositionIO: not seekable\n");
return B_ERROR;
}
ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie);
ogg_sync_reset
return B_OK;
}
@@ -147,6 +231,9 @@ oggReader::GetNextChunk(void *cookie,
void **chunkBuffer, int32 *chunkSize,
media_header *mediaHeader)
{
ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie);
return B_OK;
}
@@ -3,9 +3,12 @@
#include "ReaderPlugin.h"
#include "ogg/ogg.h"
#include <map>
namespace BPrivate { namespace media {
typedef std::map<int,ogg_stream_state> ogg_stream_map;
class oggReader : public Reader
{
public:
@@ -32,12 +35,9 @@ public:
void **chunkBuffer, int32 *chunkSize,
media_header *mediaHeader);
BPositionIO *Source() { return fSeekableSource; }
private:
BPositionIO * fSeekableSource;
ogg_stream_state fOggStreamState;
ogg_sync_state fOggSyncState;
ogg_sync_state fSync;
ogg_stream_map fStreams;
};