Search code examples
mp4ms-media-foundationencodermpeg-dashmuxer

Microsoft FileSink Mpeg4


I have 2 questions

1)How do I write raw data to a file sinker. I am trying to mux. 2)How do I make sure the sinked data is not written to a file but to a memory buffer

So in Detail:

I am trying to use windows MPEG-4 File Sink to write some Intel SDK Encoded avc or hevc to memory and send it to websocket.

what is the right approach?

Can I just feed raw hevc or avc as (byte*, length) to MPEG-4 File Sink? Or Do I need to wrap the Intel Encoder into a Custom Windows Media Foundation Encoder(well I can just use GUID to get the Intel Encoder anyway) from Windows Media Frame work. Correct me If I am wrong please.

So I have 2 problems, How do I write my raw data(avc||hevc) to MP4 Sinker(Encoded by a 3rd Party Encoder)

Do I need to implement a custom Sinker , And how custom is it. Can I inherit part of the MPEG4 Sinker(After all I do not want to re implement a full container for Mp4)

Or Modify MPEG4 Sinker behavior so that it does not write it to a file but writes to a Memory

I know I feel like I re iterated myself A few times. Sorry about that.


Solution

  • 1) If you wrap the encoded bitstream in an IMFSample you can just call IMFStreamSink::ProcessSample. To wrap it in the IMFSample, create a memory buffer IMFMediaBuffer with MFCreateMemoryBuffer , then create an IMFSample with MFCreateSample and add the buffer to it with IMFSample::AddBuffer. And then pass it to the stream sink. Also, if you can constrain the output bitstream length you can actually use the underlying memofy from IMFMediaBuffer by using IMFMediaBuffer::Lock to obtain the pointer to the underlying memory and passing that to the Intel SDK.

    2) When creating the MPEG-4 sink via MFCreateMPEG4MediaSink you pass in an IMFByteStream instance. You can make your own class which implements this interface and writes the data directly to memory or wherever you need. If you do not want to do a full implementation there are also MFCreateMFByteStreamOnStream and MFCreateMFByteStreamOnStreamEx which can wrap an IStream instance into a IMFByteStream but I have never used those and I am not aware of the underlying memory semantics. You can create a memory backed IStream with SHCreateMemStream and CreateStreamOnHGlobal.

    I have used Intel SDK quite long ago but if I remember it had a MFT compatible encoder, but I always used the plain C++ one, and thus I am not sure how they differ in terms of configuration etc. But if the MFT one works, then you can setup a proper pipeline without processing the bitstream samples yourself as stated in (1) and just handle (2).

    Also, performance wise, since as far as I remember Intel SDK did work on Direct3D surfaces as well, you could look into MFCreateDXSurfaceBuffer to used Direct3D surfaces instead of memory buffers for wrapping the data.