/* API: Put frame from stream */
static pj_status_t andgl_stream_put_frame(pjmedia_vid_dev_stream *strm,
                                          const pjmedia_frame *frame)
{
    struct andgl_stream *stream = (struct andgl_stream*)strm;
    pj_status_t status;

    if (!stream->is_running || !stream->window)
	return PJ_EINVALIDOP;
    
    stream->frame = frame;
    job_queue_post_job(stream->jq, render, strm, 0, &status);
    
    return status;
}
/* API: Destroy stream. */
static pj_status_t andgl_stream_destroy(pjmedia_vid_dev_stream *strm)
{
    struct andgl_stream *stream = (struct andgl_stream*)strm;
    
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
    
    andgl_stream_stop(strm);
    
    job_queue_post_job(stream->jq, deinit_opengl, strm, 0, NULL);
    
    if (stream->jq) {
        job_queue_destroy(stream->jq);
        stream->jq = NULL;
    }
    
    pj_pool_release(stream->pool);
    
    return PJ_SUCCESS;
}
/* API: set capability */
static pj_status_t andgl_stream_set_cap(pjmedia_vid_dev_stream *s,
                                        pjmedia_vid_dev_cap cap,
                                        const void *pval)
{
    struct andgl_stream *strm = (struct andgl_stream*)s;
    
    PJ_UNUSED_ARG(strm);
    
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
    
    if (cap==PJMEDIA_VID_DEV_CAP_FORMAT) {
        const pjmedia_video_format_info *vfi;
        pjmedia_video_format_detail *vfd;
        pjmedia_format *fmt = (pjmedia_format *)pval;
        andgl_fmt_info *ifi;
        
        if (!(ifi = get_andgl_format_info(fmt->id)))
            return PJMEDIA_EVID_BADFORMAT;
        
        vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
                                            fmt->id);
        if (!vfi)
            return PJMEDIA_EVID_BADFORMAT;
        
        pjmedia_format_copy(&strm->param.fmt, fmt);
        
        vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
        pj_memcpy(&strm->vid_size, &vfd->size, sizeof(vfd->size));
        if (strm->param.disp_size.w == 0 || strm->param.disp_size.h == 0)
            pj_memcpy(&strm->param.disp_size, &vfd->size, sizeof(vfd->size));
        
	return PJ_SUCCESS;
    } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
        pj_bool_t is_running = strm->is_running;
        pj_status_t status = PJ_SUCCESS;
        pjmedia_vid_dev_hwnd *wnd = (pjmedia_vid_dev_hwnd *)pval;
        ANativeWindow *native_wnd = (ANativeWindow *)wnd->info.android.window;

        if (strm->window == native_wnd)
            return PJ_SUCCESS;
        
        /* Stop the stream and re-init OpenGL */
    	andgl_stream_stop(s);
        job_queue_post_job(strm->jq, deinit_opengl, strm, 0, NULL);

        strm->window = strm->param.window.info.android.window = native_wnd;
        if (strm->window) {
            job_queue_post_job(strm->jq, init_opengl, strm, 0, &status);
        }

        PJ_LOG(3, (THIS_FILE, "Re-initializing OpenGL with window %p: %s",
        		      strm->window,
                              (status == PJ_SUCCESS? "success": "failed")));
        
        if (is_running)
	    andgl_stream_start(s);

        return status;
    } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
        pj_memcpy(&strm->param.disp_size, pval, sizeof(strm->param.disp_size));
        return PJ_SUCCESS;
    } else if (cap == PJMEDIA_VID_DEV_CAP_ORIENTATION) {
        pj_memcpy(&strm->param.orient, pval, sizeof(strm->param.orient));
        if (strm->param.orient == PJMEDIA_ORIENT_UNKNOWN)
            return PJ_SUCCESS;
        return PJ_SUCCESS;
    }
    
    return PJMEDIA_EVID_INVCAP;
}
Exemple #4
0
/* API: set capability */
static pj_status_t andgl_stream_set_cap(pjmedia_vid_dev_stream *s,
                                        pjmedia_vid_dev_cap cap,
                                        const void *pval)
{
    struct andgl_stream *strm = (struct andgl_stream*)s;
    
    PJ_UNUSED_ARG(strm);
    
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
    
    if (cap==PJMEDIA_VID_DEV_CAP_FORMAT) {
        const pjmedia_video_format_info *vfi;
        pjmedia_video_format_detail *vfd;
        pjmedia_format *fmt = (pjmedia_format *)pval;
        andgl_fmt_info *ifi;
        
        if (!(ifi = get_andgl_format_info(fmt->id)))
            return PJMEDIA_EVID_BADFORMAT;
        
        vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
                                            fmt->id);
        if (!vfi)
            return PJMEDIA_EVID_BADFORMAT;
        
        /* Re-init OpenGL */
        if (strm->window)
            job_queue_post_job(strm->jq, deinit_opengl, strm, 0, NULL);

        pjmedia_format_copy(&strm->param.fmt, fmt);

        vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
        pj_memcpy(&strm->vid_size, &vfd->size, sizeof(vfd->size));
        pj_memcpy(&strm->param.disp_size, &vfd->size, sizeof(vfd->size));
        
	if (strm->window)
	    job_queue_post_job(strm->jq, init_opengl, strm, 0, NULL);
	    
	PJ_LOG(4, (THIS_FILE, "Re-initializing OpenGL due to format change"));
        
	return PJ_SUCCESS;
    } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
        pj_status_t status = PJ_SUCCESS;
        pjmedia_vid_dev_hwnd *wnd = (pjmedia_vid_dev_hwnd *)pval;
        ANativeWindow *native_wnd = (ANativeWindow *)wnd->info.android.window;

        if (strm->window == native_wnd)
            return PJ_SUCCESS;
        
        /* Re-init OpenGL */
        job_queue_post_job(strm->jq, deinit_opengl, strm, 0, NULL);
        if (strm->window)
            ANativeWindow_release(strm->window);

        strm->window = strm->param.window.info.android.window = native_wnd;
        if (strm->window) {
            job_queue_post_job(strm->jq, init_opengl, strm, 0, &status);
        }

        PJ_LOG(4, (THIS_FILE, "Re-initializing OpenGL with native window"
        		      " %p: %s", strm->window,
                              (status == PJ_SUCCESS? "success": "failed")));
        
        return status;
    }
    
    return PJMEDIA_EVID_INVCAP;
}