a2dp_source: add avdtp_source_stream_send_media_payload_rtp, deprecate avdtp_source_stream_send_media_payload

This commit is contained in:
Matthias Ringwald 2021-01-07 10:28:39 +01:00
parent 636a58caf1
commit 3790661c7f
2 changed files with 66 additions and 45 deletions

View File

@ -165,12 +165,7 @@ void avdtp_source_init(void) {
}
static void avdtp_source_setup_media_header(uint8_t * media_packet, int size, int *offset, uint8_t marker, uint16_t sequence_number){
if (size < AVDTP_MEDIA_PAYLOAD_HEADER_SIZE){
log_error("small outgoing buffer");
return;
}
static void avdtp_source_setup_media_header(uint8_t * media_packet, uint8_t marker, uint16_t sequence_number){
uint8_t rtp_version = 2;
uint8_t padding = 0;
uint8_t extension = 0;
@ -181,9 +176,7 @@ static void avdtp_source_setup_media_header(uint8_t * media_packet, int size, in
uint32_t ssrc = 0x11223344;
// rtp header (min size 12B)
int pos = 0;
// int mtu = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
uint16_t pos = 0;
media_packet[pos++] = (rtp_version << 6) | (padding << 5) | (extension << 4) | csrc_count;
media_packet[pos++] = (marker << 1) | payload_type;
big_endian_store_16(media_packet, pos, sequence_number);
@ -191,48 +184,60 @@ static void avdtp_source_setup_media_header(uint8_t * media_packet, int size, in
big_endian_store_32(media_packet, pos, timestamp);
pos += 4;
big_endian_store_32(media_packet, pos, ssrc); // only used for multicast
pos += 4;
*offset = pos;
}
static void avdtp_source_copy_media_payload(uint8_t * media_packet, int size, int * offset, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames){
if (size < (num_bytes_to_copy + 1)){
log_error("small outgoing buffer: buffer size %u, but need %u", size, num_bytes_to_copy + 1);
return;
}
int pos = *offset;
media_packet[pos++] = num_frames; // (fragmentation << 7) | (starting_packet << 6) | (last_packet << 5) | num_frames;
(void)memcpy(media_packet + pos, storage, num_bytes_to_copy);
pos += num_bytes_to_copy;
*offset = pos;
}
int avdtp_source_stream_send_media_payload(uint16_t avdtp_cid, uint8_t local_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker){
// @deprecated, use avdtp_source_stream_send_media_payload_rtp instead
int avdtp_source_stream_send_media_payload(uint16_t avdtp_cid, uint8_t local_seid, uint8_t * payload, int payload_size, uint8_t num_frames, uint8_t marker){
UNUSED(avdtp_cid);
avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(local_seid);
if (!stream_endpoint) {
log_error("avdtp source: no stream_endpoint with seid %d", local_seid);
return 0;
}
if (stream_endpoint->l2cap_media_cid == 0){
log_error("avdtp source: no media connection for seid %d", local_seid);
return 0;
}
}
int size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
int offset = 0;
uint16_t buffer_size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
uint16_t packet_size = AVDTP_MEDIA_PAYLOAD_HEADER_SIZE + payload_size + 1;
if (packet_size >= buffer_size) return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
l2cap_reserve_packet_buffer();
uint8_t * media_packet = l2cap_get_outgoing_buffer();
avdtp_source_setup_media_header(media_packet, size, &offset, marker, stream_endpoint->sequence_number);
avdtp_source_copy_media_payload(media_packet, size, &offset, storage, num_bytes_to_copy, num_frames);
avdtp_source_setup_media_header(media_packet, marker, stream_endpoint->sequence_number);
media_packet[AVDTP_MEDIA_PAYLOAD_HEADER_SIZE] = num_frames; // (fragmentation << 7) | (starting_packet << 6) | (last_packet << 5) | num_frames;
(void)memcpy(&media_packet[AVDTP_MEDIA_PAYLOAD_HEADER_SIZE +1], payload, payload_size);
stream_endpoint->sequence_number++;
l2cap_send_prepared(stream_endpoint->l2cap_media_cid, offset);
return size;
l2cap_send_prepared(stream_endpoint->l2cap_media_cid, packet_size);
return packet_size;
}
uint8_t avdtp_source_stream_send_media_payload_rtp(uint16_t avdtp_cid, uint8_t local_seid, uint8_t marker, uint8_t * payload, uint16_t payload_size){
UNUSED(avdtp_cid);
avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(local_seid);
if (!stream_endpoint) {
log_error("avdtp source: no stream_endpoint with seid %d", local_seid);
return 0;
}
if (stream_endpoint->l2cap_media_cid == 0){
log_error("avdtp source: no media connection for seid %d", local_seid);
return 0;
}
uint16_t buffer_size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
uint16_t packet_size = AVDTP_MEDIA_PAYLOAD_HEADER_SIZE + payload_size;
if (packet_size >= buffer_size) return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
l2cap_reserve_packet_buffer();
uint8_t * media_packet = l2cap_get_outgoing_buffer();
avdtp_source_setup_media_header(media_packet, marker, stream_endpoint->sequence_number);
(void)memcpy(&media_packet[AVDTP_MEDIA_PAYLOAD_HEADER_SIZE +1], payload, payload_size);
stream_endpoint->sequence_number++;
return l2cap_send_prepared(stream_endpoint->l2cap_media_cid, packet_size);
}
uint8_t avdtp_source_stream_send_media_packet(uint16_t avdtp_cid, uint8_t local_seid, const uint8_t * packet, uint16_t size){
@ -253,6 +258,8 @@ uint8_t avdtp_source_stream_send_media_packet(uint16_t avdtp_cid, uint8_t local_
}
void avdtp_source_stream_endpoint_request_can_send_now(uint16_t avdtp_cid, uint8_t local_seid){
UNUSED(avdtp_cid);

View File

@ -238,7 +238,29 @@ avdtp_stream_endpoint_t * avdtp_source_create_stream_endpoint(avdtp_sep_type_t s
void avdtp_source_finalize_stream_endpoint(avdtp_stream_endpoint_t * stream_endpoint);
/**
* @brief Send media payload.
* @brief Send media packet
* @param avdtp_cid AVDTP channel identifyer.
* @param local_seid ID of a local stream endpoint.
* @param packet
* @param size
* @return status
*/
uint8_t avdtp_source_stream_send_media_packet(uint16_t avdtp_cid, uint8_t local_seid, const uint8_t * packet, uint16_t size);
/**
* @brief Send media payload including RTP header
* @param avdtp_cid AVDTP channel identifyer.
* @param local_seid ID of a local stream endpoint.
* @param marker
* @param payload
* @param size
* @return status
*/
uint8_t avdtp_source_stream_send_media_payload_rtp(uint16_t avdtp_cid, uint8_t local_seid, uint8_t marker, uint8_t * payload, uint16_t size);
/**
* @brief Send media payload including RTP header and the SBC media header
* @deprecated Please use avdtp_source_stream_send_media_payload_rtp
* @param avdtp_cid AVDTP channel identifyer.
* @param local_seid ID of a local stream endpoint.
* @param storage
@ -249,15 +271,7 @@ void avdtp_source_finalize_stream_endpoint(avdtp_stream_endpoint_t * stream_endp
*/
int avdtp_source_stream_send_media_payload(uint16_t avdtp_cid, uint8_t local_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker);
/**
* @brief Send media packet.
* @param avdtp_cid AVDTP channel identifyer.
* @param local_seid ID of a local stream endpoint.
* @param packet
* @param size
* @return status
*/
uint8_t avdtp_source_stream_send_media_packet(uint16_t avdtp_cid, uint8_t local_seid, const uint8_t * packet, uint16_t size);
/**
* @brief Request to send a media packet. Packet can be then sent on reception of AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW event.