summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-09-12 11:33:22 +0000
committerBenny Prijono <bennylp@teluu.com>2006-09-12 11:33:22 +0000
commit95907d60dddd42b86fc9d45b1396b14a31ef8f15 (patch)
tree134254aa34db10d6a331f11fb3134a52787b361e
parent025890b11ac3daf0b3bfc5f7b002b48746c373c8 (diff)
Added EOF callback and get_size() in pjmedia_mem_capture port.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@706 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/mem_port.h34
-rw-r--r--pjmedia/src/pjmedia/mem_capture.c95
2 files changed, 121 insertions, 8 deletions
diff --git a/pjmedia/include/pjmedia/mem_port.h b/pjmedia/include/pjmedia/mem_port.h
index 40c85999..fd0f0e88 100644
--- a/pjmedia/include/pjmedia/mem_port.h
+++ b/pjmedia/include/pjmedia/mem_port.h
@@ -134,6 +134,40 @@ PJ_DECL(pj_status_t) pjmedia_mem_capture_create(pj_pool_t *pool,
/**
+ * Register a callback to be called when no space left in the buffer.
+ * Note that when a callback is registered, this callback will also be
+ * called when application destroys the port and the callback has not
+ * been called before.
+ *
+ * @param port The memory recorder 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 recording will stop. In other cases
+ * recording will be restarted and the rest of the frame
+ * will be stored starting from the beginning of the
+ * buffer. Note that if application destroys the capture
+ * port in the callback, it must return non-PJ_SUCCESS
+ * here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_mem_capture_set_eof_cb(pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+/**
+ * Return the current size of the recorded data in the buffer.
+ *
+ * @param port The memory recorder port.
+ * @return The size of buffer data..
+ */
+PJ_DECL(pj_size_t)
+pjmedia_mem_capture_get_size(pjmedia_port *port);
+
+
+/**
* @}
*/
diff --git a/pjmedia/src/pjmedia/mem_capture.c b/pjmedia/src/pjmedia/mem_capture.c
index e4c26f84..e81220e2 100644
--- a/pjmedia/src/pjmedia/mem_capture.c
+++ b/pjmedia/src/pjmedia/mem_capture.c
@@ -36,6 +36,11 @@ struct mem_rec
char *buffer;
pj_size_t buf_size;
char *write_pos;
+
+ pj_bool_t eof;
+ void *user_data;
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *user_data);
};
@@ -95,6 +100,45 @@ PJ_DECL(pj_status_t) pjmedia_mem_capture_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_capture_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data))
+{
+ struct mem_rec *rec;
+
+ PJ_ASSERT_RETURN(port->info.signature == SIGNATURE,
+ PJ_EINVALIDOP);
+
+ rec = (struct mem_rec*) port;
+ rec->user_data = user_data;
+ rec->cb = cb;
+
+ return PJ_SUCCESS;
+}
+
+
+/* Get current buffer size */
+PJ_DEF(pj_size_t) pjmedia_mem_capture_get_size(pjmedia_port *port)
+{
+ struct mem_rec *rec;
+
+ PJ_ASSERT_RETURN(port->info.signature == SIGNATURE,
+ 0);
+
+ rec = (struct mem_rec*) port;
+ if (rec->eof){
+ return rec->buf_size;
+ }
+ return rec->write_pos - rec->buffer;
+}
+
+
static pj_status_t rec_put_frame( pjmedia_port *this_port,
const pjmedia_frame *frame)
{
@@ -107,25 +151,48 @@ static pj_status_t rec_put_frame( pjmedia_port *this_port,
rec = (struct mem_rec*) this_port;
+ if (rec->eof) {
+ return PJ_EEOF;
+ }
+
size_written = 0;
endpos = rec->buffer + rec->buf_size;
while (size_written < frame->size) {
pj_size_t max;
-
+
max = frame->size - size_written;
if ((endpos - rec->write_pos) < (int)max)
max = endpos - rec->write_pos;
-
+
pj_memcpy(rec->write_pos, ((char*)frame->buf)+size_written, max);
size_written += max;
rec->write_pos += max;
-
+
pj_assert(rec->write_pos <= endpos);
-
- if (rec->write_pos == endpos)
+
+ if (rec->write_pos == endpos) {
+
+ /* Rewind */
rec->write_pos = rec->buffer;
+
+ /* Call callback, if any */
+ if (rec->cb) {
+ pj_status_t status;
+
+ rec->eof = PJ_TRUE;
+ status = (*rec->cb)(this_port, rec->user_data);
+ if (status != PJ_SUCCESS) {
+ /* Must not access recorder from here on. It may be
+ * destroyed by application.
+ */
+ return status;
+ }
+ rec->eof = PJ_FALSE;
+ }
+ }
}
+
return PJ_SUCCESS;
}
@@ -147,10 +214,22 @@ static pj_status_t rec_get_frame( pjmedia_port *this_port,
static pj_status_t rec_on_destroy(pjmedia_port *this_port)
{
- /* Nothing to do */
- PJ_UNUSED_ARG(this_port);
+ /* Call callback if data was captured
+ * and we're not in the callback already.
+ */
+ struct mem_rec *rec;
+
+ PJ_ASSERT_RETURN(this_port->info.signature == SIGNATURE,
+ PJ_EINVALIDOP);
+
+ rec = (struct mem_rec*) this_port;
+
+ if(rec->cb && PJ_FALSE == rec->eof) {
+ rec->eof = PJ_TRUE;
+ (*rec->cb)(this_port, rec->user_data);
+ }
+
return PJ_SUCCESS;
}
-