Write and read from memory using: avio_alloc_context - c++

My overall goal is to capture the desktop screen and encapsulate in a webm container with encoding such as VP8 or VP9. I can save it as a file, but my intention is to stream the video to a webbrowser and using mediasource extension to view the content.
Now am stuck att writing/reading the data of memory using avio_alloc_context .
avio_alloc_context(ioBuffer, IOBUFSIZE, 1, nullptr, readFromBuffer, writeToBuffer, nullptr);
Does anyone have code snippets for both read and write functions?
From this question i found the write function:
std::vector<uint8_t> outputData;
int mediaMuxCallback(void *opaque, uint8_t *buf, int bufSize)
{
outputData.insert(outputData.end(), buf, buf + bufSize);
return bufSize;
}
How should the read function be implemented any idea?
Is a vector the best alternative or how about an IStream which one is easier?

Related

Get a ComPtr<IStream> from a IBuffer

I am struggling at connecting two APIs. From one I get a Windows::Storage::IBuffer, and the other demands a ComPtr<IStream>. I do not seem to find a way to bridge these two, even if I wanted to do a copy of the data in the stream.
So far the only way forward from IBuffer is to create a Windows::Storage::Streams::DataReader::FromBuffer(buffer). From there, I can ReadBytes to get Platform::Array<unsigned char> array, but then what?
Thanks!
There may be other methods to get a COM compatible IStream interface for the IBuffer but if you have the data bytes you can create a COM IStream on memory using the CreateStreamOnHGlobal API then copying the bytes into the new IStream. Don't forget to reset the seek pointer before handing it out.
[DllImport("ole32.dll")]
private static extern int CreateStreamOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, out IStream ppstm);
System.Runtime.InteropServices.ComTypes stm;
if (CreateStreamOnHGlobal(IntPtr.Zero, true, out stm) == 0)
{
stm.Write( ...data for the stream... );
stm.Seek(0, 0, IntPtr.Zero); // seek to start of stream
}

C++ - Read from either file or in-memory buffer with the same function

Is there a single standard C/C++ function which takes either a file handle/pointer or a pointer to an in-memory buffer and reads data from the file/buffer?
I have a function which pulls data from a file, performs operations on said data, and sends it out over a socket. I also have a function that takes data in the form of a char buffer, performs exactly the same operations on that data, and sends it over a socket. This problem isn't that hard. I just thought it would be convenient if there was a function like
read(void *dest, void *src, int src_type, size_t amount)
In C++ you can use std::istream as an abstraction on top of a file with an std::ifstream implementation, or an in-memory buffer with an std::istringstream implementation.
The beauty of this approach is that your function does not need to know about the implementation type, because receiving the argument by reference would be sufficient:
void readData(std::istream& in_data) {
...
}
The caller would then construct an appropriate implementation, and pass it to readData.
Sounds like you want to use the operator>>() on an input stream (std::istream), which can either be a filestream, a iostream or a stringstream
I don't know about windows but it will work in Linux.
void readif(int fd ,char *src,size_t nbytes){
read(fd,src,nbytes);
//error handler code
//Other stuffs
}
int fd = open(file);
//for std::input fd = 0
//for in memory data use mmap
mmap
open
read

Winforms RichTextBox as istream

I'm adapting a console based program to GUI.
The console program reads a text file and "compiles" it.
My GUI application reads the text file and displays in a RichTextBox.
I'm looking for a method to treat the RichTextBox as a C++ std::istream. This would allow me to use code from the console program without modifying it.
I searched the web and StackOverflow and didn't find any solutions for treating a RichTextBox as an std::istream.
Does anybody know of any Winforms library functions that would allow treating of RichTextBox as an std::istream?
My ideas:
Create an adapter to treat RichTextBox as a stream.
Change the console program to pass a "getline" function to the
compiler portion, and have two getline functions (one as the
std::getline, another to get a line from the RichTextBox).
Write the RichTextBox contents to a file and feed the file to the
compiler.
I'm using Visual Studio 2010 on Win 7 using ".NET" 4.0, using C++ (don't suggest any C# techniques as I'm not fluent in translating).
In real C++, you can create a stream buffer from an RTF control like this:
class RTF_buf : public std::streambuf {
std::vector<char> buffer;
public:
RTF_buf(HWND ctrl) {
DWORD len = SendMessage(ctrl, WM_GETTEXTLENGTH, 0, 0);
buffer.resize(len+1);
SendMessageA(ctrl, WM_GETTEXT, len+1, (LPARAM)&buffer[0]);
setg(&buffer[0], &buffer[0], &buffer[len]);
}
};
Note that this isn't actually restricted to an RTF control. Just for one other example, it'll also work fine with a normal EDIT control.
C++/CLI adds a few wrinkles to this. First of all, you're dealing with "wide" characters in the RichTextBox. Second, you won't (normally) start with an HWND -- you have to retrieve that from the System.Windows.Forms.RichTextBox via its Handle property. This, unfortunately, returns the HWND as an IntPtr instead of an HWND, so you have to add a cast to get it to the right type. That makes the code a little uglier, but nothing too terrible:
#include <windows.h>
#include <streambuf>
#include <iostream>
#include <vector>
#include <algorithm>
#pragma comment(lib, "user32.lib")
using namespace System;
using namespace System::Windows::Forms;
class RTF_buf : public std::wstreambuf {
std::vector<wchar_t> buffer;
public:
RTF_buf(RichTextBox^ control) {
HWND ctrl = *reinterpret_cast<HWND *>(&control->Handle);
int len = SendMessage(ctrl, WM_GETTEXTLENGTH, 0, 0);
buffer.resize(len+1);
SendMessage(ctrl, WM_GETTEXT, len+1, (LPARAM)&buffer[0]);
setg(&buffer[0], &buffer[0], &buffer[len]);
}
};
We can create a buffer and istream something like this:
RTF_buf b(this->richTextBox1);
std::wistream in(&b);
Finally, we can read data from our stream and process them like we would essentially any other (wide) stream. For example:
wchar_t ch;
while (in >> ch)
// do something with ch
So C++/CLI does add a little complexity to the task, but ultimately only a little--mostly the one line to obtain the handle of the control, and cast it to the correct type. Other than that the code for the buffer class barely needs to change at all, and instantiating and using it changes only to the extent that we're working with wide characters instead of narrow.
The proper way to create a stream plugging into the IOStreams library is to implement a stream buffer, i.e., to derive from std::streambuf or std::wstreambuf (I'm not a Windows programmer but my understanding is that most code travels in terms of wchar_t rather than char) and override the suitable virtual member functions. Assuming you can get characters in bunches (possible all in a bukl) all you'd really overload is underflow() which is called if the input buffer was exhausted. If you can get all the characters during construction you can also set up a buffer.
Once you have a stream buffer you can use a pointer to the stream buffer to initialize an std::istream. Here is a simple example which uses a memory arean passed in the constructor as its input:
#include <iostream>
#include <streambuf>
class membuf
: std::streambuf {
public:
membuf(char* buffer, std::size_t size) {
this->setg(buffer, buffer, buffer + size);
}
};
int main() {
char input[] = "hello, world!\n";
membuf sbuf(input, sizeof(input - 1));
std::istream in(&sbuf);
char buffer[100];
if (in.getline(buffer, sizeof(buffer)) {
std::cout << "read '" << buffer << "'\n";
}
else {
std::cout << "ERROR: failed to read a line but Dietmar said...!?!\n";
}
}

Getting Clipboard data in raw format in c++

I've been playing around with the windows clipboard. I noticed that you can only view the clipboard if you supply a format. I've seen programs that can dump the raw contents of the clipboard. Look at http://www.autohotkey.com/docs/misc/Clipboard.htm#ClipboardAll for an example of what I mean.
Is there a way to do something similar, what I want to do is be able to back up the clipboard, manipulate it, then restore it when my program is done.
I'm looking for a non-.net solution if that's actually a thing
EDIT:
I tried this so far:
struct clipData {
vector<void*> data;
vector<int> size;
};
struct clipData saveClipboard(int &size) {
clipData ret;
UINT currentFormat = 0;
HGLOBAL hData;
if (OpenClipboard(0)) {
while(currentFormat = EnumClipboardFormats(currentFormat)) {
hData = GetClipboardData(currentFormat);
int currentClipboardFormatSize = GlobalSize(hData); //Only works with text formats. Help!
char *savedClipboardData = new char[currentClipboardFormatSize];
char *ptrToData = (char*) GlobalLock(hData);
memcpy(savedClipboardData, ptrToData, currentClipboardFormatSize);
ret.data.push_back(savedClipboardData);
ret.size.push_back(currentClipboardFormatSize);
}
CloseClipboard();
}
return ret;
}
But the problem is theres no way to tell how big the clipboard is in each format
There's no "raw" data involved. Just enumerate all the formats currently on the clipboard, and fetch and save the contents of each format. But be careful of automatic format conversions.
If you carefully read the autohotkey documentation you linked, it even tells you that it's retrieving each format separately, and that it may only succeed in retrieving a subset of the formats.
MSDN has all the examples you need to know to manipulate clipboard data using Clipboard API.

How to get the length of IStream? C++

I'm creating an IStream as follow:
IStream* stream;
result = CreateStreamOnHGlobal(0, TRUE, &stream);
Then I have a CImage object that I save to this stream:
image->Save(stream, Gdiplus::ImageFormatBMP);
I need to get the size of bytes written to this IStream.
How can I do this?
There is no Length or something like this in the IStream...
thanks!
IStream::Stat should do what you want.
Or you can use:
ULARGE_INTEGER liSize;
IStream_Size(pStream, &liSize);
other functions you might find useful in this context:
IStream_Reset(pStream); // reset seek position to beginning
IStream_Read(pStream, mem, size);
Both IStream_Size as well as IStream::Stat can be used to request the size. IStream_Size appears to be a convenience wrapper around IStream::Stat (that's oddly only available as a C COM macro). If that is indeed the case then there's a lot of data queried: An entire STATSTG, optionally without the pwcsName member.
In that case, a less costly way to get the same information would be IStream::Seek:
HRESULT get_size(IStream* stream, ULARGE_INTEGER& size) {
return IStream->Seek({}, STREAM_SEEK_END, &size);
}
This changes the stream's current read or write pointer. If you need to save the current position you can use the following:
ULARGE_INTEGER current{};
stream->Seek({}, STREAM_SEEK_CUR, &current);