Fix webcam framerate selection

This commit is contained in:
Marvin W 2021-05-01 17:27:55 +02:00
parent d388525fc6
commit 0409f55426
No known key found for this signature in database
GPG key ID: 072E9235DB996F2A
3 changed files with 35 additions and 10 deletions

View file

@ -87,6 +87,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
return Gst.Caps.from_string("audio/x-raw,rate=48000,channels=1"); return Gst.Caps.from_string("audio/x-raw,rate=48000,channels=1");
} else if (media == "video" && device.caps.get_size() > 0) { } else if (media == "video" && device.caps.get_size() > 0) {
int best_index = 0; int best_index = 0;
Value? best_fraction = null;
int best_fps = 0; int best_fps = 0;
int best_width = 0; int best_width = 0;
int best_height = 0; int best_height = 0;
@ -94,7 +95,28 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
unowned Gst.Structure? that = device.caps.get_structure(i); unowned Gst.Structure? that = device.caps.get_structure(i);
if (!that.has_name("video/x-raw")) continue; if (!that.has_name("video/x-raw")) continue;
int num = 0, den = 0, width = 0, height = 0; int num = 0, den = 0, width = 0, height = 0;
if (!that.has_field("framerate") || !that.get_fraction("framerate", out num, out den)) continue; if (!that.has_field("framerate")) continue;
Value framerate = that.get_value("framerate");
if (framerate.type() == typeof(Gst.Fraction)) {
num = Gst.Value.get_fraction_numerator(framerate);
den = Gst.Value.get_fraction_denominator(framerate);
} else if (framerate.type() == typeof(Gst.ValueList)) {
for(uint j = 0; j < Gst.ValueList.get_size(framerate); j++) {
Value fraction = Gst.ValueList.get_value(framerate, j);
int in_num = Gst.Value.get_fraction_numerator(fraction);
int in_den = Gst.Value.get_fraction_denominator(fraction);
int fps = den > 0 ? (num/den) : 0;
int in_fps = in_den > 0 ? (in_num/in_den) : 0;
if (in_fps > fps) {
best_fraction = fraction;
num = in_num;
den = in_den;
}
}
} else {
debug("Unknown type for framerate: %s", framerate.type_name());
}
if (den == 0) continue;
if (!that.has_field("width") || !that.get_int("width", out width)) continue; if (!that.has_field("width") || !that.get_int("width", out width)) continue;
if (!that.has_field("height") || !that.get_int("height", out height)) continue; if (!that.has_field("height") || !that.get_int("height", out height)) continue;
int fps = num/den; int fps = num/den;
@ -105,7 +127,14 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
best_index = i; best_index = i;
} }
} }
return caps_copy_nth(device.caps, best_index); Gst.Caps res = caps_copy_nth(device.caps, best_index);
unowned Gst.Structure? that = res.get_structure(0);
Value framerate = that.get_value("framerate");
if (framerate.type() == typeof(Gst.ValueList)) {
that.set_value("framerate", best_fraction);
}
debug("Selected caps %s", res.to_string());
return res;
} else if (device.caps.get_size() > 0) { } else if (device.caps.get_size() > 0) {
return caps_copy_nth(device.caps, 0); return caps_copy_nth(device.caps, 0);
} else { } else {

View file

@ -136,11 +136,7 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
pipe.set_state(Gst.State.PLAYING); pipe.set_state(Gst.State.PLAYING);
break; break;
case Gst.MessageType.STATE_CHANGED: case Gst.MessageType.STATE_CHANGED:
Gst.State new_state; // Ignore
message.parse_state_changed(null, out new_state, null);
if (message.src is Gst.Element) {
debug("%s changed state to %s", ((Gst.Element)message.src).name, new_state.to_string());
}
break; break;
case Gst.MessageType.STREAM_STATUS: case Gst.MessageType.STREAM_STATUS:
Gst.StreamStatusType status; Gst.StreamStatusType status;

View file

@ -75,7 +75,7 @@ dino_plugins_rtp_voice_processor_analyze_reverse_stream(void *native_ptr, GstAud
memcpy(frame.data_, audio_buffer.planes[0], frame.samples_per_channel_ * info->bpf); memcpy(frame.data_, audio_buffer.planes[0], frame.samples_per_channel_ * info->bpf);
int err = apm->AnalyzeReverseStream(&frame); int err = apm->AnalyzeReverseStream(&frame);
if (err < 0) g_warning("ProcessReverseStream %i", err); if (err < 0) g_warning("voice_processor_native.cpp: ProcessReverseStream %i", err);
gst_audio_buffer_unmap(&audio_buffer); gst_audio_buffer_unmap(&audio_buffer);
} }
@ -108,7 +108,7 @@ extern "C" void dino_plugins_rtp_voice_processor_adjust_stream_delay(void *nativ
g_debug("voice_processor_native.cpp: Stream delay metrics: %i %i %f", median, std, fraction_poor_delays); g_debug("voice_processor_native.cpp: Stream delay metrics: %i %i %f", median, std, fraction_poor_delays);
if (fraction_poor_delays > 0.5) { if (fraction_poor_delays > 0.5) {
native->stream_delay = std::max(0, native->stream_delay + std::min(-10, std::max(median, 10))); native->stream_delay = std::max(0, native->stream_delay + std::min(-10, std::max(median, 10)));
g_debug("Adjusted stream delay %i", native->stream_delay); g_debug("voice_processor_native.cpp: Adjusted stream delay %i", native->stream_delay);
} }
} }
@ -130,7 +130,7 @@ dino_plugins_rtp_voice_processor_process_stream(void *native_ptr, GstAudioInfo *
apm->set_stream_delay_ms(native->stream_delay); apm->set_stream_delay_ms(native->stream_delay);
int err = apm->ProcessStream(&frame); int err = apm->ProcessStream(&frame);
if (err >= 0) memcpy(audio_buffer.planes[0], frame.data_, frame.samples_per_channel_ * info->bpf); if (err >= 0) memcpy(audio_buffer.planes[0], frame.data_, frame.samples_per_channel_ * info->bpf);
if (err < 0) g_warning("ProcessStream %i", err); if (err < 0) g_warning("voice_processor_native.cpp: ProcessStream %i", err);
gst_audio_buffer_unmap(&audio_buffer); gst_audio_buffer_unmap(&audio_buffer);
} }