static pj_uint32_t match_format_id(pj_uint32_t req_id, pj_uint32_t sup_id) { const pjmedia_video_format_info *req_fmt_info, *sup_fmt_info; if (req_id == sup_id) return FMT_MATCH; req_fmt_info = pjmedia_get_video_format_info( pjmedia_video_format_mgr_instance(), req_id); sup_fmt_info = pjmedia_get_video_format_info( pjmedia_video_format_mgr_instance(), sup_id); if ((req_fmt_info == NULL) || (sup_fmt_info == NULL)) { return FMT_DIFF_COLOR_SPACE; } if (req_fmt_info->color_model == sup_fmt_info->color_model) { return FMT_SAME_COLOR_SPACE; } return FMT_DIFF_COLOR_SPACE; }
static int main_func(int argc, char *argv[]) { pj_caching_pool cp; pj_pool_t *pool; int rc = 0; pj_status_t status = PJ_SUCCESS; if (argc != 2) { puts("Error: filename required"); puts(desc); return 1; } /* Must init PJLIB first: */ status = pj_init(); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); /* Must create a pool factory before we can allocate any memory. */ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); /* Create memory pool for our file player */ pool = pj_pool_create( &cp.factory, /* pool factory */ "AVI", /* pool name. */ 4000, /* init size */ 4000, /* increment size */ NULL /* callback on error */ ); pjmedia_video_format_mgr_create(pool, 64, 0, NULL); pjmedia_converter_mgr_create(pool, NULL); pjmedia_event_mgr_create(pool, 0, NULL); pjmedia_vid_codec_mgr_create(pool, NULL); status = pjmedia_vid_dev_subsys_init(&cp.factory); if (status != PJ_SUCCESS) goto on_return; status = pjmedia_aud_subsys_init(&cp.factory); if (status != PJ_SUCCESS) { goto on_return; } #if PJMEDIA_HAS_FFMPEG_VID_CODEC status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory); if (status != PJ_SUCCESS) goto on_return; #endif rc = aviplay(pool, argv[1]); /* * File should be playing and looping now */ /* Without this sleep, Windows/DirectSound will repeteadly * play the last frame during destroy. */ pj_thread_sleep(100); on_return: #if PJMEDIA_HAS_FFMPEG_VID_CODEC pjmedia_codec_ffmpeg_vid_deinit(); #endif pjmedia_aud_subsys_shutdown(); pjmedia_vid_dev_subsys_shutdown(); pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance()); pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance()); pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance()); pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance()); /* Release application pool */ pj_pool_release( pool ); /* Destroy pool factory */ pj_caching_pool_destroy( &cp ); /* Shutdown PJLIB */ pj_shutdown(); /* Done. */ return 0; }
static int aviplay(pj_pool_t *pool, const char *fname) { pjmedia_vid_port *renderer=NULL; pjmedia_vid_port_param param; const pjmedia_video_format_info *vfi; pjmedia_video_format_detail *vfd; pjmedia_snd_port *snd_port = NULL; pj_status_t status; int rc = 0; pjmedia_avi_streams *avi_streams; pjmedia_avi_stream *vid_stream, *aud_stream; pjmedia_port *vid_port = NULL, *aud_port = NULL; pjmedia_vid_codec *codec=NULL; avi_port_t avi_port; pj_bzero(&avi_port, sizeof(avi_port)); status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams); if (status != PJ_SUCCESS) { PJ_PERROR(2,("", status, " Error playing %s", fname)); rc = 210; goto on_return; } vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams, 0, PJMEDIA_TYPE_VIDEO); vid_port = pjmedia_avi_stream_get_port(vid_stream); if (vid_port) { pjmedia_vid_port_param_default(¶m); status = pjmedia_vid_dev_default_param(pool, PJMEDIA_VID_DEFAULT_RENDER_DEV, ¶m.vidparam); if (status != PJ_SUCCESS) { rc = 220; goto on_return; } /* Create renderer, set it to active */ param.active = PJ_TRUE; param.vidparam.dir = PJMEDIA_DIR_RENDER; vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt, PJ_TRUE); pjmedia_format_init_video(¶m.vidparam.fmt, vid_port->info.fmt.id, vfd->size.w, vfd->size.h, vfd->fps.num, vfd->fps.denum); vfi = pjmedia_get_video_format_info( pjmedia_video_format_mgr_instance(), vid_port->info.fmt.id); /* Check whether the frame is encoded */ if (!vfi || vfi->bpp == 0) { /* Yes, prepare codec */ pj_str_t codec_id_st; unsigned info_cnt = 1, i, k; const pjmedia_vid_codec_info *codec_info; pj_str_t port_name = {"codec", 5}; pj_uint8_t *enc_buf = NULL; pj_size_t enc_buf_size = 0; pjmedia_vid_dev_info rdr_info; pjmedia_port codec_port; codec_port_data_t codec_port_data; pjmedia_vid_codec_param codec_param; struct codec_fmt *codecp = NULL; /* Lookup codec */ for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) { if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) { codecp = &codec_fmts[i]; break; } } if (!codecp) { rc = 242; goto on_return; } pj_cstr(&codec_id_st, codecp->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; } pjmedia_format_copy(&codec_param.enc_fmt, ¶m.vidparam.fmt); pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info); for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) { for (k=0; k<rdr_info.fmt_cnt; ++k) { if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id) { param.vidparam.fmt.id = codec_info->dec_fmt_id[i]; i = codec_info->dec_fmt_id_cnt; break; } } } /* 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; } pjmedia_format_copy(&codec_param.dec_fmt, ¶m.vidparam.fmt); codec_param.dir = PJMEDIA_DIR_DECODING; codec_param.packing = PJMEDIA_VID_PACKING_WHOLE; status = pjmedia_vid_codec_open(codec, &codec_param); if (status != PJ_SUCCESS) { rc = 252; goto on_return; } /* Alloc encoding buffer */ enc_buf_size = codec_param.dec_fmt.det.vid.size.w * codec_param.dec_fmt.det.vid.size.h * 4 + 16; /*< padding, just in case */ enc_buf = pj_pool_alloc(pool,enc_buf_size); /* 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; } pj_bzero(&codec_port_data, sizeof(codec_port_data)); codec_port_data.codec = codec; codec_port_data.src_port = vid_port; codec_port_data.enc_buf = enc_buf; codec_port_data.enc_buf_size = enc_buf_size; codec_port.get_frame = &codec_get_frame; codec_port.port_data.pdata = &codec_port_data; /* Check whether we need to convert the decoded frame */ if (codecp->need_conversion) { pjmedia_conversion_param conv_param; pjmedia_format_copy(&conv_param.src, ¶m.vidparam.fmt); pjmedia_format_copy(&conv_param.dst, ¶m.vidparam.fmt); conv_param.dst.id = codecp->dst_fmt; param.vidparam.fmt.id = conv_param.dst.id; status = pjmedia_converter_create(NULL, pool, &conv_param, &codec_port_data.conv); if (status != PJ_SUCCESS) { rc = 270; goto on_return; } } status = pjmedia_vid_port_create(pool, ¶m, &renderer); if (status != PJ_SUCCESS) { rc = 230; goto on_return; } status = pjmedia_vid_port_connect(renderer, &codec_port, PJ_FALSE); } else { status = pjmedia_vid_port_create(pool, ¶m, &renderer); if (status != PJ_SUCCESS) { rc = 230; goto on_return; } /* Connect avi port to renderer */ status = pjmedia_vid_port_connect(renderer, vid_port, PJ_FALSE); } if (status != PJ_SUCCESS) { rc = 240; goto on_return; } } aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams, 0, PJMEDIA_TYPE_AUDIO); aud_port = pjmedia_avi_stream_get_port(aud_stream); if (aud_port) { /* Create sound player port. */ status = pjmedia_snd_port_create_player( pool, /* pool */ -1, /* use default dev. */ PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate. */ PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels. */ PJMEDIA_PIA_SPF(&aud_port->info), /* samples per frame. */ PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample. */ 0, /* options */ &snd_port /* returned port */ ); if (status != PJ_SUCCESS) { rc = 310; goto on_return; } /* Connect file port to the sound player. * Stream playing will commence immediately. */ status = pjmedia_snd_port_connect(snd_port, aud_port); if (status != PJ_SUCCESS) { rc = 330; goto on_return; } } if (vid_port) { pjmedia_vid_dev_cb cb; pj_bzero(&cb, sizeof(cb)); avi_port.snd_port = snd_port; avi_port.vid_port = renderer; avi_port.is_running = PJ_TRUE; pjmedia_vid_port_set_cb(renderer, &cb, &avi_port); /* subscribe events */ pjmedia_event_subscribe(NULL, &avi_event_cb, &avi_port, renderer); if (snd_port) { /* Synchronize video rendering and audio playback */ pjmedia_vid_port_set_clock_src( renderer, pjmedia_snd_port_get_clock_src( snd_port, PJMEDIA_DIR_PLAYBACK)); } /* Start video streaming.. */ status = pjmedia_vid_port_start(renderer); if (status != PJ_SUCCESS) { rc = 270; goto on_return; } } while (!avi_port.is_quitting) { pj_thread_sleep(100); } on_return: if (snd_port) { pjmedia_snd_port_disconnect(snd_port); /* Without this sleep, Windows/DirectSound will repeteadly * play the last frame during destroy. */ pj_thread_sleep(100); pjmedia_snd_port_destroy(snd_port); } if (renderer) { pjmedia_event_unsubscribe(NULL, &avi_event_cb, &avi_port, renderer); pjmedia_vid_port_destroy(renderer); } if (aud_port) pjmedia_port_destroy(aud_port); if (vid_port) pjmedia_port_destroy(vid_port); if (codec) { pjmedia_vid_codec_close(codec); pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec); } return rc; }
int test_main(void) { int rc = 0; pj_caching_pool caching_pool; pj_pool_t *pool; pj_init(); pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, 0); pool = pj_pool_create(&caching_pool.factory, "test", 1000, 512, NULL); pj_log_set_decor(PJ_LOG_HAS_NEWLINE); pj_log_set_level(3); mem = &caching_pool.factory; #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) pjmedia_video_format_mgr_create(pool, 64, 0, NULL); pjmedia_converter_mgr_create(pool, NULL); pjmedia_event_mgr_create(pool, 0, NULL); pjmedia_vid_codec_mgr_create(pool, NULL); #endif #if HAS_VID_PORT_TEST DO_TEST(vid_port_test()); #endif #if HAS_VID_DEV_TEST DO_TEST(vid_dev_test()); #endif #if HAS_VID_CODEC_TEST DO_TEST(vid_codec_test()); #endif #if HAS_SDP_NEG_TEST DO_TEST(sdp_neg_test()); #endif //DO_TEST(sdp_test (&caching_pool.factory)); //DO_TEST(rtp_test(&caching_pool.factory)); //DO_TEST(session_test (&caching_pool.factory)); #if HAS_JBUF_TEST DO_TEST(jbuf_main()); #endif #if HAS_MIPS_TEST DO_TEST(mips_test()); #endif #if HAS_CODEC_VECTOR_TEST DO_TEST(codec_test_vectors()); #endif PJ_LOG(3,(THIS_FILE," ")); on_return: if (rc != 0) { PJ_LOG(3,(THIS_FILE,"Test completed with error(s)!")); } else { PJ_LOG(3,(THIS_FILE,"Looks like everything is okay!")); } #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance()); pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance()); pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance()); pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance()); #endif pj_pool_release(pool); pj_caching_pool_destroy(&caching_pool); return rc; }
/* 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; }
/* 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; }