mfreadwrite/reader: Consider audio block alignment when creating output buffers for the decoder.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c6f133f635
commit
ca143521ed
|
@ -105,11 +105,17 @@ enum media_stream_flags
|
|||
STREAM_FLAG_PRESENTED = 0x4, /* Set if stream was selected last time Start() was called. */
|
||||
};
|
||||
|
||||
struct stream_transform
|
||||
{
|
||||
IMFTransform *transform;
|
||||
unsigned int min_buffer_size;
|
||||
};
|
||||
|
||||
struct media_stream
|
||||
{
|
||||
IMFMediaStream *stream;
|
||||
IMFMediaType *current;
|
||||
IMFTransform *decoder;
|
||||
struct stream_transform decoder;
|
||||
IMFVideoSampleAllocatorEx *allocator;
|
||||
IMFVideoSampleAllocatorNotify notify_cb;
|
||||
unsigned int id;
|
||||
|
@ -643,12 +649,13 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s
|
|||
{
|
||||
MFT_OUTPUT_STREAM_INFO stream_info = { 0 };
|
||||
MFT_OUTPUT_DATA_BUFFER out_buffer;
|
||||
unsigned int buffer_size;
|
||||
IMFMediaBuffer *buffer;
|
||||
LONGLONG timestamp;
|
||||
DWORD status;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = IMFTransform_GetOutputStreamInfo(stream->decoder, 0, &stream_info)))
|
||||
if (FAILED(hr = IMFTransform_GetOutputStreamInfo(stream->decoder.transform, 0, &stream_info)))
|
||||
{
|
||||
WARN("Failed to get output stream info, hr %#x.\n", hr);
|
||||
return hr;
|
||||
|
@ -663,7 +670,9 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s
|
|||
if (FAILED(hr = MFCreateSample(&out_buffer.pSample)))
|
||||
break;
|
||||
|
||||
if (FAILED(hr = MFCreateAlignedMemoryBuffer(stream_info.cbSize, stream_info.cbAlignment, &buffer)))
|
||||
buffer_size = max(stream_info.cbSize, stream->decoder.min_buffer_size);
|
||||
|
||||
if (FAILED(hr = MFCreateAlignedMemoryBuffer(buffer_size, stream_info.cbAlignment, &buffer)))
|
||||
{
|
||||
IMFSample_Release(out_buffer.pSample);
|
||||
break;
|
||||
|
@ -673,7 +682,7 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s
|
|||
IMFMediaBuffer_Release(buffer);
|
||||
}
|
||||
|
||||
if (FAILED(hr = IMFTransform_ProcessOutput(stream->decoder, 0, 1, &out_buffer, &status)))
|
||||
if (FAILED(hr = IMFTransform_ProcessOutput(stream->decoder.transform, 0, 1, &out_buffer, &status)))
|
||||
{
|
||||
if (out_buffer.pSample)
|
||||
IMFSample_Release(out_buffer.pSample);
|
||||
|
@ -700,7 +709,7 @@ static HRESULT source_reader_process_sample(struct source_reader *reader, struct
|
|||
LONGLONG timestamp;
|
||||
HRESULT hr;
|
||||
|
||||
if (!stream->decoder)
|
||||
if (!stream->decoder.transform)
|
||||
{
|
||||
timestamp = 0;
|
||||
if (FAILED(IMFSample_GetSampleTime(sample, ×tamp)))
|
||||
|
@ -715,7 +724,7 @@ static HRESULT source_reader_process_sample(struct source_reader *reader, struct
|
|||
hr = source_reader_pull_stream_samples(reader, stream);
|
||||
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
|
||||
{
|
||||
if (FAILED(hr = IMFTransform_ProcessInput(stream->decoder, 0, sample, 0)))
|
||||
if (FAILED(hr = IMFTransform_ProcessInput(stream->decoder.transform, 0, sample, 0)))
|
||||
{
|
||||
WARN("Transform failed to process input, hr %#x.\n", hr);
|
||||
return hr;
|
||||
|
@ -812,7 +821,7 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re
|
|||
stream->state = STREAM_STATE_EOS;
|
||||
stream->flags &= ~STREAM_FLAG_SAMPLE_REQUESTED;
|
||||
|
||||
if (stream->decoder && SUCCEEDED(IMFTransform_ProcessMessage(stream->decoder,
|
||||
if (stream->decoder.transform && SUCCEEDED(IMFTransform_ProcessMessage(stream->decoder.transform,
|
||||
MFT_MESSAGE_COMMAND_DRAIN, 0)))
|
||||
{
|
||||
if ((hr = source_reader_pull_stream_samples(reader, stream)) != MF_E_TRANSFORM_NEED_MORE_INPUT)
|
||||
|
@ -1161,8 +1170,8 @@ static void source_reader_flush_stream(struct source_reader *reader, DWORD strea
|
|||
struct media_stream *stream = &reader->streams[stream_index];
|
||||
|
||||
source_reader_release_responses(reader, stream);
|
||||
if (stream->decoder)
|
||||
IMFTransform_ProcessMessage(stream->decoder, MFT_MESSAGE_COMMAND_FLUSH, 0);
|
||||
if (stream->decoder.transform)
|
||||
IMFTransform_ProcessMessage(stream->decoder.transform, MFT_MESSAGE_COMMAND_FLUSH, 0);
|
||||
stream->requests = 0;
|
||||
}
|
||||
|
||||
|
@ -1378,8 +1387,8 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface)
|
|||
IMFMediaStream_Release(stream->stream);
|
||||
if (stream->current)
|
||||
IMFMediaType_Release(stream->current);
|
||||
if (stream->decoder)
|
||||
IMFTransform_Release(stream->decoder);
|
||||
if (stream->decoder.transform)
|
||||
IMFTransform_Release(stream->decoder.transform);
|
||||
if (stream->allocator)
|
||||
IMFVideoSampleAllocatorEx_Release(stream->allocator);
|
||||
}
|
||||
|
@ -1672,8 +1681,10 @@ static HRESULT source_reader_configure_decoder(struct source_reader *reader, DWO
|
|||
IMFMediaType *input_type, IMFMediaType *output_type)
|
||||
{
|
||||
IMFMediaTypeHandler *type_handler;
|
||||
unsigned int block_alignment = 0;
|
||||
IMFTransform *transform = NULL;
|
||||
IMFMediaType *type = NULL;
|
||||
GUID major = { 0 };
|
||||
DWORD flags;
|
||||
HRESULT hr;
|
||||
int i = 0;
|
||||
|
@ -1710,12 +1721,15 @@ static HRESULT source_reader_configure_decoder(struct source_reader *reader, DWO
|
|||
|
||||
if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)reader->streams[index].current)))
|
||||
WARN("Failed to copy attributes, hr %#x.\n", hr);
|
||||
if (SUCCEEDED(IMFMediaType_GetMajorType(type, &major)) && IsEqualGUID(&major, &MFMediaType_Audio))
|
||||
IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment);
|
||||
IMFMediaType_Release(type);
|
||||
|
||||
if (reader->streams[index].decoder)
|
||||
IMFTransform_Release(reader->streams[index].decoder);
|
||||
if (reader->streams[index].decoder.transform)
|
||||
IMFTransform_Release(reader->streams[index].decoder.transform);
|
||||
|
||||
reader->streams[index].decoder = transform;
|
||||
reader->streams[index].decoder.transform = transform;
|
||||
reader->streams[index].decoder.min_buffer_size = block_alignment;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -2082,7 +2096,7 @@ static HRESULT WINAPI src_reader_GetServiceForStream(IMFSourceReader *iface, DWO
|
|||
hr = MF_E_INVALIDSTREAMNUMBER;
|
||||
else
|
||||
{
|
||||
obj = (IUnknown *)reader->streams[index].decoder;
|
||||
obj = (IUnknown *)reader->streams[index].decoder.transform;
|
||||
if (!obj) hr = E_NOINTERFACE;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue