123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- /* Copyright (C) 2014 Mamadou DIOP
- *
- * 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.
- */
- #include "internals/DSGrabber.h"
- #include "internals/DSDisplay.h"
- #include "internals/DSUtils.h"
- #include "tinymedia/tmedia_producer.h"
- #include "tsk_string.h"
- #include "tsk_debug.h"
- #define DSPRODUCER(self) ((plugin_screencast_dshow_producer_t*)(self))
- typedef struct plugin_screencast_dshow_producer_s {
- TMEDIA_DECLARE_PRODUCER;
- DSGrabber* grabber;
- INT64 previewHwnd;
- tsk_bool_t started;
- tsk_bool_t mute;
- tsk_bool_t create_on_ui_thread;
- }
- plugin_screencast_dshow_producer_t;
- // Producer callback (From DirectShow Grabber to our plugin)
- static int plugin_video_dshow_plugin_cb(const void* callback_data, const void* buffer, tsk_size_t size)
- {
- const plugin_screencast_dshow_producer_t* producer = (const plugin_screencast_dshow_producer_t*)callback_data;
- if (producer && TMEDIA_PRODUCER(producer)->enc_cb.callback) {
- TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, buffer, size);
- }
- return 0;
- }
- /* ============ Media Producer Interface ================= */
- static int plugin_screencast_dshow_producer_set(tmedia_producer_t *self, const tmedia_param_t* param)
- {
- int ret = 0;
- plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self;
- if(!producer || !param) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(param->value_type == tmedia_pvt_int64) {
- if(tsk_striequals(param->key, "local-hwnd")) {
- DSPRODUCER(producer)->previewHwnd = (INT64)*((int64_t*)param->value);
- if(DSPRODUCER(producer)->grabber && DSPRODUCER(self)->grabber->preview) {
- DSPRODUCER(producer)->grabber->preview->attach(DSPRODUCER(producer)->previewHwnd);
- }
- }
- }
- else if(param->value_type == tmedia_pvt_int32) {
- if(tsk_striequals(param->key, "mute")) {
- producer->mute = (TSK_TO_INT32((uint8_t*)param->value) != 0);
- if(producer->started) {
- if(producer->mute) {
- producer->grabber->pause();
- }
- else {
- producer->grabber->start();
- }
- }
- }
- else if(tsk_striequals(param->key, "create-on-current-thead")) {
- producer->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true;
- }
- else if(tsk_striequals(param->key, "plugin-firefox")) {
- TSK_DEBUG_INFO("'plugin-firefox' ignored for screencast");
- }
- }
- return ret;
- }
- static int plugin_screencast_dshow_producer_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec)
- {
- plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self;
- if(!producer || !codec && codec->plugin) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- TMEDIA_PRODUCER(producer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->out.fps;
- TMEDIA_PRODUCER(producer)->video.width = TMEDIA_CODEC_VIDEO(codec)->out.width;
- TMEDIA_PRODUCER(producer)->video.height = TMEDIA_CODEC_VIDEO(codec)->out.height;
- return 0;
- }
- static int plugin_screencast_dshow_producer_start(tmedia_producer_t* self)
- {
- plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self;
- HRESULT hr = S_OK;
- if (!producer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (producer->started) {
- return 0;
- }
- // create grabber on ALWAYS current thread
- if (!producer->grabber) {
- static BOOL __isDisplayFalse = FALSE;
- static BOOL __isScreenCastTrue = TRUE;
- if(producer->create_on_ui_thread) {
- createOnUIThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastTrue);
- }
- else {
- createOnCurrentThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastTrue);
- }
- if (!producer->grabber) {
- TSK_DEBUG_ERROR("Failed to create grabber");
- return -2;
- }
- }
- // set parameters
- producer->grabber->setCaptureParameters((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height, TMEDIA_PRODUCER(producer)->video.fps);
- // set callback function
- producer->grabber->setCallback(plugin_video_dshow_plugin_cb, producer);
- // attach preview
- if (producer->grabber->preview) {
- if (producer->previewHwnd) {
- producer->grabber->preview->attach(producer->previewHwnd);
- }
- producer->grabber->preview->setSize((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height);
- }
- // start grabber
- if (!producer->mute) {
- producer->grabber->start();
- }
- producer->started = tsk_true;
- return 0;
- }
- static int plugin_screencast_dshow_producer_pause(tmedia_producer_t* self)
- {
- plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self;
- if(!producer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(!producer->grabber) {
- TSK_DEBUG_ERROR("Invalid internal grabber");
- return -2;
- }
- producer->grabber->pause();
- return 0;
- }
- static int plugin_screencast_dshow_producer_stop(tmedia_producer_t* self)
- {
- plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self;
- if(!self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(!producer->started) {
- return 0;
- }
- if(!producer->grabber) {
- TSK_DEBUG_ERROR("Invalid internal grabber");
- return -2;
- }
- producer->grabber->stop();
- producer->started = tsk_false;
- return 0;
- }
- //
- // WaveAPI producer object definition
- //
- /* constructor */
- static tsk_object_t* plugin_screencast_dshow_producer_ctor(tsk_object_t * self, va_list * app)
- {
- CoInitializeEx(NULL, COINIT_MULTITHREADED);
- plugin_screencast_dshow_producer_t *producer = (plugin_screencast_dshow_producer_t *)self;
- if(producer) {
- /* init base */
- tmedia_producer_init(TMEDIA_PRODUCER(producer));
- TMEDIA_PRODUCER(producer)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24
- /* init self with default values*/
- producer->create_on_ui_thread = tsk_true;
- TMEDIA_PRODUCER(producer)->video.fps = 15;
- TMEDIA_PRODUCER(producer)->video.width = 352;
- TMEDIA_PRODUCER(producer)->video.height = 288;
- }
- return self;
- }
- /* destructor */
- static tsk_object_t* plugin_screencast_dshow_producer_dtor(tsk_object_t * self)
- {
- plugin_screencast_dshow_producer_t *producer = (plugin_screencast_dshow_producer_t *)self;
- if(producer) {
- /* stop */
- if(producer->started) {
- plugin_screencast_dshow_producer_stop((tmedia_producer_t*)self);
- }
- /* for safety */
- if(producer->grabber) {
- producer->grabber->setCallback(tsk_null, tsk_null);
- }
- /* deinit base */
- tmedia_producer_deinit(TMEDIA_PRODUCER(producer));
- /* deinit self */
- SAFE_DELETE_PTR(producer->grabber);
- }
- return self;
- }
- /* object definition */
- static const tsk_object_def_t plugin_screencast_dshow_producer_def_s = {
- sizeof(plugin_screencast_dshow_producer_t),
- plugin_screencast_dshow_producer_ctor,
- plugin_screencast_dshow_producer_dtor,
- tsk_null,
- };
- /* plugin definition*/
- static const tmedia_producer_plugin_def_t plugin_screencast_dshow_producer_plugin_def_s = {
- &plugin_screencast_dshow_producer_def_s,
- tmedia_bfcp_video,
- "Microsoft DirectShow producer (ScrenCast)",
- plugin_screencast_dshow_producer_set,
- plugin_screencast_dshow_producer_prepare,
- plugin_screencast_dshow_producer_start,
- plugin_screencast_dshow_producer_pause,
- plugin_screencast_dshow_producer_stop
- };
- const tmedia_producer_plugin_def_t *plugin_screencast_dshow_producer_plugin_def_t = &plugin_screencast_dshow_producer_plugin_def_s;
|