如何从缓冲区创建接收器编写器?
How to create sink writer from buffer?
我的编码器实现作为输入 .wav
文件字节,并作为输出 .mp3
字节写入输出文件。
像这样
void co_AudioEncoderMF::start_encoding()
{
...
IMFSinkWriter * sink_writer = nullptr;
//Create sink writer
HRESULT hr = MFCreateSinkWriterFromURL(
L"D:\buffer\del\out\test_out.mp3",
NULL,
NULL,
&sink_writer
);
...
// Add the stream
hr = sink_writer->AddStream(
ouput_media_type,
&dwWriterStreamIndex
);
// Set input media type
hr = sink_writer->SetInputMediaType(
dwWriterStreamIndex,
input_type,
NULL
);
// Tell the sink writer to accept data
hr = sink_writer->BeginWriting();
...
hr = sink_writer->WriteSample(
dwWriterStreamIndex,
pSample
);
...
}
因此,我创建了一个 IMFSinkWriter,然后将其添加到 straem + set mediatype,然后我可以将编码字节写入输出文件 L"D:\buffer\del\out\test_out.mp3"
。
这里的问题是我不想将编码数据写入输出文件,我需要将其作为缓冲区。
我看到还有另一种可能的方法
STDAPI MFCreateSinkWriterFromMediaSink(
_In_ IMFMediaSink *pMediaSink,
_In_opt_ IMFAttributes *pAttributes,
_Out_ IMFSinkWriter **ppSinkWriter );
因此,据我所知,它在 IMFMediaSink
上需要指针,在 IMFSinkWriter
上需要指针,从这一点开始,我知道我可以实现 IMFMediaSink
接口,这将创建IMFSinkWriter
并在调用 MFCreateSinkWriterFromMediaSink
方法时设置它。 (但我不确定这是将编码数据写入缓冲区的正确方法)。
所以,我实现了 IMFMediaSink
#include "co_MediaSink.h"
#include <stdio.h>
#include "co_SinkWriter.h"
co_MediaSink::co_MediaSink()
{
}
co_MediaSink::~co_MediaSink()
{
}
HRESULT co_MediaSink::QueryInterface(REFIID riid, void ** ppvObject)
{
printf("HERE");
*ppvObject = new co_SinkWriter();
return S_OK;
}
ULONG co_MediaSink::AddRef(void)
{
printf("HERE");
return 1;
}
ULONG co_MediaSink::Release(void)
{
printf("HERE");
return 1;
}
HRESULT co_MediaSink::GetCharacteristics(DWORD * pdwCharacteristics)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::AddStreamSink(DWORD dwStreamSinkIdentifier, IMFMediaType * pMediaType, IMFStreamSink ** ppStreamSink)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::RemoveStreamSink(DWORD dwStreamSinkIdentifier)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetStreamSinkCount(DWORD * pcStreamSinkCount)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetStreamSinkByIndex(DWORD dwIndex, IMFStreamSink ** ppStreamSink)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetStreamSinkById(DWORD dwStreamSinkIdentifier, IMFStreamSink ** ppStreamSink)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::SetPresentationClock(IMFPresentationClock * pPresentationClock)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetPresentationClock(IMFPresentationClock ** ppPresentationClock)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::Shutdown(void)
{
printf("HERE");
return S_OK;
}
用法::
IMFSinkWriter * sink_writer = nullptr;
co_MediaSink media_sink;
HRESULT hr = MFCreateSinkWriterFromMediaSink(&media_sink, nullptr, &sink_writer);
所以,这里有一个调试,我看到在这个 MFCreateSinkWriterFromMediaSink
方法被调用之后,下一个调试断点是 co_MediaSink::QueryInterface(REFIID riid, void ** ppvObject)
方法中的一个 get 我需要设置(我认为)我的 IMFSinkWriter
像这样 ppvObject
对这个输出指针的实现 *ppvObject = new co_SinkWriter();
,但是我得到一个错误
Exception thrown at 0x00007FF95B4F8317 (mfreadwrite.dll) in co_Convert.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
所以,实际上有两个问题,第一个是选择了正确的方式来写入缓冲区,第二个 - 如果是,Access violation
有什么问题?
- 已实现字节流以接受数据(您在源端的开发中已经熟悉
IMFByteStream
概念)
MFCreateMP3MediaSink
(这是上述任务的关键API)为 MP3 流 创建 IMFMediaSink
的实现
MFCreateSinkWriterFromMediaSink
将在此媒体接收器之上创建一个 IMFsinkWriter
,并且您已经知道如何使用接收器编写器
这样你就可以写入接收器写入器并在另一端接受部分 MP3 字节流。
我的编码器实现作为输入 .wav
文件字节,并作为输出 .mp3
字节写入输出文件。
像这样
void co_AudioEncoderMF::start_encoding()
{
...
IMFSinkWriter * sink_writer = nullptr;
//Create sink writer
HRESULT hr = MFCreateSinkWriterFromURL(
L"D:\buffer\del\out\test_out.mp3",
NULL,
NULL,
&sink_writer
);
...
// Add the stream
hr = sink_writer->AddStream(
ouput_media_type,
&dwWriterStreamIndex
);
// Set input media type
hr = sink_writer->SetInputMediaType(
dwWriterStreamIndex,
input_type,
NULL
);
// Tell the sink writer to accept data
hr = sink_writer->BeginWriting();
...
hr = sink_writer->WriteSample(
dwWriterStreamIndex,
pSample
);
...
}
因此,我创建了一个 IMFSinkWriter,然后将其添加到 straem + set mediatype,然后我可以将编码字节写入输出文件 L"D:\buffer\del\out\test_out.mp3"
。
这里的问题是我不想将编码数据写入输出文件,我需要将其作为缓冲区。
我看到还有另一种可能的方法
STDAPI MFCreateSinkWriterFromMediaSink(
_In_ IMFMediaSink *pMediaSink,
_In_opt_ IMFAttributes *pAttributes,
_Out_ IMFSinkWriter **ppSinkWriter );
因此,据我所知,它在 IMFMediaSink
上需要指针,在 IMFSinkWriter
上需要指针,从这一点开始,我知道我可以实现 IMFMediaSink
接口,这将创建IMFSinkWriter
并在调用 MFCreateSinkWriterFromMediaSink
方法时设置它。 (但我不确定这是将编码数据写入缓冲区的正确方法)。
所以,我实现了 IMFMediaSink
#include "co_MediaSink.h"
#include <stdio.h>
#include "co_SinkWriter.h"
co_MediaSink::co_MediaSink()
{
}
co_MediaSink::~co_MediaSink()
{
}
HRESULT co_MediaSink::QueryInterface(REFIID riid, void ** ppvObject)
{
printf("HERE");
*ppvObject = new co_SinkWriter();
return S_OK;
}
ULONG co_MediaSink::AddRef(void)
{
printf("HERE");
return 1;
}
ULONG co_MediaSink::Release(void)
{
printf("HERE");
return 1;
}
HRESULT co_MediaSink::GetCharacteristics(DWORD * pdwCharacteristics)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::AddStreamSink(DWORD dwStreamSinkIdentifier, IMFMediaType * pMediaType, IMFStreamSink ** ppStreamSink)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::RemoveStreamSink(DWORD dwStreamSinkIdentifier)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetStreamSinkCount(DWORD * pcStreamSinkCount)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetStreamSinkByIndex(DWORD dwIndex, IMFStreamSink ** ppStreamSink)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetStreamSinkById(DWORD dwStreamSinkIdentifier, IMFStreamSink ** ppStreamSink)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::SetPresentationClock(IMFPresentationClock * pPresentationClock)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::GetPresentationClock(IMFPresentationClock ** ppPresentationClock)
{
printf("HERE");
return S_OK;
}
HRESULT co_MediaSink::Shutdown(void)
{
printf("HERE");
return S_OK;
}
用法::
IMFSinkWriter * sink_writer = nullptr;
co_MediaSink media_sink;
HRESULT hr = MFCreateSinkWriterFromMediaSink(&media_sink, nullptr, &sink_writer);
所以,这里有一个调试,我看到在这个 MFCreateSinkWriterFromMediaSink
方法被调用之后,下一个调试断点是 co_MediaSink::QueryInterface(REFIID riid, void ** ppvObject)
方法中的一个 get 我需要设置(我认为)我的 IMFSinkWriter
像这样 ppvObject
对这个输出指针的实现 *ppvObject = new co_SinkWriter();
,但是我得到一个错误
Exception thrown at 0x00007FF95B4F8317 (mfreadwrite.dll) in co_Convert.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
所以,实际上有两个问题,第一个是选择了正确的方式来写入缓冲区,第二个 - 如果是,Access violation
有什么问题?
- 已实现字节流以接受数据(您在源端的开发中已经熟悉
IMFByteStream
概念) MFCreateMP3MediaSink
(这是上述任务的关键API)为 MP3 流 创建 MFCreateSinkWriterFromMediaSink
将在此媒体接收器之上创建一个IMFsinkWriter
,并且您已经知道如何使用接收器编写器
IMFMediaSink
的实现
这样你就可以写入接收器写入器并在另一端接受部分 MP3 字节流。