initial implementation
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9823 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
685eec2577
commit
08229584f5
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Marcus Overhagen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <DataIO.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <MediaFormats.h>
|
||||
#include "RawFormats.h"
|
||||
#include "matroska_reader.h"
|
||||
|
||||
#define TRACE_MKV_READER
|
||||
#ifdef TRACE_MKV_READER
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
#define ERROR(a...) fprintf(stderr, a)
|
||||
|
||||
|
||||
enum {
|
||||
TRACK_TYPE_VIDEO = 1,
|
||||
TRACK_TYPE_AUDIO = 2,
|
||||
TRACK_TYPE_TEXT = 17,
|
||||
};
|
||||
|
||||
|
||||
struct mkv_cookie
|
||||
{
|
||||
unsigned stream;
|
||||
char * buffer;
|
||||
unsigned buffer_size;
|
||||
|
||||
const TrackInfo *track_info;
|
||||
|
||||
int64 frame_count;
|
||||
bigtime_t duration;
|
||||
media_format format;
|
||||
/*
|
||||
bool audio;
|
||||
|
||||
// audio only:
|
||||
int64 byte_pos;
|
||||
uint32 bytes_per_sec_rate;
|
||||
uint32 bytes_per_sec_scale;
|
||||
|
||||
// video only:
|
||||
uint32 frame_pos;
|
||||
uint32 frames_per_sec_rate;
|
||||
uint32 frames_per_sec_scale;
|
||||
uint32 line_count;
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
mkvReader::mkvReader()
|
||||
: fFileCache(0)
|
||||
, fFile(0)
|
||||
, fFileInfo(0)
|
||||
{
|
||||
TRACE("mkvReader::mkvReader\n");
|
||||
}
|
||||
|
||||
|
||||
mkvReader::~mkvReader()
|
||||
{
|
||||
mkv_Close(fFile);
|
||||
free(fFileCache);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
mkvReader::Copyright()
|
||||
{
|
||||
return "Matroska reader, " B_UTF8_COPYRIGHT " by Marcus Overhagen";
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::Sniff(int32 *streamCount)
|
||||
{
|
||||
TRACE("mkvReader::Sniff\n");
|
||||
|
||||
char err_msg[100];
|
||||
|
||||
fFileCache = CreateFileCache(Source());
|
||||
if (!fFileCache) {
|
||||
TRACE("mkvReader::Sniff: failed to create file cache\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fFile = mkv_Open(fFileCache, err_msg, sizeof(err_msg));
|
||||
if (!fFile) {
|
||||
TRACE("mkvReader::Sniff: open failed, error: %s\n", err_msg);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fFileInfo = mkv_GetFileInfo(fFile);
|
||||
|
||||
*streamCount = mkv_GetNumTracks(fFile);
|
||||
|
||||
TRACE("mkvReader::Sniff: file has %ld streams\n", *streamCount);
|
||||
TRACE("mkvReader::Sniff: TimecodeScale %Ld\n", fFileInfo->TimecodeScale);
|
||||
TRACE("mkvReader::Sniff: Duration %Ld\n", fFileInfo->Duration);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
mkvReader::GetFileFormatInfo(media_file_format *mff)
|
||||
{
|
||||
mff->capabilities = media_file_format::B_READABLE
|
||||
| media_file_format::B_KNOWS_ENCODED_VIDEO
|
||||
| media_file_format::B_KNOWS_ENCODED_AUDIO
|
||||
| media_file_format::B_IMPERFECTLY_SEEKABLE;
|
||||
mff->family = B_MISC_FORMAT_FAMILY;
|
||||
mff->version = 100;
|
||||
strcpy(mff->mime_type, "video/x-matroska"); // "audio/x-matroska"
|
||||
strcpy(mff->file_extension, "mkv");
|
||||
strcpy(mff->short_name, "Matroska");
|
||||
strcpy(mff->pretty_name, "Matroska file format");
|
||||
}
|
||||
|
||||
status_t
|
||||
mkvReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
||||
{
|
||||
mkv_cookie *cookie = new mkv_cookie;
|
||||
*_cookie = cookie;
|
||||
|
||||
TRACE("mkvReader::AllocateCookie: stream %ld\n", streamNumber);
|
||||
|
||||
cookie->stream = streamNumber;
|
||||
cookie->buffer = 0;
|
||||
cookie->buffer_size = 0;
|
||||
cookie->track_info = mkv_GetTrackInfo(fFile, streamNumber);
|
||||
|
||||
// TRACE("Number: %d\n", cookie->track_info->Number);
|
||||
// TRACE("Type: %d\n", cookie->track_info->Type);
|
||||
// TRACE("TrackOverlay: %d\n", cookie->track_info->TrackOverlay);
|
||||
// TRACE("UID: %Ld\n", cookie->track_info->UID);
|
||||
// TRACE("MinCache: %Ld\n", cookie->track_info->MinCache);
|
||||
// TRACE("MaxCache: %Ld\n", cookie->track_info->MaxCache);
|
||||
TRACE("DefaultDuration: %Ld\n", cookie->track_info->DefaultDuration);
|
||||
TRACE("TimecodeScale: %.6f\n", cookie->track_info->TimecodeScale);
|
||||
TRACE("Name: %s\n", cookie->track_info->Name);
|
||||
TRACE("Language: %s\n", cookie->track_info->Language);
|
||||
TRACE("CodecID: %s\n", cookie->track_info->CodecID);
|
||||
|
||||
status_t status;
|
||||
switch (cookie->track_info->Type) {
|
||||
case TRACK_TYPE_VIDEO:
|
||||
status = SetupVideoCookie(cookie);
|
||||
break;
|
||||
case TRACK_TYPE_AUDIO:
|
||||
status = SetupAudioCookie(cookie);
|
||||
break;
|
||||
case TRACK_TYPE_TEXT:
|
||||
status = SetupTextCookie(cookie);
|
||||
break;
|
||||
default:
|
||||
TRACE("unknown track type %d\n", cookie->track_info->Type);
|
||||
status = B_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != B_OK)
|
||||
delete cookie;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::SetupVideoCookie(mkv_cookie *cookie)
|
||||
{
|
||||
TRACE("video StereoMode: %d\n", cookie->track_info->Video.StereoMode);
|
||||
TRACE("video DisplayUnit: %d\n", cookie->track_info->Video.DisplayUnit);
|
||||
TRACE("video AspectRatioType: %d\n", cookie->track_info->Video.AspectRatioType);
|
||||
TRACE("video PixelWidth: %d\n", cookie->track_info->Video.PixelWidth);
|
||||
TRACE("video PixelHeight: %d\n", cookie->track_info->Video.PixelHeight);
|
||||
TRACE("video DisplayWidth: %d\n", cookie->track_info->Video.DisplayWidth);
|
||||
TRACE("video DisplayHeight: %d\n", cookie->track_info->Video.DisplayHeight);
|
||||
TRACE("video ColourSpace: %d\n", cookie->track_info->Video.ColourSpace);
|
||||
TRACE("video GammaValue: %.4f\n", cookie->track_info->Video.GammaValue);
|
||||
TRACE("video Interlaced: %d\n", cookie->track_info->Video.Interlaced);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::SetupAudioCookie(mkv_cookie *cookie)
|
||||
{
|
||||
TRACE("audio SamplingFreq: %.3f\n", cookie->track_info->Audio.SamplingFreq);
|
||||
TRACE("audio OutputSamplingFreq: %.3f\n", cookie->track_info->Audio.OutputSamplingFreq);
|
||||
TRACE("audio Channels: %d\n", cookie->track_info->Audio.Channels);
|
||||
TRACE("audio BitDepth: %d\n", cookie->track_info->Audio.BitDepth);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::SetupTextCookie(mkv_cookie *cookie)
|
||||
{
|
||||
TRACE("text\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::FreeCookie(void *_cookie)
|
||||
{
|
||||
mkv_cookie *cookie = (mkv_cookie *)_cookie;
|
||||
|
||||
delete [] cookie->buffer;
|
||||
|
||||
delete cookie;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format, void **infoBuffer, int32 *infoSize)
|
||||
{
|
||||
mkv_cookie *cookie = (mkv_cookie *)_cookie;
|
||||
*frameCount = cookie->frame_count;
|
||||
*duration = cookie->duration;
|
||||
*format = cookie->format;
|
||||
*infoBuffer = 0;
|
||||
*infoSize = 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::Seek(void *cookie,
|
||||
uint32 seekTo,
|
||||
int64 *frame, bigtime_t *time)
|
||||
{
|
||||
TRACE("mkvReader::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n",
|
||||
(seekTo & B_MEDIA_SEEK_TO_TIME) ? " B_MEDIA_SEEK_TO_TIME" : "",
|
||||
(seekTo & B_MEDIA_SEEK_TO_FRAME) ? " B_MEDIA_SEEK_TO_FRAME" : "",
|
||||
(seekTo & B_MEDIA_SEEK_CLOSEST_FORWARD) ? " B_MEDIA_SEEK_CLOSEST_FORWARD" : "",
|
||||
(seekTo & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? " B_MEDIA_SEEK_CLOSEST_BACKWARD" : "",
|
||||
*time, *frame);
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
mkvReader::GetNextChunk(void *_cookie,
|
||||
void **chunkBuffer, int32 *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
mkv_cookie *cookie = (mkv_cookie *)_cookie;
|
||||
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
Reader *
|
||||
mkvReaderPlugin::NewReader()
|
||||
{
|
||||
return new mkvReader;
|
||||
}
|
||||
|
||||
|
||||
MediaPlugin *instantiate_plugin()
|
||||
{
|
||||
return new mkvReaderPlugin;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Marcus Overhagen
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _MATROSKA_READER_H
|
||||
#define _MATROSKA_READER_H
|
||||
|
||||
#include "ReaderPlugin.h"
|
||||
#include "libMatroskaParser/StreamIO.h"
|
||||
|
||||
struct mkv_cookie;
|
||||
|
||||
class mkvReader : public Reader
|
||||
{
|
||||
public:
|
||||
mkvReader();
|
||||
~mkvReader();
|
||||
|
||||
const char *Copyright();
|
||||
|
||||
status_t Sniff(int32 *streamCount);
|
||||
|
||||
void GetFileFormatInfo(media_file_format *mff);
|
||||
|
||||
status_t AllocateCookie(int32 streamNumber, void **cookie);
|
||||
status_t FreeCookie(void *cookie);
|
||||
|
||||
status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format, void **infoBuffer, int32 *infoSize);
|
||||
|
||||
status_t Seek(void *cookie,
|
||||
uint32 seekTo,
|
||||
int64 *frame, bigtime_t *time);
|
||||
|
||||
status_t GetNextChunk(void *cookie,
|
||||
void **chunkBuffer, int32 *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
private:
|
||||
status_t SetupVideoCookie(mkv_cookie *cookie);
|
||||
status_t SetupAudioCookie(mkv_cookie *cookie);
|
||||
status_t SetupTextCookie(mkv_cookie *cookie);
|
||||
|
||||
private:
|
||||
FileCache * fFileCache;
|
||||
MatroskaFile * fFile;
|
||||
const SegmentInfo * fFileInfo;
|
||||
};
|
||||
|
||||
|
||||
class mkvReaderPlugin : public ReaderPlugin
|
||||
{
|
||||
public:
|
||||
Reader *NewReader();
|
||||
};
|
||||
|
||||
MediaPlugin *instantiate_plugin();
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user