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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user