mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
bluetooth: ldac: Fix RTP payloading of encoded packet
Drop rtpldacpay and payload the LDAC encoded output manually in the RTP header. The RTP payload seems to be required as it carries the frame count information. Right now, rtpldacpay does not add this so construct the RTP header and payload manually. Strangely some devices like Shanling MP4 and Sony XM3 would still work without this while some like the Sony XM4 does not. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/689>
This commit is contained in:
parent
4b996e2a7b
commit
9f0a18b290
1 changed files with 24 additions and 23 deletions
|
|
@ -46,13 +46,6 @@ static bool can_be_supported(bool for_encoding) {
|
||||||
}
|
}
|
||||||
gst_object_unref(element_factory);
|
gst_object_unref(element_factory);
|
||||||
|
|
||||||
element_factory = gst_element_factory_find("rtpldacpay");
|
|
||||||
if (element_factory == NULL) {
|
|
||||||
pa_log_info("LDAC RTP payloader element `rtpldacpay` not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
gst_object_unref(element_factory);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,7 +199,6 @@ static uint8_t fill_preferred_configuration(const pa_sample_spec *default_sample
|
||||||
|
|
||||||
GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) {
|
GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) {
|
||||||
GstElement *bin;
|
GstElement *bin;
|
||||||
GstElement *rtpldacpay;
|
|
||||||
GstElement *enc;
|
GstElement *enc;
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
|
|
||||||
|
|
@ -270,28 +262,16 @@ GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_en
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtpldacpay = gst_element_factory_make("rtpldacpay", "rtp_ldac_pay");
|
|
||||||
if (!rtpldacpay) {
|
|
||||||
pa_log_error("Could not create RTP LDAC payloader element");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
bin = gst_bin_new("ldac_enc_bin");
|
bin = gst_bin_new("ldac_enc_bin");
|
||||||
pa_assert(bin);
|
pa_assert(bin);
|
||||||
|
|
||||||
gst_bin_add_many(GST_BIN(bin), enc, rtpldacpay, NULL);
|
gst_bin_add_many(GST_BIN(bin), enc, NULL);
|
||||||
|
|
||||||
if (!gst_element_link(enc, rtpldacpay)) {
|
|
||||||
pa_log_error("Failed to link LDAC encoder to LDAC RTP payloader");
|
|
||||||
gst_object_unref(bin);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pad = gst_element_get_static_pad(enc, "sink");
|
pad = gst_element_get_static_pad(enc, "sink");
|
||||||
pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)));
|
pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)));
|
||||||
gst_object_unref(GST_OBJECT(pad));
|
gst_object_unref(GST_OBJECT(pad));
|
||||||
|
|
||||||
pad = gst_element_get_static_pad(rtpldacpay, "src");
|
pad = gst_element_get_static_pad(enc, "src");
|
||||||
pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("src", pad)));
|
pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("src", pad)));
|
||||||
gst_object_unref(GST_OBJECT(pad));
|
gst_object_unref(GST_OBJECT(pad));
|
||||||
|
|
||||||
|
|
@ -421,12 +401,33 @@ static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
|
static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
|
||||||
|
struct gst_info *info = (struct gst_info *) codec_info;
|
||||||
|
struct rtp_header *header;
|
||||||
|
struct rtp_sbc_payload *payload;
|
||||||
size_t written;
|
size_t written;
|
||||||
|
|
||||||
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
|
if (PA_UNLIKELY(output_size < sizeof(*header) + sizeof(*payload))) {
|
||||||
|
*processed = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer + sizeof(*header) + sizeof(*payload), output_size - sizeof(*header) - sizeof(*payload), processed);
|
||||||
if (PA_UNLIKELY(*processed != input_size))
|
if (PA_UNLIKELY(*processed != input_size))
|
||||||
pa_log_error("LDAC encoding error");
|
pa_log_error("LDAC encoding error");
|
||||||
|
|
||||||
|
if (PA_LIKELY(written > 0)) {
|
||||||
|
header = (struct rtp_header *) output_buffer;
|
||||||
|
pa_zero(*header);
|
||||||
|
header->v = 2;
|
||||||
|
header->pt = 96;
|
||||||
|
header->sequence_number = htons(info->seq_num++);
|
||||||
|
header->timestamp = htonl(timestamp);
|
||||||
|
header->ssrc = htonl(1);
|
||||||
|
payload = (struct rtp_sbc_payload*) (output_buffer + sizeof(*header));
|
||||||
|
payload->frame_count = get_ldac_num_frames(codec_info, info->codec_type);
|
||||||
|
written += sizeof(*header) + sizeof(*payload);
|
||||||
|
}
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue