2012-12-03 03:11:21 +00:00
/*
* Copyright ( C ) 2010 - 2011 Mamadou Diop .
*
* Contact : Mamadou Diop < diopmamadou ( at ) doubango . org >
*
* This file is part of Open Source Doubango Framework .
*
* DOUBANGO 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 3 of the License , or
* ( at your option ) any later version .
*
* DOUBANGO 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 DOUBANGO .
*
*/
/**@file ProxyConsumer.c
* @ brief Audio / Video proxy consumers .
*
* @ author Mamadou Diop < diopmamadou ( at ) doubango . org >
*
*/
# include "ProxyConsumer.h"
# include "AudioResampler.h"
# include "tsk_memory.h"
# include "tsk_debug.h"
# include "tinydav/audio/tdav_consumer_audio.h"
# include "tinydav/video/tdav_consumer_video.h"
/* ============ Audio Consumer Interface ================= */
typedef struct twrap_consumer_proxy_audio_s
{
TDAV_DECLARE_CONSUMER_AUDIO ;
uint64_t id ;
tsk_bool_t started ;
2013-04-09 22:22:16 +00:00
const ProxyAudioConsumer * pcConsumer ; // thread-safe and will be destroyed at the time as the "struct"
2012-12-03 03:11:21 +00:00
}
twrap_consumer_proxy_audio_t ;
# define TWRAP_CONSUMER_PROXY_AUDIO(self) ((twrap_consumer_proxy_audio_t*)(self))
int twrap_consumer_proxy_audio_set ( tmedia_consumer_t * _self , const tmedia_param_t * param )
{
twrap_consumer_proxy_audio_t * self = ( twrap_consumer_proxy_audio_t * ) _self ;
if ( param - > plugin_type = = tmedia_ppt_consumer ) {
// specific proxy consumer
}
return tdav_consumer_audio_set ( TDAV_CONSUMER_AUDIO ( self ) , param ) ;
}
int twrap_consumer_proxy_audio_prepare ( tmedia_consumer_t * self , const tmedia_codec_t * codec )
{
2013-04-09 22:22:16 +00:00
twrap_consumer_proxy_audio_t * audio = TWRAP_CONSUMER_PROXY_AUDIO ( self ) ;
2012-12-03 03:11:21 +00:00
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( codec & & ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
2013-04-09 22:22:16 +00:00
if ( ( audio - > pcConsumer = manager - > findAudioConsumer ( audio - > id ) ) & & audio - > pcConsumer - > getCallback ( ) ) {
2013-05-07 04:55:21 +00:00
self - > audio . ptime = TMEDIA_CODEC_PTIME_AUDIO_DECODING ( codec ) ;
self - > audio . in . channels = TMEDIA_CODEC_CHANNELS_AUDIO_DECODING ( codec ) ;
self - > audio . in . rate = TMEDIA_CODEC_RATE_DECODING ( codec ) ;
ret = audio - > pcConsumer - > getCallback ( ) - > prepare ( ( int ) self - > audio . ptime , self - > audio . in . rate , self - > audio . in . channels ) ;
2013-05-07 06:33:42 +00:00
if ( ret = = 0 ) {
// say consumer can output these params
2013-06-10 05:47:01 +00:00
if ( ! self - > audio . out . rate ) self - > audio . out . rate = self - > audio . in . rate ;
if ( ! self - > audio . out . channels ) self - > audio . out . channels = self - > audio . in . channels ;
2013-05-07 06:33:42 +00:00
}
2012-12-03 03:11:21 +00:00
}
}
return ret ;
}
int twrap_consumer_proxy_audio_start ( tmedia_consumer_t * self )
{
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
const ProxyAudioConsumer * audioConsumer ;
if ( ( audioConsumer = manager - > findAudioConsumer ( TWRAP_CONSUMER_PROXY_AUDIO ( self ) - > id ) ) & & audioConsumer - > getCallback ( ) ) {
ret = audioConsumer - > getCallback ( ) - > start ( ) ;
}
}
TWRAP_CONSUMER_PROXY_AUDIO ( self ) - > started = ( ret = = 0 ) ;
return ret ;
}
int twrap_consumer_proxy_audio_consume ( tmedia_consumer_t * self , const void * buffer , tsk_size_t size , const tsk_object_t * proto_hdr )
{
2013-04-09 22:22:16 +00:00
twrap_consumer_proxy_audio_t * audio = TWRAP_CONSUMER_PROXY_AUDIO ( self ) ;
if ( ! audio - > pcConsumer ) {
ProxyPluginMgr * manager ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
audio - > pcConsumer = manager - > findAudioConsumer ( audio - > id ) ;
}
}
ProxyAudioConsumerCallback * callback ;
2012-12-03 03:11:21 +00:00
int ret = - 1 ;
2013-04-09 22:22:16 +00:00
if ( audio - > pcConsumer & & ( callback = audio - > pcConsumer - > getCallback ( ) ) ) {
if ( callback - > putInJitterBuffer ( ) ) {
ret = tdav_consumer_audio_put ( TDAV_CONSUMER_AUDIO ( self ) , buffer , size , proto_hdr ) ;
}
else {
ret = callback - > consume ( buffer , size , proto_hdr ) ;
2012-12-03 03:11:21 +00:00
}
}
return ret ;
}
int twrap_consumer_proxy_audio_pause ( tmedia_consumer_t * self )
{
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
const ProxyAudioConsumer * audioConsumer ;
if ( ( audioConsumer = manager - > findAudioConsumer ( TWRAP_CONSUMER_PROXY_AUDIO ( self ) - > id ) ) & & audioConsumer - > getCallback ( ) ) {
ret = audioConsumer - > getCallback ( ) - > pause ( ) ;
}
}
return ret ;
}
int twrap_consumer_proxy_audio_stop ( tmedia_consumer_t * self )
{
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
const ProxyAudioConsumer * audioConsumer ;
if ( ( audioConsumer = manager - > findAudioConsumer ( TWRAP_CONSUMER_PROXY_AUDIO ( self ) - > id ) ) & & audioConsumer - > getCallback ( ) ) {
ret = audioConsumer - > getCallback ( ) - > stop ( ) ;
}
}
TWRAP_CONSUMER_PROXY_AUDIO ( self ) - > started = ( ret = = 0 ) ? tsk_false : tsk_true ;
return ret ;
}
//
// Audio consumer object definition
//
/* constructor */
static tsk_object_t * twrap_consumer_proxy_audio_ctor ( tsk_object_t * self , va_list * app )
{
twrap_consumer_proxy_audio_t * consumer = ( twrap_consumer_proxy_audio_t * ) self ;
if ( consumer ) {
/* init base */
tdav_consumer_audio_init ( TDAV_CONSUMER_AUDIO ( consumer ) ) ;
/* init self */
/* Add the plugin to the manager */
ProxyPluginMgr * manager = ProxyPluginMgr : : getInstance ( ) ;
if ( manager ) {
ProxyPlugin * proxyConsumer = new ProxyAudioConsumer ( consumer ) ;
uint64_t id = proxyConsumer - > getId ( ) ;
manager - > addPlugin ( & proxyConsumer ) ;
manager - > getCallback ( ) - > OnPluginCreated ( id , twrap_proxy_plugin_audio_consumer ) ;
}
}
return self ;
}
/* destructor */
static tsk_object_t * twrap_consumer_proxy_audio_dtor ( tsk_object_t * self )
{
twrap_consumer_proxy_audio_t * consumer = ( twrap_consumer_proxy_audio_t * ) self ;
if ( consumer ) {
/* stop */
if ( consumer - > started ) {
twrap_consumer_proxy_audio_stop ( TMEDIA_CONSUMER ( consumer ) ) ;
}
/* deinit base */
tdav_consumer_audio_deinit ( TDAV_CONSUMER_AUDIO ( consumer ) ) ;
/* deinit self */
/* Remove plugin from the manager */
ProxyPluginMgr * manager = ProxyPluginMgr : : getInstance ( ) ;
if ( manager ) {
manager - > getCallback ( ) - > OnPluginDestroyed ( consumer - > id , twrap_proxy_plugin_audio_consumer ) ;
manager - > removePlugin ( consumer - > id ) ;
}
}
return self ;
}
/* object definition */
static const tsk_object_def_t twrap_consumer_proxy_audio_def_s =
{
sizeof ( twrap_consumer_proxy_audio_t ) ,
twrap_consumer_proxy_audio_ctor ,
twrap_consumer_proxy_audio_dtor ,
tdav_consumer_audio_cmp ,
} ;
/* plugin definition*/
static const tmedia_consumer_plugin_def_t twrap_consumer_proxy_audio_plugin_def_s =
{
& twrap_consumer_proxy_audio_def_s ,
tmedia_audio ,
" Audio Proxy Consumer " ,
twrap_consumer_proxy_audio_set ,
twrap_consumer_proxy_audio_prepare ,
twrap_consumer_proxy_audio_start ,
twrap_consumer_proxy_audio_consume ,
twrap_consumer_proxy_audio_pause ,
twrap_consumer_proxy_audio_stop
} ;
TINYWRAP_GEXTERN const tmedia_consumer_plugin_def_t * twrap_consumer_proxy_audio_plugin_def_t = & twrap_consumer_proxy_audio_plugin_def_s ;
/* ============ ProxyAudioConsumer Class ================= */
ProxyAudioConsumer : : ProxyAudioConsumer ( twrap_consumer_proxy_audio_t * pConsumer )
: ProxyPlugin ( twrap_proxy_plugin_audio_consumer ) ,
m_pWrappedPlugin ( pConsumer ) ,
m_pCallback ( tsk_null )
{
memset ( & m_PullBuffer , 0 , sizeof ( m_PullBuffer ) ) ;
memset ( & m_Resampler , 0 , sizeof ( m_Resampler ) ) ;
if ( m_pWrappedPlugin ) {
m_pWrappedPlugin - > id = this - > getId ( ) ;
}
}
ProxyAudioConsumer : : ~ ProxyAudioConsumer ( )
{
TSK_FREE ( m_Resampler . pInBufferPtr ) ;
m_Resampler . nInBufferSizeInByte = 0 ;
if ( m_Resampler . pResampler ) {
delete m_Resampler . pResampler , m_Resampler . pResampler = tsk_null ;
}
}
2013-06-10 05:47:01 +00:00
// Use this function to request resampling when your sound card can't honor negotaited record parameters
bool ProxyAudioConsumer : : setActualSndCardPlaybackParams ( int nPtime , int nRate , int nChannels )
{
if ( m_pWrappedPlugin ) {
TSK_DEBUG_INFO ( " ProxyAudioConsumer::setActualSndCardRecordParams(ptime=%d, rate=%d, channels=%d) " , nPtime , nRate , nChannels ) ;
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > audio . ptime = nPtime ;
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > audio . out . rate = nRate ;
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > audio . out . channels = nChannels ;
return true ;
}
else {
TSK_DEBUG_ERROR ( " Invalid state " ) ;
return false ;
}
}
2012-12-03 03:11:21 +00:00
bool ProxyAudioConsumer : : queryForResampler ( uint16_t nInFreq , uint16_t nOutFreq , uint16_t nFrameDuration , uint16_t nChannels , uint16_t nResamplerQuality )
{
TSK_DEBUG_INFO ( " queryForResampler(%hu,%hu,%hu,%hu,%hu) " , nInFreq , nOutFreq , nFrameDuration , nChannels , nResamplerQuality ) ;
if ( nResamplerQuality > 10 ) {
TSK_DEBUG_WARN ( " %d is invalid value for quality " , nResamplerQuality ) ;
}
m_Resampler . pResampler = new AudioResampler ( nInFreq , nOutFreq , nFrameDuration , nChannels , nResamplerQuality ) ;
if ( ! m_Resampler . pResampler ) {
TSK_DEBUG_ERROR ( " Failed to create new 'AudioResampler' object " ) ;
return false ;
}
bool bOK = m_Resampler . pResampler - > isValid ( ) ;
if ( ! bOK ) {
goto bail ;
}
m_Resampler . nInBufferSizeInByte = m_Resampler . pResampler - > getInputRequiredSizeInShort ( ) * 2 ;
m_Resampler . pInBufferPtr = tsk_calloc ( m_Resampler . nInBufferSizeInByte , 1 ) ;
bOK = ( m_Resampler . pInBufferPtr ! = tsk_null ) ;
bail :
if ( ! bOK ) {
if ( m_Resampler . pResampler ) {
delete m_Resampler . pResampler , m_Resampler . pResampler = tsk_null ;
}
TSK_FREE ( m_Resampler . pInBufferPtr ) ;
m_Resampler . nInBufferSizeInByte = 0 ;
}
return bOK ;
}
bool ProxyAudioConsumer : : setPullBuffer ( const void * pPullBufferPtr , unsigned nPullBufferSize )
{
m_PullBuffer . pPullBufferPtr = pPullBufferPtr ;
m_PullBuffer . nPullBufferSize = nPullBufferSize ;
return true ;
}
unsigned ProxyAudioConsumer : : pull ( void * _pOutput /*=tsk_null*/ , unsigned _nSize /*=0*/ )
{
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_audio_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
void * pOutput ;
unsigned nSize ;
if ( _pOutput & & _nSize ) {
pOutput = _pOutput , nSize = _nSize ;
}
else {
pOutput = ( void * ) m_PullBuffer . pPullBufferPtr , nSize = m_PullBuffer . nPullBufferSize ;
}
tsk_size_t nRetSize = 0 ;
if ( m_Resampler . pResampler & & m_Resampler . pInBufferPtr ) {
nRetSize = tdav_consumer_audio_get ( TDAV_CONSUMER_AUDIO ( m_pWrappedPlugin ) , m_Resampler . pInBufferPtr , m_Resampler . nInBufferSizeInByte ) ;
if ( nRetSize ) {
nRetSize = m_Resampler . pResampler - > process ( m_Resampler . pInBufferPtr , nRetSize , pOutput , nSize ) ;
}
}
else {
nRetSize = tdav_consumer_audio_get ( TDAV_CONSUMER_AUDIO ( m_pWrappedPlugin ) , pOutput , nSize ) ;
}
tdav_consumer_audio_tick ( TDAV_CONSUMER_AUDIO ( m_pWrappedPlugin ) ) ;
m_pWrappedPlugin = ( twrap_consumer_proxy_audio_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
return nRetSize ;
}
return 0 ;
}
bool ProxyAudioConsumer : : setGain ( unsigned nGain )
{
if ( m_pWrappedPlugin ) {
// see also: MediaSessionMgr.consumerSetInt32(org.doubango.tinyWRAP.twrap_media_type_t.twrap_media_audio, "gain", nGain);
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > audio . gain = TSK_MIN ( nGain , 14 ) ;
return true ;
}
return false ;
}
unsigned ProxyAudioConsumer : : getGain ( )
{
if ( m_pWrappedPlugin ) {
return TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > audio . gain ;
}
return 0 ;
}
bool ProxyAudioConsumer : : reset ( )
{
if ( m_pWrappedPlugin ) {
return ( tdav_consumer_audio_reset ( TDAV_CONSUMER_AUDIO ( m_pWrappedPlugin ) ) = = 0 ) ;
}
return false ;
}
bool ProxyAudioConsumer : : registerPlugin ( )
{
/* HACK: Unregister all other audio plugins */
tmedia_consumer_plugin_unregister_by_type ( tmedia_audio ) ;
/* Register our proxy plugin */
return ( tmedia_consumer_plugin_register ( twrap_consumer_proxy_audio_plugin_def_t ) = = 0 ) ;
}
/* ============ Video Consumer Interface ================= */
typedef struct twrap_consumer_proxy_video_s
{
TDAV_DECLARE_CONSUMER_VIDEO ;
uint64_t id ;
tsk_bool_t started ;
2013-04-09 22:22:16 +00:00
const ProxyVideoConsumer * pcConsumer ; // thread-safe and will be destroyed at the time as the "struct"
2012-12-03 03:11:21 +00:00
}
twrap_consumer_proxy_video_t ;
# define TWRAP_CONSUMER_PROXY_VIDEO(self) ((twrap_consumer_proxy_video_t*)(self))
int twrap_consumer_proxy_video_set ( tmedia_consumer_t * self , const tmedia_param_t * params )
{
return 0 ;
}
int twrap_consumer_proxy_video_prepare ( tmedia_consumer_t * self , const tmedia_codec_t * codec )
{
ProxyPluginMgr * manager ;
2013-04-09 22:22:16 +00:00
twrap_consumer_proxy_video_t * video = TWRAP_CONSUMER_PROXY_VIDEO ( self ) ;
2012-12-03 03:11:21 +00:00
int ret = - 1 ;
if ( codec & & ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
2013-04-09 22:22:16 +00:00
if ( ( video - > pcConsumer = manager - > findVideoConsumer ( video - > id ) ) & & video - > pcConsumer - > getCallback ( ) ) {
2012-12-03 03:11:21 +00:00
self - > video . fps = TMEDIA_CODEC_VIDEO ( codec ) - > in . fps ;
// in
self - > video . in . chroma = tmedia_chroma_yuv420p ;
self - > video . in . width = TMEDIA_CODEC_VIDEO ( codec ) - > in . width ;
self - > video . in . height = TMEDIA_CODEC_VIDEO ( codec ) - > in . height ;
// display (out)
2013-04-09 22:22:16 +00:00
self - > video . display . chroma = video - > pcConsumer - > getChroma ( ) ;
self - > video . display . auto_resize = video - > pcConsumer - > getAutoResizeDisplay ( ) ;
2012-12-03 03:11:21 +00:00
if ( ! self - > video . display . width ) {
self - > video . display . width = self - > video . in . width ;
}
if ( ! self - > video . display . height ) {
self - > video . display . height = self - > video . in . height ;
}
2013-04-09 22:22:16 +00:00
ret = video - > pcConsumer - > getCallback ( ) - > prepare ( TMEDIA_CODEC_VIDEO ( codec ) - > in . width , TMEDIA_CODEC_VIDEO ( codec ) - > in . height , TMEDIA_CODEC_VIDEO ( codec ) - > in . fps ) ;
2012-12-03 03:11:21 +00:00
}
}
return ret ;
}
int twrap_consumer_proxy_video_start ( tmedia_consumer_t * self )
{
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
const ProxyVideoConsumer * videoConsumer ;
if ( ( videoConsumer = manager - > findVideoConsumer ( TWRAP_CONSUMER_PROXY_VIDEO ( self ) - > id ) ) & & videoConsumer - > getCallback ( ) ) {
ret = videoConsumer - > getCallback ( ) - > start ( ) ;
}
}
TWRAP_CONSUMER_PROXY_VIDEO ( self ) - > started = ( ret = = 0 ) ;
return ret ;
}
int twrap_consumer_proxy_video_consume ( tmedia_consumer_t * self , const void * buffer , tsk_size_t size , const tsk_object_t * proto_hdr )
{
if ( ! self | | ! buffer | | ! size ) {
TSK_DEBUG_ERROR ( " Invalid parameter " ) ;
return - 1 ;
}
2013-04-09 22:22:16 +00:00
twrap_consumer_proxy_video_t * video = TWRAP_CONSUMER_PROXY_VIDEO ( self ) ;
if ( ! video - > pcConsumer ) {
ProxyPluginMgr * manager ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
video - > pcConsumer = manager - > findVideoConsumer ( video - > id ) ;
}
}
int ret = - 1 ;
ProxyVideoConsumerCallback * callback ;
2012-12-03 03:11:21 +00:00
2013-04-09 22:22:16 +00:00
if ( video - > pcConsumer & & ( callback = video - > pcConsumer - > getCallback ( ) ) ) {
if ( tdav_consumer_video_has_jb ( TDAV_CONSUMER_VIDEO ( self ) ) ) {
ret = tdav_consumer_video_put ( TDAV_CONSUMER_VIDEO ( self ) , buffer , size , proto_hdr ) ;
}
else {
if ( video - > pcConsumer - > hasConsumeBuffer ( ) ) {
unsigned nCopiedSize = video - > pcConsumer - > copyBuffer ( buffer , size ) ;
ret = callback - > bufferCopied ( nCopiedSize , size ) ;
2012-12-03 03:11:21 +00:00
}
else {
2013-04-09 22:22:16 +00:00
ProxyVideoFrame * frame = new ProxyVideoFrame ( buffer , size , const_cast < ProxyVideoConsumer * > ( video - > pcConsumer ) - > getDecodedWidth ( ) , const_cast < ProxyVideoConsumer * > ( video - > pcConsumer ) - > getDecodedHeight ( ) , proto_hdr ) ;
ret = callback - > consume ( frame ) ;
delete frame , frame = tsk_null ;
2012-12-03 03:11:21 +00:00
}
}
}
2013-04-09 22:22:16 +00:00
else if ( ! video - > pcConsumer ) {
TSK_DEBUG_ERROR ( " Cannot find consumer with id=%lld " , TWRAP_CONSUMER_PROXY_VIDEO ( self ) - > id ) ;
}
2012-12-03 03:11:21 +00:00
return ret ;
}
int twrap_consumer_proxy_video_pause ( tmedia_consumer_t * self )
{
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
const ProxyVideoConsumer * videoConsumer ;
if ( ( videoConsumer = manager - > findVideoConsumer ( TWRAP_CONSUMER_PROXY_VIDEO ( self ) - > id ) ) & & videoConsumer - > getCallback ( ) ) {
ret = videoConsumer - > getCallback ( ) - > pause ( ) ;
}
}
return ret ;
}
int twrap_consumer_proxy_video_stop ( tmedia_consumer_t * self )
{
ProxyPluginMgr * manager ;
int ret = - 1 ;
if ( ( manager = ProxyPluginMgr : : getInstance ( ) ) ) {
const ProxyVideoConsumer * videoConsumer ;
if ( ( videoConsumer = manager - > findVideoConsumer ( TWRAP_CONSUMER_PROXY_VIDEO ( self ) - > id ) ) & & videoConsumer - > getCallback ( ) ) {
ret = videoConsumer - > getCallback ( ) - > stop ( ) ;
}
}
TWRAP_CONSUMER_PROXY_VIDEO ( self ) - > started = ( ret = = 0 ) ? tsk_false : tsk_true ;
return ret ;
}
//
// Video consumer object definition
//
/* constructor */
static tsk_object_t * twrap_consumer_proxy_video_ctor ( tsk_object_t * self , va_list * app )
{
twrap_consumer_proxy_video_t * consumer = ( twrap_consumer_proxy_video_t * ) self ;
if ( consumer ) {
/* init base */
tdav_consumer_video_init ( TDAV_CONSUMER_VIDEO ( consumer ) ) ;
/* init self */
/* Add the plugin to the manager */
ProxyPluginMgr * manager = ProxyPluginMgr : : getInstance ( ) ;
if ( manager ) {
ProxyPlugin * proxyConsumer = new ProxyVideoConsumer ( ProxyVideoConsumer : : getDefaultChroma ( ) , consumer ) ;
uint64_t id = proxyConsumer - > getId ( ) ;
manager - > addPlugin ( & proxyConsumer ) ;
manager - > getCallback ( ) - > OnPluginCreated ( id , twrap_proxy_plugin_video_consumer ) ;
}
}
return self ;
}
/* destructor */
static tsk_object_t * twrap_consumer_proxy_video_dtor ( tsk_object_t * self )
{
twrap_consumer_proxy_video_t * consumer = ( twrap_consumer_proxy_video_t * ) self ;
if ( consumer ) {
/* stop */
if ( consumer - > started ) {
twrap_consumer_proxy_video_stop ( TMEDIA_CONSUMER ( consumer ) ) ;
}
/* deinit base */
tdav_consumer_video_deinit ( TDAV_CONSUMER_VIDEO ( consumer ) ) ;
/* deinit self */
/* Remove plugin from the manager */
ProxyPluginMgr * manager = ProxyPluginMgr : : getInstance ( ) ;
if ( manager ) {
manager - > getCallback ( ) - > OnPluginDestroyed ( consumer - > id , twrap_proxy_plugin_video_consumer ) ;
manager - > removePlugin ( consumer - > id ) ;
}
}
return self ;
}
/* object definition */
static const tsk_object_def_t twrap_consumer_proxy_video_def_s =
{
sizeof ( twrap_consumer_proxy_video_t ) ,
twrap_consumer_proxy_video_ctor ,
twrap_consumer_proxy_video_dtor ,
tsk_null ,
} ;
/* plugin definition*/
static const tmedia_consumer_plugin_def_t twrap_consumer_proxy_video_plugin_def_s =
{
& twrap_consumer_proxy_video_def_s ,
tmedia_video ,
" Video Proxy Consumer " ,
twrap_consumer_proxy_video_set ,
twrap_consumer_proxy_video_prepare ,
twrap_consumer_proxy_video_start ,
twrap_consumer_proxy_video_consume ,
twrap_consumer_proxy_video_pause ,
twrap_consumer_proxy_video_stop
} ;
TINYWRAP_GEXTERN const tmedia_consumer_plugin_def_t * twrap_consumer_proxy_video_plugin_def_t = & twrap_consumer_proxy_video_plugin_def_s ;
/* ============ ProxyVideoConsumer Class ================= */
tmedia_chroma_t ProxyVideoConsumer : : s_eDefaultChroma = tmedia_chroma_rgb565le ;
bool ProxyVideoConsumer : : s_bAutoResizeDisplay = false ;
ProxyVideoConsumer : : ProxyVideoConsumer ( tmedia_chroma_t eChroma , struct twrap_consumer_proxy_video_s * pConsumer )
: m_eChroma ( eChroma ) ,
m_bAutoResizeDisplay ( ProxyVideoConsumer : : getDefaultAutoResizeDisplay ( ) ) ,
m_pWrappedPlugin ( pConsumer ) ,
m_pCallback ( tsk_null ) ,
ProxyPlugin ( twrap_proxy_plugin_video_consumer )
{
m_pWrappedPlugin - > id = this - > getId ( ) ;
m_ConsumeBuffer . pConsumeBufferPtr = tsk_null ;
m_ConsumeBuffer . nConsumeBufferSize = 0 ;
}
ProxyVideoConsumer : : ~ ProxyVideoConsumer ( )
{
}
bool ProxyVideoConsumer : : setDisplaySize ( unsigned nWidth , unsigned nHeight )
{
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . display . width = nWidth ;
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . display . height = nHeight ;
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
return true ;
}
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
return false ;
}
unsigned ProxyVideoConsumer : : getDisplayWidth ( )
{
unsigned displayWidth = 0 ;
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
displayWidth = TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . display . width ;
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
}
else {
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
}
return displayWidth ;
}
unsigned ProxyVideoConsumer : : getDisplayHeight ( )
{
unsigned displayHeight = 0 ;
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
displayHeight = TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . display . height ;
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
}
else {
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
}
return displayHeight ;
}
unsigned ProxyVideoConsumer : : getDecodedWidth ( )
{
unsigned width = 0 ;
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
width = TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . in . width ;
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
}
else {
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
}
return width ;
}
unsigned ProxyVideoConsumer : : getDecodedHeight ( )
{
unsigned height = 0 ;
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
height = TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . in . height ;
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
}
else {
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
}
return height ;
}
tmedia_chroma_t ProxyVideoConsumer : : getChroma ( ) const
{
return m_eChroma ;
}
bool ProxyVideoConsumer : : setAutoResizeDisplay ( bool bAutoResizeDisplay ) {
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
TMEDIA_CONSUMER ( m_pWrappedPlugin ) - > video . display . auto_resize = bAutoResizeDisplay ? tsk_true : tsk_false ;
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
m_bAutoResizeDisplay = bAutoResizeDisplay ;
return true ;
}
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
return false ;
}
bool ProxyVideoConsumer : : getAutoResizeDisplay ( ) const
{
return m_bAutoResizeDisplay ;
}
bool ProxyVideoConsumer : : setConsumeBuffer ( const void * pConsumeBufferPtr , unsigned nConsumeBufferSize )
{
m_ConsumeBuffer . pConsumeBufferPtr = pConsumeBufferPtr ;
m_ConsumeBuffer . nConsumeBufferSize = nConsumeBufferSize ;
return true ;
}
unsigned ProxyVideoConsumer : : copyBuffer ( const void * pBuffer , unsigned nSize ) const
{
unsigned nRetsize = 0 ;
if ( pBuffer & & nSize & & m_ConsumeBuffer . pConsumeBufferPtr & & m_ConsumeBuffer . nConsumeBufferSize ) {
nRetsize = ( nSize > m_ConsumeBuffer . nConsumeBufferSize ) ? m_ConsumeBuffer . nConsumeBufferSize : nSize ;
memcpy ( ( void * ) m_ConsumeBuffer . pConsumeBufferPtr , pBuffer , nRetsize ) ;
}
return nRetsize ;
}
unsigned ProxyVideoConsumer : : pull ( void * pOutput , unsigned nSize )
{
if ( pOutput & & nSize & & ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
tsk_size_t nRetSize = 0 ;
if ( ! tdav_consumer_video_has_jb ( TDAV_CONSUMER_VIDEO ( m_pWrappedPlugin ) ) ) {
TSK_DEBUG_ERROR ( " This consumer doesn't hold any jitter buffer. \n \n To pull a buffer you must register a callback ('class ProxyVideoConsumerCallback') and listen for either 'consume' or 'bufferCopied' functions " ) ;
goto done ;
}
nRetSize = tdav_consumer_video_get ( TDAV_CONSUMER_VIDEO ( m_pWrappedPlugin ) , pOutput , nSize ) ;
tdav_consumer_video_tick ( TDAV_CONSUMER_VIDEO ( m_pWrappedPlugin ) ) ;
done :
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
return nRetSize ;
}
return 0 ;
}
bool ProxyVideoConsumer : : reset ( )
{
bool ret = false ;
if ( ( m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_ref ( m_pWrappedPlugin ) ) ) {
if ( tdav_consumer_video_has_jb ( TDAV_CONSUMER_VIDEO ( m_pWrappedPlugin ) ) ) {
ret = ( tdav_consumer_video_reset ( TDAV_CONSUMER_VIDEO ( m_pWrappedPlugin ) ) = = 0 ) ;
}
else {
TSK_DEBUG_ERROR ( " This consumer doesn't hold any jitter buffer " ) ;
}
m_pWrappedPlugin = ( twrap_consumer_proxy_video_t * ) tsk_object_unref ( m_pWrappedPlugin ) ;
}
TSK_DEBUG_ERROR ( " This consumer doesn't wrap any plugin " ) ;
return ret ;
}
bool ProxyVideoConsumer : : registerPlugin ( )
{
/* HACK: Unregister all other video plugins */
tmedia_consumer_plugin_unregister_by_type ( tmedia_video ) ;
/* Register our proxy plugin */
return ( tmedia_consumer_plugin_register ( twrap_consumer_proxy_video_plugin_def_t ) = = 0 ) ;
}
ProxyVideoFrame : : ProxyVideoFrame ( const void * pBufferPtr , unsigned nSize , unsigned nFrameWidth , unsigned nFrameHeight , const tsk_object_t * pProtoHdr )
{
m_pBufferPtr = pBufferPtr ;
m_nBufferSize = nSize ;
m_nFrameWidth = nFrameWidth ;
m_nFrameHeight = nFrameHeight ;
m_pProtoHdr = pProtoHdr ;
}
ProxyVideoFrame : : ~ ProxyVideoFrame ( )
{
}
unsigned ProxyVideoFrame : : getSize ( )
{
return m_nBufferSize ;
}
unsigned ProxyVideoFrame : : getContent ( void * pOutput , unsigned nMaxsize )
{
unsigned nRetsize = 0 ;
if ( pOutput & & nMaxsize & & m_pBufferPtr ) {
nRetsize = ( m_nBufferSize > nMaxsize ) ? nMaxsize : m_nBufferSize ;
memcpy ( pOutput , m_pBufferPtr , nRetsize ) ;
}
return nRetsize ;
}