From 64533d446695fe13a750b0cd5386e0d159a2b160 Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Tue, 7 Apr 2015 11:23:41 +0000 Subject: Close #1836: Added colorbar device with active role. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5050 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/src/pjmedia-videodev/colorbar_dev.c | 87 +++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/pjmedia/src/pjmedia-videodev/colorbar_dev.c b/pjmedia/src/pjmedia-videodev/colorbar_dev.c index 0b5e1449..a65b0d65 100644 --- a/pjmedia/src/pjmedia-videodev/colorbar_dev.c +++ b/pjmedia/src/pjmedia-videodev/colorbar_dev.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include @@ -28,13 +29,13 @@ PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC != 0 - #define THIS_FILE "colorbar_dev.c" #define DEFAULT_CLOCK_RATE 90000 #define DEFAULT_WIDTH 352 //640 #define DEFAULT_HEIGHT 288 //480 #define DEFAULT_FPS 25 + /* cbar_ device info */ struct cbar_dev_info { @@ -99,6 +100,10 @@ struct cbar_stream pj_uint8_t *first_line[PJMEDIA_MAX_VIDEO_PLANES]; pj_timestamp ts; unsigned ts_inc; + + /* For active capturer only */ + pjmedia_clock *clock; + pj_uint8_t *clock_buf; }; @@ -188,11 +193,13 @@ static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f) struct cbar_dev_info *ddi; unsigned i; - cf->dev_count = 1; + cf->dev_count = 2; + cf->dev_info = (struct cbar_dev_info*) pj_pool_calloc(cf->pool, cf->dev_count, sizeof(struct cbar_dev_info)); + /* Passive capturer */ ddi = &cf->dev_info[0]; pj_bzero(ddi, sizeof(*ddi)); pj_ansi_strncpy(ddi->info.name, "Colorbar generator", @@ -212,6 +219,26 @@ static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f) DEFAULT_FPS, 1); } + /* Active capturer */ + ddi = &cf->dev_info[1]; + pj_bzero(ddi, sizeof(*ddi)); + pj_ansi_strncpy(ddi->info.name, "Colorbar-active", + sizeof(ddi->info.name)); + ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0'; + pj_ansi_strncpy(ddi->info.driver, "Colorbar", sizeof(ddi->info.driver)); + ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0'; + ddi->info.dir = PJMEDIA_DIR_CAPTURE; + ddi->info.has_callback = PJ_TRUE; + + ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT; + ddi->info.fmt_cnt = sizeof(cbar_fmts)/sizeof(cbar_fmts[0]); + for (i = 0; i < ddi->info.fmt_cnt; i++) { + pjmedia_format *fmt = &ddi->info.fmt[i]; + pjmedia_format_init_video(fmt, cbar_fmts[i].fmt_id, + DEFAULT_WIDTH, DEFAULT_HEIGHT, + DEFAULT_FPS, 1); + } + PJ_LOG(4, (THIS_FILE, "Colorbar video src initialized with %d device(s):", cf->dev_count)); for (i = 0; i < cf->dev_count; i++) { @@ -375,6 +402,25 @@ static void fill_first_line(pj_uint8_t *first_lines[], } } + +static void clock_cb(const pj_timestamp *ts, void *user_data) +{ + struct cbar_stream *stream = (struct cbar_stream*)user_data; + pjmedia_frame f; + pj_status_t status; + + PJ_UNUSED_ARG(ts); + + pj_bzero(&f, sizeof(f)); + f.buf = stream->clock_buf; + f.size = stream->vafp.framebytes; + status = cbar_stream_get_frame(&stream->base, &f); + if (status == PJ_SUCCESS) { + (*stream->vid_cb.capture_cb)(&stream->base, stream->user_data, &f); + } +} + + /* API: create stream */ static pj_status_t cbar_factory_create_stream( pjmedia_vid_dev_factory *f, @@ -438,6 +484,29 @@ static pj_status_t cbar_factory_create_stream( ¶m->fmt); } */ + + /* Active role? */ + if (param->cap_id == 1 && cb && cb->capture_cb) { + pjmedia_clock_param clock_param; + pj_status_t status; + + /* Allocate buffer */ + strm->clock_buf = pj_pool_alloc(pool, strm->vafp.framebytes); + + /* Create clock */ + pj_bzero(&clock_param, sizeof(clock_param)); + clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps); + clock_param.clock_rate = param->clock_rate; + status = pjmedia_clock_create2(pool, &clock_param, + PJMEDIA_CLOCK_NO_HIGHEST_PRIO, + &clock_cb, + strm, &strm->clock); + if (status != PJ_SUCCESS) { + pj_pool_release(pool); + return status; + } + } + /* Done */ strm->base.op = &stream_op; *p_vid_strm = &strm->base; @@ -596,10 +665,11 @@ static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm) { struct cbar_stream *stream = (struct cbar_stream*)strm; - PJ_UNUSED_ARG(stream); - PJ_LOG(4, (THIS_FILE, "Starting cbar video stream")); + if (stream->clock) + return pjmedia_clock_start(stream->clock); + return PJ_SUCCESS; } @@ -608,10 +678,11 @@ static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm) { struct cbar_stream *stream = (struct cbar_stream*)strm; - PJ_UNUSED_ARG(stream); - PJ_LOG(4, (THIS_FILE, "Stopping cbar video stream")); + if (stream->clock) + return pjmedia_clock_stop(stream->clock); + return PJ_SUCCESS; } @@ -625,6 +696,10 @@ static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm) cbar_stream_stop(strm); + if (stream->clock) + pjmedia_clock_destroy(stream->clock); + stream->clock = NULL; + pj_pool_release(stream->pool); return PJ_SUCCESS; -- cgit v1.2.3