IMFMediaEngine and an array of bytes - audio

I've a large pack file which contains multiple media assets (there's 5 mp3s in one file). I'm reading the pack file and retrieving an array of bytes (and size of the array). How can I forward this information to IMFMediaEngine for it to play it?
Currently I'm creating a IRandomAccessStream from a unpacked file and transforming it to IMFByteStream by MFCreateMFByteStreamOnStreamEx and then sending it to SetSourceFromByteStream.
I'd rather just use byte* data and size_t size to feed the media object. Is it possible?

Related

How to make Ogg segment table from opus packet?

I am writing my own Opus Ogg writer following these specifications: RFC7845 and RFC3533.
Currently, I am facing an issue that I believe is related to how I am setting the lacing values (segment table).
My current setup is to basically read (using an existing Ogg reader) an Ogg file with a single Opus track and put that Opus track in another Ogg file that I create using my own Ogg writer.
So I have a function that takes the Opus content of each page from the original Ogg file and put it in pages in my new Ogg file.
I am being able to create the file successfully, but when I try playing it on VLC, it shows the correct timestamp but it does not play any sound.
I noticed that the issue is being caused by the way my segment table (or lacing values) is set.
I am currently creating it by filling each segment with as much data as possible (i.e 255 bytes), and letting only the last segment have a size < 255. This seems to be the way that other implementations are doing it (see Rust implementation, C implementation).
However, when I inspect the lacing values for a page containing that Opus content in the original Ogg file, it is not filled with 255s. It's another combination of segment sizes that still sums up to the same page size, but that uses more segments (since it's not taking up the max segment size). When I try using the exact segments combination in the original file, the file plays on VLC successfully.
So that makes me conclude that the approach I am taking with creating as many 255-sized segments is incorrect. Does anyone have any idea how to properly set the lacing values?

Nodejs - Image Buffer size is way larger than the original file

I need to send a byte array representation of an image from an express server to an android device. After some researches, found this solution
const buffer= fs.readFileSync('image_path');
res.send(Uint8Array.from(buffer));
It works BUT the size of the sent response is like 3 times higher than the original file (136Ko becomes 487Ko).
Turns out that the it is the size of buffer.
Is there a way to fix this so that the sent response matches the original file size? or a better way to send the file to match Java's byte array?

Deflating data from MSZIP format

I'm trying to read a compressed binary .x mesh file but my decompression is failing. The file is basically some directx header info and then a bunch of data in MSZIP format (i.e. 2 bytes are an int blockSize, 2 bytes are a "magic number" and then there are blockSize deflated bytes and then repeat until there's no more data) so for each block I'm just getting the compressed bytes and deflating like so-
internal static byte[] DecompressBlock(byte[] data) {
var result = new List<byte>();
var ms = new MemoryStream(data);
var ds = new DeflateStream(ms, CompressionMode.Decompress);
var newStream = new MemoryStream();
ds.CopyTo(newStream);
ds.Flush();
ds.Close();
return newStream.GetBuffer();
}
The first block deflates as expected. Subsequent blocks are the right inflated size but, seemingly randomly, some bytes are 0 when they shouldn't be, usually in in groups of 4-12.
How I can deflate different blocks of zipped data while maintaining the same history buffer?
UPDATE: After a little more research it looks like in MSZIP compression these blocks ARE the results of separate deflate operations but the "history buffer" is maintained between them I don't know if deflatestream is gonna be able to handle this. updated the actual question
Yes, there is something that you are missing. Each deflate block can and does use history from the previous deflate block. So at each block you must initialize the deflate dictionary with the last 32K of uncompressed data from the previous blocks.
If anyone is trying to read/write the MSZIP format for DirectX meshes using C# only, I found out it is possible to do it with SharpZipLib.
For reference, the format of the compressed DirectX file is the following:
16 bytes -> DirectX header
4 bytes -> total uncompressed file size (including the 16 bytes of its header)
2 bytes -> size of uncompressed block, up to 32KB
2 bytes -> size of compressed block, plus 2 (because it includes the magic number's size)
2 bytes -> magic number ("CK" in ascii)
a compressed block
Parts 3-6 are repeated until the end of file. In practice all blocks but the last will be 32KB when uncompressed.
To decompress the file, you will have to implement the logic that extracts each compressed block, then give them to SharpZipLib's Zip.Compression.Inflater class. Reuse the same inflater for all blocks, but call its Reset method between each block.
This partly works, but you may get the "broken uncompressed block" error for some blocks. To overcome this problem, you will have to modify SharpZipLib's source, specifically the file Inflater.cs. The change is trivial - all you have to do is to disable/skip the DECODE_STORED_LEN2 case and go directly to DECODE_STORED instead.
To compress a file, split its contents into 32KB blocks, and the same logic applies: feed each block to the same Deflater and call Reset between each call. Again, you will have to modify the file DeflaterHuffman.cs, removing the line pending.WriteShort(~storedLength).

Distinguish between PCM and BWF file format?

How can we distinguish between PCM and BWF format?
Is it necessary for BWF to have "bext" header?
I have some streams that don't have "bext" header but contains "JUNK" header... Are these files BWF files?
Thanks you.
The JUNK chunk is reserved space to allow a BWF file to be converted into an RF64 file on the fly if the size goes over 4GB. The JUNK chunk is the same size as a ds64 chunk, and will be replaced with a ds64 chunk if the conversion to RF64 is needed. Read more about it here.
My reading of the BWF spec is that you have to have a bext chunk for it to be a BWF.
As far as I know, a broadcast wave file will have the 'bext' header extension.
If a file does not have the 'bext' header extension, it will be a normal WAV/AIFF or whatever file.
Broadcast wave headers are used especially if you want to give a file more information about itself in the header which isn't to be seen immediately from its name.
For playing back, this info isn't necessary to know. Just if you want to show or search the meta information somehow.
PCM isn't a file format. All files that handle uncompressed data are PCM files.
Such as WAV/BWF, AIFF or SD2 for example.
With encoded files like MP3 or AAC you get the raw PCM values after decoding.
Yes. The 'bext' chunk is what distinguishes a BWF file from a wav file.
Some manufacturers actually use '.bwf' as a file extension but mostly the '.wav' extension will be used. It is only the presence of this chunk that makes the difference.
Other chunks can also be present and a well designed player will ignore chunks that it doesn't recognize.
Generally the 'data' chunk containing the audio data will be the last one in the file. However I have seen a few examples of other chunks, usually xml metadata, appearing after the 'data' chunk. This confuses some players.
For more information search for tech3285.pdf from the European Broadcasting Union website (tech.EBU.ch).

Get PNG image file dimension

I would like to get the dimension of a PNG image file inside my local folder on Windows. How can I achieve this using visual c++?
Should be easy, the png file is formed by an 8 byte intro, followed by a header chunk. Inside the header chunk you have the length (4 bytes), type (4 bytes), followed by the width and height.
So basically, the width is the 4 byte number at 8+8=16 bytes in the file, and the height is at 8+8+4=20 bytes in the file. Just read them!
aside from the well-known GDI APIs (I get the feeling you are trying to avoid these) it is worth giving http://msdn.microsoft.com/en-us/library/bb776499%28v=VS.85%29.aspx a shot. Never used it myself though :/

Resources