Bluetooth: MPL: Add track position notifications during seeking

When seeking the media player should notify clients about the
track position change.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2023-12-15 13:31:38 +01:00 committed by Carles Cufí
commit 8df987935b
3 changed files with 50 additions and 0 deletions

View file

@ -8,7 +8,9 @@
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/time_units.h>
#include <zephyr/bluetooth/services/ots.h>
#include <zephyr/bluetooth/audio/media_proxy.h>
@ -26,6 +28,9 @@ LOG_MODULE_REGISTER(bt_mpl, CONFIG_BT_MPL_LOG_LEVEL);
#define TRACK_STATUS_INVALID 0x00
#define TRACK_STATUS_VALID 0x01
#define TRACK_POS_WORK_DELAY_MS 1000
#define TRACK_POS_WORK_DELAY K_MSEC(TRACK_POS_WORK_DELAY_MS)
#define PLAYBACK_SPEED_PARAM_DEFAULT MEDIA_PROXY_PLAYBACK_SPEED_UNITY
/* Temporary hardcoded setup for groups, tracks and segments */
@ -1346,7 +1351,10 @@ static void mpl_set_state(uint8_t state)
case MEDIA_PROXY_STATE_INACTIVE:
case MEDIA_PROXY_STATE_PLAYING:
case MEDIA_PROXY_STATE_PAUSED:
(void)k_work_cancel_delayable(&media_player.pos_work);
break;
case MEDIA_PROXY_STATE_SEEKING:
(void)k_work_schedule(&media_player.pos_work, TRACK_POS_WORK_DELAY);
break;
default:
__ASSERT(false, "Invalid state: %u", state);
@ -2286,6 +2294,24 @@ static uint8_t get_content_ctrl_id(void)
return media_player.content_ctrl_id;
}
static void pos_work_cb(struct k_work *work)
{
if (media_player.state == MEDIA_PROXY_STATE_SEEKING) {
const int32_t pos_diff_cs =
TRACK_POS_WORK_DELAY_MS / 10; /* position is in centiseconds*/
/* When seeking, apply the seeking speed factor */
set_relative_track_position(pos_diff_cs * media_player.seeking_speed_factor);
if (media_player.track_pos == media_player.group->track->duration) {
/* Go to next track */
do_next_track(&media_player);
}
(void)k_work_schedule(&media_player.pos_work, TRACK_POS_WORK_DELAY);
}
}
int media_proxy_pl_init(void)
{
static bool initialized;
@ -2387,6 +2413,8 @@ int media_proxy_pl_init(void)
return ret;
}
k_work_init_delayable(&media_player.pos_work, pos_work_cb);
initialized = true;
return 0;
}

View file

@ -89,6 +89,8 @@ struct mpl_mediaplayer {
struct mpl_track *track; /* The track explicitly set as next track */
struct mpl_group *group; /* The group of the set track */
} next;
struct k_work_delayable pos_work;
};

View file

@ -784,11 +784,14 @@ static void test_cp_pause(void)
static void test_cp_fast_rewind(void)
{
const int32_t tmp_pos = g_pos;
struct mpl_cmd cmd;
cmd.opcode = BT_MCS_OPC_FAST_REWIND;
cmd.use_param = false;
UNSET_FLAG(track_position_read);
test_send_cmd_wait_flags(&cmd);
if (g_command_result != BT_MCS_OPC_NTF_SUCCESS) {
@ -799,15 +802,25 @@ static void test_cp_fast_rewind(void)
if (test_verify_media_state_wait_flags(BT_MCS_MEDIA_STATE_SEEKING)) {
printk("FAST REWIND command succeeded\n");
}
/* Wait for the track position to change during rewinding */
WAIT_FOR_FLAG(track_position_read);
if (tmp_pos <= g_pos) {
FAIL("Position did not change during rewinding");
return;
}
}
static void test_cp_fast_forward(void)
{
const int32_t tmp_pos = g_pos;
struct mpl_cmd cmd;
cmd.opcode = BT_MCS_OPC_FAST_FORWARD;
cmd.use_param = false;
UNSET_FLAG(track_position_read);
test_send_cmd_wait_flags(&cmd);
if (g_command_result != BT_MCS_OPC_NTF_SUCCESS) {
@ -818,6 +831,13 @@ static void test_cp_fast_forward(void)
if (test_verify_media_state_wait_flags(BT_MCS_MEDIA_STATE_SEEKING)) {
printk("FAST FORWARD command succeeded\n");
}
/* Wait for the track position to change during forwarding */
WAIT_FOR_FLAG(track_position_read);
if (tmp_pos >= g_pos) {
FAIL("Position did not change during forwarding");
return;
}
}
static void test_cp_stop(void)