static int find_device(pjmedia_dir dir, pj_bool_t has_callback) { unsigned i, count = pjmedia_vid_dev_count(); for (i = 0; i < count; ++i) { pjmedia_vid_dev_info cdi; if (pjmedia_vid_dev_get_info(i, &cdi) != PJ_SUCCESS) continue; if ((cdi.dir & dir) != 0 && cdi.has_callback == has_callback) return i; } return -999; }
static int encode_decode_test(pj_pool_t *pool, const char *codec_id, pjmedia_vid_packing packing) { const pj_str_t port_name = {"codec", 5}; pjmedia_vid_codec *codec=NULL; pjmedia_port codec_port; codec_port_data_t codec_port_data; pjmedia_vid_codec_param codec_param; const pjmedia_vid_codec_info *codec_info; const char *packing_name; pjmedia_vid_dev_index cap_idx, rdr_idx; pjmedia_vid_port *capture=NULL, *renderer=NULL; pjmedia_vid_port_param vport_param; pjmedia_video_format_detail *vfd; char codec_name[5]; pj_status_t status; int rc = 0; switch (packing) { case PJMEDIA_VID_PACKING_PACKETS: packing_name = "framed"; break; case PJMEDIA_VID_PACKING_WHOLE: packing_name = "whole"; break; default: packing_name = "unknown"; break; } PJ_LOG(3, (THIS_FILE, " encode decode test: codec=%s, packing=%s", codec_id, packing_name)); /* Lookup codec */ { pj_str_t codec_id_st; unsigned info_cnt = 1; /* Lookup codec */ pj_cstr(&codec_id_st, codec_id); status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st, &info_cnt, &codec_info, NULL); if (status != PJ_SUCCESS) { rc = 205; goto on_return; } } #if CAPTURE_DEV == -1 /* Lookup colorbar source */ status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx); if (status != PJ_SUCCESS) { rc = 206; goto on_return; } #elif CAPTURE_DEV == -2 /* Lookup any first non-colorbar source */ { unsigned i, cnt; pjmedia_vid_dev_info info; cap_idx = -1; cnt = pjmedia_vid_dev_count(); for (i = 0; i < cnt; ++i) { status = pjmedia_vid_dev_get_info(i, &info); if (status != PJ_SUCCESS) { rc = 206; goto on_return; } if (info.dir & PJMEDIA_DIR_CAPTURE && pj_ansi_stricmp(info.driver, "Colorbar")) { cap_idx = i; break; } } if (cap_idx == -1) { status = PJ_ENOTFOUND; rc = 206; goto on_return; } } #else cap_idx = CAPTURE_DEV; #endif /* Lookup SDL renderer */ status = pjmedia_vid_dev_lookup("SDL", "SDL renderer", &rdr_idx); if (status != PJ_SUCCESS) { rc = 207; goto on_return; } /* Prepare codec */ { pj_str_t codec_id_st; unsigned info_cnt = 1; const pjmedia_vid_codec_info *codec_info; /* Lookup codec */ pj_cstr(&codec_id_st, codec_id); status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st, &info_cnt, &codec_info, NULL); if (status != PJ_SUCCESS) { rc = 245; goto on_return; } status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, &codec_param); if (status != PJ_SUCCESS) { rc = 246; goto on_return; } codec_param.packing = packing; /* Open codec */ status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info, &codec); if (status != PJ_SUCCESS) { rc = 250; goto on_return; } status = pjmedia_vid_codec_init(codec, pool); if (status != PJ_SUCCESS) { rc = 251; goto on_return; } status = pjmedia_vid_codec_open(codec, &codec_param); if (status != PJ_SUCCESS) { rc = 252; goto on_return; } /* After opened, codec will update the param, let's sync encoder & * decoder format detail. */ codec_param.dec_fmt.det = codec_param.enc_fmt.det; /* Subscribe to codec events */ pjmedia_event_subscribe(NULL, &codec_on_event, &codec_port_data, codec); } pjmedia_vid_port_param_default(&vport_param); /* Create capture, set it to active (master) */ status = pjmedia_vid_dev_default_param(pool, cap_idx, &vport_param.vidparam); if (status != PJ_SUCCESS) { rc = 220; goto on_return; } pjmedia_format_copy(&vport_param.vidparam.fmt, &codec_param.dec_fmt); vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE; vport_param.active = PJ_TRUE; if (vport_param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) { rc = 221; goto on_return; } vfd = pjmedia_format_get_video_format_detail(&vport_param.vidparam.fmt, PJ_TRUE); if (vfd == NULL) { rc = 225; goto on_return; } status = pjmedia_vid_port_create(pool, &vport_param, &capture); if (status != PJ_SUCCESS) { rc = 226; goto on_return; } /* Create renderer, set it to passive (slave) */ vport_param.active = PJ_FALSE; vport_param.vidparam.dir = PJMEDIA_DIR_RENDER; vport_param.vidparam.rend_id = rdr_idx; vport_param.vidparam.disp_size = vfd->size; status = pjmedia_vid_port_create(pool, &vport_param, &renderer); if (status != PJ_SUCCESS) { rc = 230; goto on_return; } /* Init codec port */ pj_bzero(&codec_port, sizeof(codec_port)); status = pjmedia_port_info_init2(&codec_port.info, &port_name, 0x1234, PJMEDIA_DIR_ENCODING, &codec_param.dec_fmt); if (status != PJ_SUCCESS) { rc = 260; goto on_return; } codec_port_data.codec = codec; codec_port_data.rdr_port = renderer; codec_port_data.enc_buf_size = codec_param.dec_fmt.det.vid.size.w * codec_param.dec_fmt.det.vid.size.h * 4; codec_port_data.enc_buf = pj_pool_alloc(pool, codec_port_data.enc_buf_size); codec_port_data.pack_buf_size = codec_port_data.enc_buf_size; codec_port_data.pack_buf = pj_pool_alloc(pool, codec_port_data.pack_buf_size); codec_port.put_frame = &codec_put_frame; codec_port.port_data.pdata = &codec_port_data; /* Connect capture to codec port */ status = pjmedia_vid_port_connect(capture, &codec_port, PJ_FALSE); if (status != PJ_SUCCESS) { rc = 270; goto on_return; } PJ_LOG(3, (THIS_FILE, " starting codec test: %s<->%.*s %dx%d", pjmedia_fourcc_name(codec_param.dec_fmt.id, codec_name), codec_info->encoding_name.slen, codec_info->encoding_name.ptr, codec_param.dec_fmt.det.vid.size.w, codec_param.dec_fmt.det.vid.size.h )); /* Start streaming.. */ status = pjmedia_vid_port_start(renderer); if (status != PJ_SUCCESS) { rc = 275; goto on_return; } status = pjmedia_vid_port_start(capture); if (status != PJ_SUCCESS) { rc = 280; goto on_return; } /* Sleep while the video is being displayed... */ pj_thread_sleep(10000); on_return: if (status != PJ_SUCCESS) { PJ_PERROR(3, (THIS_FILE, status, " error")); } if (capture) pjmedia_vid_port_stop(capture); if (renderer) pjmedia_vid_port_stop(renderer); if (capture) pjmedia_vid_port_destroy(capture); if (renderer) pjmedia_vid_port_destroy(renderer); if (codec) { pjmedia_event_unsubscribe(NULL, &codec_on_event, &codec_port_data, codec); pjmedia_vid_codec_close(codec); pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec); } return rc; }