123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #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
|