Мы используем PJSIP для звонков на Android. Когда мы используем метод onFrameReceived для получения аудиокадров, мы сталкиваемся с большим количеством шума. Затем мы передаем эти кадры в конвейер GStreamer, который отправляет их на определенный порт. Однако когда мы получаем этот звук из этого порта, он по-прежнему полон шума.
Может ли кто-нибудь помочь нам устранить эту проблему?
вот при получении кадра функция Java
Код: Выделить всё
public void onFrameReceived(MediaFrame frame)
{
Log.i("ashish", "Receiving callback on frameReceived");
// Check if the frame is valid
if (frame == null) {
Log.e("ashish", "Received a null MediaFrame");
return;
}
// Get the size of the audio data
int size = (int) frame.getSize(); // Get the size (number of shorts)
Log.d("ashish", "Audio data size: " + size);
// Convert buffer to Short[]
Short[] audioDataShort = frame.getBuf().toArray(new Short[0]);
// Check if audioDataShort is not null and has the expected length
if (audioDataShort == null || audioDataShort.length == 0) {
Log.e("ashish", "Received empty audio data");
return;
}
if (audioDataShort.length != size) {
Log.e("ashish", "Size mismatch: expected " + size + ", got " + audioDataShort.length);
return;
}
// Create a byte array to hold the data
byte[] audioData = new byte[size * 2]; // Each short is 2 bytes
// Convert Short[] to byte[]
for (int i = 0; i < audioDataShort.length; i++) {
// Convert each short to byte array in little-endian order
audioData[i * 2] = (byte) ((audioDataShort[i] >> 8) & 0xFF); // Lower byte
audioData[i * 2 + 1] = (byte) (audioDataShort[i] & 0xFF); // Upper byte
}
// Debug: Log the byte array
Log.d("ashish", "Audio Data Bytes: " + Arrays.toString(audioData));
// Call the native method to send the byte array
nativeSend(audioData, size); // Send the byte array and its length
МЫ ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ КОД C++ ДЛЯ ПОМЕЩЕНИЯ АУДИО В КОНВЕЙЕР GSTREAMER
Код: Выделить всё
JNIEXPORT void JNICALL Java_GStreamerApp_pushBuffer(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length)
{
if (buffer == NULL || length GetByteArrayElements(env, buffer, NULL);
if (nativeBuffer == NULL) {
return; // Handle error
}
CustomData *data = GET_CUSTOM_DATA(env, thiz, custom_data_field_id);
if (data == NULL || data->send_src == NULL) {
(*env)->ReleaseByteArrayElements(env, buffer, nativeBuffer, 0);
return;
}
GstBuffer *gstBuffer = gst_buffer_new_and_alloc(length);
if (gstBuffer == NULL) {
(*env)->ReleaseByteArrayElements(env, buffer, nativeBuffer, 0);
return;
}
// Fill the GStreamer buffer with audio data
gst_buffer_fill(gstBuffer, 0, nativeBuffer, length);
// Push the buffer into appsrc
GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(data->send_src), gstBuffer);
if (ret != GST_FLOW_OK) {
GST_ERROR("Error pushing buffer to appsrc: %d", ret);
}
(*env)->ReleaseByteArrayElements(env, buffer, nativeBuffer, 0);
}
Код: Выделить всё
static void *send_data_pipeline(void *userdata) {
CustomData *data = (CustomData *)userdata;
GstBus *bus;
GError *error = NULL;
GST_DEBUG("Creating pipeline in CustomData at %p", data);
// Create pipeline and elements
data->send_pipeline = gst_pipeline_new("data-pipeline-send");
data->send_src = gst_element_factory_make("appsrc", "source_send");
data->send_queue = gst_element_factory_make("queue", "storage_queue");
data->send_capsfilter = gst_element_factory_make("capsfilter", "filter");
data->send_sink = gst_element_factory_make("udpsink", "sinksend");
// Check for element creation
if (!data->send_pipeline || !data->send_src || !data->send_sink || !data->send_queue || !data->send_capsfilter) {
GST_ERROR("Failed to create elements in the pipeline.");
return NULL;
}
// Set properties for the sink and source
g_object_set(G_OBJECT(data->send_sink), "host", "172.16.7.73", "port", 5000, NULL);
g_object_set(G_OBJECT(data->send_src), "format", GST_FORMAT_TIME, "is-live", TRUE, NULL);
g_object_set(G_OBJECT(data->send_src), "buffer-size", 4096, NULL);
// Create and set caps
GstCaps *caps = gst_caps_from_string("audio/x-raw, format=(string)S16LE, channels=(int)2, rate=(int)8000");
g_object_set(G_OBJECT(data->send_capsfilter), "caps", caps, NULL);
gst_caps_unref(caps); // Unreference the caps after setting
// Add elements to the pipeline
gst_bin_add_many(GST_BIN(data->send_pipeline), data->send_src, data->send_capsfilter, data->send_queue, data->send_sink, NULL);
// Link elements
if (!gst_element_link_many(data->send_src, data->send_capsfilter, data->send_queue, data->send_sink, NULL)) {
GST_ERROR("Elements could not be linked.");
return NULL; // Cleanup if necessary
}
// Set the pipeline to the playing state
gst_element_set_state(data->send_pipeline, GST_STATE_PLAYING);
// Start processing bus messages
bus = gst_element_get_bus(data->send_pipeline);
gboolean running = TRUE;
gst_element_set_state(data->send_pipeline, GST_STATE_PLAYING);
gst_object_unref(bus);
gst_object_unref(data->send_pipeline); // If needed, depending on your ownership semantics
return NULL;
}`
Подробнее здесь: https://stackoverflow.com/questions/791 ... udiostream