ProxyProducer.cxx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. /*
  2. * Copyright (C) 2010-2011 Mamadou Diop.
  3. *
  4. * Contact: Mamadou Diop <diopmamadou(at)doubango.org>
  5. *
  6. * This file is part of Open Source Doubango Framework.
  7. *
  8. * DOUBANGO is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * DOUBANGO is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with DOUBANGO.
  20. *
  21. */
  22. /**@file ProxyProducer.c
  23. * @brief Audio/Video proxy producers.
  24. *
  25. * @author Mamadou Diop <diopmamadou(at)doubango.org>
  26. *
  27. */
  28. #include "ProxyProducer.h"
  29. #include "tsk_timer.h"
  30. #include "tsk_memory.h"
  31. #include "tsk_debug.h"
  32. #include "tinydav/audio/tdav_producer_audio.h"
  33. /* ============ Audio Media Producer Interface ================= */
  34. typedef struct twrap_producer_proxy_audio_s {
  35. TDAV_DECLARE_PRODUCER_AUDIO;
  36. uint64_t id;
  37. tsk_bool_t started;
  38. }
  39. twrap_producer_proxy_audio_t;
  40. #define TWRAP_PRODUCER_PROXY_AUDIO(self) ((twrap_producer_proxy_audio_t*)(self))
  41. static int twrap_producer_proxy_audio_set(tmedia_producer_t* _self, const tmedia_param_t* param)
  42. {
  43. twrap_producer_proxy_audio_t* self = (twrap_producer_proxy_audio_t*)_self;
  44. if(param->plugin_type == tmedia_ppt_producer) {
  45. // specific proxy producer
  46. }
  47. return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param);
  48. }
  49. static int twrap_producer_proxy_audio_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec)
  50. {
  51. ProxyPluginMgr* manager;
  52. int ret = -1;
  53. if(codec && (manager = ProxyPluginMgr::getInstance())) {
  54. const ProxyAudioProducer* audioProducer;
  55. if((audioProducer = manager->findAudioProducer(TWRAP_PRODUCER_PROXY_AUDIO(self)->id)) && audioProducer->getCallback()) {
  56. self->audio.channels = TMEDIA_CODEC_CHANNELS_AUDIO_ENCODING(codec);
  57. self->audio.rate = TMEDIA_CODEC_RATE_ENCODING(codec);
  58. self->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_ENCODING(codec);
  59. ret = audioProducer->getCallback()->prepare((int)self->audio.ptime, self->audio.rate, self->audio.channels);
  60. }
  61. }
  62. return ret;
  63. }
  64. static int twrap_producer_proxy_audio_start(tmedia_producer_t* self)
  65. {
  66. ProxyPluginMgr* manager;
  67. int ret = -1;
  68. if((manager = ProxyPluginMgr::getInstance())) {
  69. const ProxyAudioProducer* audioProducer;
  70. if((audioProducer = manager->findAudioProducer(TWRAP_PRODUCER_PROXY_AUDIO(self)->id)) && audioProducer->getCallback()) {
  71. const_cast<ProxyAudioProducer*>(audioProducer)->startPushCallback();
  72. ret = audioProducer->getCallback()->start();
  73. }
  74. }
  75. TWRAP_PRODUCER_PROXY_AUDIO(self)->started = (ret == 0);
  76. return ret;
  77. }
  78. static int twrap_producer_proxy_audio_pause(tmedia_producer_t* self)
  79. {
  80. ProxyPluginMgr* manager;
  81. int ret = -1;
  82. if((manager = ProxyPluginMgr::getInstance())) {
  83. const ProxyAudioProducer* audioProducer;
  84. if((audioProducer = manager->findAudioProducer(TWRAP_PRODUCER_PROXY_AUDIO(self)->id)) && audioProducer->getCallback()) {
  85. ret = audioProducer->getCallback()->pause();
  86. }
  87. }
  88. return ret;
  89. }
  90. static int twrap_producer_proxy_audio_stop(tmedia_producer_t* self)
  91. {
  92. ProxyPluginMgr* manager;
  93. int ret = -1;
  94. if((manager = ProxyPluginMgr::getInstance())) {
  95. const ProxyAudioProducer* audioProducer;
  96. if((audioProducer = manager->findAudioProducer(TWRAP_PRODUCER_PROXY_AUDIO(self)->id)) && audioProducer->getCallback()) {
  97. const_cast<ProxyAudioProducer*>(audioProducer)->stopPushCallback();
  98. ret = audioProducer->getCallback()->stop();
  99. }
  100. }
  101. TWRAP_PRODUCER_PROXY_AUDIO(self)->started = (ret == 0) ? tsk_false : tsk_true;
  102. return ret;
  103. }
  104. //
  105. // Audio producer object definition
  106. //
  107. /* constructor */
  108. static tsk_object_t* twrap_producer_proxy_audio_ctor(tsk_object_t * self, va_list * app)
  109. {
  110. twrap_producer_proxy_audio_t *producer = (twrap_producer_proxy_audio_t *)self;
  111. if(producer) {
  112. /* init base */
  113. tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(producer));
  114. /* init self */
  115. /* Add the plugin to the manager */
  116. ProxyPluginMgr* manager = ProxyPluginMgr::getInstance();
  117. if(manager) {
  118. ProxyPlugin* proxyProducer = new ProxyAudioProducer(producer);
  119. uint64_t id = proxyProducer->getId();
  120. manager->addPlugin(&proxyProducer);
  121. manager->getCallback()->OnPluginCreated(id, twrap_proxy_plugin_audio_producer);
  122. }
  123. }
  124. return self;
  125. }
  126. /* destructor */
  127. static tsk_object_t* twrap_producer_proxy_audio_dtor(tsk_object_t * self)
  128. {
  129. twrap_producer_proxy_audio_t *producer = (twrap_producer_proxy_audio_t *)self;
  130. if(producer) {
  131. /* stop */
  132. if(producer->started) {
  133. twrap_producer_proxy_audio_stop(TMEDIA_PRODUCER(producer));
  134. }
  135. /* deinit base */
  136. tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(producer));
  137. /* deinit self */
  138. /* Remove plugin from the manager */
  139. ProxyPluginMgr* manager = ProxyPluginMgr::getInstance();
  140. if(manager) {
  141. manager->getCallback()->OnPluginDestroyed(producer->id, twrap_proxy_plugin_audio_producer);
  142. manager->removePlugin(producer->id);
  143. }
  144. }
  145. return self;
  146. }
  147. /* object definition */
  148. static const tsk_object_def_t twrap_producer_proxy_audio_def_s = {
  149. sizeof(twrap_producer_proxy_audio_t),
  150. twrap_producer_proxy_audio_ctor,
  151. twrap_producer_proxy_audio_dtor,
  152. tdav_producer_audio_cmp,
  153. };
  154. /* plugin definition*/
  155. static const tmedia_producer_plugin_def_t twrap_producer_proxy_audio_plugin_def_s = {
  156. &twrap_producer_proxy_audio_def_s,
  157. tmedia_audio,
  158. "Audio Proxy Producer",
  159. twrap_producer_proxy_audio_set,
  160. twrap_producer_proxy_audio_prepare,
  161. twrap_producer_proxy_audio_start,
  162. twrap_producer_proxy_audio_pause,
  163. twrap_producer_proxy_audio_stop
  164. };
  165. /*TINYWRAP_GEXTERN*/ const tmedia_producer_plugin_def_t *twrap_producer_proxy_audio_plugin_def_t = &twrap_producer_proxy_audio_plugin_def_s;
  166. /* ============ ProxyAudioProducer Class ================= */
  167. ProxyAudioProducer::ProxyAudioProducer(twrap_producer_proxy_audio_t* pProducer)
  168. :m_pCallback(tsk_null), m_pWrappedPlugin(pProducer), m_bUsePushCallback(false), m_hPushTimerMgr(tsk_null), ProxyPlugin(twrap_proxy_plugin_audio_producer)
  169. {
  170. m_pWrappedPlugin->id = this->getId();
  171. m_PushBuffer.pPushBufferPtr = tsk_null;
  172. m_PushBuffer.nPushBufferSize = 0;
  173. }
  174. ProxyAudioProducer::~ProxyAudioProducer()
  175. {
  176. stopPushCallback();
  177. }
  178. // Use this function to request resampling when your sound card can't honor negotaited record parameters
  179. bool ProxyAudioProducer::setActualSndCardRecordParams(int nPtime, int nRate, int nChannels)
  180. {
  181. if(m_pWrappedPlugin) {
  182. TSK_DEBUG_INFO("setActualSndCardRecordParams(ptime=%d, rate=%d, channels=%d)", nPtime, nRate, nChannels);
  183. TMEDIA_PRODUCER(m_pWrappedPlugin)->audio.ptime = nPtime;
  184. TMEDIA_PRODUCER(m_pWrappedPlugin)->audio.rate = nRate;
  185. TMEDIA_PRODUCER(m_pWrappedPlugin)->audio.channels = nChannels;
  186. return true;
  187. }
  188. else {
  189. TSK_DEBUG_ERROR("Invalid state");
  190. return false;
  191. }
  192. }
  193. bool ProxyAudioProducer::setPushBuffer(const void* pPushBufferPtr, unsigned nPushBufferSize, bool bUsePushCallback/*=false*/)
  194. {
  195. m_PushBuffer.pPushBufferPtr = pPushBufferPtr;
  196. m_PushBuffer.nPushBufferSize = nPushBufferSize;
  197. m_bUsePushCallback = bUsePushCallback;
  198. if(!pPushBufferPtr || !nPushBufferSize || !bUsePushCallback) {
  199. return stopPushCallback();
  200. }
  201. else if(m_bUsePushCallback && m_pWrappedPlugin && m_pWrappedPlugin->started) {
  202. return startPushCallback();
  203. }
  204. return true;
  205. }
  206. int ProxyAudioProducer::push(const void* _pBuffer/*=tsk_null*/, unsigned _nSize/*=0*/)
  207. {
  208. if(m_pWrappedPlugin && TMEDIA_PRODUCER(m_pWrappedPlugin)->enc_cb.callback) {
  209. const void* pBuffer;
  210. unsigned nSize;
  211. if(_pBuffer && _nSize) {
  212. pBuffer = _pBuffer, nSize = _nSize;
  213. }
  214. else {
  215. pBuffer = m_PushBuffer.pPushBufferPtr, nSize = m_PushBuffer.nPushBufferSize;
  216. }
  217. return TMEDIA_PRODUCER(m_pWrappedPlugin)->enc_cb.callback(TMEDIA_PRODUCER(m_pWrappedPlugin)->enc_cb.callback_data, pBuffer, nSize);
  218. }
  219. return 0;
  220. }
  221. bool ProxyAudioProducer::setGain(unsigned nGain)
  222. {
  223. if(m_pWrappedPlugin) {
  224. // see also: MediaSessionMgr.producerSetInt32(org.doubango.tinyWRAP.twrap_media_type_t.twrap_media_audio, "gain", nGain);
  225. TMEDIA_PRODUCER(m_pWrappedPlugin)->audio.gain = TSK_MIN(nGain,14);
  226. return true;
  227. }
  228. return false;
  229. }
  230. unsigned ProxyAudioProducer::getGain()
  231. {
  232. if(m_pWrappedPlugin) {
  233. return TMEDIA_PRODUCER(m_pWrappedPlugin)->audio.gain;
  234. }
  235. return 0;
  236. }
  237. bool ProxyAudioProducer::startPushCallback()
  238. {
  239. if(!m_bUsePushCallback) {
  240. return true;
  241. }
  242. if(!m_pWrappedPlugin) {
  243. TSK_DEBUG_ERROR("Not wrapping plugin");
  244. return false;
  245. }
  246. if(!m_hPushTimerMgr) {
  247. if(!(m_hPushTimerMgr = tsk_timer_manager_create())) {
  248. TSK_DEBUG_ERROR("Failed to create timer manager");
  249. return false;
  250. }
  251. }
  252. if(!TSK_RUNNABLE(m_hPushTimerMgr)->started) {
  253. if((tsk_timer_manager_start(m_hPushTimerMgr)) == 0) {
  254. m_uPushTimer = tsk_timer_manager_schedule(m_hPushTimerMgr, TMEDIA_PRODUCER(m_pWrappedPlugin)->audio.ptime, &ProxyAudioProducer::pushTimerCallback, this);
  255. }
  256. else {
  257. TSK_DEBUG_ERROR("Failed to start timer");
  258. return false;
  259. }
  260. }
  261. return true;
  262. }
  263. bool ProxyAudioProducer::stopPushCallback()
  264. {
  265. if(m_hPushTimerMgr) {
  266. tsk_timer_manager_destroy(&m_hPushTimerMgr);
  267. }
  268. return true;
  269. }
  270. int ProxyAudioProducer::pushTimerCallback(const void* arg, tsk_timer_id_t timer_id)
  271. {
  272. ProxyAudioProducer* This = (ProxyAudioProducer*)arg;
  273. This->m_uPushTimer = tsk_timer_manager_schedule(This->m_hPushTimerMgr, TMEDIA_PRODUCER(This->m_pWrappedPlugin)->audio.ptime, &ProxyAudioProducer::pushTimerCallback, This);
  274. if(This->m_pCallback) {
  275. if(This->m_pCallback->fillPushBuffer() == 0) {
  276. return This->push();
  277. }
  278. }
  279. return 0;
  280. }
  281. bool ProxyAudioProducer::registerPlugin()
  282. {
  283. /* HACK: Unregister all other audio plugins */
  284. tmedia_producer_plugin_unregister_by_type(tmedia_audio);
  285. /* Register our proxy plugin */
  286. return (tmedia_producer_plugin_register(twrap_producer_proxy_audio_plugin_def_t) == 0);
  287. }
  288. /* ============ Video Media Producer Interface ================= */
  289. typedef struct twrap_producer_proxy_video_s {
  290. TMEDIA_DECLARE_PRODUCER;
  291. int rotation;
  292. uint64_t id;
  293. tsk_bool_t started;
  294. #if 0
  295. // https://code.google.com/p/doubango/issues/detail?id=416
  296. // The lock on the producer is useless because all tinyDAV proxied functions (push(), stop(), prepare()...) are already thread safe.
  297. // Locking the push method while tinDAV locks the stop() function produce a deadlock on Android devices with slow video producer implementations (e.g. Hovis Box v1)
  298. TSK_DECLARE_SAFEOBJ;
  299. #endif
  300. }
  301. twrap_producer_proxy_video_t;
  302. #define TWRAP_PRODUCER_PROXY_VIDEO(self) ((twrap_producer_proxy_video_t*)(self))
  303. int twrap_producer_proxy_video_set(tmedia_producer_t* self, const tmedia_param_t* params)
  304. {
  305. return 0;
  306. }
  307. int twrap_producer_proxy_video_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec)
  308. {
  309. ProxyPluginMgr* manager;
  310. int ret = -1;
  311. if(codec && (manager = ProxyPluginMgr::getInstance())) {
  312. const ProxyVideoProducer* videoProducer;
  313. if((videoProducer = manager->findVideoProducer(TWRAP_PRODUCER_PROXY_VIDEO(self)->id)) && videoProducer->getCallback()) {
  314. self->video.chroma = videoProducer->getChroma();
  315. self->video.rotation = videoProducer->getRotation();
  316. ret = videoProducer->getCallback()->prepare(TMEDIA_CODEC_VIDEO(codec)->out.width, TMEDIA_CODEC_VIDEO(codec)->out.height, TMEDIA_CODEC_VIDEO(codec)->out.fps);
  317. }
  318. }
  319. return ret;
  320. }
  321. int twrap_producer_proxy_video_start(tmedia_producer_t* self)
  322. {
  323. ProxyPluginMgr* manager;
  324. int ret = -1;
  325. if((manager = ProxyPluginMgr::getInstance())) {
  326. const ProxyVideoProducer* videoProducer;
  327. if((videoProducer = manager->findVideoProducer(TWRAP_PRODUCER_PROXY_VIDEO(self)->id)) && videoProducer->getCallback()) {
  328. ret = videoProducer->getCallback()->start();
  329. TWRAP_PRODUCER_PROXY_VIDEO(self)->started = (ret == 0);
  330. }
  331. }
  332. return ret;
  333. }
  334. int twrap_producer_proxy_video_pause(tmedia_producer_t* self)
  335. {
  336. ProxyPluginMgr* manager;
  337. int ret = -1;
  338. if((manager = ProxyPluginMgr::getInstance())) {
  339. const ProxyVideoProducer* videoProducer;
  340. if((videoProducer = manager->findVideoProducer(TWRAP_PRODUCER_PROXY_VIDEO(self)->id)) && videoProducer->getCallback()) {
  341. ret = videoProducer->getCallback()->pause();
  342. }
  343. }
  344. return ret;
  345. }
  346. int twrap_producer_proxy_video_stop(tmedia_producer_t* self)
  347. {
  348. ProxyPluginMgr* manager;
  349. int ret = -1;
  350. if((manager = ProxyPluginMgr::getInstance())) {
  351. const ProxyVideoProducer* videoProducer;
  352. if((videoProducer = manager->findVideoProducer(TWRAP_PRODUCER_PROXY_VIDEO(self)->id)) && videoProducer->getCallback()) {
  353. ret = videoProducer->getCallback()->stop();
  354. TWRAP_PRODUCER_PROXY_VIDEO(self)->started = ((ret == 0) ? tsk_false : tsk_true);
  355. }
  356. }
  357. return ret;
  358. }
  359. //
  360. // Video producer object definition
  361. //
  362. /* constructor */
  363. static tsk_object_t* twrap_producer_proxy_video_ctor(tsk_object_t * self, va_list * app)
  364. {
  365. twrap_producer_proxy_video_t *producer = (twrap_producer_proxy_video_t *)self;
  366. if(producer) {
  367. /* init base */
  368. tmedia_producer_init(TMEDIA_PRODUCER(producer));
  369. /* init self */
  370. /* Add the plugin to the manager */
  371. ProxyPluginMgr* manager = ProxyPluginMgr::getInstance();
  372. if(manager) {
  373. ProxyPlugin* proxyProducer = new ProxyVideoProducer(ProxyVideoProducer::getDefaultChroma(), producer);
  374. uint64_t id = proxyProducer->getId();
  375. manager->addPlugin(&proxyProducer);
  376. manager->getCallback()->OnPluginCreated(id, twrap_proxy_plugin_video_producer);
  377. }
  378. }
  379. return self;
  380. }
  381. /* destructor */
  382. static tsk_object_t* twrap_producer_proxy_video_dtor(tsk_object_t * self)
  383. {
  384. twrap_producer_proxy_video_t *producer = (twrap_producer_proxy_video_t *)self;
  385. if(producer) {
  386. TSK_DEBUG_INFO("twrap_producer_proxy_video_dtor()");
  387. /* stop */
  388. if(producer->started) {
  389. twrap_producer_proxy_video_stop(TMEDIA_PRODUCER(producer));
  390. }
  391. /* deinit base */
  392. tmedia_producer_deinit(TMEDIA_PRODUCER(producer));
  393. /* deinit self */
  394. /* Remove plugin from the manager */
  395. ProxyPluginMgr* manager = ProxyPluginMgr::getInstance();
  396. if(manager) {
  397. manager->getCallback()->OnPluginDestroyed(producer->id, twrap_proxy_plugin_video_producer);
  398. manager->removePlugin(producer->id);
  399. }
  400. }
  401. return self;
  402. }
  403. /* object definition */
  404. static const tsk_object_def_t twrap_producer_proxy_video_def_s = {
  405. sizeof(twrap_producer_proxy_video_t),
  406. twrap_producer_proxy_video_ctor,
  407. twrap_producer_proxy_video_dtor,
  408. tsk_null,
  409. };
  410. /* plugin definition*/
  411. static const tmedia_producer_plugin_def_t twrap_producer_proxy_video_plugin_def_s = {
  412. &twrap_producer_proxy_video_def_s,
  413. tmedia_video,
  414. "Video Proxy Producer",
  415. twrap_producer_proxy_video_set,
  416. twrap_producer_proxy_video_prepare,
  417. twrap_producer_proxy_video_start,
  418. twrap_producer_proxy_video_pause,
  419. twrap_producer_proxy_video_stop
  420. };
  421. /*TINYWRAP_GEXTERN*/ const tmedia_producer_plugin_def_t *twrap_producer_proxy_video_plugin_def_t = &twrap_producer_proxy_video_plugin_def_s;
  422. /* ============ ProxyVideoProducer Class ================= */
  423. tmedia_chroma_t ProxyVideoProducer::s_eDefaultChroma = tmedia_chroma_nv21;
  424. ProxyVideoProducer::ProxyVideoProducer(tmedia_chroma_t eChroma, struct twrap_producer_proxy_video_s* pProducer)
  425. :m_pCallback(tsk_null), m_eChroma(eChroma), m_nRotation(0), m_bMirror(false), m_pWrappedPlugin(pProducer), ProxyPlugin(twrap_proxy_plugin_video_producer)
  426. {
  427. if(m_pWrappedPlugin) {
  428. m_pWrappedPlugin->id = this->getId();
  429. }
  430. }
  431. ProxyVideoProducer::~ProxyVideoProducer()
  432. {
  433. TSK_DEBUG_INFO("~ProxyVideoProducer");
  434. }
  435. int ProxyVideoProducer::getRotation()const
  436. {
  437. return m_nRotation;
  438. }
  439. bool ProxyVideoProducer::setRotation(int nRot)
  440. {
  441. m_nRotation = nRot;
  442. if (m_pWrappedPlugin) {
  443. TMEDIA_PRODUCER(m_pWrappedPlugin)->video.rotation = m_nRotation;
  444. return true;
  445. }
  446. return false;
  447. }
  448. bool ProxyVideoProducer::getMirror()const
  449. {
  450. return m_bMirror;
  451. }
  452. bool ProxyVideoProducer::setMirror(bool bMirror)
  453. {
  454. m_bMirror = bMirror;
  455. if (m_pWrappedPlugin) {
  456. TMEDIA_PRODUCER(m_pWrappedPlugin)->video.mirror = m_bMirror ? tsk_true : tsk_false;
  457. return true;
  458. }
  459. return false;
  460. }
  461. // alert the encoder which size your camera is using because it's very hard to retrieve it from send(buffer, size) function
  462. // this function is only needed if the actual size (output from your camera) is different than the negociated one
  463. bool ProxyVideoProducer::setActualCameraOutputSize(unsigned nWidth, unsigned nHeight)
  464. {
  465. if(m_pWrappedPlugin) {
  466. TMEDIA_PRODUCER(m_pWrappedPlugin)->video.width = nWidth;
  467. TMEDIA_PRODUCER(m_pWrappedPlugin)->video.height = nHeight;
  468. return true;
  469. }
  470. return false;
  471. }
  472. // encode() then send()
  473. int ProxyVideoProducer::push(const void* pBuffer, unsigned nSize)
  474. {
  475. if (m_pWrappedPlugin && TMEDIA_PRODUCER(m_pWrappedPlugin)->enc_cb.callback) {
  476. int ret = -1;
  477. if (m_pWrappedPlugin->started) {
  478. ret = TMEDIA_PRODUCER(m_pWrappedPlugin)->enc_cb.callback(TMEDIA_PRODUCER(m_pWrappedPlugin)->enc_cb.callback_data, pBuffer, nSize);
  479. }
  480. return ret;
  481. }
  482. return 0;
  483. }
  484. // send() "as is"
  485. // only used by telepresence system with a H.264 SVC hardaware encoder
  486. int ProxyVideoProducer::sendRaw(const void* pBuffer, unsigned nSize, unsigned nDuration, bool bMarker)
  487. {
  488. if(m_pWrappedPlugin && TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.callback) {
  489. //tmedia_video_encode_result_reset(&TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr);
  490. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.buffer.ptr = pBuffer;
  491. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.buffer.size = nSize;
  492. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.duration = nDuration;
  493. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.last_chunck = (bMarker == true);
  494. return TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.callback(&TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr);
  495. }
  496. return 0;
  497. }
  498. int ProxyVideoProducer::sendRaw(const void* pBuffer, unsigned nSize, const void* proto_hdr)
  499. {
  500. if(m_pWrappedPlugin && TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.callback) {
  501. //tmedia_video_encode_result_reset(&TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr);
  502. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.buffer.ptr = pBuffer;
  503. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.buffer.size = nSize;
  504. TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr.proto_hdr = proto_hdr;
  505. return TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.callback(&TMEDIA_PRODUCER(m_pWrappedPlugin)->raw_cb.chunck_curr);
  506. }
  507. return 0;
  508. }
  509. tmedia_chroma_t ProxyVideoProducer::getChroma()const
  510. {
  511. return m_eChroma;
  512. }
  513. bool ProxyVideoProducer::registerPlugin()
  514. {
  515. /* HACK: Unregister all other video plugins */
  516. tmedia_producer_plugin_unregister_by_type(tmedia_video);
  517. /* Register our proxy plugin */
  518. return (tmedia_producer_plugin_register(twrap_producer_proxy_video_plugin_def_t) == 0);
  519. }