[Matroska-cvs] [matroska] r1250 - trunk/foo_matroska
ayana at matroska.org
ayana at matroska.org
Sun Apr 30 14:46:27 CEST 2006
Author: ayana
Date: 2006-04-30 16:46:18 +0400 (Sun, 30 Apr 2006)
New Revision: 1250
Added:
trunk/foo_matroska/foo_input_matroska.rc
trunk/foo_matroska/foo_input_matroska.vcproj
Removed:
trunk/foo_matroska/foo_matroska.dsp
trunk/foo_matroska/foo_matroska.rc
Modified:
trunk/foo_matroska/DbgOut.h
trunk/foo_matroska/Foobar2000ReaderIOCallback.h
trunk/foo_matroska/foo_input_matroska.cpp
trunk/foo_matroska/matroska_parser.cpp
trunk/foo_matroska/matroska_parser.h
Log:
poted to foobar2000 0.9.x
Modified: trunk/foo_matroska/DbgOut.h
===================================================================
--- trunk/foo_matroska/DbgOut.h 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/DbgOut.h 2006-04-30 12:46:18 UTC (rev 1250)
@@ -24,6 +24,27 @@
#ifdef _DEBUG
//#define DEBUG_OUT_PUT
+#include <tchar.h>
+#include <stdarg.h>
+#define HPRINTF_MES_LENGTH 256
+inline void hprintf( const _TCHAR * format, ... )
+{
+ _TCHAR buff[HPRINTF_MES_LENGTH];
+ va_list vl;
+ va_start(vl, format);
+ _vsntprintf(buff, HPRINTF_MES_LENGTH, format, vl);
+ va_end(vl);
+ OutputDebugString(buff);
+}
+#include <boost/timer.hpp>
+#define TIMER boost::timer t
+#define RETIMER t.restart()
+#define _TIMER(x) hprintf(L"%S: %f sec.\n",x,t.elapsed())
+#else
+#define TIMER __noop
+#define RETIMER __noop
+#define _TIMER(x) __noop
+#define hprintf __noop
#endif
#ifdef DEBUG_OUT_PUT
Modified: trunk/foo_matroska/Foobar2000ReaderIOCallback.h
===================================================================
--- trunk/foo_matroska/Foobar2000ReaderIOCallback.h 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/Foobar2000ReaderIOCallback.h 2006-04-30 12:46:18 UTC (rev 1250)
@@ -23,13 +23,16 @@
class Foobar2000ReaderIOCallback : public IOCallback {
public:
- Foobar2000ReaderIOCallback(reader *source) {
+ Foobar2000ReaderIOCallback(service_ptr_t<file> source, abort_callback & p_abort)
+ : m_abort(p_abort)
+ {
m_NoSeekReader = NULL;
m_Reader = source;
- m_Reader->service_add_ref();
+ m_abort = p_abort;
+ //m_Reader->service_add_ref();
if (!m_Reader->can_seek()) {
m_NoSeekReader = source;
- m_Reader = new service_impl_p2_t<reader_seekback_wrap,reader*,unsigned>(source, 1024*1024);
+ //m_Reader = new service_impl_p2_t<reader_seekback_wrap,service_ptr_t<file>,unsigned>(source, 1024*1024);
}
};
virtual ~Foobar2000ReaderIOCallback() {
@@ -37,20 +40,20 @@
};
virtual uint32 read(void*Buffer, size_t Size) {
- return m_Reader->read(Buffer, Size);
+ return m_Reader->read(Buffer, Size, m_abort);
};
virtual void setFilePointer(int64 Offset, seek_mode Mode=seek_beginning) {
switch (Mode)
{
case seek_beginning:
- m_Reader->seek(Offset);
+ m_Reader->seek(Offset, m_abort);
break;
case seek_current:
- m_Reader->seek2(Offset, SEEK_CUR);
+ m_Reader->seek_ex(Offset, file::t_seek_mode::seek_from_current, m_abort);
break;
case seek_end:
- m_Reader->seek2(Offset, SEEK_END);
+ m_Reader->seek_ex(Offset, file::t_seek_mode::seek_from_eof, m_abort);
break;
default:
//throw "Invalid Seek Mode!!!";
@@ -59,20 +62,21 @@
}
virtual size_t write(const void*Buffer, size_t Size) {
- return m_Reader->write(Buffer, Size);
+ m_Reader->write(Buffer, Size, m_abort);
+ return Size;
}
virtual uint64 getFilePointer() {
- return m_Reader->get_position();
+ return m_Reader->get_position(m_abort);
};
virtual void close() {
if (m_Reader != NULL) {
- m_Reader->service_release();
+ //m_Reader->service_release();
m_Reader = NULL;
}
if (m_NoSeekReader != NULL) {
- m_NoSeekReader->service_release();
+ //m_NoSeekReader->service_release();
m_NoSeekReader = NULL;
}
}
@@ -85,12 +89,14 @@
bool truncate()
{
- return m_Reader->set_eof();
+ m_Reader->set_eof(m_abort);
+ return true;
}
protected:
- reader *m_Reader;
- reader *m_NoSeekReader;
+ service_ptr_t<file> m_Reader;
+ service_ptr_t<file> m_NoSeekReader;
+ abort_callback & m_abort;
};
#endif // _FOOBAR2000_IO_CALLBACK_H_
Modified: trunk/foo_matroska/foo_input_matroska.cpp
===================================================================
--- trunk/foo_matroska/foo_input_matroska.cpp 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/foo_input_matroska.cpp 2006-04-30 12:46:18 UTC (rev 1250)
@@ -56,25 +56,27 @@
#include <commctrl.h>
#include <Shlwapi.h>
#include <time.h>
+#include "matroska_parser.h"
#include "resource.h"
-#include "matroska_parser.h"
#include "DbgOut.h"
-class input_matroska : public input
+class input_matroska
{
MatroskaAudioParser *m_parser;
- reader *m_matroskaFile;
- packet_decoder *m_decoder;
+ service_ptr_t<packet_decoder> m_decoder;
+ t_input_open_reason m_reason;
int m_TrackNo;
+ int m_subsong;
// Compressed data frame
MatroskaAudioFrame * m_frame;
unsigned m_frame_remaining;
- unsigned m_skip_samples;
- unsigned m_skip_frames;
+ uint64 m_skip_samples;
+ uint64 m_skip_frames;
unsigned m_expected_sample_rate;
unsigned m_expected_channels;
+ unsigned m_expected_bitspersample;
uint64 m_timescale;
// VBR bitrate display stuff
@@ -87,10 +89,15 @@
// A temp decoding buffer
audio_chunk_i m_tempchunk;
+
+public:
+ service_ptr_t<file> m_file;
+ pfc::array_t<t_uint8> m_buffer;
public:
input_matroska()
{
+ hprintf(L"Matroska: input_matroska()\n");
m_parser = NULL;
m_decoder = NULL;
m_TrackNo = 0;
@@ -113,16 +120,12 @@
~input_matroska()
{
+ hprintf(L"Matroska: ~input_matroska()\n");
cleanup();
}
- virtual bool test_filename(const char * fn,const char * ext)
+ void open(service_ptr_t<file> p_filehint, const char * p_path, t_input_open_reason p_reason, abort_callback & p_abort)
{
- return (!stricmp(ext,"MKA") || !stricmp(ext,"MKV"));
- }
-
- virtual bool open(reader *r, file_info *info, unsigned flags)
- {
// TODO : Use the Cueing Data if we can seek
/*if (!r->can_seek())
@@ -130,121 +133,124 @@
console::error("Matroska: unseekable streams not supported.");
return false;
}*/
+ hprintf(L"Matroska: open() p_reason=%d\n", p_reason);
cleanup();
- m_parser = new MatroskaAudioParser(r);
+ m_file = p_filehint;
+ input_open_file_helper(m_file, p_path, p_reason, p_abort);
+ m_reason = p_reason;
- if (m_parser->Parse(!(flags & OPEN_FLAG_DECODE))) {
+ m_parser = new MatroskaAudioParser(m_file, p_abort);
+
+ if (m_parser->Parse(!(p_reason & input_open_decode))) {
console::error("Matroska: Invalid Matroska file.");
- return false;
- }
+ throw exception_io_unsupported_format();
+ }
m_TrackNo = m_parser->GetFirstAudioTrack();
if (m_TrackNo == -1) {
console::error("Matroska: no decodable streams found.");
- return false;
- }
+ throw exception_io_unsupported_format();
+ }
+ }
-#ifdef MULTITRACK
+ unsigned int get_subsong_count() {
+ hprintf(L"Matroska: get_subsong_count() chapters=%d, AudioTrackCount=%d\n", m_parser->GetChapters().size(), m_parser->GetAudioTrackCount());
+ if (m_parser->GetChapters().size() > 0) {
+ return m_parser->GetChapters().size();
+ } else if(m_parser->GetAudioTrackCount() > 0) {
+ return m_parser->GetAudioTrackCount();
+ }
+ return 0;
+ }
+
+ t_uint32 get_subsong(unsigned p_index) {
+ hprintf(L"Matroska: get_subsong() chapters= %d, p_index=%d\n", m_parser->GetChapters().size(), p_index);
+ return p_index;
if(m_parser->GetChapters().size() > 0)
- {
- int idx = info->get_subsong_index() / m_parser->GetChapters().size();
+ {
+ int tr = 0;
+ int idx = p_index / m_parser->GetChapters().size();
m_TrackNo = m_parser->GetAudioTrackIndex(idx);
+ m_subsong = p_index % m_parser->GetChapters().size();
m_parser->SetCurrentTrack(m_TrackNo);
- m_parser->SetSubSong(info->get_subsong_index() % m_parser->GetChapters().size());
+ return p_index;
} else {
- m_TrackNo = m_parser->GetAudioTrackIndex(info->get_subsong_index());
+ m_TrackNo = m_parser->GetAudioTrackIndex(p_index);
+ m_subsong = 0;
m_parser->SetCurrentTrack(m_TrackNo);
- m_parser->SetSubSong(0);
+ return p_index;
}
-#else
- m_parser->SetSubSong(info->get_subsong_index());
- m_parser->SetCurrentTrack(m_TrackNo);
-#endif
-
- // Set the current track
+ }
- MatroskaTrackInfo ¤tTrack = m_parser->GetTrack(m_TrackNo);
- m_expected_channels = currentTrack.channels;
- m_expected_sample_rate = currentTrack.samplesOutputPerSec == 0 ? currentTrack.samplesPerSec : currentTrack.samplesOutputPerSec;
+ void get_info(t_uint32 p_subsong,file_info & p_info,abort_callback & p_abort) {
+ hprintf(L"Matroska: get_info() = %d\n", p_subsong);
+ if (m_reason != input_open_decode || m_decoder == NULL) {
+ set_current_track(p_subsong);
+ initialize_decorder(p_abort);
+ }
+ p_info.info_set_int("channels", m_expected_channels);
+ p_info.info_set_int("samplerate", m_expected_sample_rate);
- info->info_set_int("channels", m_expected_channels);
- info->info_set_int("samplerate", m_expected_sample_rate);
-// info->info_set_int("bitspersample", currentTrack.bitsPerSample);
+ m_decoder->get_info(p_info);
+
+ m_expected_channels = (unsigned)p_info.info_get_int("channels");
+ m_expected_sample_rate = (unsigned)p_info.info_get_int("samplerate");
+ m_expected_bitspersample = (unsigned)p_info.info_get_int("bitspersample");
+
+ m_decoder->set_stream_property(packet_decoder::property_channels, m_expected_channels, 0, 0);
+ m_decoder->set_stream_property(packet_decoder::property_samplerate, m_expected_sample_rate, 0, 0);
+ m_decoder->set_stream_property(packet_decoder::property_bitspersample, m_expected_bitspersample, 0, 0);
- {
- packet_decoder::matroska_setup setup;
- string8 codec_temp(currentTrack.codecID.c_str());
- setup.codec_id = codec_temp;
- setup.sample_rate = currentTrack.samplesPerSec;
- setup.sample_rate_output = currentTrack.samplesOutputPerSec;
- setup.channels = m_expected_channels;
- setup.codec_private_size = currentTrack.codecPrivate.size();
- setup.codec_private = ¤tTrack.codecPrivate[0];
+ m_parser->SetFB2KInfo(p_info, m_subsong);
- m_decoder = packet_decoder::g_open(packet_decoder::owner_matroska,0,&setup,sizeof(setup),info);
-
- if (m_decoder == NULL)
- {
- console::error(uStringPrintf("Matroska: unable to find a \"%s\" packet decoder object.", (const char*)codec_temp));
- cleanup();
- return false;
- } else {
- console::info(uStringPrintf("Matroska: using '%s' decoder.", (const char*)m_decoder->get_name()));
- }
- }
+ //hprintf(L"Matroska: m_parser->GetDuration(): %f\n", (double)(int64)m_parser->GetDuration() / 1000000000.0);
+ p_info.set_length((double)(int64)m_parser->GetDuration() / 1000000000.0);
- m_expected_channels = info->info_get_int("channels");
- m_expected_sample_rate = info->info_get_int("samplerate");
-
- m_decoder->set_stream_property(packet_decoder::property_channels,m_expected_channels,0,0,info);
- m_decoder->set_stream_property(packet_decoder::property_samplerate,m_expected_sample_rate,0,0,info);
- m_decoder->set_stream_property(packet_decoder::property_bitspersample,currentTrack.bitsPerSample,0,0,info);
+ p_info.info_set_bitrate(m_parser->GetAvgBitrate());
+ }
- m_parser->SetFB2KInfo(info);
+ t_filestats get_file_stats(abort_callback & p_abort) {
+ hprintf(L"Matroska: get_file_stats()\n");
+ return m_file->get_stats(p_abort);
+ }
+
+ void decode_initialize(t_uint32 p_subsong, unsigned p_flags, abort_callback & p_abort) {
+ hprintf(L"Matroska: decode_initialize() = %d\n", p_subsong);
+ set_current_track(p_subsong);
+ initialize_decorder(p_abort);
+ m_decoder->reset_after_seek();
// The timecode scale in Matroska is in milliseconds, but foobar deals in seconds
- m_timescale = m_parser->GetTimecodeScale() * 1000;
-
+ m_timescale = m_parser->GetTimecodeScale() * 1000;
m_length = duration_to_samples(m_parser->GetDuration());
m_position = 0;
-
- info->set_length((double)(int64)m_parser->GetDuration() / 1000000000.0);
-
- info->info_set_bitrate(m_parser->GetAvgBitrate());
-
-
- if (flags & OPEN_FLAG_DECODE)
- {
- m_skip_samples = 0;
- m_skip_frames = 0;
- m_frame_remaining = 0;
- m_frame = 0;
-
- if (!seek(0)) return false;
- }
-
- return true;
+ m_skip_samples = 0;
+ m_skip_frames = 0;
+ m_frame_remaining = 0;
+ m_frame = 0;
+ decode_seek(0, p_abort);
}
- virtual int run(audio_chunk * chunk)
- {
+ bool decode_run(audio_chunk & p_chunk, abort_callback & p_abort) {
+ //hprintf(L"Matroska: decode_run(): m_skip_samples=%d, m_skip_frames=%d, m_frame_remaining=%d, m_frame=%p\n", (int)m_skip_samples, (int)m_skip_frames, m_frame_remaining, m_frame);
if (m_decoder == NULL)
{
- console::error("Matroska: attempting to decode without a loaded decoder.");
- return -1;
+ hprintf(L"Matroska: attempting to decode without a loaded decoder.\n");
+ return false;
}
if (m_position>=m_length)
{
- return 0;
+ hprintf(L"Matroska: decode_run() return false\n");
+ return false;
}
-
+
bool done = false;
do
{
- unsigned char *buffer = NULL;
+ //unsigned char *buffer = NULL;
unsigned int buffer_size = 0;
bool skip_this_frame = false;
/*
@@ -260,31 +266,38 @@
delete m_frame;
m_frame = m_parser->ReadSingleFrame();
if (m_frame==0)
- return 0;
+ return false;
m_frame_remaining = m_frame->dataBuffer.size();
if (m_frame_remaining == 0)
- return 0;
+ return false;
}
{
unsigned ptr = m_frame->dataBuffer.size() - (m_frame_remaining--);
- buffer = (unsigned char*)&m_frame->dataBuffer.at(ptr)[0];
+ //buffer = (unsigned char*)&m_frame->dataBuffer.at(ptr)[0];
buffer_size = m_frame->dataBuffer.at(ptr).size();
+ m_buffer.set_size(buffer_size);
+ m_buffer.set_data_fromptr(&m_frame->dataBuffer.at(ptr)[0], buffer_size);
}
m_tempchunk.reset();
- if (!m_decoder->decode(buffer,buffer_size,&m_tempchunk))
+ m_decoder->decode(m_buffer.get_ptr(), buffer_size, m_tempchunk, p_abort);
+ if (m_tempchunk.is_empty())
{
- console::error(uStringPrintf("Matroska: '%s' decode error.", (const char*)m_decoder->get_name()));
+ /*
+ MatroskaTrackInfo ¤tTrack = m_parser->GetTrack(m_TrackNo);
+ console::error(uStringPrintf("Matroska: '%s' decode error.", (const char*)currentTrack.codecID.c_str()));
console::error(uStringPrintf("buffer_size = %d, m_frame_remaining = %d", buffer_size, m_frame_remaining));
- console::error(uStringPrintf("buffer 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]));
+ console::error(uStringPrintf("buffer 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", m_buffer[0], m_buffer[1], m_buffer[2], m_buffer[3], m_buffer[4], m_buffer[5], m_buffer[6], m_buffer[7]));
cleanup();
- return -1;
+ return false;
+ */
}
- else if (m_tempchunk.is_valid())
+ if (m_tempchunk.is_valid())
{
m_vbr_update_frames++;
m_vbr_update_bytes += buffer_size;
+ //m_vbr_update_bytes += m_buffer.get_size();
m_vbr_update_time += (m_vbr_last_duration = m_tempchunk.get_duration());
}
@@ -299,8 +312,8 @@
if (!skip_this_frame)
{
- unsigned offset = (unsigned)duration_to_samples(0);//m_frame.timecode);
- unsigned duration = (unsigned)duration_to_samples(m_frame->duration);
+ uint64 offset = duration_to_samples(0);//m_frame.timecode);
+ uint64 duration = duration_to_samples(m_frame->duration);
// console::info(uStringPrintf("duration: %u, offset: %u",duration,offset));
if (m_tempchunk.is_empty())
@@ -309,7 +322,7 @@
{
m_tempchunk.set_srate(m_expected_sample_rate);
m_tempchunk.set_channels(m_expected_channels);
- m_tempchunk.pad_with_silence(duration);
+ m_tempchunk.pad_with_silence((t_size)duration);
#ifdef _DEBUG
console::warning("Matroska: decoder returned empty chunk from a non-empty Matroska frame.");
#endif
@@ -319,7 +332,7 @@
{
console::error("Matroska: decoder produced invalid chunk.");
cleanup();
- return -1;
+ return false;
}
unsigned samplerate,channels,decoded_sample_count;
@@ -336,7 +349,7 @@
#ifdef _DEBUG
console::warning("Matroska: decoded frame smaller than expected.");
#endif
- decoded_sample_count = duration;
+ decoded_sample_count = (unsigned)duration;
m_tempchunk.pad_with_silence(decoded_sample_count);
}
@@ -347,7 +360,7 @@
if (m_skip_samples>0)
{
- unsigned int delta = (unsigned)m_skip_samples;
+ uint64 delta = m_skip_samples;
if (delta > duration) delta = duration;
offset += delta;
duration -= delta;
@@ -360,70 +373,48 @@
duration = max;
m_position += duration;
if (m_position==m_length && duration==0)
- return 0;
+ return false;
}
if (duration > 0)
{
- chunk->set_data_64(m_tempchunk.get_data() + offset * channels,
- duration,channels,samplerate);
+ p_chunk.set_data(m_tempchunk.get_data() + offset * channels,
+ (t_size)duration,channels,samplerate);
+ //p_chunk.set_data_fixedpoint(m_tempchunk.get_data() + offset * channels, buffer_size, m_expected_sample_rate,m_expected_channels,m_expected_bitspersample,audio_chunk::g_guess_channel_config(m_expected_channels));
done = true;
}
}
}
while(!done);
- return done ? 1 : 0;
+ return done;
}
- virtual set_info_t set_info(reader *r, const file_info * info)
- {
- NOTE2("input_matroska::set_info(r = 0x%p, info = 0x%p)", r, info);
- unsigned rv = 1;
+ void decode_seek(double p_seconds, abort_callback & p_abort) {
+ hprintf(L"Matroska: decode_seek() = %f\n", p_seconds);
- // We have to create a new parser
- MatroskaAudioParser writeReader(r);
- writeReader.Parse(true);
-
- int TrackNo = writeReader.GetFirstAudioTrack();
- if (TrackNo != -1) {
- // Set the current track
- writeReader.SetCurrentTrack(m_TrackNo);
- writeReader.SetSubSong(info->get_subsong_index());
-
- rv = writeReader.WriteTags(info);
- }
-
- return !rv ? SET_INFO_SUCCESS : SET_INFO_FAILURE;
- }
-
- virtual bool seek(double seconds)
- {
- NOTE1("input_matroska::seek(seconds = %f)", seconds);
-
if (m_decoder == NULL)
{
console::error("Matroska: attempting to seek while not open.");
- return false;
+ throw exception_io_object_not_seekable();
}
-
{
double srate = (double)m_expected_sample_rate;
- seconds = floor(seconds * srate + 0.5) / srate;
+ p_seconds = floor(p_seconds * srate + 0.5) / srate;
}
double max_frame_dependency_time = m_decoder->get_max_frame_dependency_time();
- if (max_frame_dependency_time>seconds) max_frame_dependency_time = seconds;
+ if (max_frame_dependency_time>p_seconds) max_frame_dependency_time = p_seconds;
unsigned max_frame_dependency_samples = (unsigned)(m_expected_sample_rate * max_frame_dependency_time + 0.5);
unsigned frames_to_skip = 0;
- m_position = (uint64)(m_expected_sample_rate * seconds + 0.5);
+ m_position = (uint64)(m_expected_sample_rate * p_seconds + 0.5);
double time_to_skip = 0;
- if (!m_parser->Seek(seconds-max_frame_dependency_time,frames_to_skip,time_to_skip,m_expected_sample_rate)) return false;
+ if (!m_parser->Seek(p_seconds-max_frame_dependency_time,frames_to_skip,time_to_skip,m_expected_sample_rate)) throw exception_io_object_not_seekable();
m_skip_frames = frames_to_skip;
@@ -431,51 +422,97 @@
m_frame_remaining = 0;
//console::info(uStringPrintf("skip samples: %u",m_skip_samples));
-
- return true;
}
- virtual bool is_our_content_type(const char *url, const char *type)
- {
- NOTE2("input_matroska::is_our_content_type(url = %s, type = %s)", url, type);
-
- return !stricmp(type, "audio/x-matroska")
- || !stricmp(type, "video/x-matroska")
- // Just to be safe check for ones without x-
- // However, You're supposed to use x-* unless it's offically registered
- || !stricmp(type, "audio/matroska")
- || !stricmp(type, "video/matroska");
+ bool decode_can_seek() {
+ hprintf(L"Matroska: decode_can_seek()\n");
+ return m_file->can_seek();
}
- virtual bool get_dynamic_info(file_info * out,double * timestamp_delta,bool * b_track_change)
- {
+ bool decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta) {
+ //hprintf(L"Matroska: decode_get_dynamic_info()\n");
bool ret = false;
if (m_vbr_update_enabled)
{
if (m_vbr_update_time > 0 && m_vbr_update_frames >= m_vbr_update_interval)
{
int val = (int) ( ((double)m_vbr_update_bytes * 8.0 / m_vbr_update_time + 500.0) / 1000.0 );
- if (val != out->info_get_bitrate_vbr())
+ if (val != p_out.info_get_bitrate_vbr())
{
- *timestamp_delta = - (m_vbr_update_time - m_vbr_last_duration); //relative to last frame beginning;
- out->info_set_bitrate_vbr(val);
+ p_timestamp_delta = - (m_vbr_update_time - m_vbr_last_duration); //relative to last frame beginning;
+ p_out.info_set_bitrate_vbr(val);
ret = true;
}
m_vbr_update_frames = 0; m_vbr_update_bytes = 0;
m_vbr_update_time = 0;
}
- }
+ }
return ret;
}
+ bool decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {
+ //hprintf(L"Matroska: decode_get_dynamic_info_track()\n");
+ return false;
+ }
+
+ void decode_on_idle(abort_callback & p_abort) {
+ m_file->on_idle(p_abort);
+ }
+
+ void retag_set_info(t_uint32 p_subsong,const file_info & p_info,abort_callback & p_abort) {
+ hprintf(L"Matroska: retag_set_info()\n");
+ unsigned rv = 1;
+
+ if (m_parser == NULL) throw exception_io_unsupported_format();
+
+ int TrackNo = m_parser->GetFirstAudioTrack();
+ if (TrackNo != -1) {
+ // Set the current track
+ m_parser->SetCurrentTrack(m_TrackNo);
+ m_parser->SetSubSong(p_subsong);
+ m_parser->SetTags(p_info);
+ }
+
+ //return !rv ? SET_INFO_SUCCESS : SET_INFO_FAILURE;
+ }
+
+ void retag_commit(abort_callback & p_abort) {
+ hprintf(L"Matroska: retag_commit()\n");
+ m_parser->WriteTags();
+ }
+
+ static bool g_is_our_content_type(const char * p_content_type) {
+ hprintf(L"Matroska: g_is_our_content_type() p_content_type=%S\n", p_content_type);
+ return !stricmp_utf8(p_content_type, "audio/x-matroska")
+ || !stricmp_utf8(p_content_type, "video/x-matroska")
+ // Just to be safe check for ones without x-
+ // However, You're supposed to use x-* unless it's offically registered
+ || !stricmp_utf8(p_content_type, "audio/matroska")
+ || !stricmp_utf8(p_content_type, "video/matroska");
+ }
+
+ static bool g_is_our_path(const char * p_path,const char * p_extension) {
+ hprintf(L"Matroska: g_is_our_path() p_path=%S p_extension=%S\n", p_path, p_extension);
+ if (stricmp_utf8_partial(p_path, "http://", 7) == 0) {
+ // HTTP streams and chapters togther are not supported, requires seeking
+ return false;
+ } else {
+ if (stricmp_utf8(p_extension, "MKA") != 0 && stricmp_utf8(p_extension, "MKV") != 0)
+ return false;
+ }
+ return true;
+ }
+
protected:
void cleanup()
{
- if (m_decoder != NULL)
+ /*
+ if (m_decoder != NULL)
{
- m_decoder->service_release();
+ //m_decoder->service_release();
m_decoder = NULL;
}
+ */
if (m_frame)
{
delete m_frame;
@@ -496,68 +533,59 @@
return (int64) ( (double)val * 1000000000.0 / (double)m_expected_sample_rate + 0.5);
}
-};
-
-static service_factory_t<input, input_matroska> foo_matroska;
-
-class track_indexer_matroska : public track_indexer
-{
-public:
- virtual int get_tracks(const char* filename, callback * out, reader * r)
- {
- NOTE3("track_indexer_matroska::get_tracks(filename = %s, out = 0x%p, r = 0x%p", filename, out, r);
- // Let's check the filename
- if (!stricmp_utf8_partial(filename, "http://", 7)) {
- // HTTP streams and chapters togther are not supported, requires seeking
- return 0;
- } else if (strlen(filename) > 3) {
- const char *ext = filename+strlen(filename)-3;
- if (!!stricmp(ext, "MKA") && !!stricmp(ext, "MKV"))
- return 0;
+ void set_current_track(unsigned int p_index) {
+ if(m_parser->GetChapters().size() > 0)
+ {
+ int idx = p_index / m_parser->GetChapters().size();
+ m_TrackNo = m_parser->GetAudioTrackIndex(idx);
+ m_subsong = p_index % m_parser->GetChapters().size();
} else {
- return 0;
+ m_TrackNo = m_parser->GetAudioTrackIndex(p_index);
+ m_subsong = 0;
}
- if (r == NULL)
- r = file::g_open_read(filename);
- if (r == NULL) return 0;
-
- MatroskaAudioParser scanner(r);
- scanner.Parse(true);
+ m_parser->SetCurrentTrack(m_TrackNo);
+ m_parser->SetSubSong(m_subsong);
+ hprintf(L"Matroska: set_current_track(): m_TrackNo=%d, m_subsong=%d\n", m_TrackNo, m_subsong);
+ }
- std::vector<MatroskaChapterInfo> &chapters = scanner.GetChapters();
+ void initialize_decorder(abort_callback & p_abort) {
+ bool p_decode = false;
+ if (m_reason == input_open_decode) {
+ p_decode = true;
+ }
+ hprintf(L"Matroska: initialize_decoder(): m_TrackNo=%d\n", m_TrackNo);
+ MatroskaTrackInfo ¤tTrack = m_parser->GetTrack(m_TrackNo);
+ {
+ packet_decoder::matroska_setup setup;
+ pfc::string8 codec_temp(currentTrack.codecID.c_str());
+ setup.codec_id = codec_temp;
+ setup.sample_rate = (unsigned)currentTrack.samplesPerSec;
+ setup.sample_rate_output = (unsigned)currentTrack.samplesOutputPerSec;
+ setup.channels = (unsigned)currentTrack.channels;
+ setup.codec_private_size = currentTrack.codecPrivate.size();
+ if (setup.codec_private_size)
+ setup.codec_private = ¤tTrack.codecPrivate.at(0);
+ else
+ setup.codec_private = NULL;
-#ifdef MULTITRACK
- if (chapters.size() > 0) {
- for (size_t c = 0; c < chapters.size() * scanner.GetAudioTrackCount(); c++) {
- out->on_entry(make_playable_location(filename, (int)c));
+ packet_decoder::g_open(m_decoder, p_decode, packet_decoder::owner_matroska, 0, &setup, sizeof(setup), p_abort);
+ if (m_decoder == NULL)
+ {
+ console::error(uStringPrintf("Matroska: unable to find a \"%s\" packet decoder object.", (const char*)codec_temp));
+ cleanup();
+ throw exception_io_data();
+ } else {
+ hprintf(L"Matroska: using '%S' decoder.\n", (const char*)codec_temp);
}
- r->reader_release();
- return 1;
- } else if(scanner.GetAudioTrackCount() > 0) {
- for (size_t t = 0; t < scanner.GetAudioTrackCount(); t++) {
- out->on_entry(make_playable_location(filename, (int)t));
- }
- r->reader_release();
- return 1;
}
-#else
- if (chapters.size() > 0) {
- for (size_t c = 0; c < chapters.size(); c++) {
- out->on_entry(make_playable_location(filename, (int)c));
- }
- r->reader_release();
- return 1;
- }
-#endif
-
- r->reader_release();
- return 0;
+ m_expected_channels = currentTrack.channels;
+ m_expected_sample_rate = (unsigned)(currentTrack.samplesOutputPerSec == 0 ? currentTrack.samplesPerSec : currentTrack.samplesOutputPerSec);
+ m_expected_bitspersample = currentTrack.bitsPerSample;
}
};
-static service_factory_single_t<track_indexer,track_indexer_matroska> foo_matroska1;
+static input_factory_t<input_matroska> g_input_matroska_factory;
-DECLARE_COMPONENT_VERSION("Matroska Plugin" ,"0.8.5","Copyright (C) 2003-2004 Jory Stone (jcsston at toughguy.net)\nCopyright (C) 2003-2004 Peter Pawlowski");
+DECLARE_COMPONENT_VERSION("Matroska Plugin" ,"0.9.0.7","ported to 0.9 by Haru Ayana <ayana at reharmonize.net>\nCopyright (C) 2003-2004 Jory Stone (jcsston at toughguy.net)\nCopyright (C) 2003-2004 Peter Pawlowski");
-
DECLARE_FILE_TYPE("Matroska Audio files","*.MKA");
Added: trunk/foo_matroska/foo_input_matroska.rc
===================================================================
--- trunk/foo_matroska/foo_input_matroska.rc 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/foo_input_matroska.rc 2006-04-30 12:46:18 UTC (rev 1250)
@@ -0,0 +1,63 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
Added: trunk/foo_matroska/foo_input_matroska.vcproj
===================================================================
--- trunk/foo_matroska/foo_input_matroska.vcproj 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/foo_input_matroska.vcproj 2006-04-30 12:46:18 UTC (rev 1250)
@@ -0,0 +1,341 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="foo_input_matroska"
+ ProjectGUID="{B481726C-6D1C-4711-AA8E-33CB30A7DC6D}"
+ RootNamespace="foo_input_matroska"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\../Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\../Debug/foo_matroska.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../libebml;../../libmatroska"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FOO_MATROSKA_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug/foo_matroska.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories=""
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shared.lib libebmld.lib libmatroskad.lib"
+ ShowProgress="0"
+ OutputFile=".\../foobar2000/components/foo_matroska.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="../shared"
+ IgnoreAllDefaultLibraries="false"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\../Debug/foo_matroska.pdb"
+ ImportLibrary=".\../Debug/foo_matroska.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\../Debug/foo_matroska.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\../Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\../Release/foo_matroska.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="../../libebml,../../libmatroska"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FOO_MATROSKA_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/foo_matroska.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shared.lib libebml.lib libmatroska.lib"
+ OutputFile=".\../Release/foo_input_matroska.dll"
+ Version=""
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories="../shared"
+ IgnoreAllDefaultLibraries="false"
+ IgnoreDefaultLibraryNames=""
+ ProgramDatabaseFile=".\../Release/foo_matroska.pdb"
+ ImportLibrary=".\../Release/foo_matroska.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\../Release/foo_matroska.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="DbgOut.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="foo_input_matroska.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="matroska_parser.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="DbgOut.h"
+ >
+ </File>
+ <File
+ RelativePath="Foobar2000ReaderIOCallback.h"
+ >
+ </File>
+ <File
+ RelativePath="matroska_parser.h"
+ >
+ </File>
+ <File
+ RelativePath="resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath=".\foo_input_matroska.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Deleted: trunk/foo_matroska/foo_matroska.dsp
Deleted: trunk/foo_matroska/foo_matroska.rc
Modified: trunk/foo_matroska/matroska_parser.cpp
===================================================================
--- trunk/foo_matroska/matroska_parser.cpp 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/matroska_parser.cpp 2006-04-30 12:46:18 UTC (rev 1250)
@@ -194,8 +194,8 @@
codecPrivateReady = false;
};
-MatroskaAudioParser::MatroskaAudioParser(reader *input)
- : m_IOCallback(input),
+MatroskaAudioParser::MatroskaAudioParser(service_ptr_t<file> input, abort_callback & p_abort)
+ : m_IOCallback(input, p_abort),
m_InputStream(m_IOCallback)
{
m_TimecodeScale = TIMECODE_SCALE;
@@ -206,7 +206,7 @@
//UpperElementLevel = 0;
m_CurrentEdition = 0;
m_CurrentChapter = 0;
- m_FileSize = input->get_length();
+ m_FileSize = input->get_size(p_abort);
m_TagPos = 0;
m_TagSize = 0;
m_TagScanRange = 1024 * 64;
@@ -277,36 +277,73 @@
// Search for them at the end of the file
if (m_TagScanRange > 0)
{
+ TIMER;
m_IOCallback.setFilePointer(m_FileSize - m_TagScanRange);
- binary Buffer[4];
- while (m_IOCallback.read(Buffer, 3) >= 3)
- {//0x18
- if ((Buffer[0] == 0x54) && (Buffer[1] == 0xc3) && (Buffer[2] == 0x67))
- {
+ uint64 init_pos = m_IOCallback.getFilePointer();
+ /*
+ BM Search
+ */
+ binary buf[1024*64];
+ binary pat[3]; pat[0] = 0x54; pat[1] = 0xc3; pat[2] = 0x67;
+ uint64 s_pos = m_IOCallback.getFilePointer();
+ m_IOCallback.read(buf, m_TagScanRange);
+ MatroskaSearch search(buf, pat);
+ int pos = search.Match();
+ if (pos != -1) {
+ do {
+ m_IOCallback.setFilePointer(s_pos+pos+3);
uint64 startPos = m_IOCallback.getFilePointer();
-
- //seek back 3 bytes, so libmatroska can find the Tags element Ebml ID
m_IOCallback.setFilePointer(-4, seek_current);
-
EbmlElement *levelUnknown = m_InputStream.FindNextID(KaxTags::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
if ((levelUnknown != NULL)
&& (m_FileSize >= startPos + levelUnknown->GetSize())
&& (EbmlId(*levelUnknown) == KaxTags::ClassInfos.GlobalId))
{
Parse_Tags(static_cast<KaxTags *>(levelUnknown));
- delete levelUnknown;
- levelUnknown = NULL;
+ _TIMER("MatroskaAudioParser::Parse(BM)");
break;
}
delete levelUnknown;
levelUnknown = NULL;
+ m_IOCallback.setFilePointer(s_pos);
+ pos = search.Match(pos+1);
+ } while (pos != -1);
+ /*
+ ~BM Search
+ */
+ } else {
+ m_IOCallback.setFilePointer(init_pos);
+ binary Buffer[4];
+ while (m_IOCallback.read(Buffer, 3) >= 3)
+ {//0x18
+ if ((Buffer[0] == 0x54) && (Buffer[1] == 0xc3) && (Buffer[2] == 0x67))
+ {
+ uint64 startPos = m_IOCallback.getFilePointer();
- //Restore the file pos
- m_IOCallback.setFilePointer(startPos);
+ //seek back 3 bytes, so libmatroska can find the Tags element Ebml ID
+ m_IOCallback.setFilePointer(-4, seek_current);
+
+ EbmlElement *levelUnknown = m_InputStream.FindNextID(KaxTags::ClassInfos, 0xFFFFFFFFFFFFFFFFL);
+ if ((levelUnknown != NULL)
+ && (m_FileSize >= startPos + levelUnknown->GetSize())
+ && (EbmlId(*levelUnknown) == KaxTags::ClassInfos.GlobalId))
+ {
+ _TIMER("MatroskaAudioParser::Parse()");
+ Parse_Tags(static_cast<KaxTags *>(levelUnknown));
+ delete levelUnknown;
+ levelUnknown = NULL;
+ break;
+ }
+ delete levelUnknown;
+ levelUnknown = NULL;
+
+ //Restore the file pos
+ m_IOCallback.setFilePointer(startPos);
+ }
+ //seek back 2 bytes
+ m_IOCallback.setFilePointer(-2, seek_current);
}
- //seek back 2 bytes
- m_IOCallback.setFilePointer(-2, seek_current);
- }
+ }
} else {
//m_TagPos = m_FileSize;
}
@@ -617,10 +654,9 @@
return 0;
};
-int MatroskaAudioParser::WriteTags(const file_info *info)
+//int MatroskaAudioParser::WriteTags(const file_info & info)
+int MatroskaAudioParser::WriteTags()
{
- SetTags(info);
-
KaxTags & MyKaxTags = GetChild<KaxTags>(*static_cast<EbmlMaster *>(m_ElementLevel0));
// On to writing :)
@@ -774,20 +810,20 @@
return name;
}
-int meta_get_num(const file_info *info, const char* name, int idx)
+int meta_get_num(const file_info &info, const char* name, int idx)
{
- assert(is_valid_utf8(name));
- int n, m = min(info->meta_get_count(), idx);
+ assert(pfc::is_valid_utf8(name));
+ int n, m = min(info.meta_get_count(), idx);
int rv = 0;
for(n=0; n<m; n++)
{
- if (!stricmp_utf8(name, info->meta_enum_name(n)))
+ if (!stricmp_utf8(name, info.meta_enum_name(n)))
rv++;
}
return rv;
}
-void MatroskaAudioParser::SetTags(const file_info *info)
+void MatroskaAudioParser::SetTags(const file_info &info)
{
int i, idx;
const char *name, *value;
@@ -807,22 +843,38 @@
if(trackTag->targetTypeValue == 0)
trackTag->targetTypeValue = 50;
trackTag->MarkAllAsRemovalPending();
- int metaDataCount = info->meta_get_count();
+ int metaDataCount = info.meta_get_count();
for (i = 0; i < metaDataCount; i++)
{
- name = info->meta_enum_name(i);
- value = info->meta_enum_value(i);
- idx = meta_get_num(info, name, i);
- name = foobar2k_to_matroska_chapter_tag(name);
- if ((name != NULL) && (value != NULL)) {
- trackTag->SetTagValue(name, value, idx);
+ for (int j = 0; j != info.meta_enum_value_count(i); ++j) {
+ name = info.meta_enum_name(i);
+ value = info.meta_enum_value(i, j);
+ //idx = meta_get_num(info, name, i);
+ idx = j;
+ name = foobar2k_to_matroska_chapter_tag(name);
+ if ((name != NULL) && (value != NULL)) {
+ trackTag->SetTagValue(name, value, idx);
+ }
}
}
// Add the replay_gain tags
- value = info->info_get("REPLAYGAIN_TRACK_GAIN");
+ replaygain_info rg = info.get_replaygain();
+ if (rg.is_track_gain_present()) {
+ char tmp[rg.text_buffer_size];
+ pfc::float_to_string(tmp, rg.text_buffer_size, rg.m_track_gain, 7);
+ value = (const char*)tmp;
+ } else {
+ value = NULL;
+ }
if (value)
trackTag->SetTagValue("REPLAYGAIN_GAIN", value);
- value = info->info_get("REPLAYGAIN_TRACK_PEAK");
+ if (rg.is_track_peak_present()) {
+ char tmp[rg.text_buffer_size];
+ pfc::float_to_string(tmp, rg.text_buffer_size, rg.m_track_peak, 7);
+ value = (const char*)tmp;
+ } else {
+ value = NULL;
+ }
if (value)
trackTag->SetTagValue("REPLAYGAIN_PEAK", value);
trackTag->RemoveMarkedTags();
@@ -843,28 +895,44 @@
if(trackTag->targetTypeValue == 0)
trackTag->targetTypeValue = 50;
trackTag->MarkAllAsRemovalPending();
- int metaDataCount = info->meta_get_count();
+ int metaDataCount = info.meta_get_count();
for (i = 0; i < metaDataCount; i++)
{
- name = info->meta_enum_name(i);
- value = info->meta_enum_value(i);
- idx = meta_get_num(info, name, i);
- if (starts_with(name, "ALBUM") ||
- starts_with(name, "SUBALBUM") ||
- starts_with(name, "DISCID"))
- {
- name = foobar2k_to_matroska_edition_tag(name);
- } else {
- name = NULL;
+ for (int j = 0; j != info.meta_enum_value_count(i); ++j) {
+ name = info.meta_enum_name(i);
+ value = info.meta_enum_value(i, j);
+ //idx = meta_get_num(info, name, i);
+ idx = j;
+ if (starts_with(name, "ALBUM") ||
+ starts_with(name, "SUBALBUM") ||
+ starts_with(name, "DISCID"))
+ {
+ name = foobar2k_to_matroska_edition_tag(name);
+ } else {
+ name = NULL;
+ }
+ if ((name != NULL) && (value != NULL)) {
+ trackTag->SetTagValue(name, value, idx);
+ }
}
- if ((name != NULL) && (value != NULL)) {
- trackTag->SetTagValue(name, value, idx);
- }
}
- value = info->info_get("REPLAYGAIN_ALBUM_GAIN");
+ replaygain_info rg = info.get_replaygain();
+ if (rg.is_album_gain_present()) {
+ char tmp[rg.text_buffer_size];
+ pfc::float_to_string(tmp, rg.text_buffer_size, rg.m_album_gain, 7);
+ value = (const char*)tmp;
+ } else {
+ value = NULL;
+ }
if (value)
trackTag->SetTagValue("REPLAYGAIN_GAIN", value);
- value = info->info_get("REPLAYGAIN_ALBUM_PEAK");
+ if (rg.is_album_peak_present()) {
+ char tmp[rg.text_buffer_size];
+ pfc::float_to_string(tmp, rg.text_buffer_size, rg.m_album_peak, 7);
+ value = (const char*)tmp;
+ } else {
+ value = NULL;
+ }
if (value)
trackTag->SetTagValue("REPLAYGAIN_PEAK", value);
trackTag->RemoveMarkedTags();
@@ -889,28 +957,44 @@
if(chapterTag->targetTypeValue == 0)
chapterTag->targetTypeValue = 30;
chapterTag->MarkAllAsRemovalPending();
- int metaDataCount = info->meta_get_count();
+ int metaDataCount = info.meta_get_count();
for (i = 0; i < metaDataCount; i++)
{
- name = info->meta_enum_name(i);
- value = info->meta_enum_value(i);
- idx = meta_get_num(info, name, i);
- if (starts_with(name, "ALBUM") ||
- starts_with(name, "SUBALBUM") ||
- starts_with(name, "DISCID"))
- {
- name = NULL;
- } else {
- name = foobar2k_to_matroska_chapter_tag(name);
+ for (int j = 0; j != info.meta_enum_value_count(i); ++j) {
+ name = info.meta_enum_name(i);
+ value = info.meta_enum_value(i, j);
+ //idx = meta_get_num(info, name, i);
+ idx = j;
+ if (starts_with(name, "ALBUM") ||
+ starts_with(name, "SUBALBUM") ||
+ starts_with(name, "DISCID"))
+ {
+ name = NULL;
+ } else {
+ name = foobar2k_to_matroska_chapter_tag(name);
+ }
+ if ((name != NULL) && (value != NULL)) {
+ chapterTag->SetTagValue(name, value, idx);
+ }
}
- if ((name != NULL) && (value != NULL)) {
- chapterTag->SetTagValue(name, value, idx);
- }
}
- value = info->info_get("REPLAYGAIN_TRACK_GAIN");
+ replaygain_info rg = info.get_replaygain();
+ if (rg.is_track_gain_present()) {
+ char tmp[rg.text_buffer_size];
+ pfc::float_to_string(tmp, rg.text_buffer_size, rg.m_track_gain, 7);
+ value = (const char*)tmp;
+ } else {
+ value = NULL;
+ }
if (value)
chapterTag->SetTagValue("REPLAYGAIN_GAIN", value);
- value = info->info_get("REPLAYGAIN_TRACK_PEAK");
+ if (rg.is_track_peak_present()) {
+ char tmp[rg.text_buffer_size];
+ pfc::float_to_string(tmp, rg.text_buffer_size, rg.m_track_peak, 7);
+ value = (const char*)tmp;
+ } else {
+ value = NULL;
+ }
if (value)
chapterTag->SetTagValue("REPLAYGAIN_PEAK", value);
chapterTag->RemoveMarkedTags();
@@ -978,6 +1062,9 @@
return m_CurrentChapter->timeEnd - m_CurrentChapter->timeStart;
};
return m_Duration;
+ if (m_Tracks.size() != 0) {
+ return m_Tracks.at(m_CurrentTrackNo).defaultDuration * (int64)m_TimecodeScale;
+ }
};
int32 MatroskaAudioParser::GetFirstAudioTrack()
@@ -1028,7 +1115,7 @@
return false;
}
-static is_hidden_edition_field(const char * name)
+static bool is_hidden_edition_field(const char * name)
{
for (int i = 0; i < tabsize(hidden_edition_field); i++)
if (!stricmp_utf8(name, hidden_edition_field[i]))
@@ -1036,7 +1123,7 @@
return false;
}
-static is_hidden_chapter_field(const char * name)
+static bool is_hidden_chapter_field(const char * name)
{
for (int i = 0; i < tabsize(hidden_chapter_field); i++)
if (!stricmp_utf8(name, hidden_chapter_field[i]))
@@ -1198,7 +1285,7 @@
return AtLeastOneChapter;
}
-void MatroskaAudioParser::SetAlbumTags(file_info *info,
+void MatroskaAudioParser::SetAlbumTags(file_info & info,
MatroskaTagInfo* AlbumTags,
MatroskaTagInfo* TrackTags)
{
@@ -1213,11 +1300,11 @@
{
if(IsTagNamed(simpleTag, "REPLAYGAIN_GAIN"))
{
- info->info_set("REPLAYGAIN_ALBUM_GAIN",
- simpleTag.value.GetUTF8().c_str());
+ info.info_set_replaygain("replaygain_album_gain", simpleTag.value.GetUTF8().c_str());
+ if (TrackTags == NULL) info.info_set_replaygain("replaygain_track_gain", simpleTag.value.GetUTF8().c_str());
} else if(IsTagNamed(simpleTag, "REPLAYGAIN_PEAK")) {
- info->info_set("REPLAYGAIN_ALBUM_PEAK",
- simpleTag.value.GetUTF8().c_str());
+ info.info_set_replaygain("replaygain_album_peak", simpleTag.value.GetUTF8().c_str());
+ if (TrackTags == NULL) info.info_set_replaygain("replaygain_track_peak", simpleTag.value.GetUTF8().c_str());
}
}
else if (is_hidden_edition_field(simpleTag.name.GetUTF8().c_str()))
@@ -1230,9 +1317,9 @@
// Special case for Edition/TITLE
if(TagExistsAtChapterLevel(TrackTags, "ALBUM"))
{
- info->meta_add("ALBUM TITLE", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("ALBUM TITLE", simpleTag.value.GetUTF8().c_str());
} else {
- info->meta_add("ALBUM", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("ALBUM", simpleTag.value.GetUTF8().c_str());
}
}
else if(IsTagNamed(simpleTag,"SUBTITLE"))
@@ -1240,18 +1327,18 @@
// Special case for Edition/SUBTITLE
if(TagExistsAtChapterLevel(TrackTags, "SUBALBUM"))
{
- info->meta_add("ALBUM SUBTITLE", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("ALBUM SUBTITLE", simpleTag.value.GetUTF8().c_str());
} else {
- info->meta_add("SUBALBUM", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("SUBALBUM", simpleTag.value.GetUTF8().c_str());
}
}
else if(IsTagNamed(simpleTag,"DISCID"))
{
- info->meta_add("DISCID", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("DISCID", simpleTag.value.GetUTF8().c_str());
}
else if(IsTagNamed(simpleTag,"COMMENTS"))
{
- info->meta_add("ALBUM COMMENT", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("ALBUM COMMENT", simpleTag.value.GetUTF8().c_str());
}
else if((!AreTagsIdenticalAtAllLevels(simpleTag.name.GetUTF8().c_str()))
|| (!TagExistsAtChapterLevel(TrackTags, simpleTag.name.GetUTF8().c_str())))
@@ -1259,7 +1346,7 @@
// Prefix tag with "ALBUM "
char newTagName[255] = "ALBUM ";
strncat(newTagName, matroska_to_foobar2k_edition_tag(simpleTag.name.GetUTF8().c_str()),255);
- info->meta_add(newTagName, simpleTag.value.GetUTF8().c_str());
+ info.meta_add(newTagName, simpleTag.value.GetUTF8().c_str());
}
else
{
@@ -1269,7 +1356,7 @@
}
}
-void MatroskaAudioParser::SetTrackTags(file_info *info, MatroskaTagInfo* TrackTags)
+void MatroskaAudioParser::SetTrackTags(file_info &info, MatroskaTagInfo* TrackTags)
{
if(TrackTags == NULL)
return;
@@ -1282,11 +1369,9 @@
{
if(IsTagNamed(simpleTag, "REPLAYGAIN_GAIN"))
{
- info->info_set("REPLAYGAIN_TRACK_GAIN",
- simpleTag.value.GetUTF8().c_str());
+ info.info_set_replaygain("replaygain_track_gain", simpleTag.value.GetUTF8().c_str());
} else if(IsTagNamed(simpleTag, "REPLAYGAIN_PEAK")) {
- info->info_set("REPLAYGAIN_TRACK_PEAK",
- simpleTag.value.GetUTF8().c_str());
+ info.info_set_replaygain("replaygain_track_peak", simpleTag.value.GetUTF8().c_str());
}
}
else if (is_hidden_chapter_field(simpleTag.name.GetUTF8().c_str()))
@@ -1296,33 +1381,33 @@
}
else if(IsTagNamed(simpleTag,"COMMENTS"))
{
- info->meta_add("COMMENT", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("COMMENT", simpleTag.value.GetUTF8().c_str());
}
else if(IsTagNamed(simpleTag,"ALBUM"))
{
if(!TagExistsAtEditionLevel(TrackTags, "TITLE") && AreTagsIdenticalAtChapterLevel("ALBUM")) {
- info->meta_add("ALBUM", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("ALBUM", simpleTag.value.GetUTF8().c_str());
} else {
- info->meta_add("ORIGINAL_ALBUM", simpleTag.value.GetUTF8().c_str());
+ info.meta_add("ORIGINAL_ALBUM", simpleTag.value.GetUTF8().c_str());
}
}
else
{
- info->meta_add(
+ info.meta_add(
matroska_to_foobar2k_chapter_tag(simpleTag.name.GetUTF8().c_str()),
simpleTag.value.GetUTF8().c_str());
}
}
}
-bool MatroskaAudioParser::SetFB2KInfo(file_info *info)
+bool MatroskaAudioParser::SetFB2KInfo(file_info &info, t_uint32 p_subsong)
{
if (m_MuxingApp.length() > 0)
- info->info_set("MUXING_APP", m_MuxingApp.GetUTF8().c_str());
+ info.info_set("MUXING_APP", m_MuxingApp.GetUTF8().c_str());
if (m_WritingApp.length() > 0)
- info->info_set("WRITING_APP", m_WritingApp.GetUTF8().c_str());
+ info.info_set("WRITING_APP", m_WritingApp.GetUTF8().c_str());
if (m_FileTitle.length() > 0)
- info->info_set("TITLE", m_FileTitle.GetUTF8().c_str());
+ info.info_set("TITLE", m_FileTitle.GetUTF8().c_str());
MatroskaTagInfo *TrackTags = FindTagWithTrackUID(m_Tracks.at(m_CurrentTrackNo).trackUID);
MatroskaTagInfo *ChapterTags = NULL;
@@ -1359,27 +1444,27 @@
{
// If TITLE tag is empty we get it from the chapter name
if ( (m_CurrentChapter->display.size() > 0) &&
- ((info->meta_get("TITLE") == NULL) ||
- (strlen(info->meta_get("TITLE")) == 0) ) )
+ ((info.meta_get("TITLE", 0) == NULL) ||
+ (strlen(info.meta_get("TITLE", 0)) == 0) ) )
{
- info->meta_set("TITLE", m_CurrentChapter->display.at(0).string.GetUTF8().c_str());
+ info.meta_set("TITLE", m_CurrentChapter->display.at(0).string.GetUTF8().c_str());
}
- if ((info->meta_get("TRACKNUMBER") == NULL) || (strlen(info->meta_get("TRACKNUMBER")) == 0))
+ if ((info.meta_get("TRACKNUMBER", 0) == NULL) || (strlen(info.meta_get("TRACKNUMBER", 0)) == 0))
{
char trackNumberString[32];
#ifdef MULTITRACK
- wsprintf(trackNumberString, "%d",
- (info->get_subsong_index() % m_Chapters.size()) +1);
+ wsprintf((LPWSTR)trackNumberString, (LPCWSTR)"%d",
+ (p_subsong % m_Chapters.size()) +1);
#else
- wsprintf(trackNumberString, "%d",info->get_subsong_index()+1);
+ wsprintf(trackNumberString, "%d",p_subsong+1);
#endif
- info->meta_set("TRACKNUMBER", trackNumberString);
+ info.meta_set("TRACKNUMBER", trackNumberString);
}
- if ((info->meta_get("ALBUM") == NULL) || (strlen(info->meta_get("ALBUM")) == 0))
+ if ((info.meta_get("ALBUM", 0) == NULL) || (strlen(info.meta_get("ALBUM", 0)) == 0))
{
if(m_FileTitle.length() > 0)
- info->meta_set("ALBUM", m_FileTitle.GetUTF8().c_str());
+ info.meta_set("ALBUM", m_FileTitle.GetUTF8().c_str());
}
}
@@ -1392,8 +1477,8 @@
// do nothing, so we will only mark hidden tags.
// Hidden tag will be copied to keep track of them.
// This is needed cause tag are read and written in 2 different instances
- dummy_file_info info;
- SetFB2KInfo(&info);
+ file_info_impl info;
+ SetFB2KInfo(info, 0);
};
void MatroskaAudioParser::SetCurrentTrack(uint32 newTrackNo)
@@ -2376,3 +2461,57 @@
}
};
+
+bool MatroskaSearch::Skip()
+{
+ int j;
+
+ for (j = 0; j < SEARCH_TABLE_SIZE; j++) skip[j] = SEARCH_PATTERN_SIZE;
+ for (j = 0; j < SEARCH_PATTERN_SIZE - 1; j++)
+ skip[pattern[j] & 0x00ff] = SEARCH_PATTERN_SIZE-1-j;
+ return true;
+}
+
+bool MatroskaSearch::Next()
+{
+ int j, k, s;
+ int *g;
+
+ if ((g = (int *)malloc(sizeof(int)*SEARCH_PATTERN_SIZE)) == NULL) return false;
+ for (j = 0; j < SEARCH_PATTERN_SIZE; j++) next[j] = 2*SEARCH_PATTERN_SIZE - 1 - j;
+ j = SEARCH_PATTERN_SIZE;
+ for (k = SEARCH_PATTERN_SIZE - 1; k >= 0; k--) {
+ g[k] = j;
+ while (j != SEARCH_PATTERN_SIZE && pattern[j] != pattern[k]) {
+ next[j] = (next[j] <= SEARCH_PATTERN_SIZE-1-k) ? next[j] : SEARCH_PATTERN_SIZE-1-k;
+ j = g[j];
+ }
+ j--;
+ }
+ s = j;
+ for (j = 0; j < SEARCH_PATTERN_SIZE; j++) {
+ next[j] = (next[j] <= s+SEARCH_PATTERN_SIZE-j) ? next[j] : s+SEARCH_PATTERN_SIZE-j;
+ if (j >= s) s = g[s];
+ }
+ free(g);
+ return true;
+}
+
+int MatroskaSearch::Match(unsigned int start)
+{
+ int i, j;
+
+ i = SEARCH_PATTERN_SIZE - 1 + start;
+ while (i < SEARCH_SOURCE_SIZE) {
+ j = SEARCH_PATTERN_SIZE - 1;
+ while (j >= 0 && source[i] == pattern[j]) {
+ i--;
+ j--;
+ }
+ if (j < 0) return i + 1;
+ if (skip[source[i] & 0x00ff] >= next[j])
+ i += skip[source[i] & 0x00ff];
+ else i += next[j];
+ }
+ return -1;
+};
\ No newline at end of file
Modified: trunk/foo_matroska/matroska_parser.h
===================================================================
--- trunk/foo_matroska/matroska_parser.h 2006-04-30 12:41:04 UTC (rev 1249)
+++ trunk/foo_matroska/matroska_parser.h 2006-04-30 12:46:18 UTC (rev 1250)
@@ -26,6 +26,7 @@
#define MULTITRACK 1
#include "../SDK/foobar2000.h"
+#include "../../pfc/pfc.h"
#include "Foobar2000ReaderIOCallback.h"
#include "DbgOut.h"
#include <queue>
@@ -86,6 +87,9 @@
#define new DEBUG_CLIENTBLOCK
#endif
+#ifdef _DEBUG
+#endif
+
using namespace LIBEBML_NAMESPACE;
using namespace LIBMATROSKA_NAMESPACE;
@@ -195,14 +199,14 @@
uint8 channels;
float samplesPerSec;
float samplesOutputPerSec;
- uint8 bitsPerSample;
+ uint8 bitsPerSample;
uint32 avgBytesPerSec;
float defaultDuration;
};
class MatroskaAudioParser {
public:
- MatroskaAudioParser(reader *input);
+ MatroskaAudioParser(service_ptr_t<file> input, abort_callback & p_abort);
~MatroskaAudioParser();
/// The main header parsing function
@@ -213,7 +217,9 @@
/// \param info All the tags we need to write
/// \return 0 Tags written A OK
/// \return 1 Failed to write tags
- int WriteTags(const file_info *info);
+ int WriteTags();
+ /// Set the info tags to the current tags file in memory
+ void SetTags(const file_info &info);
MatroskaTrackInfo &GetTrack(uint16 trackNo) { return m_Tracks.at(trackNo); };
uint64 GetTimecodeScale() { return m_TimecodeScale; };
@@ -227,7 +233,7 @@
/// Set the fb2k info from the matroska file
/// \param info This will be filled up with tags ;)
- bool SetFB2KInfo(file_info *info);
+ bool SetFB2KInfo(file_info &info, t_uint32 p_subsong);
/// Get the foobar2000 style format string
// const char *GetFoobar2000Format(uint16 trackNo, bool bSetupCodecPrivate = true);
@@ -283,9 +289,8 @@
// \return false Nope
bool FindChapterUID(uint64 uid);
/// Adds the info tags to the current file in memory
- void AddTags(const file_info *info);
- /// Set the info tags to the current tags file in memory
- void SetTags(const file_info *info);
+ void AddTags(file_info &info);
+
MatroskaTagInfo *FindTagWithTrackUID(uint64 trackUID);
MatroskaTagInfo *FindTagWithEditionUID(uint64 editionUID, uint64 trackUID = 0);
MatroskaTagInfo *FindTagWithChapterUID(uint64 chapterUID, uint64 trackUID = 0);
@@ -294,8 +299,8 @@
bool AreTagsIdenticalAtChapterLevel(const char * name);
void MarkHiddenTags();
- void SetAlbumTags(file_info *info, MatroskaTagInfo* AlbumTags, MatroskaTagInfo* TrackTags);
- void SetTrackTags(file_info *info, MatroskaTagInfo* TrackTags);
+ void SetAlbumTags(file_info &info, MatroskaTagInfo* AlbumTags, MatroskaTagInfo* TrackTags);
+ void SetTrackTags(file_info &info, MatroskaTagInfo* TrackTags);
Foobar2000ReaderIOCallback m_IOCallback;
@@ -331,7 +336,8 @@
uint32 m_TagSize;
uint32 m_TagScanRange;
- mem_block_fastalloc<BYTE> m_framebuffer;
+ pfc::alloc_fast<BYTE> m_framebuffer;
+ //mem_block_factalloc<BYTE> m_framebuffer;
//int UpperElementLevel;
private:
// We have no need for these
@@ -341,37 +347,29 @@
void PrintChapters(std::vector<MatroskaChapterInfo> &theChapters);
-class dummy_playable_location : public playable_location
+class MatroskaSearch
{
- const char * get_path() const { return NULL; }
- void set_path(const char*) {}
- int get_number() const { return 0; }
- void set_number(int) { };
-};
-
-class dummy_file_info : public file_info
-{
private:
- dummy_playable_location m_pl;
+ static const int SEARCH_SOURCE_SIZE = 1024*64;
+ static const int SEARCH_TABLE_SIZE = SEARCH_SOURCE_SIZE;
+ static const int SEARCH_PATTERN_SIZE = 3;
+ binary * source, * pattern;
+ int pos;
+ int next[SEARCH_TABLE_SIZE], skip[SEARCH_TABLE_SIZE];
+ bool Skip();
+ bool Next();
public:
- int meta_get_count(void) const { return 0; }
- const char *meta_enum_name(int) const { return NULL; }
- const char *meta_enum_value(int) const { return NULL; }
- void meta_modify_value(int,const char *) { }
- void meta_insert(int,const char *,const char *) { }
- void meta_add(const char *,const char *) { }
- void meta_remove(int) { }
- void meta_remove_all(void) { }
- void info_set(const char *,const char *) { }
- int info_get_count(void) const { return 0; }
- const char *info_enum_name(int) const { return NULL; }
- const char *info_enum_value(int) const { return NULL; }
- void info_remove(int) { }
- void info_remove_all(void) { }
- const class playable_location *get_location(void) const { return &m_pl; }
- void set_location(const class playable_location *) { }
- void set_length(double) { }
- double get_length(void) const { return 0; }
+ MatroskaSearch(binary * p_source, binary * p_pattern)
+ {
+ ZeroMemory(next, sizeof(next));
+ ZeroMemory(skip, sizeof(skip));
+ source = p_source;
+ pattern = p_pattern;
+ Skip();
+ Next();
+ }
+ ~MatroskaSearch() {};
+ int Match(unsigned int start = 0);
};
#endif // _MATROSKA_PARSER_H_
More information about the Matroska-cvs
mailing list