/* $Id$ */ /* * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #define THIS_FILE "converter.c" struct pjmedia_converter_mgr { pjmedia_converter_factory factory_list; }; static pjmedia_converter_mgr *converter_manager_instance; #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \ defined(PJMEDIA_HAS_LIBSWSCALE) && (PJMEDIA_HAS_LIBSWSCALE != 0) PJ_DECL(pj_status_t) pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr); #endif #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \ defined(PJMEDIA_HAS_LIBYUV) && (PJMEDIA_HAS_LIBYUV != 0) PJ_DECL(pj_status_t) pjmedia_libyuv_converter_init(pjmedia_converter_mgr *mgr); #endif PJ_DEF(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool, pjmedia_converter_mgr **p_mgr) { pjmedia_converter_mgr *mgr; pj_status_t status = PJ_SUCCESS; mgr = PJ_POOL_ALLOC_T(pool, pjmedia_converter_mgr); pj_list_init(&mgr->factory_list); if (!converter_manager_instance) converter_manager_instance = mgr; #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \ defined(PJMEDIA_HAS_LIBSWSCALE) && (PJMEDIA_HAS_LIBSWSCALE != 0) status = pjmedia_libswscale_converter_init(mgr); if (status != PJ_SUCCESS) { PJ_PERROR(4,(THIS_FILE, status, "Error initializing libswscale converter")); } #endif #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \ defined(PJMEDIA_HAS_LIBYUV) && (PJMEDIA_HAS_LIBYUV != 0) status = pjmedia_libyuv_converter_init(mgr); if (status != PJ_SUCCESS) { PJ_PERROR(4,(THIS_FILE, status, "Error initializing libyuv converter")); } #endif if (p_mgr) *p_mgr = mgr; return status; } PJ_DEF(pjmedia_converter_mgr*) pjmedia_converter_mgr_instance(void) { pj_assert(converter_manager_instance != NULL); return converter_manager_instance; } PJ_DEF(void) pjmedia_converter_mgr_set_instance(pjmedia_converter_mgr *mgr) { converter_manager_instance = mgr; } PJ_DEF(void) pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr) { pjmedia_converter_factory *f; if (!mgr) mgr = pjmedia_converter_mgr_instance(); PJ_ASSERT_ON_FAIL(mgr != NULL, return); f = mgr->factory_list.next; while (f != &mgr->factory_list) { pjmedia_converter_factory *next = f->next; pj_list_erase(f); (*f->op->destroy_factory)(f); f = next; } if (converter_manager_instance == mgr) converter_manager_instance = NULL; } PJ_DEF(pj_status_t) pjmedia_converter_mgr_register_factory(pjmedia_converter_mgr *mgr, pjmedia_converter_factory *factory) { pjmedia_converter_factory *pf; if (!mgr) mgr = pjmedia_converter_mgr_instance(); PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL); PJ_ASSERT_RETURN(!pj_list_find_node(&mgr->factory_list, factory), PJ_EEXISTS); pf = mgr->factory_list.next; while (pf != &mgr->factory_list) { if (pf->priority > factory->priority) break; pf = pf->next; } pj_list_insert_before(pf, factory); return PJ_SUCCESS; } PJ_DEF(pj_status_t) pjmedia_converter_mgr_unregister_factory(pjmedia_converter_mgr *mgr, pjmedia_converter_factory *f, pj_bool_t destroy) { if (!mgr) mgr = pjmedia_converter_mgr_instance(); PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL); PJ_ASSERT_RETURN(pj_list_find_node(&mgr->factory_list, f), PJ_ENOTFOUND); pj_list_erase(f); if (destroy) (*f->op->destroy_factory)(f); return PJ_SUCCESS; } PJ_DEF(pj_status_t) pjmedia_converter_create(pjmedia_converter_mgr *mgr, pj_pool_t *pool, pjmedia_conversion_param *param, pjmedia_converter **p_cv) { pjmedia_converter_factory *f; pjmedia_converter *cv = NULL; pj_status_t status = PJ_ENOTFOUND; if (!mgr) mgr = pjmedia_converter_mgr_instance(); PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL); *p_cv = NULL; f = mgr->factory_list.next; while (f != &mgr->factory_list) { status = (*f->op->create_converter)(f, pool, param, &cv); if (status == PJ_SUCCESS) break; f = f->next; } if (status != PJ_SUCCESS) return status; *p_cv = cv; return PJ_SUCCESS; } PJ_DEF(pj_status_t) pjmedia_converter_convert(pjmedia_converter *cv, pjmedia_frame *src_frame, pjmedia_frame *dst_frame) { return (*cv->op->convert)(cv, src_frame, dst_frame); } PJ_DEF(void) pjmedia_converter_destroy(pjmedia_converter *cv) { (*cv->op->destroy)(cv); } PJ_DEF(pj_status_t) pjmedia_converter_convert2( pjmedia_converter *cv, pjmedia_frame *src_frame, const pjmedia_rect_size *src_frame_size, const pjmedia_coord *src_pos, pjmedia_frame *dst_frame, const pjmedia_rect_size *dst_frame_size, const pjmedia_coord *dst_pos, void *param) { if (!cv->op->convert2) return PJ_ENOTSUP; return (*cv->op->convert2)(cv, src_frame, src_frame_size, src_pos, dst_frame, dst_frame_size, dst_pos, param); }