Esempio n. 1
0
/* API: create stream */
pj_status_t
pjmedia_vid_dev_opengl_imp_create_stream(pj_pool_t *pool,
                                         pjmedia_vid_dev_param *param,
                                         const pjmedia_vid_dev_cb *cb,
                                         void *user_data,
                                         pjmedia_vid_dev_stream **p_vid_strm)
{
    struct andgl_stream *strm;
    const pjmedia_video_format_detail *vfd;
    pj_status_t status = PJ_SUCCESS;
    
    strm = PJ_POOL_ZALLOC_T(pool, struct andgl_stream);
    pj_memcpy(&strm->param, param, sizeof(*param));
    strm->pool = pool;
    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
    strm->user_data = user_data;
    strm->display = EGL_NO_DISPLAY;
    
    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
    
    /* Set video format */
    status = andgl_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_FORMAT,
                                  &param->fmt);
    if (status != PJ_SUCCESS)
        goto on_error;

    status = job_queue_create(pool, &strm->jq);
    if (status != PJ_SUCCESS)
        goto on_error;

    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
        status = andgl_stream_set_cap(&strm->base,
                	  	      PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
                             	      &param->window);
    }
    
    if (status != PJ_SUCCESS) {
        PJ_LOG(3, (THIS_FILE, "Failed to initialize OpenGL with the specified"
			      " output window"));
        goto on_error;
    }

    PJ_LOG(4, (THIS_FILE, "Android OpenGL ES renderer successfully created"));
                    
    /* Done */
    strm->base.op = &stream_op;
    *p_vid_strm = &strm->base;
    
    return PJ_SUCCESS;
    
on_error:
    andgl_stream_destroy((pjmedia_vid_dev_stream *)strm);
    
    return status;
}
Esempio n. 2
0
/* API: create stream */
static pj_status_t and_factory_create_stream(
					pjmedia_vid_dev_factory *ff,
					pjmedia_vid_dev_param *param,
					const pjmedia_vid_dev_cb *cb,
					void *user_data,
					pjmedia_vid_dev_stream **p_vid_strm)
{
    and_factory *f = (and_factory*)ff;
    pj_pool_t *pool;
    and_stream *strm;
    and_dev_info *adi;
    const pjmedia_video_format_detail *vfd;
    const pjmedia_video_format_info *vfi;
    pjmedia_video_apply_fmt_param vafp;
    pj_uint32_t and_fmt;
    unsigned convert_to_i420 = 0;
    pj_status_t status = PJ_SUCCESS;

    JNIEnv *jni_env;
    pj_bool_t with_attach;
    jobject jcam;

    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
		     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
                     param->dir == PJMEDIA_DIR_CAPTURE,
		     PJ_EINVAL);

    pj_bzero(&vafp, sizeof(vafp));
    adi = &f->dev_info[param->cap_id];
    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);

    if (param->fmt.id == PJMEDIA_FORMAT_I420 && adi->forced_i420) {
	/* Not really support I420, need to convert it from YV12/NV21 */
	if (adi->has_nv21) {
	    and_fmt = pj_fmt_to_and(PJMEDIA_FORMAT_NV21);
	    convert_to_i420 = 1;
	} else if (adi->has_yv12) {
	    and_fmt = pj_fmt_to_and(PJMEDIA_FORMAT_YV12);
	    convert_to_i420 = 2;
	} else
	    pj_assert(!"Bug!");
    } else {
	and_fmt = pj_fmt_to_and(param->fmt.id);
    }
    if (!vfi || !and_fmt)
        return PJMEDIA_EVID_BADFORMAT;

    vafp.size = vfd->size;
    if (vfi->apply_fmt(vfi, &vafp) != PJ_SUCCESS)
        return PJMEDIA_EVID_BADFORMAT;

    /* Create and Initialize stream descriptor */
    pool = pj_pool_create(f->pf, "and-dev", 512, 512, NULL);
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);

    strm = PJ_POOL_ZALLOC_T(pool, and_stream);
    pj_memcpy(&strm->param, param, sizeof(*param));
    strm->pool = pool;
    strm->factory = f;
    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
    strm->user_data = user_data;
    pj_memcpy(&strm->vafp, &vafp, sizeof(vafp));
    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);

    /* Allocate buffer for YV12 -> I420 conversion */
    if (convert_to_i420) {
	pj_assert(vfi->plane_cnt > 1);
	strm->convert_to_i420 = convert_to_i420;
	strm->convert_buf = pj_pool_alloc(pool, vafp.plane_bytes[1]);
    }

    /* Native preview */
    if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW) {
    }

    with_attach = jni_get_env(&jni_env);

    /* Instantiate PjCamera */
    strm->cam_size.w = (vfd->size.w > vfd->size.h? vfd->size.w: vfd->size.h);
    strm->cam_size.h = (vfd->size.w > vfd->size.h? vfd->size.h: vfd->size.w);
    jcam = (*jni_env)->NewObject(jni_env, jobjs.cam.cls, jobjs.cam.m_init,
				 adi->dev_idx,		/* idx */
				 strm->cam_size.w,	/* w */
				 strm->cam_size.h,	/* h */
				 and_fmt,		/* fmt */
				 vfd->fps.num*1000/
				 vfd->fps.denum,	/* fps */
				 (jlong)(intptr_t)strm,	/* user data */
				 NULL			/* SurfaceView */
				 );	   
    if (jcam == NULL) {
        PJ_LOG(3, (THIS_FILE, "Unable to create PjCamera instance"));
        status = PJMEDIA_EVID_SYSERR;
	goto on_return;
    }
    strm->jcam = (jobject)(*jni_env)->NewGlobalRef(jni_env, jcam);
    (*jni_env)->DeleteLocalRef(jni_env, jcam);
    if (strm->jcam == NULL) {
        PJ_LOG(3, (THIS_FILE, "Unable to create global ref to PjCamera"));
        status = PJMEDIA_EVID_SYSERR;
	goto on_return;
    }
    
    /* Video orientation.
     * If we send in portrait, we need to set up orientation converter
     * as well.
     */
    if ((param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) ||
        (vfd->size.h > vfd->size.w))
    {
        if (param->orient == PJMEDIA_ORIENT_UNKNOWN)
    	    param->orient = PJMEDIA_ORIENT_NATURAL;
        and_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
    		           &param->orient);
    }

on_return:
    jni_detach_env(with_attach);

    /* Success */
    if (status == PJ_SUCCESS) {
	strm->base.op = &stream_op;
	*p_vid_strm = &strm->base;
    }

    return status;
}