summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-02-21 08:51:37 +0000
committerBenny Prijono <bennylp@teluu.com>2008-02-21 08:51:37 +0000
commit7d6f281850fadac4b6824e6785ecd90ab0d0b27e (patch)
tree0e0cccd6ac889b54efcf80761e2ad8c3a3209465 /pjmedia
parent65c07c4340a2c8ce192545f1360c8129946c7139 (diff)
Ticket #468: Added support for non looping playback in memory player
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1808 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/include/pjmedia/mem_port.h17
-rw-r--r--pjmedia/src/pjmedia/mem_player.c52
2 files changed, 48 insertions, 21 deletions
diff --git a/pjmedia/include/pjmedia/mem_port.h b/pjmedia/include/pjmedia/mem_port.h
index 63c5f335..47b911f2 100644
--- a/pjmedia/include/pjmedia/mem_port.h
+++ b/pjmedia/include/pjmedia/mem_port.h
@@ -38,6 +38,21 @@ PJ_BEGIN_DECL
* situation where filesystems are not available in the target system.
*/
+
+/**
+ * Memory player options.
+ */
+enum pjmedia_mem_player_option
+{
+ /**
+ * Tell the memory player to return NULL frame when the whole
+ * buffer has been played instead of rewinding the buffer back
+ * to start position.
+ */
+ PJMEDIA_MEM_NO_LOOP = 1
+};
+
+
/**
* Create the buffer based playback to play the media from the specified
* buffer.
@@ -52,7 +67,7 @@ PJ_BEGIN_DECL
* @param channel_count Number of channels.
* @param samples_per_frame Number of samples per frame.
* @param bits_per_sample Number of bits per sample.
- * @param options Option flags.
+ * @param options Option flags, see #pjmedia_mem_player_option
* @param p_port Pointer to receive the port instance.
*
* @return PJ_SUCCESS on success, or the appropriate
diff --git a/pjmedia/src/pjmedia/mem_player.c b/pjmedia/src/pjmedia/mem_player.c
index 678391c0..038577ef 100644
--- a/pjmedia/src/pjmedia/mem_player.c
+++ b/pjmedia/src/pjmedia/mem_player.c
@@ -146,8 +146,22 @@ 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;
+ pj_status_t status = PJ_SUCCESS;
+
+ /* Call callback, if any */
+ if (player->cb)
+ status = (*player->cb)(this_port, player->user_data);
+
+ /* If callback returns non PJ_SUCCESS or 'no loop' is specified
+ * return immediately (and don't try to access player port since
+ * it might have been destroyed by the callback).
+ */
+ if ((status != PJ_SUCCESS) || (player->options & PJMEDIA_MEM_NO_LOOP)) {
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ return PJ_EEOF;
+ }
+
+ player->eof = PJ_FALSE;
}
size_needed = this_port->info.bytes_per_frame;
@@ -169,24 +183,18 @@ static pj_status_t mem_get_frame( pjmedia_port *this_port,
pj_assert(player->read_pos <= endpos);
if (player->read_pos == endpos) {
+ /* Set EOF flag */
+ player->eof = PJ_TRUE;
+ /* Reset read pointer */
player->read_pos = player->buffer;
- /* 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;
+ /* Pad with zeroes then return for no looped play */
+ if (player->options & PJMEDIA_MEM_NO_LOOP) {
+ pj_size_t null_len;
+
+ null_len = size_needed - size_written;
+ pj_bzero(dst + max, null_len);
+ break;
}
}
}
@@ -203,8 +211,12 @@ static pj_status_t mem_get_frame( pjmedia_port *this_port,
static pj_status_t mem_on_destroy(pjmedia_port *this_port)
{
- /* Nothing to do */
- PJ_UNUSED_ARG(this_port);
+ PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,
+ PJ_EINVALIDOP);
+
+ /* Destroy signature */
+ this_port->info.signature = 0;
+
return PJ_SUCCESS;
}