Ignore:
Timestamp:
Jul 30, 2015 6:23:35 AM (9 years ago)
Author:
ming
Message:

Fixed #1861: Add support for video capture orientation on Android

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-videodev/android_dev.c

    r5003 r5138  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
    1818 */ 
     19#include "util.h" 
    1920#include <pjmedia-videodev/videodev_imp.h> 
    2021#include <pj/assert.h> 
     
    3940#define ALIGN16(x)              ((((x)+15) >> 4) << 4) 
    4041 
     42/* Define whether we should maintain the aspect ratio when rotating the image. 
     43 * For more details, please refer to util.h. 
     44 */ 
     45#define MAINTAIN_ASPECT_RATIO   PJ_TRUE 
    4146 
    4247/* Format map info */ 
     
    119124    /** NV21/YV12 -> I420 Conversion buffer  */ 
    120125    pj_uint8_t             *convert_buf; 
     126    pjmedia_rect_size       cam_size; 
     127     
     128    /** Converter to rotate frame  */ 
     129    pjmedia_vid_dev_conv    conv; 
    121130     
    122131    /** Frame format param for NV21/YV12 -> I420 conversion */ 
     
    512521        vdi->dir = PJMEDIA_DIR_CAPTURE; 
    513522        vdi->has_callback = PJ_TRUE; 
    514         vdi->caps = PJMEDIA_VID_DEV_CAP_SWITCH; 
     523        vdi->caps = PJMEDIA_VID_DEV_CAP_SWITCH | 
     524                    PJMEDIA_VID_DEV_CAP_ORIENTATION; 
    515525 
    516526        /* Set driver & name info */ 
     
    579589 
    580590                for (k = 0; k < adi->sup_size_cnt && 
    581                             vdi->fmt_cnt < max_fmt_cnt; k++) 
     591                            vdi->fmt_cnt < max_fmt_cnt-1; k++) 
    582592                { 
     593                    /* Landscape video */ 
    583594                    pjmedia_format_init_video(&vdi->fmt[vdi->fmt_cnt++], 
    584595                                              fmt, 
    585596                                              adi->sup_size[k].w, 
    586597                                              adi->sup_size[k].h, 
     598                                              DEFAULT_FPS, 1); 
     599                    /* Portrait video */ 
     600                    pjmedia_format_init_video(&vdi->fmt[vdi->fmt_cnt++], 
     601                                              fmt, 
     602                                              adi->sup_size[k].h, 
     603                                              adi->sup_size[k].w, 
    587604                                              DEFAULT_FPS, 1); 
    588605                } 
     
    599616                adi->forced_i420 = PJ_TRUE; 
    600617                for (k = 0; k < adi->sup_size_cnt && 
    601                             vdi->fmt_cnt < max_fmt_cnt; k++) 
     618                            vdi->fmt_cnt < max_fmt_cnt-1; k++) 
    602619                { 
    603620                    pjmedia_format_init_video(&vdi->fmt[vdi->fmt_cnt++], 
     
    605622                                              adi->sup_size[k].w, 
    606623                                              adi->sup_size[k].h, 
     624                                              DEFAULT_FPS, 1); 
     625                    pjmedia_format_init_video(&vdi->fmt[vdi->fmt_cnt++], 
     626                                              PJMEDIA_FORMAT_I420, 
     627                                              adi->sup_size[k].h, 
     628                                              adi->sup_size[k].w, 
    607629                                              DEFAULT_FPS, 1); 
    608630                } 
     
    637659    for (i = 0; i < f->dev_count; i++) { 
    638660        and_dev_info *adi = &f->dev_info[i]; 
    639         char tmp_str[1024], *p; 
     661        char tmp_str[2048], *p; 
    640662        int j, plen, slen; 
    641663        PJ_LOG(4, (THIS_FILE, "%2d: %s", i, f->dev_info[i].info.name)); 
     
    793815 
    794816    /* Instantiate PjCamera */ 
     817    strm->cam_size.w = (vfd->size.w > vfd->size.h? vfd->size.w: vfd->size.h); 
     818    strm->cam_size.h = (vfd->size.w > vfd->size.h? vfd->size.h: vfd->size.w); 
    795819    jcam = (*jni_env)->NewObject(jni_env, jobjs.cam.cls, jobjs.cam.m_init, 
    796820                                 adi->dev_idx,          /* idx */ 
    797                                  vfd->size.w,           /* w */ 
    798                                  vfd->size.h,           /* h */ 
     821                                 strm->cam_size.w,      /* w */ 
     822                                 strm->cam_size.h,      /* h */ 
    799823                                 and_fmt,               /* fmt */ 
    800824                                 vfd->fps.num*1000/ 
     
    814838        status = PJMEDIA_EVID_SYSERR; 
    815839        goto on_return; 
     840    } 
     841     
     842    /* Video orientation. 
     843     * If we send in portrait, we need to set up orientation converter 
     844     * as well. 
     845     */ 
     846    if ((param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) || 
     847        (vfd->size.h > vfd->size.w)) 
     848    { 
     849        if (param->orient == PJMEDIA_ORIENT_UNKNOWN) 
     850            param->orient = PJMEDIA_ORIENT_NATURAL; 
     851        and_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION, 
     852                           &param->orient); 
    816853    } 
    817854 
     
    922959        } 
    923960 
     961        case PJMEDIA_VID_DEV_CAP_ORIENTATION: 
     962        { 
     963            pjmedia_orient orient = *(pjmedia_orient *)pval; 
     964 
     965            pj_assert(orient >= PJMEDIA_ORIENT_UNKNOWN && 
     966                      orient <= PJMEDIA_ORIENT_ROTATE_270DEG); 
     967 
     968            if (orient == PJMEDIA_ORIENT_UNKNOWN) 
     969                return PJ_EINVAL; 
     970 
     971            pj_memcpy(&strm->param.orient, pval, 
     972                      sizeof(strm->param.orient)); 
     973 
     974            if (!strm->conv.conv) { 
     975                status = pjmedia_vid_dev_conv_create_converter( 
     976                                                 &strm->conv, strm->pool, 
     977                                                 &strm->param.fmt, 
     978                                                 strm->cam_size, 
     979                                                 strm->param.fmt.det.vid.size, 
     980                                                 PJ_TRUE, 
     981                                                 MAINTAIN_ASPECT_RATIO); 
     982                 
     983                if (status != PJ_SUCCESS) 
     984                    return status; 
     985            } 
     986             
     987            pjmedia_vid_dev_conv_set_rotation(&strm->conv, strm->param.orient); 
     988             
     989            PJ_LOG(4, (THIS_FILE, "Video capture orientation set to %d", 
     990                                  strm->param.orient)); 
     991 
     992            break; 
     993        } 
     994 
    924995        default: 
    925996            status = PJMEDIA_EVID_INVCAP; 
     
    10061077    jni_detach_env(with_attach); 
    10071078     
     1079    pjmedia_vid_dev_conv_destroy_converter(&strm->conv); 
     1080     
    10081081    if (strm->pool) 
    10091082        pj_pool_release(strm->pool); 
     
    10211094    pjmedia_frame f; 
    10221095    pj_uint8_t *Y, *U, *V; 
     1096    pj_status_t status;  
     1097    void *frame_buf, *data_buf;      
    10231098 
    10241099    strm->frame_ts.u64 += strm->ts_inc; 
     
    10401115    f.size = length; 
    10411116    f.timestamp.u64 = strm->frame_ts.u64; 
    1042     f.buf = (*env)->GetByteArrayElements(env, data, 0); 
     1117    f.buf = data_buf = (*env)->GetByteArrayElements(env, data, 0); 
    10431118 
    10441119    Y = (pj_uint8_t*)f.buf; 
     
    11161191        } 
    11171192    } 
     1193     
     1194    status = pjmedia_vid_dev_conv_resize_and_rotate(&strm->conv,  
     1195                                                    f.buf, 
     1196                                                    &frame_buf); 
     1197    if (status == PJ_SUCCESS) { 
     1198        f.buf = frame_buf; 
     1199    } 
    11181200 
    11191201    (*strm->vid_cb.capture_cb)(&strm->base, strm->user_data, &f); 
    1120     (*env)->ReleaseByteArrayElements(env, data, f.buf, JNI_ABORT); 
     1202    (*env)->ReleaseByteArrayElements(env, data, data_buf, JNI_ABORT); 
    11211203} 
    11221204 
Note: See TracChangeset for help on using the changeset viewer.