From 59c2f096b7a12746db4e6916894e8126d2b3b6b2 Mon Sep 17 00:00:00 2001 From: shatty Date: Mon, 9 Feb 2004 01:30:44 +0000 Subject: [PATCH] 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 --- src/add-ons/media/plugins/ogg/OggStream.cpp | 2 +- src/add-ons/media/plugins/ogg/OggStream.h | 2 +- .../media/plugins/ogg/OggTobiasFormats.h | 29 ++++ .../media/plugins/ogg/OggTobiasStream.cpp | 158 +++++++++++++----- .../media/plugins/ogg/OggTobiasStream.h | 4 + 5 files changed, 155 insertions(+), 40 deletions(-) diff --git a/src/add-ons/media/plugins/ogg/OggStream.cpp b/src/add-ons/media/plugins/ogg/OggStream.cpp index 5a6eb0aa3d..76700fcf69 100644 --- a/src/add-ons/media/plugins/ogg/OggStream.cpp +++ b/src/add-ons/media/plugins/ogg/OggStream.cpp @@ -65,7 +65,7 @@ OggStream::~OggStream() status_t OggStream::AddPage(off_t position, const ogg_page & page) { - TRACE("OggStream::AddPage\n"); +// TRACE("OggStream::AddPage\n"); BAutolock autolock(fSyncLock); char * buffer; // copy the header to our local sync diff --git a/src/add-ons/media/plugins/ogg/OggStream.h b/src/add-ons/media/plugins/ogg/OggStream.h index 751b372dc5..cf241bc420 100644 --- a/src/add-ons/media/plugins/ogg/OggStream.h +++ b/src/add-ons/media/plugins/ogg/OggStream.h @@ -24,7 +24,7 @@ public: virtual ~OggStream(); // 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: // subclass pull input function diff --git a/src/add-ons/media/plugins/ogg/OggTobiasFormats.h b/src/add-ons/media/plugins/ogg/OggTobiasFormats.h index ecca23410e..509ef59a09 100644 --- a/src/add-ons/media/plugins/ogg/OggTobiasFormats.h +++ b/src/add-ons/media/plugins/ogg/OggTobiasFormats.h @@ -3,12 +3,14 @@ #include #include +#include /* * tobias descriptions/formats */ +// video static media_format_description tobias_video_description() { @@ -34,5 +36,32 @@ tobias_video_encoded_media_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 diff --git a/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp b/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp index 3d999676f5..9175c91f0d 100644 --- a/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp +++ b/src/add-ons/media/plugins/ogg/OggTobiasStream.cpp @@ -40,7 +40,7 @@ typedef struct tobias_stream_header 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_int32_t default_len; // in media time @@ -62,20 +62,99 @@ typedef struct tobias_stream_header /* static */ bool 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) : 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) @@ -105,40 +184,27 @@ OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, tobias_stream_header * header = (tobias_stream_header *)data; if (strcmp(header->streamtype, "video") == 0) { - // 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; - result = formats.InitCheck(); - if (result == B_OK) { - result = formats.GetFormatFor(description, format); - } + result = get_video_format(header, format); if (result != B_OK) { - *format = tobias_video_encoded_media_format(); - // ignore error, allow user to use ReadChunk interface + return result; } - - // 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 + *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 @@ -151,12 +217,13 @@ OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration, } format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); - *frameCount = 2000000; - *duration = *frameCount * format->u.encoded_video.output.field_rate; fMediaFormat = *format; + fMicrosecPerFrame = header->time_unit / 10.0; + *duration = (bigtime_t)(*frameCount * fMicrosecPerFrame); return B_OK; } + status_t OggTobiasStream::GetNextChunk(void **chunkBuffer, int32 *chunkSize, media_header *mediaHeader) @@ -177,8 +244,23 @@ OggTobiasStream::GetNextChunk(void **chunkBuffer, int32 *chunkSize, = fMediaFormat.u.encoded_video.output.first_active; mediaHeader->u.encoded_video.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; } + + +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 index fa5d83e06b..c9e27d531e 100644 --- a/src/add-ons/media/plugins/ogg/OggTobiasStream.h +++ b/src/add-ons/media/plugins/ogg/OggTobiasStream.h @@ -17,8 +17,12 @@ public: virtual status_t GetNextChunk(void **chunkBuffer, int32 *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