-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: route audio from CEF #1517
base: master
Are you sure you want to change the base?
Conversation
Is there any progress on this feature? |
@qu1rk3y I did this prototype implementation a while back because I was curious on how hard it would be, but haven't done as much testing as I think it needs before it can be merged. If anyone wants to give it a try, there is a build based on top of the master branch at the time of writing at https://builds.julusian.dev/casparcg/casparcg-server-b52edd40855b659798c9b78643e66d1d8e6aebdc-windows.zip |
I tried to test this but I was unable to run this server, it was complaining about an asio io_service. I don't know if the error comes from that or the diagnostics exception. This happens in b52edd4 as well as latest master build e4e9ed2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It runs on WIndows for me, but I don't understand how it could (see the other comments). The audio doesn't sound right at all though. It's not choppy, it more like every other audio frame is missing is something like that.
It crashes on Linux.
@@ -302,7 +369,10 @@ class html_client | |||
{ | |||
std::lock_guard<std::mutex> lock(frames_mutex_); | |||
|
|||
frames_.push(std::make_pair(now(), core::draw_frame(std::move(frame)))); | |||
core::draw_frame new_frame = core::draw_frame(std::move(frame)); | |||
last_generated_frame_ = new_frame; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Julusian Could you talk me through how the move semantics works here? As far as I can tell, the draw_frame assignment operator moves the content of new_frame to last_generated_frame_ which would leave new_frame invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, the draw_frame assignment operator moves the content of new_frame to last_generated_frame_ which would leave new_frame invalid.
The parameter of the assignment operator is not a reference, so will be a copy of new_frame
making it safe to mutate. You have made me question this now, but this same pattern has been in place for draw_frame
for years, with the core::frame_producer
doing it with any draw_frame
that gets produced by every producer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see it now. I missed the implicit call to the copy constructor during the assignment. It looks OK.
auto audio = audioResampler_->convert(samples, reinterpret_cast<const void**>(data)); | ||
auto audio_frame = core::mutable_frame(this, {}, std::move(audio), core::pixel_format_desc()); | ||
|
||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This crashes on Linux. If i comment out this entire block, it runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this is from the hardcoded 8 in
auto result = caspar::array<int32_t>(frames * 8 * sizeof(int32_t)); |
I appear to have opened this PR a few hours before I made a change to support 16 channel audio 28c4dcd
That would explain the slowness/broken audio you are experiencing too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try that
{ | ||
std::lock_guard<std::mutex> lock(frames_mutex_); | ||
if (frames_.empty()) { | ||
presentation_frame wrapped_frame(last_generated_frame_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I don't understand how this would work. When you construct a presentation_frame from a draw_frame, you move the draw_frame into the presentation_frame. Doesn't that invalidate last_generated_frame_?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the other question, the constructor parameter isnt a r-value or l-value, so I think it is fine
Inspired by/based upon a start made by nxtedition at https://github.com/nxtedition/casparcg
This needs a bit more testing to ensure it works smoothly and without glitches.
In particular, when audio starts/stops within the page, and when motion starts/stops
This also needs a sync test, to check that the audio is in sync and remains in sync with both video and audio pausing and resuming