int pluginid;
int status;
- bool stop_by_user;
-
} __mmsound_mgr_codec_handle_t;
static MMSoundPluginType *g_codec_plugins = NULL;
#endif
static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
-static int _MMSoundMgrCodecStopCallback(int param);
+static int _MMSoundMgrCodecStopCallback(int param, bool stop_by_user);
static gboolean _mm_sound_mgr_codec_slot_is_empty();
static gboolean _idle_cb(gpointer user_data)
debug_msg("Found slot, Slotid [%d] State [%d]", slotid, g_slots[slotid].status);
#endif
- g_slots[slotid].stop_by_user = true;
-
err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
if (err != MM_ERROR_NONE)
debug_error("Fail to STOP Code : 0x%08X", err);
return err;
}
-static int _MMSoundMgrCodecStopCallback(int param)
+static int _MMSoundMgrCodecStopCallback(int param, bool stop_by_user)
{
int err = MM_ERROR_NONE;
return MM_ERROR_INVALID_ARGUMENT;
}
- debug_enter("Slot(%d) : stop-by-user(%d)", param, g_slots[param].stop_by_user);
+ debug_enter("Slot(%d) : stop-by-user(%d)", param, stop_by_user);
- if (!g_slots[param].stop_by_user) {
+ if (!stop_by_user) {
SLOT_LOCK();
__mm_sound_mgr_ipc_notify_play_file_end(param);
debug_msg("Client callback msg_type (instance) : [%d]", (int)g_slots[param].param);
if (_mm_sound_mgr_codec_slot_is_empty())
_mm_sound_mgr_codec_shutdown_timer_start();
- if (!g_slots[param].stop_by_user)
+ if (!stop_by_user)
SLOT_UNLOCK();
debug_fleave();
typedef struct {
int handle;
int repeat_count;
- int (*stop_cb)(int);
+ int (*stop_cb)(int, bool);
char filename[MM_SOUND_MAX_FILENAME];
int cb_param;
char stream_type[MAX_STREAM_TYPE_LEN];
pa_sample_spec spec;
SNDFILE *sf;
SF_INFO si;
+
+ size_t written;
} wave_info_t;
static int _sound_prepare(wave_info_t *h)
debug_msg("Invoke stop callback(%p, %d) of mgr_codec", h->stop_cb, h->cb_param);
if (h->stop_cb)
- h->stop_cb(h->cb_param);
+ h->stop_cb(h->cb_param, false);
}
static void _pa_stream_moved_callback(pa_stream *s, void *userdata)
debug_msg("stream(%p)", s);
}
+static void _pa_stream_started_callback(pa_stream *s, void *userdata)
+{
+ assert(s);
+ debug_msg("stream(%p)", s);
+}
+
static void _pa_stream_write_callback(pa_stream *s, size_t length, void *userdata)
{
sf_count_t bytes = 0;
if ((bytes = sf_readf_short(h->sf, data, (sf_count_t)(data_length / frame_size))) > 0)
bytes *= (sf_count_t)frame_size;
- debug_msg("stream(%p) : === %"PRId64" / %zu ===", s, bytes, data_length);
+ debug_msg("stream(%p) : === %"PRId64" / %zu / %zu ===", s, bytes, data_length, h->written);
if (bytes > 0)
pa_stream_write(s, data, (size_t)bytes, NULL, 0, PA_SEEK_RELATIVE);
else
pa_stream_cancel_write(s);
+ h->written += bytes;
+
/* If No more data, drain stream */
if (bytes < (sf_count_t)data_length) {
debug_msg("stream(%p) : End Of Stream", s);
pa_stream_set_moved_callback(s, _pa_stream_moved_callback, h);
pa_stream_set_underflow_callback(s, _pa_stream_underflow_callback, h);
pa_stream_set_buffer_attr_callback(s, _pa_stream_buffer_attr_callback, h);
+ pa_stream_set_started_callback(s, _pa_stream_started_callback, h);
ret = pa_stream_connect_playback(s, NULL, NULL,
PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_START_CORKED,
{
wave_info_t *h = (wave_info_t *)handle;
- debug_msg("Start handle(%p), stream(%p)", h, h->s);
+ debug_msg("Start handle(%p), stream(%p), written(%zu)", h, h->s, h->written);
_pa_stream_uncork(h);
return MM_ERROR_NONE;
_pa_stream_stop_disconnect(h);
if (h->stop_cb)
- h->stop_cb(h->cb_param);
+ h->stop_cb(h->cb_param, true);
return MM_ERROR_NONE;
}