no noisy AddPage. AddPage hack for OggTobiasStream dumps subtitles to stderr

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6540 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty
2004-02-09 01:30:44 +00:00
parent 350710ea5e
commit 59c2f096b7
5 changed files with 155 additions and 40 deletions
+1 -1
View File
@@ -65,7 +65,7 @@ OggStream::~OggStream()
status_t status_t
OggStream::AddPage(off_t position, const ogg_page & page) OggStream::AddPage(off_t position, const ogg_page & page)
{ {
TRACE("OggStream::AddPage\n"); // TRACE("OggStream::AddPage\n");
BAutolock autolock(fSyncLock); BAutolock autolock(fSyncLock);
char * buffer; char * buffer;
// copy the header to our local sync // copy the header to our local sync
+1 -1
View File
@@ -24,7 +24,7 @@ public:
virtual ~OggStream(); virtual ~OggStream();
// reader push input function // reader push input function
status_t AddPage(off_t position, const ogg_page & page); virtual status_t AddPage(off_t position, const ogg_page & page);
protected: protected:
// subclass pull input function // subclass pull input function
@@ -3,12 +3,14 @@
#include <MediaFormats.h> #include <MediaFormats.h>
#include <ogg/ogg.h> #include <ogg/ogg.h>
#include <string.h>
/* /*
* tobias descriptions/formats * tobias descriptions/formats
*/ */
// video
static media_format_description static media_format_description
tobias_video_description() tobias_video_description()
{ {
@@ -34,5 +36,32 @@ tobias_video_encoded_media_format()
return format; return format;
} }
// audio
// TODO: add these
// text
static media_format_description
tobias_text_description()
{
media_format_description description;
description.family = B_MISC_FORMAT_FAMILY;
description.u.misc.file_format = 'OggS';
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 #endif _OGG_TOBIAS_FORMATS_H
+120 -38
View File
@@ -40,7 +40,7 @@ typedef struct tobias_stream_header
ogg_int32_t size; // size of the structure ogg_int32_t size; // size of the structure
ogg_int64_t time_unit; // in reference time ogg_int64_t time_unit; // in reference time (100 ns units)
ogg_int64_t samples_per_unit; ogg_int64_t samples_per_unit;
ogg_int32_t default_len; // in media time ogg_int32_t default_len; // in media time
@@ -62,20 +62,99 @@ typedef struct tobias_stream_header
/* static */ bool /* static */ bool
OggTobiasStream::IsValidHeader(const ogg_packet & packet) OggTobiasStream::IsValidHeader(const ogg_packet & packet)
{ {
return findIdentifier(packet,"video",1); return findIdentifier(packet,"video",1)
|| findIdentifier(packet,"audio",1)
|| findIdentifier(packet,"text",1);
} }
OggTobiasStream::OggTobiasStream(long serialno) OggTobiasStream::OggTobiasStream(long serialno)
: OggStream(serialno) : OggStream(serialno)
{ {
TRACE("OggTobiasStream::OggTobiasStream\n"); TRACE("OggTobiasStream::OggTobiasStream\n");
fMicrosecPerFrame = 0;
} }
OggTobiasStream::~OggTobiasStream() OggTobiasStream::~OggTobiasStream()
{ {
TRACE("OggTobiasStream::~OggTobiasStream\n"); 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 status_t
OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
media_format *format) media_format *format)
@@ -105,40 +184,27 @@ OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
tobias_stream_header * header = (tobias_stream_header *)data; tobias_stream_header * header = (tobias_stream_header *)data;
if (strcmp(header->streamtype, "video") == 0) { if (strcmp(header->streamtype, "video") == 0) {
// get the format for the description result = get_video_format(header, format);
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;
result = formats.InitCheck();
if (result == B_OK) {
result = formats.GetFormatFor(description, format);
}
if (result != B_OK) { if (result != B_OK) {
*format = tobias_video_encoded_media_format(); return result;
// ignore error, allow user to use ReadChunk interface
} }
*frameCount = (bigtime_t)(3 * 3600 * format->u.encoded_video.output.field_rate);
// fill out format from header packet } else if (strcmp(header->streamtype, "audio") == 0) {
format->user_data_type = B_CODEC_TYPE_INFO; result = get_audio_format(header, format);
strncpy((char*)format->user_data, header->subtype, 4); if (result != B_OK) {
format->u.encoded_video.frame_size return result;
= header->video.width * header->video.height; }
format->u.encoded_video.output.field_rate = 10000000.0 / header->time_unit; *frameCount = 2000000;
format->u.encoded_video.output.interlace = 1; } else if (strcmp(header->streamtype, "text") == 0) {
format->u.encoded_video.output.first_active = 0; result = get_text_format(header, format);
format->u.encoded_video.output.last_active = header->video.height - 1; if (result != B_OK) {
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT; return result;
format->u.encoded_video.output.pixel_width_aspect = 1; }
format->u.encoded_video.output.pixel_height_aspect = 1; *frameCount = 2000000;
format->u.encoded_video.output.display.line_width = header->video.width; } else {
format->u.encoded_video.output.display.line_count = header->video.height; *frameCount = 0;
format->u.encoded_video.output.display.bytes_per_row = 0; // unknown streamtype
format->u.encoded_video.output.display.pixel_offset = 0; return B_BAD_VALUE;
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
} }
// get comment packet // get comment packet
@@ -151,12 +217,13 @@ OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
} }
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
*frameCount = 2000000;
*duration = *frameCount * format->u.encoded_video.output.field_rate;
fMediaFormat = *format; fMediaFormat = *format;
fMicrosecPerFrame = header->time_unit / 10.0;
*duration = (bigtime_t)(*frameCount * fMicrosecPerFrame);
return B_OK; return B_OK;
} }
status_t status_t
OggTobiasStream::GetNextChunk(void **chunkBuffer, int32 *chunkSize, OggTobiasStream::GetNextChunk(void **chunkBuffer, int32 *chunkSize,
media_header *mediaHeader) media_header *mediaHeader)
@@ -177,8 +244,23 @@ OggTobiasStream::GetNextChunk(void **chunkBuffer, int32 *chunkSize,
= fMediaFormat.u.encoded_video.output.first_active; = fMediaFormat.u.encoded_video.output.first_active;
mediaHeader->u.encoded_video.line_count mediaHeader->u.encoded_video.line_count
= fMediaFormat.u.encoded_video.output.display.line_count; = fMediaFormat.u.encoded_video.output.display.line_count;
fCurrentFrame++;
fCurrentTime = 1000000LL * fCurrentFrame / fMediaFormat.u.encoded_video.output.field_rate;
} }
fCurrentFrame++;
fCurrentTime = (bigtime_t)(fCurrentFrame * fMicrosecPerFrame);
return B_OK; 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;
}
@@ -17,8 +17,12 @@ public:
virtual status_t GetNextChunk(void **chunkBuffer, int32 *chunkSize, virtual status_t GetNextChunk(void **chunkBuffer, int32 *chunkSize,
media_header *mediaHeader); media_header *mediaHeader);
// reader push input function
virtual status_t AddPage(off_t position, const ogg_page & page);
private: private:
media_format fMediaFormat; media_format fMediaFormat;
double fMicrosecPerFrame;
}; };
} } // namespace BPrivate::media } } // namespace BPrivate::media