Page MenuHomePhabricator

No OneTemporary

diff --git a/deps/pjsip/pjmedia/build/Makefile b/deps/pjsip/pjmedia/build/Makefile
index c686c81d..151e09ab 100644
--- a/deps/pjsip/pjmedia/build/Makefile
+++ b/deps/pjsip/pjmedia/build/Makefile
@@ -1,231 +1,231 @@
include ../../build.mak
include ../../version.mak
THIRD_PARTY:=$(PJDIR)/third_party
SRTP_INC=$(CC_INC)$(THIRD_PARTY)/build/srtp \
$(CC_INC)$(THIRD_PARTY)/srtp/crypto/include \
$(CC_INC)$(THIRD_PARTY)/srtp/include
include $(PJDIR)/build/common.mak
RULES_MAK := $(PJDIR)/build/rules.mak
PJLIB_LIB:=$(PJDIR)/pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)
PJLIB_UTIL_LIB:=$(PJDIR)/pjlib-util/lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)
PJNATH_LIB:=$(PJDIR)/pjnath/lib/libpjnath-$(TARGET_NAME)$(LIBEXT)
export PJMEDIA_LIB:=../lib/libpjmedia-$(TARGET_NAME)$(LIBEXT)
export PJMEDIA_CODEC_LIB:=../lib/libpjmedia-codec-$(TARGET_NAME)$(LIBEXT)
export PJSDP_LIB:=../lib/libpjsdp-$(TARGET_NAME)$(LIBEXT)
export PJMEDIA_AUDIODEV_LIB:=../lib/libpjmedia-audiodev-$(TARGET_NAME)$(LIBEXT)
export PJMEDIA_VIDEODEV_LIB:=../lib/libpjmedia-videodev-$(TARGET_NAME)$(LIBEXT)
###############################################################################
# Gather all flags.
#
export _CFLAGS := $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \
$(CFLAGS) $(CC_INC)../include \
$(CC_INC)../../pjlib/include \
$(CC_INC)../../pjlib-util/include \
$(CC_INC)../../pjmedia/include \
$(CC_INC)../../pjnath/include \
$(CC_INC)../.. \
$(SRTP_INC)
export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \
$(HOST_CXXFLAGS) $(CXXFLAGS)
export _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJMEDIA_VIDEODEV_LIB)) \
$(subst /,$(HOST_PSEP),$(PJMEDIA_CODEC_LIB)) \
$(subst /,$(HOST_PSEP),$(PJMEDIA_LIB)) \
$(subst /,$(HOST_PSEP),$(PJMEDIA_AUDIODEV_LIB)) \
$(subst /,$(HOST_PSEP),$(PJLIB_LIB)) \
$(subst /,$(HOST_PSEP),$(PJLIB_UTIL_LIB)) \
$(subst /,$(HOST_PSEP),$(PJNATH_LIB)) \
-L$(PJDIR)/third_party/lib \
$(APP_THIRD_PARTY_LIBS) \
$(APP_THIRD_PARTY_EXT) \
$(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \
$(LDFLAGS)
###############################################################################
# Defines for building PJMEDIA library
#
export PJMEDIA_SRCDIR = ../src/pjmedia
export PJMEDIA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
alaw_ulaw.o alaw_ulaw_table.o avi_player.o \
bidirectional.o clock_thread.o codec.o conference.o \
conf_switch.o converter.o converter_libswscale.o \
delaybuf.o echo_common.o \
echo_port.o echo_suppress.o endpoint.o errno.o \
event.o format.o ffmpeg_util.o \
g711.o jbuf.o master_port.o mem_capture.o mem_player.o \
mixer_port.o null_port.o plc_common.o port.o splitcomb.o \
resample_resample.o resample_libsamplerate.o \
resample_port.o rtcp.o rtcp_xr.o rtp.o \
sdp.o sdp_cmp.o sdp_neg.o session.o silencedet.o \
sound_legacy.o sound_port.o stereo_port.o stream_common.o \
stream.o stream_info.o tonegen.o transport_adapter_sample.o \
transport_ice.o transport_loop.o transport_srtp.o transport_udp.o \
types.o vid_codec.o vid_codec_util.o \
vid_port.o vid_stream.o vid_stream_info.o vid_tee.o \
wav_player.o wav_playlist.o wav_writer.o wave.o \
wsola.o
export PJMEDIA_CFLAGS += $(_CFLAGS)
###############################################################################
# Defines for building PJMEDIA-AUDIODEV library
#
export PJMEDIA_AUDIODEV_SRCDIR = ../src/pjmedia-audiodev
export PJMEDIA_AUDIODEV_OBJS += audiodev.o audiotest.o errno.o \
legacy_dev.o null_dev.o wmme_dev.o \
alsa_dev.o bb10_dev.o bdimad_dev.o \
android_jni_dev.o opensl_dev.o
export PJMEDIA_AUDIODEV_CFLAGS += $(_CFLAGS)
###############################################################################
# Defines for building PJMEDIA-VIDEODEV library
#
export PJMEDIA_VIDEODEV_SRCDIR = ../src/pjmedia-videodev
export PJMEDIA_VIDEODEV_OBJS += errno.o videodev.o avi_dev.o ffmpeg_dev.o \
- colorbar_dev.o v4l2_dev.o opengl_dev.o
+ colorbar_dev.o v4l2_dev.o opengl_dev.o fb_dev.o
export PJMEDIA_VIDEODEV_CFLAGS += $(_CFLAGS)
export PJMEDIA_VIDEODEV_CXXFLAGS += $(_CXXFLAGS)
###############################################################################
# Defines for building PJSDP library
# Note that SDP functionality is already INCLUDED in PJMEDIA.
# The PJSDP library should only be used for applications that want SDP
# but don't want to use the rest of the media framework.
#
export PJSDP_SRCDIR = ../src/pjmedia
export PJSDP_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
errno.o sdp.o sdp_cmp.o sdp_neg.o
export PJSDP_CFLAGS += $(_CFLAGS)
###############################################################################
# Defines for building PJMEDIA-Codec library
#
export PJMEDIA_CODEC_SRCDIR = ../src/pjmedia-codec
export PJMEDIA_CODEC_OBJS += audio_codecs.o ffmpeg_vid_codecs.o openh264.o \
h263_packetizer.o h264_packetizer.o \
$(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
ipp_codecs.o opencore_amr.o silk.o $(CODEC_OBJS) \
g7221_sdp_match.o amr_sdp_match.o
export PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \
$(ILBC_CFLAGS) $(IPP_CFLAGS) $(G7221_CFLAGS)
export PJMEDIA_CODEC_CXXFLAGS += $(_CXXFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \
$(ILBC_CFLAGS) $(IPP_CFLAGS) $(G7221_CFLAGS)
###############################################################################
# Defines for building test application
#
export PJMEDIA_TEST_SRCDIR = ../src/test
export PJMEDIA_TEST_OBJS += codec_vectors.o jbuf_test.o main.o mips_test.o \
vid_codec_test.o vid_dev_test.o vid_port_test.o \
rtp_test.o test.o
export PJMEDIA_TEST_OBJS += sdp_neg_test.o
export PJMEDIA_TEST_CFLAGS += $(_CFLAGS)
export PJMEDIA_TEST_LDFLAGS += $(_LDFLAGS)
export PJMEDIA_TEST_EXE:=../bin/pjmedia-test-$(TARGET_NAME)$(HOST_EXE)
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
###############################################################################
# Main entry
#
# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.
#
TARGETS := pjmedia pjmedia-videodev pjmedia-audiodev pjmedia-codec pjsdp
all: $(TARGETS)
doc:
cd .. && rm -rf docs/$(PJ_VERSION) && doxygen docs/doxygen.cfg
@if [ -n "$(WWWDIR)" ] && ! [ -d "$(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html" ] ; then \
echo "Creating docs/$(PJ_VERSION)/pjmedia/docs/html" ; \
mkdir -p $(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html ; \
fi
@if [ -n "$(WWWDIR)" ] && [ -d "$(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html" ] ; then \
echo "Copying docs/$(PJ_VERSION) to $(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html.." ; \
cp -v -a ../docs/$(PJ_VERSION)/html/* $(WWWDIR)/docs/$(PJ_VERSION)/pjmedia/docs/html/ ; \
fi
dep: depend
distclean: realclean
.PHONY: dep depend pjmedia pjmedia-codec pjmedia-videodev pjmedia-audiodev pjmedia-test clean realclean distclean
pjmedia:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $(PJMEDIA_LIB)
pjmedia-codec:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $(PJMEDIA_CODEC_LIB)
pjmedia-videodev:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $(PJMEDIA_VIDEODEV_LIB)
pjmedia-audiodev:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $(PJMEDIA_AUDIODEV_LIB)
pjsdp:
$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $(PJSDP_LIB)
$(PJMEDIA_LIB): pjmedia
pjmedia-test: $(PJMEDIA_LIB) pjmedia
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $(PJMEDIA_TEST_EXE)
.PHONY: ../lib/pjmedia.ko
../lib/pjmedia.ko:
echo Making $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
.PHONY: ../lib/pjmedia-codec.ko
../lib/pjmedia-codec.ko:
echo Making $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
.PHONY: ../lib/pjmedia-test.ko
../lib/pjmedia-test.ko:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
clean:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@
$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
realclean:
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-videodev-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-audiodev-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-codec-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-test-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjsdp-$(TARGET_NAME).depend),$(HOST_RMR))
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@
depend:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@
echo '$(PJMEDIA_TEST_EXE): $(PJMEDIA_LIB) $(PJMEDIA_CODEC_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjmedia-test-$(TARGET_NAME).depend
diff --git a/deps/pjsip/pjmedia/include/pjmedia-videodev/config.h b/deps/pjsip/pjmedia/include/pjmedia-videodev/config.h
index 84042dc8..6e6915ed 100644
--- a/deps/pjsip/pjmedia/include/pjmedia-videodev/config.h
+++ b/deps/pjsip/pjmedia/include/pjmedia-videodev/config.h
@@ -1,218 +1,227 @@
/* $Id: config.h 4414 2013-03-05 08:21:02Z riza $ */
/*
* Copyright (C) 2008-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
*/
#ifndef __PJMEDIA_VIDEODEV_CONFIG_H__
#define __PJMEDIA_VIDEODEV_CONFIG_H__
/**
* @file config.h
* @brief Video config.
*/
#include <pjmedia/types.h>
#include <pj/pool.h>
PJ_BEGIN_DECL
/**
* @defgroup video_device_api Video Device API
* @brief PJMEDIA video device abstraction API.
*/
/**
* @defgroup s1_video_device_config Compile time configurations
* @ingroup video_device_api
* @brief Compile time configurations
* @{
*/
/**
* This setting controls the maximum number of formats that can be
* supported by a video device.
*
* Default: 16
*/
#ifndef PJMEDIA_VID_DEV_INFO_FMT_CNT
# define PJMEDIA_VID_DEV_INFO_FMT_CNT 16
#endif
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
/**
* This setting controls whether SDL support should be included.
*
* Default: 0 (or detected by configure)
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_SDL
# define PJMEDIA_VIDEO_DEV_HAS_SDL 0
# define PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 0
#endif
/**
* This setting controls whether QT support should be included.
*
* Default: 0 (or detected by configure)
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_QT
# define PJMEDIA_VIDEO_DEV_HAS_QT 0
#endif
/**
* This setting controls whether IOS support should be included.
*
* Default: 0 (or detected by configure)
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_IOS
# define PJMEDIA_VIDEO_DEV_HAS_IOS 0
#endif
/**
* This setting controls whether Direct Show support should be included.
*
* Default: 0 (unfinished)
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_DSHOW
# define PJMEDIA_VIDEO_DEV_HAS_DSHOW 0 //PJ_WIN32
#endif
/**
* This setting controls whether colorbar source support should be included.
*
* Default: 1
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
# define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC 1
#endif
/**
* This setting controls whether ffmpeg support should be included.
*
* Default: 0 (unfinished)
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_FFMPEG
# define PJMEDIA_VIDEO_DEV_HAS_FFMPEG 0
#endif
/**
* Video4Linux2
*
* Default: 0 (or detected by configure)
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_V4L2
# define PJMEDIA_VIDEO_DEV_HAS_V4L2 0
#endif
/**
* Enable support for AVI player virtual capture device.
*
* Default: 1
*/
#ifndef PJMEDIA_VIDEO_DEV_HAS_AVI
# define PJMEDIA_VIDEO_DEV_HAS_AVI 1
#endif
+/**
+ * Enable support for frame buffer render device.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_FB
+# define PJMEDIA_VIDEO_DEV_HAS_FB 1
+#endif
+
/**
* Specify the SDL library name to be linked with Visual Studio project.
* By default, the name is autodetected based on SDL version ("sdl.lib" or
* "sdl2.lib"), but application may explicitly specify the library name if this
* autodetection fails. Common names are: "sdl2.lib" or "sdl.lib".
*
* Default: undeclared.
*/
#ifndef PJMEDIA_SDL_LIB
# undef PJMEDIA_SDL_LIB
#endif
#endif /* defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) */
/**
* @}
*/
PJ_END_DECL
#endif /* __PJMEDIA_VIDEODEV_CONFIG_H__ */
/*
--------------------- DOCUMENTATION FOLLOWS ---------------------------
*/
/**
* @addtogroup video_device_api Video Device API
* @{
PJMEDIA Video Device API is a cross-platform video API appropriate for use with
VoIP applications and many other types of video streaming applications.
The API abstracts many different video API's on various platforms, such as:
- native Direct Show video for Win32 and Windows Mobile devices
- null-video implementation
- and more to be implemented in the future
The Video Device API/library is an evolution from PJMEDIA @ref PJMED_SND and
contains many enhancements:
- Forward compatibility:
\n
The new API has been designed to be extensible, it will support new API's as
well as new features that may be introduced in the future without breaking
compatibility with applications that use this API as well as compatibility
with existing device implementations.
- Device capabilities:
\n
At the heart of the API is device capabilities management, where all possible
video capabilities of video devices should be able to be handled in a generic
manner. With this framework, new capabilities that may be discovered in the
future can be handled in manner without breaking existing applications.
- Built-in features:
\n
The device capabilities framework enables applications to use and control
video features built-in in the device, such as:
- built-in formats,
- etc.
- Codec support:
\n
Some video devices support built-in hardware video codecs, and application
can use the video device in encoded mode to make use of these hardware
codecs.
- Multiple backends:
\n
The new API supports multiple video backends (called factories or drivers in
the code) to be active simultaneously, and video backends may be added or
removed during run-time.
*/
/**
* @}
*/
diff --git a/deps/pjsip/pjmedia/include/pjmedia_videodev.h b/deps/pjsip/pjmedia/include/pjmedia-videodev/fb_dev.h
similarity index 57%
copy from deps/pjsip/pjmedia/include/pjmedia_videodev.h
copy to deps/pjsip/pjmedia/include/pjmedia-videodev/fb_dev.h
index c3c9bb00..f114f98d 100644
--- a/deps/pjsip/pjmedia/include/pjmedia_videodev.h
+++ b/deps/pjsip/pjmedia/include/pjmedia-videodev/fb_dev.h
@@ -1,31 +1,32 @@
-/* $Id: pjmedia_videodev.h 4016 2012-04-04 05:05:50Z bennylp $ */
-/*
- * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+/* $Id$ */
+/*
+ * Copyright (C) 2014-present AG Projects
+ * Copyright (C) 2013-2014 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef __PJMEDIA_VIDEODEV_H__
-#define __PJMEDIA_VIDEODEV_H__
+#ifndef PJMEDIA_VIDEODEV_FB_DEV_H__
+#define PJMEDIA_VIDEODEV_FB_DEV_H__
-/**
- * @file pjmedia_videodev.h
- * @brief PJMEDIA main header file.
- */
-
-#include <pjmedia-videodev/videodev.h>
#include <pjmedia-videodev/videodev_imp.h>
-#include <pjmedia-videodev/avi_dev.h>
-#endif /* __PJMEDIA_VIDEODEV_H__ */
+typedef void (*pjmedia_vid_dev_fb_frame_cb)(const pjmedia_frame *frame, const pjmedia_rect_size size, void *user_data);
+
+pj_status_t
+pjmedia_vid_dev_fb_set_callback(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_fb_frame_cb cb,
+ void *user_data);
+
+#endif /* PJMEDIA_VIDEODEV_FB_DEV_H__ */
diff --git a/deps/pjsip/pjmedia/include/pjmedia_videodev.h b/deps/pjsip/pjmedia/include/pjmedia_videodev.h
index c3c9bb00..4d204ecc 100644
--- a/deps/pjsip/pjmedia/include/pjmedia_videodev.h
+++ b/deps/pjsip/pjmedia/include/pjmedia_videodev.h
@@ -1,31 +1,32 @@
/* $Id: pjmedia_videodev.h 4016 2012-04-04 05:05:50Z bennylp $ */
/*
* Copyright (C) 2008-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
*/
#ifndef __PJMEDIA_VIDEODEV_H__
#define __PJMEDIA_VIDEODEV_H__
/**
* @file pjmedia_videodev.h
* @brief PJMEDIA main header file.
*/
#include <pjmedia-videodev/videodev.h>
#include <pjmedia-videodev/videodev_imp.h>
#include <pjmedia-videodev/avi_dev.h>
+#include <pjmedia-videodev/fb_dev.h>
#endif /* __PJMEDIA_VIDEODEV_H__ */
diff --git a/deps/pjsip/pjmedia/src/pjmedia-videodev/fb_dev.c b/deps/pjsip/pjmedia/src/pjmedia-videodev/fb_dev.c
new file mode 100644
index 00000000..fc5894c2
--- /dev/null
+++ b/deps/pjsip/pjmedia/src/pjmedia-videodev/fb_dev.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (C) 2014-present AG Projects
+ * Copyright (C) 2008-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 <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+
+#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \
+ defined(PJMEDIA_VIDEO_DEV_HAS_FB) && PJMEDIA_VIDEO_DEV_HAS_FB != 0
+
+#include <pjmedia-videodev/fb_dev.h>
+
+#define THIS_FILE "fb_dev.c"
+#define DEFAULT_CLOCK_RATE 90000
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_FPS 25
+
+
+/* Supported formats */
+static pjmedia_format_id fb_fmts[] = {PJMEDIA_FORMAT_BGRA};
+
+
+/* fb device info */
+struct fb_dev_info
+{
+ pjmedia_vid_dev_info info;
+};
+
+
+/* factory */
+struct fb_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ struct fb_dev_info *dev_info;
+};
+
+
+/* Video stream. */
+struct fb_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback. */
+ void *user_data; /**< Application data. */
+
+ struct fb_factory *ff;
+ pj_bool_t is_running;
+ pjmedia_rect_size vid_size;
+
+ struct {
+ pjmedia_vid_dev_fb_frame_cb cb;
+ void *user_data;
+ } frame_handler;
+};
+
+
+/* Prototypes */
+static pj_status_t fb_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t fb_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t fb_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned fb_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t fb_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t fb_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t fb_factory_create_stream(pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm);
+
+static pj_status_t fb_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t fb_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t fb_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t fb_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+static pj_status_t fb_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t fb_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t fb_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &fb_factory_init,
+ &fb_factory_destroy,
+ &fb_factory_get_dev_count,
+ &fb_factory_get_dev_info,
+ &fb_factory_default_param,
+ &fb_factory_create_stream,
+ &fb_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &fb_stream_get_param,
+ &fb_stream_get_cap,
+ &fb_stream_set_cap,
+ &fb_stream_start,
+ NULL,
+ &fb_stream_put_frame,
+ &fb_stream_stop,
+ &fb_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init FB video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_fb_factory(pj_pool_factory *pf)
+{
+ struct fb_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "fb video", 1000, 1000, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, struct fb_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t fb_factory_init(pjmedia_vid_dev_factory *f)
+{
+ struct fb_factory *ff = (struct fb_factory*)f;
+ struct fb_dev_info *di;
+ unsigned i, l;
+
+ /* Initialize input and output devices here */
+ ff->dev_info = (struct fb_dev_info*)
+ pj_pool_calloc(ff->pool, 1, sizeof(struct fb_dev_info));
+
+ ff->dev_count = 0;
+ di = &ff->dev_info[ff->dev_count++];
+ pj_bzero(di, sizeof(*di));
+ strcpy(di->info.name, "FrameBuffer renderer");
+ strcpy(di->info.driver, "FrameBuffer");
+ di->info.dir = PJMEDIA_DIR_RENDER;
+ di->info.has_callback = PJ_FALSE;
+ di->info.caps = 0;
+
+ for (i = 0; i < ff->dev_count; i++) {
+ di = &ff->dev_info[i];
+ di->info.fmt_cnt = PJ_ARRAY_SIZE(fb_fmts);
+ di->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT;
+
+ for (l = 0; l < PJ_ARRAY_SIZE(fb_fmts); l++) {
+ pjmedia_format *fmt = &di->info.fmt[l];
+ pjmedia_format_init_video(fmt,
+ fb_fmts[l],
+ DEFAULT_WIDTH,
+ DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+ }
+
+ PJ_LOG(4, (THIS_FILE, "FrameBuffer initialized"));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: destroy factory */
+static pj_status_t fb_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ struct fb_factory *ff = (struct fb_factory*)f;
+ pj_pool_t *pool = ff->pool;
+
+ ff->pool = NULL;
+ pj_pool_release(pool);
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: refresh the list of devices */
+static pj_status_t fb_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_SUCCESS;
+}
+
+
+/* API: get number of devices */
+static unsigned fb_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ struct fb_factory *ff = (struct fb_factory*)f;
+ return ff->dev_count;
+}
+
+
+/* API: get device info */
+static pj_status_t fb_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ struct fb_factory *ff = (struct fb_factory*)f;
+
+ PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV);
+ pj_memcpy(info, &ff->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: create default device parameter */
+static pj_status_t fb_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ struct fb_factory *ff = (struct fb_factory*)f;
+ struct fb_dev_info *di = &ff->dev_info[index];
+
+ PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV);
+ PJ_UNUSED_ARG(pool);
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_RENDER;
+ param->rend_id = index;
+ param->cap_id = PJMEDIA_VID_INVALID_DEV;
+
+ /* Set the device capabilities here */
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Put frame from stream */
+static pj_status_t fb_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame)
+{
+ struct fb_stream *stream = (struct fb_stream*)strm;
+
+ if (!stream->is_running)
+ return PJ_EINVALIDOP;
+
+ if (frame->size==0 || frame->buf==NULL)
+ return PJ_SUCCESS;
+
+ if (stream->frame_handler.cb)
+ stream->frame_handler.cb(frame, stream->vid_size, stream->frame_handler.user_data);
+
+ return PJ_SUCCESS;
+}
+
+/* API: create stream */
+static pj_status_t fb_factory_create_stream(pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm)
+{
+ struct fb_factory *ff = (struct fb_factory*)f;
+ pj_pool_t *pool;
+ pj_status_t status;
+ struct fb_stream *strm;
+ const pjmedia_video_format_info *vfi;
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_RENDER, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+ param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+ param->dir == PJMEDIA_DIR_RENDER,
+ PJ_EINVAL);
+
+ vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
+ if (!vfi)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(ff->pf, "fb-dev", 1000, 1000, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct fb_stream);
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ strm->pool = pool;
+ strm->ff = ff;
+ pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+ strm->user_data = user_data;
+
+ status = fb_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_FORMAT, &param->fmt);
+ if (status != PJ_SUCCESS) {
+ fb_stream_destroy((pjmedia_vid_dev_stream *)strm);
+ return status;
+ }
+
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Get stream info. */
+static pj_status_t fb_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ struct fb_stream *strm = (struct fb_stream*)s;
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: get capability */
+static pj_status_t fb_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ struct fb_stream *strm = (struct fb_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+ PJ_UNUSED_ARG(cap);
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+
+/* API: set capability */
+static pj_status_t fb_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ struct fb_stream *strm = (struct fb_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;
+
+ 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;
+ }
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+
+/* API: Start stream. */
+static pj_status_t fb_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ struct fb_stream *stream = (struct fb_stream*)strm;
+ PJ_UNUSED_ARG(strm);
+
+ PJ_LOG(4, (THIS_FILE, "Starting FB video stream"));
+ stream->is_running = PJ_TRUE;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Stop stream. */
+static pj_status_t fb_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ struct fb_stream *stream = (struct fb_stream*)strm;
+ PJ_UNUSED_ARG(strm);
+
+ PJ_LOG(4, (THIS_FILE, "Stopping FB video stream"));
+ stream->is_running = PJ_FALSE;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t fb_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ struct fb_stream *stream = (struct fb_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ fb_stream_stop(strm);
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: set callback for handling frames */
+pj_status_t
+pjmedia_vid_dev_fb_set_callback(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_fb_frame_cb cb,
+ void *user_data)
+{
+ struct fb_stream *stream = (struct fb_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+ if (stream->is_running)
+ return PJ_EBUSY;
+
+ stream->frame_handler.cb = cb;
+ stream->frame_handler.user_data = user_data;
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_FB */
diff --git a/deps/pjsip/pjmedia/src/pjmedia-videodev/videodev.c b/deps/pjsip/pjmedia/src/pjmedia-videodev/videodev.c
index bec1266f..786caabb 100644
--- a/deps/pjsip/pjmedia/src/pjmedia-videodev/videodev.c
+++ b/deps/pjsip/pjmedia/src/pjmedia-videodev/videodev.c
@@ -1,884 +1,891 @@
/* $Id: videodev.c 4016 2012-04-04 05:05:50Z bennylp $ */
/*
* Copyright (C) 2008-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 <pjmedia-videodev/videodev_imp.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/string.h>
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
#define THIS_FILE "videodev.c"
#define DEFINE_CAP(name, info) {name, info}
/* Capability names */
static struct cap_info
{
const char *name;
const char *info;
} cap_infos[] =
{
DEFINE_CAP("format", "Video format"),
DEFINE_CAP("scale", "Input dimension"),
DEFINE_CAP("window", "Window handle"),
DEFINE_CAP("resize", "Renderer resize"),
DEFINE_CAP("position", "Renderer position"),
DEFINE_CAP("hide", "Renderer hide"),
DEFINE_CAP("preview", "Input preview"),
DEFINE_CAP("orientation", "Video orientation"),
DEFINE_CAP("switch", "Switch device"),
DEFINE_CAP("wndflags", "Window flags")
};
/*
* The device index seen by application and driver is different.
*
* At application level, device index is index to global list of device.
* At driver level, device index is index to device list on that particular
* factory only.
*/
#define MAKE_DEV_ID(f_id, index) (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
#define GET_INDEX(dev_id) ((dev_id) & 0xFFFF)
#define GET_FID(dev_id) ((dev_id) >> 16)
#define DEFAULT_DEV_ID 0
/* extern functions to create factories */
#if PJMEDIA_VIDEO_DEV_HAS_NULL_VIDEO
pjmedia_vid_dev_factory* pjmedia_null_video_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
pjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
pjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_SDL
pjmedia_vid_dev_factory* pjmedia_sdl_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
pjmedia_vid_dev_factory* pjmedia_ffmpeg_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_V4L2
pjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_QT
pjmedia_vid_dev_factory* pjmedia_qt_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_IOS
pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_VIDEO_DEV_HAS_OPENGL
pjmedia_vid_dev_factory* pjmedia_opengl_factory(pj_pool_factory *pf);
#endif
+#if PJMEDIA_VIDEO_DEV_HAS_FB
+pjmedia_vid_dev_factory* pjmedia_fb_factory(pj_pool_factory *pf);
+#endif
+
#define MAX_DRIVERS 16
#define MAX_DEVS 64
/* driver structure */
struct driver
{
/* Creation function */
pjmedia_vid_dev_factory_create_func_ptr create;
/* Factory instance */
pjmedia_vid_dev_factory *f;
char name[32]; /* Driver name */
unsigned dev_cnt; /* Number of devices */
unsigned start_idx; /* Start index in global list */
int cap_dev_idx; /* Default capture device. */
int rend_dev_idx; /* Default render device */
};
/* The video device subsystem */
static struct vid_subsys
{
unsigned init_count; /* How many times init() is called */
pj_pool_factory *pf; /* The pool factory. */
unsigned drv_cnt; /* Number of drivers. */
struct driver drv[MAX_DRIVERS]; /* Array of drivers. */
unsigned dev_cnt; /* Total number of devices. */
pj_uint32_t dev_list[MAX_DEVS];/* Array of device IDs. */
} vid_subsys;
/* API: get capability name/info */
PJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
const char **p_desc)
{
const char *desc;
unsigned i;
if (p_desc==NULL) p_desc = &desc;
for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
if ((1 << i)==cap)
break;
}
if (i==PJ_ARRAY_SIZE(cap_infos)) {
*p_desc = "??";
return "??";
}
*p_desc = cap_infos[i].info;
return cap_infos[i].name;
}
static pj_status_t get_cap_pointer(const pjmedia_vid_dev_param *param,
pjmedia_vid_dev_cap cap,
void **ptr,
unsigned *size)
{
#define FIELD_INFO(name) *ptr = (void*)&param->name; \
*size = sizeof(param->name)
switch (cap) {
case PJMEDIA_VID_DEV_CAP_FORMAT:
FIELD_INFO(fmt);
break;
case PJMEDIA_VID_DEV_CAP_INPUT_SCALE:
FIELD_INFO(disp_size);
break;
case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
FIELD_INFO(window);
break;
case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
FIELD_INFO(disp_size);
break;
case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
FIELD_INFO(window_pos);
break;
case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
FIELD_INFO(window_hide);
break;
case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
FIELD_INFO(native_preview);
break;
case PJMEDIA_VID_DEV_CAP_ORIENTATION:
FIELD_INFO(orient);
break;
/* The PJMEDIA_VID_DEV_CAP_SWITCH does not have an entry in the
* param (it doesn't make sense to open a stream and tell it
* to switch immediately).
*/
case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS:
FIELD_INFO(window_flags);
break;
default:
return PJMEDIA_EVID_INVCAP;
}
#undef FIELD_INFO
return PJ_SUCCESS;
}
/* API: set cap value to param */
PJ_DEF(pj_status_t)
pjmedia_vid_dev_param_set_cap( pjmedia_vid_dev_param *param,
pjmedia_vid_dev_cap cap,
const void *pval)
{
void *cap_ptr;
unsigned cap_size;
pj_status_t status;
status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
if (status != PJ_SUCCESS)
return status;
pj_memcpy(cap_ptr, pval, cap_size);
param->flags |= cap;
return PJ_SUCCESS;
}
/* API: get cap value from param */
PJ_DEF(pj_status_t)
pjmedia_vid_dev_param_get_cap( const pjmedia_vid_dev_param *param,
pjmedia_vid_dev_cap cap,
void *pval)
{
void *cap_ptr;
unsigned cap_size;
pj_status_t status;
status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
if (status != PJ_SUCCESS)
return status;
if ((param->flags & cap) == 0) {
pj_bzero(cap_ptr, cap_size);
return PJMEDIA_EVID_INVCAP;
}
pj_memcpy(pval, cap_ptr, cap_size);
return PJ_SUCCESS;
}
/* Internal: init driver */
static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)
{
struct driver *drv = &vid_subsys.drv[drv_idx];
pjmedia_vid_dev_factory *f;
unsigned i, dev_cnt;
pj_status_t status;
if (!refresh) {
/* Create the factory */
f = (*drv->create)(vid_subsys.pf);
if (!f)
return PJ_EUNKNOWN;
/* Call factory->init() */
status = f->op->init(f);
if (status != PJ_SUCCESS) {
f->op->destroy(f);
return status;
}
} else {
f = drv->f;
}
/* Get number of devices */
dev_cnt = f->op->get_dev_count(f);
if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) {
PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
" there are too many devices",
vid_subsys.dev_cnt + dev_cnt - MAX_DEVS));
dev_cnt = MAX_DEVS - vid_subsys.dev_cnt;
}
/* enabling this will cause pjsua-lib initialization to fail when there
* is no video device installed in the system, even when pjsua has been
* run with --null-video
*
if (dev_cnt == 0) {
f->op->destroy(f);
return PJMEDIA_EVID_NODEV;
}
*/
/* Fill in default devices */
drv->rend_dev_idx = drv->cap_dev_idx = -1;
for (i=0; i<dev_cnt; ++i) {
pjmedia_vid_dev_info info;
status = f->op->get_dev_info(f, i, &info);
if (status != PJ_SUCCESS) {
f->op->destroy(f);
return status;
}
if (drv->name[0]=='\0') {
/* Set driver name */
pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
drv->name[sizeof(drv->name)-1] = '\0';
}
if (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) {
/* Set default render device */
drv->rend_dev_idx = i;
}
if (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) {
/* Set default capture device */
drv->cap_dev_idx = i;
}
if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) {
/* Done. */
break;
}
}
/* Register the factory */
drv->f = f;
drv->f->sys.drv_idx = drv_idx;
drv->start_idx = vid_subsys.dev_cnt;
drv->dev_cnt = dev_cnt;
/* Register devices to global list */
for (i=0; i<dev_cnt; ++i) {
vid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
}
return PJ_SUCCESS;
}
/* Internal: deinit driver */
static void deinit_driver(unsigned drv_idx)
{
struct driver *drv = &vid_subsys.drv[drv_idx];
if (drv->f) {
drv->f->op->destroy(drv->f);
drv->f = NULL;
}
drv->dev_cnt = 0;
drv->rend_dev_idx = drv->cap_dev_idx = -1;
}
/* API: Initialize the video device subsystem. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
{
unsigned i;
pj_status_t status = PJ_SUCCESS;
/* Allow init() to be called multiple times as long as there is matching
* number of shutdown().
*/
if (vid_subsys.init_count++ != 0) {
return PJ_SUCCESS;
}
/* Register error subsystem */
pj_register_strerror(PJMEDIA_VIDEODEV_ERRNO_START,
PJ_ERRNO_SPACE_SIZE,
&pjmedia_videodev_strerror);
/* Init */
vid_subsys.pf = pf;
vid_subsys.drv_cnt = 0;
vid_subsys.dev_cnt = 0;
/* Register creation functions */
#if PJMEDIA_VIDEO_DEV_HAS_V4L2
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_v4l2_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_QT
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_qt_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_IOS
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ios_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_OPENGL
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_opengl_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_dshow_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ffmpeg_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_cbar_factory;
#endif
#if PJMEDIA_VIDEO_DEV_HAS_SDL
vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_sdl_factory;
#endif
+#if PJMEDIA_VIDEO_DEV_HAS_FB
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_fb_factory;
+#endif
/* Initialize each factory and build the device ID list */
for (i=0; i<vid_subsys.drv_cnt; ++i) {
status = init_driver(i, PJ_FALSE);
if (status != PJ_SUCCESS) {
deinit_driver(i);
continue;
}
}
return vid_subsys.dev_cnt ? PJ_SUCCESS : status;
}
/* API: register a video device factory to the video device subsystem. */
PJ_DEF(pj_status_t)
pjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr adf,
pjmedia_vid_dev_factory *factory)
{
pj_bool_t refresh = PJ_FALSE;
pj_status_t status;
if (vid_subsys.init_count == 0)
return PJMEDIA_EVID_INIT;
vid_subsys.drv[vid_subsys.drv_cnt].create = adf;
vid_subsys.drv[vid_subsys.drv_cnt].f = factory;
if (factory) {
/* Call factory->init() */
status = factory->op->init(factory);
if (status != PJ_SUCCESS) {
factory->op->destroy(factory);
return status;
}
refresh = PJ_TRUE;
}
status = init_driver(vid_subsys.drv_cnt, refresh);
if (status == PJ_SUCCESS) {
vid_subsys.drv_cnt++;
} else {
deinit_driver(vid_subsys.drv_cnt);
}
return status;
}
/* API: unregister a video device factory from the video device subsystem. */
PJ_DEF(pj_status_t)
pjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr adf,
pjmedia_vid_dev_factory *factory)
{
unsigned i, j;
if (vid_subsys.init_count == 0)
return PJMEDIA_EVID_INIT;
for (i=0; i<vid_subsys.drv_cnt; ++i) {
struct driver *drv = &vid_subsys.drv[i];
if ((factory && drv->f==factory) || (adf && drv->create == adf)) {
for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
{
vid_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV;
}
deinit_driver(i);
pj_bzero(drv, sizeof(*drv));
return PJ_SUCCESS;
}
}
return PJMEDIA_EVID_ERR;
}
/* API: get the pool factory registered to the video device subsystem. */
PJ_DEF(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void)
{
return vid_subsys.pf;
}
/* API: Shutdown the video device subsystem. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_shutdown(void)
{
unsigned i;
/* Allow shutdown() to be called multiple times as long as there is
* matching number of init().
*/
if (vid_subsys.init_count == 0) {
return PJ_SUCCESS;
}
--vid_subsys.init_count;
if (vid_subsys.init_count == 0) {
for (i=0; i<vid_subsys.drv_cnt; ++i) {
deinit_driver(i);
}
vid_subsys.pf = NULL;
}
return PJ_SUCCESS;
}
/* API: Refresh the list of video devices installed in the system. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_refresh(void)
{
unsigned i;
vid_subsys.dev_cnt = 0;
for (i=0; i<vid_subsys.drv_cnt; ++i) {
struct driver *drv = &vid_subsys.drv[i];
if (drv->f && drv->f->op->refresh) {
pj_status_t status = drv->f->op->refresh(drv->f);
if (status != PJ_SUCCESS) {
PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device "
"list for %s", drv->name));
}
}
init_driver(i, PJ_TRUE);
}
return PJ_SUCCESS;
}
/* API: Get the number of video devices installed in the system. */
PJ_DEF(unsigned) pjmedia_vid_dev_count(void)
{
return vid_subsys.dev_cnt;
}
/* Internal: convert local index to global device index */
static pj_status_t make_global_index(unsigned drv_idx,
pjmedia_vid_dev_index *id)
{
if (*id < 0) {
return PJ_SUCCESS;
}
/* Check that factory still exists */
PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG);
/* Check that device index is valid */
PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt,
PJ_EBUG);
*id += vid_subsys.drv[drv_idx].start_idx;
return PJ_SUCCESS;
}
/* Internal: lookup device id */
static pj_status_t lookup_dev(pjmedia_vid_dev_index id,
pjmedia_vid_dev_factory **p_f,
unsigned *p_local_index)
{
int f_id, index;
if (id < 0) {
unsigned i;
if (id <= PJMEDIA_VID_INVALID_DEV)
return PJMEDIA_EVID_INVDEV;
for (i=0; i<vid_subsys.drv_cnt; ++i) {
struct driver *drv = &vid_subsys.drv[i];
if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV &&
drv->cap_dev_idx >= 0)
{
id = drv->cap_dev_idx;
make_global_index(i, &id);
break;
} else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV &&
drv->rend_dev_idx >= 0)
{
id = drv->rend_dev_idx;
make_global_index(i, &id);
break;
}
}
if (id < 0) {
return PJMEDIA_EVID_NODEFDEV;
}
}
f_id = GET_FID(vid_subsys.dev_list[id]);
index = GET_INDEX(vid_subsys.dev_list[id]);
if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt)
return PJMEDIA_EVID_INVDEV;
if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt)
return PJMEDIA_EVID_INVDEV;
*p_f = vid_subsys.drv[f_id].f;
*p_local_index = (unsigned)index;
return PJ_SUCCESS;
}
/* API: lookup device id */
PJ_DEF(pj_status_t)
pjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id,
pjmedia_vid_dev_factory **p_f,
unsigned *p_local_index)
{
return lookup_dev(id, p_f, p_local_index);
}
/* API: from factory and local index, get global index */
PJ_DEF(pj_status_t)
pjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f,
unsigned local_idx,
pjmedia_vid_dev_index *pid)
{
PJ_ASSERT_RETURN(f->sys.drv_idx >= 0 && f->sys.drv_idx < MAX_DRIVERS,
PJ_EINVALIDOP);
*pid = local_idx;
return make_global_index(f->sys.drv_idx, pid);
}
/* API: Get device information. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
pjmedia_vid_dev_info *info)
{
pjmedia_vid_dev_factory *f;
unsigned index;
pj_status_t status;
PJ_ASSERT_RETURN(info, PJ_EINVAL);
PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
if (id <= PJMEDIA_VID_INVALID_DEV)
return PJMEDIA_EVID_INVDEV;
status = lookup_dev(id, &f, &index);
if (status != PJ_SUCCESS)
return status;
status = f->op->get_dev_info(f, index, info);
/* Make sure device ID is the real ID (not PJMEDIA_VID_DEFAULT_*_DEV) */
info->id = index;
make_global_index(f->sys.drv_idx, &info->id);
return status;
}
/* API: find device */
PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,
const char *dev_name,
pjmedia_vid_dev_index *id)
{
pjmedia_vid_dev_factory *f = NULL;
unsigned drv_idx, dev_idx;
PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {
if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))
{
f = vid_subsys.drv[drv_idx].f;
break;
}
}
if (!f)
return PJ_ENOTFOUND;
for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)
{
pjmedia_vid_dev_info info;
pj_status_t status;
status = f->op->get_dev_info(f, dev_idx, &info);
if (status != PJ_SUCCESS)
return status;
if (!pj_ansi_stricmp(dev_name, info.name))
break;
}
if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)
return PJ_ENOTFOUND;
*id = dev_idx;
make_global_index(drv_idx, id);
return PJ_SUCCESS;
}
/* API: Initialize the video device parameters with default values for the
* specified device.
*/
PJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool,
pjmedia_vid_dev_index id,
pjmedia_vid_dev_param *param)
{
pjmedia_vid_dev_factory *f;
unsigned index;
pj_status_t status;
PJ_ASSERT_RETURN(param, PJ_EINVAL);
PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
if (id <= PJMEDIA_VID_INVALID_DEV)
return PJMEDIA_EVID_INVDEV;
status = lookup_dev(id, &f, &index);
if (status != PJ_SUCCESS)
return status;
status = f->op->default_param(pool, f, index, param);
if (status != PJ_SUCCESS)
return status;
/* Normalize device IDs */
make_global_index(f->sys.drv_idx, &param->cap_id);
make_global_index(f->sys.drv_idx, &param->rend_id);
return PJ_SUCCESS;
}
/* API: Open video stream object using the specified parameters. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(
pjmedia_vid_dev_param *prm,
const pjmedia_vid_dev_cb *cb,
void *user_data,
pjmedia_vid_dev_stream **p_vid_strm)
{
pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;
pj_status_t status;
PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL);
PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
prm->dir==PJMEDIA_DIR_RENDER ||
prm->dir==PJMEDIA_DIR_CAPTURE_RENDER,
PJ_EINVAL);
/* Normalize cap_id */
if (prm->dir & PJMEDIA_DIR_CAPTURE) {
unsigned index;
if (prm->cap_id < 0)
prm->cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
status = lookup_dev(prm->cap_id, &cap_f, &index);
if (status != PJ_SUCCESS)
return status;
prm->cap_id = index;
f = cap_f;
}
/* Normalize rend_id */
if (prm->dir & PJMEDIA_DIR_RENDER) {
unsigned index;
if (prm->rend_id < 0)
prm->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;
status = lookup_dev(prm->rend_id, &rend_f, &index);
if (status != PJ_SUCCESS)
return status;
prm->rend_id = index;
f = rend_f;
}
PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
/* For now, cap_id and rend_id must belong to the same factory */
PJ_ASSERT_RETURN((prm->dir != PJMEDIA_DIR_CAPTURE_RENDER) ||
(cap_f == rend_f),
PJMEDIA_EVID_INVDEV);
/* Create the stream */
status = f->op->create_stream(f, prm, cb,
user_data, p_vid_strm);
if (status != PJ_SUCCESS)
return status;
/* Assign factory id to the stream */
(*p_vid_strm)->sys.drv_idx = f->sys.drv_idx;
return PJ_SUCCESS;
}
/* API: Get the running parameters for the specified video stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param(
pjmedia_vid_dev_stream *strm,
pjmedia_vid_dev_param *param)
{
pj_status_t status;
PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
status = strm->op->get_param(strm, param);
if (status != PJ_SUCCESS)
return status;
/* Normalize device id's */
make_global_index(strm->sys.drv_idx, &param->cap_id);
make_global_index(strm->sys.drv_idx, &param->rend_id);
return PJ_SUCCESS;
}
/* API: Get the value of a specific capability of the video stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap(
pjmedia_vid_dev_stream *strm,
pjmedia_vid_dev_cap cap,
void *value)
{
return strm->op->get_cap(strm, cap, value);
}
/* API: Set the value of a specific capability of the video stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap(
pjmedia_vid_dev_stream *strm,
pjmedia_vid_dev_cap cap,
const void *value)
{
return strm->op->set_cap(strm, cap, value);
}
/* API: Start the stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm)
{
pj_status_t status;
if (pjmedia_vid_dev_stream_is_running(strm))
return PJ_SUCCESS;
status = strm->op->start(strm);
if (status == PJ_SUCCESS)
strm->sys.is_running = PJ_TRUE;
return status;
}
/* API: has it been started? */
PJ_DEF(pj_bool_t)
pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm)
{
return strm->sys.is_running;
}
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame(
pjmedia_vid_dev_stream *strm,
pjmedia_frame *frame)
{
pj_assert(strm->op->get_frame);
return strm->op->get_frame(strm, frame);
}
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame(
pjmedia_vid_dev_stream *strm,
const pjmedia_frame *frame)
{
pj_assert(strm->op->put_frame);
return strm->op->put_frame(strm, frame);
}
/* API: Stop the stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm)
{
strm->sys.is_running = PJ_FALSE;
return strm->op->stop(strm);
}
/* API: Destroy the stream. */
PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy(
pjmedia_vid_dev_stream *strm)
{
strm->sys.is_running = PJ_FALSE;
return strm->op->destroy(strm);
}
#endif /* PJMEDIA_HAS_VIDEO */

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 23, 2:28 AM (13 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3408598
Default Alt Text
(56 KB)

Event Timeline