summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-09-11 19:55:41 +0000
committerBenny Prijono <bennylp@teluu.com>2006-09-11 19:55:41 +0000
commit18fd894546492261e3abff8d5d1d7b45c352e4cc (patch)
tree3e1259c0654df2b1b5bc8d3a9cf5565ab4d45405
parent785a7742999d3ffea53a4a24912174ce858e53f9 (diff)
Added EOF callback in memory playback port.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@704 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/mem_port.h22
-rw-r--r--pjmedia/src/pjmedia/mem_player.c60
2 files changed, 79 insertions, 3 deletions
diff --git a/pjmedia/include/pjmedia/mem_port.h b/pjmedia/include/pjmedia/mem_port.h
index 7c62b614..40c85999 100644
--- a/pjmedia/include/pjmedia/mem_port.h
+++ b/pjmedia/include/pjmedia/mem_port.h
@@ -70,6 +70,28 @@ PJ_DECL(pj_status_t) pjmedia_mem_player_create(pj_pool_t *pool,
/**
+ * Register a callback to be called when the buffer reading has reached the
+ * end of buffer. If the player is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each player port.
+ *
+ * @param port The memory player port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the player port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_mem_player_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
* @}
*/
diff --git a/pjmedia/src/pjmedia/mem_player.c b/pjmedia/src/pjmedia/mem_player.c
index 5bc82caf..a2aec01a 100644
--- a/pjmedia/src/pjmedia/mem_player.c
+++ b/pjmedia/src/pjmedia/mem_player.c
@@ -37,6 +37,12 @@ struct mem_player
char *buffer;
pj_size_t buf_size;
char *read_pos;
+
+ pj_bool_t eof;
+ void *user_data;
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *user_data);
+
};
@@ -94,6 +100,30 @@ PJ_DEF(pj_status_t) pjmedia_mem_player_create( pj_pool_t *pool,
}
+
+/*
+ * Register a callback to be called when the file reading has reached the
+ * end of buffer.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_mem_player_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data))
+{
+ struct mem_player *player;
+
+ PJ_ASSERT_RETURN(port->info.signature == SIGNATURE,
+ PJ_EINVALIDOP);
+
+ player = (struct mem_player*) port;
+ player->user_data = user_data;
+ player->cb = cb;
+
+ return PJ_SUCCESS;
+}
+
+
static pj_status_t mem_put_frame( pjmedia_port *this_port,
const pjmedia_frame *frame)
{
@@ -116,6 +146,11 @@ static pj_status_t mem_get_frame( pjmedia_port *this_port,
player = (struct mem_player*) this_port;
+ if (player->eof) {
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ return PJ_EEOF;
+ }
+
size_needed = this_port->info.bytes_per_frame;
size_written = 0;
endpos = player->buffer + player->buf_size;
@@ -134,16 +169,35 @@ static pj_status_t mem_get_frame( pjmedia_port *this_port,
pj_assert(player->read_pos <= endpos);
- if (player->read_pos == endpos)
+ if (player->read_pos == endpos) {
player->read_pos = player->buffer;
- }
- player->timestamp.u64 += this_port->info.samples_per_frame;
+ /* Call callback, if any */
+ if (player->cb) {
+ pj_status_t status;
+
+ player->eof = PJ_TRUE;
+ status = (*player->cb)(this_port, player->user_data);
+ if (status != PJ_SUCCESS) {
+ /* Must not access player from here on. It may be
+ * destroyed by application.
+ */
+ frame->size = size_written;
+ frame->timestamp.u64 = player->timestamp.u64;
+ frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+ return status;
+ }
+ player->eof = PJ_FALSE;
+ }
+ }
+ }
frame->size = this_port->info.bytes_per_frame;
frame->timestamp.u64 = player->timestamp.u64;
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+ player->timestamp.u64 += this_port->info.samples_per_frame;
+
return PJ_SUCCESS;
}