aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wmvdrm/RawReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Input/in_wmvdrm/RawReader.cpp')
-rw-r--r--Src/Plugins/Input/in_wmvdrm/RawReader.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wmvdrm/RawReader.cpp b/Src/Plugins/Input/in_wmvdrm/RawReader.cpp
new file mode 100644
index 00000000..1189b0ab
--- /dev/null
+++ b/Src/Plugins/Input/in_wmvdrm/RawReader.cpp
@@ -0,0 +1,173 @@
+#include "main.h"
+#include "RawReader.h"
+#include "FileTypes.h"
+#include <shlwapi.h>
+
+#define NS_E_FILE_IS_CORRUPTED _HRESULT_TYPEDEF_(0xC00D080DL)
+
+bool IsMyExtension(const wchar_t *filename)
+{
+ const wchar_t *ext = PathFindExtension(filename);
+ if (ext && *ext)
+ {
+ ext++;
+ return fileTypes.GetAVType(ext) != -1;
+ }
+ return false;
+}
+
+int RawMediaReaderService::CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **out_reader)
+{
+ if (IsMyExtension(filename))
+ {
+ IWMSyncReader *reader = 0;
+ if (!SUCCEEDED(WMCreateSyncReader(NULL, 0, &reader)))
+ {
+ return NErr_FailedCreate;
+ }
+
+ if (FAILED(reader->Open(filename)))
+ {
+ reader->Release();
+ reader = 0;
+ return NErr_FileNotFound; // TODO: check HRESULT
+ }
+
+ RawMediaReader *raw_reader = new RawMediaReader();
+ if (!raw_reader)
+ {
+ reader->Close();
+ reader->Release();
+ return NErr_OutOfMemory;
+ }
+
+ int ret = raw_reader->Initialize(reader);
+ if (ret != NErr_Success)
+ {
+ delete raw_reader;
+ return ret;
+ }
+
+ *out_reader = raw_reader;
+ return NErr_Success;
+ }
+ else
+ {
+ return NErr_False;
+ }
+}
+
+#define CBCLASS RawMediaReaderService
+START_DISPATCH;
+CB(CREATERAWMEDIAREADER, CreateRawMediaReader);
+END_DISPATCH;
+#undef CBCLASS
+
+RawMediaReader::RawMediaReader()
+{
+ reader=0;
+ stream_num=0;
+ buffer_used=0;
+ end_of_file=false;
+ length=0;
+ buffer=0;
+ next_output=0;
+}
+
+RawMediaReader::~RawMediaReader()
+{
+ if (reader)
+ {
+ reader->Close();
+ reader->Release();
+ }
+
+ if (buffer)
+ {
+ buffer->Release();
+ }
+}
+
+int RawMediaReader::Initialize(IWMSyncReader *reader)
+{
+ this->reader=reader;
+ return NErr_Success;
+}
+
+int RawMediaReader::Read(void *out_buffer, size_t buffer_size, size_t *bytes_read)
+{
+ /* we don't care about these, but the API does not allows NULL */
+ QWORD sample_time = 0, duration = 0;
+ size_t bytesCopied = 0;
+ uint8_t *dest = (uint8_t *)out_buffer;
+ for (;;)
+ {
+ if (buffer)
+ {
+ BYTE *bufferBytes = 0;
+ DWORD bufferTotal = 0;
+ buffer->GetBufferAndLength(&bufferBytes, &bufferTotal);
+
+ if (buffer_used < bufferTotal)
+ {
+ size_t toCopy = min(bufferTotal - buffer_used, buffer_size);
+ memcpy(dest, bufferBytes + buffer_used, toCopy);
+ buffer_used += toCopy;
+ buffer_size -= toCopy;
+ dest += toCopy;
+ bytesCopied += toCopy;
+
+ if (buffer_used == bufferTotal)
+ {
+ buffer_used = 0;
+ buffer->Release();
+ buffer = 0;
+ }
+ }
+ if (buffer_size == 0)
+ {
+ *bytes_read = bytesCopied;
+ return NErr_Success;
+ }
+ }
+
+ if (stream_num == 0)
+ {
+ DWORD outputs = 0;
+ HRESULT hr=reader->GetOutputCount(&outputs);
+ if (FAILED(hr))
+ return NErr_Error;
+ if (next_output >= outputs)
+ return NErr_EndOfFile;
+ hr=reader->GetStreamNumberForOutput(next_output, &stream_num);
+ if (FAILED(hr))
+ return NErr_Error;
+ hr=reader->SetReadStreamSamples(stream_num, TRUE);
+ if (FAILED(hr))
+ return NErr_Error;
+ next_output++;
+ }
+
+ DWORD flags = 0;
+ HRESULT r = reader->GetNextSample(stream_num, &buffer, &sample_time, &duration, &flags, 0, 0);
+ if (r == NS_E_NO_MORE_SAMPLES || r == NS_E_FILE_IS_CORRUPTED)
+ {
+ stream_num=0;
+ }
+ }
+
+ return NErr_Error;
+}
+
+size_t RawMediaReader::Release()
+{
+ delete this;
+ return 0;
+}
+
+#define CBCLASS RawMediaReader
+START_DISPATCH;
+CB(RELEASE, Release);
+CB(RAW_READ, Read);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file