diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_wmvdrm/RawReader.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_wmvdrm/RawReader.cpp')
-rw-r--r-- | Src/Plugins/Input/in_wmvdrm/RawReader.cpp | 173 |
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 |