I had forgotten how constants worked when compiled; constants are
uploaded as constant registers. When constants are used with shaders,
multiple constants are often packed in to a single register when
possible to reduce constant register count.
For example, one 'float' constant and one 'float3' constant will be
packed in to a single register (c0.x for constant 1, c0.yzw for constant
2), but two 'float' constants and one 'float3' constant must inhabit two
registers (c0.xy for constant 1, c1.xyz for constant 2), so it must
start on a new register boundry (every 16 bytes).
I had first instinctively thought it was just a simple case of
alignment like it is on the CPU, but then I realized that it didn't
sound right, so I went back and did some more tests and then ultimately
remembered how constants actually are uploaded.
Starting with VS2012, microsoft made a terribly stupid change to the way
working directory is handled. It basically will not work properly if
you need to run your executable from a specific location, it would only
run properly from debug if you also had your target directory set to an
environment variable, which was incredibly stupid. The visual studio
development team is run by chimpanzees with tiny brains, headed by
a broken AI core designed by gilbert gottfried.
I made a workaround for it so that it's much easier to set up debugging
in VS2013, so that all you need to do is enter in the the working
directory for it to work properly. Still somewhat of a pain but the Qt
addin kept overwriting the god forsaken environment path, and made
setting it up much more difficult than it was supposed to be.
If a source with async video wasn't currently active, it would endlessly
buffer the video data, which would cause memory to grow endlessly until
available memory was extinguished.
This really needs to be replaced with a proper caching mechanism at some
point.
With this option enabled the plugin will generate timestamps
based on the system time instead of using the ones provided by
pulse audio. This might fix problems with audio desync and may
become the default/only option in the future.
The defaults functions will now return the default device for the
input/output as provided by pulseaudio.
The default output device is the monitor of the default sink.
This saves scenes/sources from json on exit, and properly loads it back
up when starting up the program again, as well as the currently active
scene.
I had to add a 'load' and 'save' callback to the source interface
structure because I realizes that certain sources (such as scenes)
operate different with their saved data; scenes for example would have
to keep track of their settings information constantly, and that was
somewhat unacceptable to make it functional.
The optional 'load' callback will be called only after having loaded
setttings specifically from file/imported data, and the 'save' function
will be called only specifically when data actually needs to be saved.
I also had to adjust the obs_scene code so that it's a regular input
source type now, and I also modified it so that it doesn't have some
strange custom creation code anymore. The obs_scene_create function is
now simply just a wrapper for obs_source_create. You could even create
a scene with obs_source_create manually as well.
The 'wait' constant was a terrible means of trying to ensure that the
packets were interleaved. Instead, calculate the current highest
timestamps of each encoder that's present in the interleaved buffer, and
use that as a means of detecting whether the current packet should be
sent off. This will guarantee sorting without relying on some arbirary
constant that 'assumes' that it'll be interleaved. It also reduces
buffering any more than what is needed to interleave.
It didn't really look very nice in most cases and the controls were
always compacted, doing this makes it look a bit better.
Also change it so the properties window shows the properties on the
bottom below the source rather than to the right, seeing as in most
cases the source has a greater width than height, and it feels just a
little bit better to look at (thought that's just my opinion).
Controls still stretch really far sometimes though, I wonder what should
be done about that to be honest. Maybe prevent it from scrolling to the
right?
The wrapping library uses a global mainloop and context which
allows operations to share the connection. The global mainloop
is created and destroyed based on internal reference counting.
The capture code won't spawn a new thread for each input anymore
but instead just create the recording stream and rely on the
threaded mainloop to execute the read callback when data is available.
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.