switch_core_media_bug.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490
  1. /*
  2. * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  3. * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
  4. *
  5. * Version: MPL 1.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License Version
  8. * 1.1 (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. * for the specific language governing rights and limitations under the
  15. * License.
  16. *
  17. * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  18. *
  19. * The Initial Developer of the Original Code is
  20. * Anthony Minessale II <anthm@freeswitch.org>
  21. * Portions created by the Initial Developer are Copyright (C)
  22. * the Initial Developer. All Rights Reserved.
  23. *
  24. * Contributor(s):
  25. *
  26. * Anthony Minessale II <anthm@freeswitch.org>
  27. * Michael Jerris <mike@jerris.com>
  28. * Paul D. Tinsley <pdt at jackhammer.org>
  29. *
  30. *
  31. * switch_core_media_bug.c -- Main Core Library (Media Bugs)
  32. *
  33. */
  34. #include "switch.h"
  35. #include "private/switch_core_pvt.h"
  36. static void switch_core_media_bug_destroy(switch_media_bug_t **bug)
  37. {
  38. switch_event_t *event = NULL;
  39. switch_media_bug_t *bp = *bug;
  40. *bug = NULL;
  41. if (bp->text_buffer) {
  42. switch_buffer_destroy(&bp->text_buffer);
  43. switch_safe_free(bp->text_framedata);
  44. }
  45. switch_img_free(&bp->spy_img[0]);
  46. switch_img_free(&bp->spy_img[1]);
  47. if (bp->video_bug_thread) {
  48. switch_status_t st;
  49. int i;
  50. for (i = 0; i < 2; i++) {
  51. void *pop;
  52. switch_image_t *img;
  53. if (bp->spy_video_queue[i]) {
  54. while (switch_queue_trypop(bp->spy_video_queue[i], &pop) == SWITCH_STATUS_SUCCESS && pop) {
  55. img = (switch_image_t *) pop;
  56. switch_img_free(&img);
  57. }
  58. }
  59. }
  60. switch_thread_join(&st, bp->video_bug_thread);
  61. }
  62. if (bp->session && switch_test_flag(bp, SMBF_READ_VIDEO_PATCH) && bp->session->video_read_codec) {
  63. switch_clear_flag(bp->session->video_read_codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING);
  64. }
  65. if (bp->raw_read_buffer) {
  66. switch_buffer_destroy(&bp->raw_read_buffer);
  67. }
  68. if (bp->raw_write_buffer) {
  69. switch_buffer_destroy(&bp->raw_write_buffer);
  70. }
  71. if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_STOP) == SWITCH_STATUS_SUCCESS) {
  72. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bp->function);
  73. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bp->target);
  74. if (bp->session) switch_channel_event_set_data(bp->session->channel, event);
  75. switch_event_fire(&event);
  76. }
  77. }
  78. SWITCH_DECLARE(void) switch_core_media_bug_pause(switch_core_session_t *session)
  79. {
  80. switch_channel_set_flag(session->channel, CF_PAUSE_BUGS);
  81. }
  82. SWITCH_DECLARE(void) switch_core_media_bug_resume(switch_core_session_t *session)
  83. {
  84. switch_channel_clear_flag(session->channel, CF_PAUSE_BUGS);
  85. }
  86. SWITCH_DECLARE(uint32_t) switch_core_media_bug_test_flag(switch_media_bug_t *bug, uint32_t flag)
  87. {
  88. return switch_test_flag(bug, flag);
  89. }
  90. SWITCH_DECLARE(uint32_t) switch_core_media_bug_set_flag(switch_media_bug_t *bug, uint32_t flag)
  91. {
  92. if ((flag & SMBF_PRUNE)) {
  93. switch_clear_flag(bug, SMBF_LOCK);
  94. }
  95. return switch_set_flag(bug, flag);
  96. }
  97. SWITCH_DECLARE(uint32_t) switch_core_media_bug_clear_flag(switch_media_bug_t *bug, uint32_t flag)
  98. {
  99. return switch_clear_flag(bug, flag);
  100. }
  101. SWITCH_DECLARE(void) switch_core_media_bug_set_media_params(switch_media_bug_t *bug, switch_mm_t *mm)
  102. {
  103. bug->mm = *mm;
  104. }
  105. SWITCH_DECLARE(void) switch_core_media_bug_get_media_params(switch_media_bug_t *bug, switch_mm_t *mm)
  106. {
  107. *mm = bug->mm;
  108. }
  109. SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(switch_media_bug_t *bug)
  110. {
  111. return bug->session;
  112. }
  113. SWITCH_DECLARE(const char *) switch_core_media_bug_get_text(switch_media_bug_t *bug)
  114. {
  115. return bug->text_framedata;
  116. }
  117. SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_video_ping_frame(switch_media_bug_t *bug)
  118. {
  119. return bug->video_ping_frame;
  120. }
  121. SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_write_replace_frame(switch_media_bug_t *bug)
  122. {
  123. return bug->write_replace_frame_in;
  124. }
  125. SWITCH_DECLARE(void) switch_core_media_bug_set_write_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame)
  126. {
  127. bug->write_replace_frame_out = frame;
  128. }
  129. SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_read_replace_frame(switch_media_bug_t *bug)
  130. {
  131. return bug->read_replace_frame_in;
  132. }
  133. SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_native_read_frame(switch_media_bug_t *bug)
  134. {
  135. return bug->native_read_frame;
  136. }
  137. SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_native_write_frame(switch_media_bug_t *bug)
  138. {
  139. return bug->native_write_frame;
  140. }
  141. SWITCH_DECLARE(void) switch_core_media_bug_set_read_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame)
  142. {
  143. bug->read_replace_frame_out = frame;
  144. }
  145. SWITCH_DECLARE(void) switch_core_media_bug_set_read_demux_frame(switch_media_bug_t *bug, switch_frame_t *frame)
  146. {
  147. bug->read_demux_frame = frame;
  148. }
  149. SWITCH_DECLARE(void *) switch_core_media_bug_get_user_data(switch_media_bug_t *bug)
  150. {
  151. return bug->user_data;
  152. }
  153. SWITCH_DECLARE(void) switch_core_media_bug_flush(switch_media_bug_t *bug)
  154. {
  155. bug->record_pre_buffer_count = 0;
  156. if (bug->raw_read_buffer) {
  157. switch_mutex_lock(bug->read_mutex);
  158. switch_buffer_zero(bug->raw_read_buffer);
  159. switch_mutex_unlock(bug->read_mutex);
  160. }
  161. if (bug->raw_write_buffer) {
  162. switch_mutex_lock(bug->write_mutex);
  163. switch_buffer_zero(bug->raw_write_buffer);
  164. switch_mutex_unlock(bug->write_mutex);
  165. }
  166. bug->record_frame_size = 0;
  167. bug->record_pre_buffer_count = 0;
  168. }
  169. SWITCH_DECLARE(void) switch_core_media_bug_inuse(switch_media_bug_t *bug, switch_size_t *readp, switch_size_t *writep)
  170. {
  171. if (switch_test_flag(bug, SMBF_READ_STREAM)) {
  172. switch_mutex_lock(bug->read_mutex);
  173. *readp = bug->raw_read_buffer ? switch_buffer_inuse(bug->raw_read_buffer) : 0;
  174. switch_mutex_unlock(bug->read_mutex);
  175. } else {
  176. *readp = 0;
  177. }
  178. if (switch_test_flag(bug, SMBF_WRITE_STREAM)) {
  179. switch_mutex_lock(bug->write_mutex);
  180. *writep = bug->raw_write_buffer ? switch_buffer_inuse(bug->raw_write_buffer) : 0;
  181. switch_mutex_unlock(bug->write_mutex);
  182. } else {
  183. *writep = 0;
  184. }
  185. }
  186. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_set_pre_buffer_framecount(switch_media_bug_t *bug, uint32_t framecount)
  187. {
  188. bug->record_pre_buffer_max = framecount;
  189. return SWITCH_STATUS_SUCCESS;
  190. }
  191. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(switch_media_bug_t *bug, switch_frame_t *frame, switch_bool_t fill)
  192. {
  193. switch_size_t bytes = 0, datalen = 0;
  194. int16_t *dp, *fp;
  195. uint32_t x;
  196. size_t rlen = 0;
  197. size_t wlen = 0;
  198. uint32_t blen;
  199. switch_codec_implementation_t read_impl = { 0 };
  200. int16_t *tp;
  201. switch_size_t do_read = 0, do_write = 0, has_read = 0, has_write = 0, fill_read = 0, fill_write = 0;
  202. switch_core_session_get_read_impl(bug->session, &read_impl);
  203. bytes = read_impl.decoded_bytes_per_packet;
  204. if (frame->buflen < bytes) {
  205. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "%s frame buffer too small!\n",
  206. switch_channel_get_name(bug->session->channel));
  207. return SWITCH_STATUS_FALSE;
  208. }
  209. if ((!bug->raw_read_buffer && (!bug->raw_write_buffer || !switch_test_flag(bug, SMBF_WRITE_STREAM)))) {
  210. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR,
  211. "%s Buffer Error (raw_read_buffer=%p, raw_write_buffer=%p, read=%s, write=%s)\n",
  212. switch_channel_get_name(bug->session->channel),
  213. (void *)bug->raw_read_buffer, (void *)bug->raw_write_buffer,
  214. switch_test_flag(bug, SMBF_READ_STREAM) ? "yes" : "no",
  215. switch_test_flag(bug, SMBF_WRITE_STREAM) ? "yes" : "no");
  216. return SWITCH_STATUS_FALSE;
  217. }
  218. frame->flags = 0;
  219. frame->datalen = 0;
  220. if (switch_test_flag(bug, SMBF_READ_STREAM)) {
  221. has_read = 1;
  222. switch_mutex_lock(bug->read_mutex);
  223. do_read = switch_buffer_inuse(bug->raw_read_buffer);
  224. switch_mutex_unlock(bug->read_mutex);
  225. }
  226. if (switch_test_flag(bug, SMBF_WRITE_STREAM)) {
  227. has_write = 1;
  228. switch_mutex_lock(bug->write_mutex);
  229. do_write = switch_buffer_inuse(bug->raw_write_buffer);
  230. switch_mutex_unlock(bug->write_mutex);
  231. }
  232. if (bug->record_frame_size && bug->record_pre_buffer_max && (do_read || do_write) && bug->record_pre_buffer_count < bug->record_pre_buffer_max) {
  233. bug->record_pre_buffer_count++;
  234. return SWITCH_STATUS_FALSE;
  235. } else {
  236. uint32_t frame_size;
  237. switch_codec_implementation_t read_impl = { 0 };
  238. switch_core_session_get_read_impl(bug->session, &read_impl);
  239. frame_size = read_impl.decoded_bytes_per_packet;
  240. bug->record_frame_size = frame_size;
  241. }
  242. if (bug->record_frame_size && do_write > do_read && do_write > (bug->record_frame_size * 2)) {
  243. switch_mutex_lock(bug->write_mutex);
  244. switch_buffer_toss(bug->raw_write_buffer, bug->record_frame_size);
  245. do_write = switch_buffer_inuse(bug->raw_write_buffer);
  246. switch_mutex_unlock(bug->write_mutex);
  247. }
  248. if ((has_read && !do_read)) {
  249. fill_read = 1;
  250. }
  251. if ((has_write && !do_write)) {
  252. fill_write = 1;
  253. }
  254. if (bug->record_frame_size) {
  255. if ((do_read && do_read < bug->record_frame_size) || (do_write && do_write < bug->record_frame_size)) {
  256. return SWITCH_STATUS_FALSE;
  257. }
  258. if (do_read && do_read > bug->record_frame_size) {
  259. do_read = bug->record_frame_size;
  260. }
  261. if (do_write && do_write > bug->record_frame_size) {
  262. do_write = bug->record_frame_size;
  263. }
  264. }
  265. if ((fill_read && fill_write) || (fill && (fill_read || fill_write))) {
  266. return SWITCH_STATUS_FALSE;
  267. }
  268. if (do_read && do_read > SWITCH_RECOMMENDED_BUFFER_SIZE) {
  269. do_read = 1280;
  270. }
  271. if (do_write && do_write > SWITCH_RECOMMENDED_BUFFER_SIZE) {
  272. do_write = 1280;
  273. }
  274. if (do_read) {
  275. switch_mutex_lock(bug->read_mutex);
  276. frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, do_read);
  277. if (frame->datalen != do_read) {
  278. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "Framing Error Reading!\n");
  279. switch_core_media_bug_flush(bug);
  280. switch_mutex_unlock(bug->read_mutex);
  281. return SWITCH_STATUS_FALSE;
  282. }
  283. switch_mutex_unlock(bug->read_mutex);
  284. } else if (fill_read) {
  285. frame->datalen = (uint32_t)bytes;
  286. memset(frame->data, 255, frame->datalen);
  287. }
  288. if (do_write) {
  289. switch_assert(bug->raw_write_buffer);
  290. switch_mutex_lock(bug->write_mutex);
  291. datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, do_write);
  292. if (datalen != do_write) {
  293. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, "Framing Error Writing!\n");
  294. switch_core_media_bug_flush(bug);
  295. switch_mutex_unlock(bug->write_mutex);
  296. return SWITCH_STATUS_FALSE;
  297. }
  298. switch_mutex_unlock(bug->write_mutex);
  299. } else if (fill_write) {
  300. datalen = bytes;
  301. memset(bug->data, 255, datalen);
  302. }
  303. tp = bug->tmp;
  304. dp = (int16_t *) bug->data;
  305. fp = (int16_t *) frame->data;
  306. rlen = frame->datalen / 2;
  307. wlen = datalen / 2;
  308. blen = (uint32_t)(bytes / 2);
  309. if (switch_test_flag(bug, SMBF_STEREO)) {
  310. int16_t *left, *right;
  311. size_t left_len, right_len;
  312. if (switch_test_flag(bug, SMBF_STEREO_SWAP)) {
  313. left = dp; /* write stream */
  314. left_len = wlen;
  315. right = fp; /* read stream */
  316. right_len = rlen;
  317. } else {
  318. left = fp; /* read stream */
  319. left_len = rlen;
  320. right = dp; /* write stream */
  321. right_len = wlen;
  322. }
  323. for (x = 0; x < blen; x++) {
  324. if (x < left_len) {
  325. *(tp++) = *(left + x);
  326. } else {
  327. *(tp++) = 0;
  328. }
  329. if (x < right_len) {
  330. *(tp++) = *(right + x);
  331. } else {
  332. *(tp++) = 0;
  333. }
  334. }
  335. memcpy(frame->data, bug->tmp, bytes * 2);
  336. } else {
  337. for (x = 0; x < blen; x++) {
  338. int32_t w = 0, r = 0, z = 0;
  339. if (x < rlen) {
  340. r = (int32_t) * (fp + x);
  341. }
  342. if (x < wlen) {
  343. w = (int32_t) * (dp + x);
  344. }
  345. z = w + r;
  346. if (z > SWITCH_SMAX || z < SWITCH_SMIN) {
  347. if (r) z += (r/2);
  348. if (w) z += (w/2);
  349. }
  350. switch_normalize_to_16bit(z);
  351. *(fp + x) = (int16_t) z;
  352. }
  353. }
  354. frame->datalen = (uint32_t)bytes;
  355. frame->samples = (uint32_t)(bytes / sizeof(int16_t) / read_impl.number_of_channels);
  356. frame->rate = read_impl.actual_samples_per_second;
  357. frame->codec = NULL;
  358. if (switch_test_flag(bug, SMBF_STEREO)) {
  359. frame->datalen *= 2;
  360. frame->channels = 2;
  361. } else {
  362. frame->channels = read_impl.number_of_channels;
  363. }
  364. return SWITCH_STATUS_SUCCESS;
  365. }
  366. SWITCH_DECLARE(switch_vid_spy_fmt_t) switch_media_bug_parse_spy_fmt(const char *name)
  367. {
  368. if (zstr(name)) goto end;
  369. if (!strcasecmp(name, "dual-crop")) {
  370. return SPY_DUAL_CROP;
  371. }
  372. if (!strcasecmp(name, "lower-right-large")) {
  373. return SPY_LOWER_RIGHT_LARGE;
  374. }
  375. end:
  376. return SPY_LOWER_RIGHT_SMALL;
  377. }
  378. SWITCH_DECLARE(void) switch_media_bug_set_spy_fmt(switch_media_bug_t *bug, switch_vid_spy_fmt_t spy_fmt)
  379. {
  380. bug->spy_fmt = spy_fmt;
  381. }
  382. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_patch_spy_frame(switch_media_bug_t *bug, switch_image_t *img, switch_rw_t rw)
  383. {
  384. switch_queue_t *spy_q = NULL;
  385. int w = 0, h = 0;
  386. void *pop;
  387. int i;
  388. for (i = 0; i < 2; i++) {
  389. if (!bug->spy_video_queue[i]) {
  390. switch_queue_create(&bug->spy_video_queue[i], SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(bug->session));
  391. }
  392. }
  393. spy_q = bug->spy_video_queue[rw];
  394. while(switch_queue_size(spy_q) > 0) {
  395. if (switch_queue_trypop(spy_q, &pop) == SWITCH_STATUS_SUCCESS) {
  396. switch_img_free(&bug->spy_img[rw]);
  397. if (!(bug->spy_img[rw] = (switch_image_t *) pop)) {
  398. break;
  399. }
  400. }
  401. }
  402. w = img->d_w;
  403. h = img->d_h;
  404. if (bug->spy_img[rw]) {
  405. switch (bug->spy_fmt) {
  406. case SPY_DUAL_CROP:
  407. {
  408. switch_image_t *spy_tmp = NULL;
  409. switch_image_t *img_tmp = NULL;
  410. switch_image_t *img_dup = NULL;
  411. int x = 0, y = 0;
  412. float aspect169 = (float)1920 / 1080;
  413. switch_rgb_color_t bgcolor = { 0 };
  414. if ((float)w/h == aspect169) {
  415. if ((float)bug->spy_img[rw]->d_w / bug->spy_img[rw]->d_h == aspect169) {
  416. spy_tmp = switch_img_copy_rect(bug->spy_img[rw], bug->spy_img[rw]->d_w / 4, 0, bug->spy_img[rw]->d_w / 2, bug->spy_img[rw]->d_h);
  417. } else {
  418. switch_img_copy(bug->spy_img[rw], &spy_tmp);
  419. }
  420. } else {
  421. if ((float)bug->spy_img[rw]->d_w / bug->spy_img[rw]->d_h == aspect169) {
  422. spy_tmp = switch_img_copy_rect(bug->spy_img[rw], bug->spy_img[rw]->d_w / 6, 0, bug->spy_img[rw]->d_w / 4, bug->spy_img[rw]->d_h);
  423. } else {
  424. spy_tmp = switch_img_copy_rect(bug->spy_img[rw], bug->spy_img[rw]->d_w / 4, 0, bug->spy_img[rw]->d_w / 2, bug->spy_img[rw]->d_h);
  425. }
  426. }
  427. switch_img_copy(img, &img_dup);
  428. img_tmp = switch_img_copy_rect(img_dup, w / 4, 0, w / 2, h);
  429. switch_img_fit(&spy_tmp, w / 2, h, SWITCH_FIT_SIZE);
  430. switch_img_fit(&img_tmp, w / 2, h, SWITCH_FIT_SIZE);
  431. switch_color_set_rgb(&bgcolor, "#000000");
  432. switch_img_fill(img, 0, 0, img->d_w, img->d_h, &bgcolor);
  433. switch_img_find_position(POS_CENTER_MID, w / 2, h, img_tmp->d_w, img_tmp->d_h, &x, &y);
  434. switch_img_patch(img, img_tmp, x, y);
  435. switch_img_find_position(POS_CENTER_MID, w / 2, h, spy_tmp->d_w, spy_tmp->d_h, &x, &y);
  436. switch_img_patch(img, spy_tmp, x + w / 2, y);
  437. switch_img_free(&img_tmp);
  438. switch_img_free(&img_dup);
  439. switch_img_free(&spy_tmp);
  440. }
  441. break;
  442. case SPY_LOWER_RIGHT_SMALL:
  443. case SPY_LOWER_RIGHT_LARGE:
  444. default:
  445. {
  446. float scaler = 0.125f;
  447. int spyw, spyh;
  448. if (bug->spy_fmt == SPY_LOWER_RIGHT_LARGE) {
  449. scaler = 0.25f;
  450. }
  451. spyw = (int) (float)w * scaler;
  452. spyh = (int) (float)h * scaler;
  453. if (bug->spy_img[rw]->d_w != spyw || bug->spy_img[rw]->d_h != spyh) {
  454. switch_image_t *tmp_img = NULL;
  455. switch_img_scale(bug->spy_img[rw], &tmp_img, spyw, spyh);
  456. switch_img_free(&bug->spy_img[rw]);
  457. bug->spy_img[rw] = tmp_img;
  458. }
  459. switch_img_patch(img, bug->spy_img[rw], w - spyw, h - spyh);
  460. }
  461. break;
  462. }
  463. return SWITCH_STATUS_SUCCESS;
  464. }
  465. return SWITCH_STATUS_FALSE;
  466. }
  467. static int flush_video_queue(switch_queue_t *q, int min)
  468. {
  469. void *pop;
  470. if (switch_queue_size(q) > min) {
  471. while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) {
  472. switch_image_t *img = (switch_image_t *) pop;
  473. switch_img_free(&img);
  474. if (min && switch_queue_size(q) <= min) {
  475. break;
  476. }
  477. }
  478. }
  479. return switch_queue_size(q);
  480. }
  481. static void *SWITCH_THREAD_FUNC video_bug_thread(switch_thread_t *thread, void *obj)
  482. {
  483. switch_media_bug_t *bug = (switch_media_bug_t *) obj;
  484. switch_queue_t *main_q = NULL, *other_q = NULL;
  485. switch_image_t *IMG = NULL, *img = NULL, *other_img = NULL;
  486. void *pop, *other_pop;
  487. uint8_t *buf;
  488. switch_size_t buflen = SWITCH_RTP_MAX_BUF_LEN;
  489. switch_frame_t frame = { 0 };
  490. switch_timer_t timer = { 0 };
  491. switch_mm_t mm = { 0 };
  492. int vw = 1280;
  493. int vh = 720;
  494. int last_w = 0, last_h = 0, other_last_w = 0, other_last_h = 0;
  495. switch_fps_t fps_data = { 0 };
  496. float fps;
  497. switch_rgb_color_t color = { 0 };
  498. switch_color_set_rgb(&color, "#000000");
  499. buf = switch_core_session_alloc(bug->session, buflen);
  500. frame.packet = buf;
  501. frame.data = buf + 12;
  502. frame.packetlen = buflen;
  503. frame.buflen = buflen - 12;
  504. frame.flags = SFF_RAW_RTP;
  505. if (switch_test_flag(bug, SMBF_READ_VIDEO_STREAM)) {
  506. main_q = bug->read_video_queue;
  507. if (switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM)) {
  508. other_q = bug->write_video_queue;
  509. }
  510. } else if (switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM)) {
  511. main_q = bug->write_video_queue;
  512. } else {
  513. return NULL;
  514. }
  515. switch_core_media_bug_get_media_params(bug, &mm);
  516. if (mm.vw) vw = mm.vw;
  517. if (mm.vh) vh = mm.vh;
  518. if (mm.fps) {
  519. fps = mm.fps;
  520. } else {
  521. fps = 15;
  522. }
  523. switch_calc_video_fps(&fps_data, fps);
  524. switch_core_timer_init(&timer, "soft", fps_data.ms, fps_data.samples, NULL);
  525. while (bug->ready) {
  526. int w = 0, h = 0, ok = 1, new_main = 0, new_other = 0, new_canvas = 0;
  527. switch_core_timer_next(&timer);
  528. if (!switch_channel_test_flag(bug->session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bug, SMBF_ANSWER_REQ)) {
  529. flush_video_queue(main_q, 0);
  530. if (other_q) flush_video_queue(other_q, 0);
  531. continue;
  532. }
  533. flush_video_queue(main_q, 1);
  534. w = vw / 2;
  535. h = vh;
  536. if (switch_queue_trypop(main_q, &pop) == SWITCH_STATUS_SUCCESS) {
  537. switch_img_free(&img);
  538. if (!pop) {
  539. goto end;
  540. }
  541. img = (switch_image_t *) pop;
  542. new_main = 1;
  543. if (IMG && !(last_w == img->d_w && last_h == img->d_h)) {
  544. switch_img_fill(IMG, 0, 0, w, h, &color);
  545. }
  546. last_w = img->d_w;
  547. last_h = img->d_h;
  548. }
  549. if (other_q) {
  550. flush_video_queue(other_q, 1);
  551. if (switch_queue_trypop(other_q, &other_pop) == SWITCH_STATUS_SUCCESS) {
  552. switch_img_free(&other_img);
  553. other_img = (switch_image_t *) other_pop;
  554. if (IMG && !(other_last_w == other_img->d_w && other_last_h == other_img->d_h)) {
  555. switch_img_fill(IMG, w, 0, w, h, &color);
  556. }
  557. other_last_w = other_img->d_w;
  558. other_last_h = other_img->d_h;
  559. new_other = 1;
  560. }
  561. if (img && new_main) {
  562. switch_img_fit(&img, w, h, SWITCH_FIT_SIZE);
  563. }
  564. if (other_img && new_other) {
  565. switch_img_fit(&other_img, w, h, SWITCH_FIT_SIZE);
  566. }
  567. if (!IMG) {
  568. IMG = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, vw, vh, 1);
  569. new_canvas = 1;
  570. switch_img_fill(IMG, 0, 0, IMG->d_w, IMG->d_h, &color);
  571. }
  572. }
  573. if (IMG) {
  574. if (img && (new_canvas || new_main)) {
  575. int x = 0, y = 0;
  576. switch_img_find_position(POS_CENTER_MID, w, h, img->d_w, img->d_h, &x, &y);
  577. switch_img_patch(IMG, img, x, y);
  578. }
  579. if (other_img && (new_canvas || new_other)) {
  580. int x = 0, y = 0;
  581. switch_img_find_position(POS_CENTER_MID, w, h, other_img->d_w, other_img->d_h, &x, &y);
  582. switch_img_patch(IMG, other_img, w + x, y);
  583. }
  584. }
  585. if (IMG || img) {
  586. switch_thread_rwlock_rdlock(bug->session->bug_rwlock);
  587. frame.img = other_q ? IMG : img;
  588. bug->video_ping_frame = &frame;
  589. if (bug->callback) {
  590. if (bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_STREAM_VIDEO_PING) == SWITCH_FALSE
  591. || (bug->stop_time && bug->stop_time <= switch_epoch_time_now(NULL))) {
  592. ok = SWITCH_FALSE;
  593. }
  594. }
  595. bug->video_ping_frame = NULL;
  596. switch_thread_rwlock_unlock(bug->session->bug_rwlock);
  597. if (!ok) {
  598. switch_set_flag(bug, SMBF_PRUNE);
  599. goto end;
  600. }
  601. }
  602. }
  603. end:
  604. switch_core_timer_destroy(&timer);
  605. switch_img_free(&IMG);
  606. switch_img_free(&img);
  607. switch_img_free(&other_img);
  608. while (switch_queue_trypop(main_q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
  609. img = (switch_image_t *) pop;
  610. switch_img_free(&img);
  611. }
  612. if (other_q) {
  613. while (switch_queue_trypop(other_q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
  614. img = (switch_image_t *) pop;
  615. switch_img_free(&img);
  616. }
  617. }
  618. return NULL;
  619. }
  620. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_push_spy_frame(switch_media_bug_t *bug, switch_frame_t *frame, switch_rw_t rw)
  621. {
  622. switch_assert(bug);
  623. switch_assert(frame);
  624. if (bug->spy_video_queue[rw] && frame->img) {
  625. switch_image_t *img = NULL;
  626. switch_img_copy(frame->img, &img);
  627. if (img) {
  628. switch_queue_push(bug->spy_video_queue[rw], img);
  629. return SWITCH_STATUS_SUCCESS;
  630. }
  631. }
  632. return SWITCH_STATUS_FALSE;
  633. }
  634. #define MAX_BUG_BUFFER 1024 * 512
  635. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t *session,
  636. const char *function,
  637. const char *target,
  638. switch_media_bug_callback_t callback,
  639. void *user_data, time_t stop_time,
  640. switch_media_bug_flag_t flags,
  641. switch_media_bug_t **new_bug)
  642. {
  643. switch_media_bug_t *bug, *bp;
  644. switch_size_t bytes;
  645. switch_event_t *event;
  646. int tap_only = 1, punt = 0, added = 0;
  647. const char *p;
  648. if (!zstr(function)) {
  649. if ((flags & SMBF_ONE_ONLY)) {
  650. switch_thread_rwlock_wrlock(session->bug_rwlock);
  651. for (bp = session->bugs; bp; bp = bp->next) {
  652. if (!zstr(bp->function) && !strcasecmp(function, bp->function)) {
  653. punt = 1;
  654. break;
  655. }
  656. }
  657. switch_thread_rwlock_unlock(session->bug_rwlock);
  658. }
  659. }
  660. if (punt) {
  661. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
  662. return SWITCH_STATUS_GENERR;
  663. }
  664. if (!switch_channel_media_ready(session->channel)) {
  665. if (switch_channel_pre_answer(session->channel) != SWITCH_STATUS_SUCCESS) {
  666. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media. Media bug add failed.\n");
  667. return SWITCH_STATUS_FALSE;
  668. }
  669. }
  670. *new_bug = NULL;
  671. if ((p = switch_channel_get_variable(session->channel, "media_bug_answer_req")) && switch_true(p)) {
  672. flags |= SMBF_ANSWER_REQ;
  673. }
  674. #if 0
  675. if (flags & SMBF_WRITE_REPLACE) {
  676. switch_thread_rwlock_wrlock(session->bug_rwlock);
  677. for (bp = session->bugs; bp; bp = bp->next) {
  678. if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
  679. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
  680. switch_thread_rwlock_unlock(session->bug_rwlock);
  681. return SWITCH_STATUS_GENERR;
  682. }
  683. }
  684. switch_thread_rwlock_unlock(session->bug_rwlock);
  685. }
  686. if (flags & SMBF_READ_REPLACE) {
  687. switch_thread_rwlock_wrlock(session->bug_rwlock);
  688. for (bp = session->bugs; bp; bp = bp->next) {
  689. if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
  690. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
  691. switch_thread_rwlock_unlock(session->bug_rwlock);
  692. return SWITCH_STATUS_GENERR;
  693. }
  694. }
  695. switch_thread_rwlock_unlock(session->bug_rwlock);
  696. }
  697. #endif
  698. if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
  699. return SWITCH_STATUS_MEMERR;
  700. }
  701. bug->callback = callback;
  702. bug->user_data = user_data;
  703. bug->session = session;
  704. bug->flags = flags;
  705. bug->function = "N/A";
  706. bug->target = "N/A";
  707. switch_core_session_get_read_impl(session, &bug->read_impl);
  708. switch_core_session_get_write_impl(session, &bug->write_impl);
  709. if (function) {
  710. bug->function = switch_core_session_strdup(session, function);
  711. }
  712. if (target) {
  713. bug->target = switch_core_session_strdup(session, target);
  714. }
  715. bug->stop_time = stop_time;
  716. if (!(bytes = bug->read_impl.decoded_bytes_per_packet)) {
  717. bytes = 320;
  718. }
  719. if (!bug->flags) {
  720. bug->flags = (SMBF_READ_STREAM | SMBF_WRITE_STREAM);
  721. }
  722. if (switch_test_flag(bug, SMBF_READ_STREAM) || switch_test_flag(bug, SMBF_READ_PING)) {
  723. switch_buffer_create_dynamic(&bug->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER);
  724. switch_mutex_init(&bug->read_mutex, SWITCH_MUTEX_NESTED, session->pool);
  725. }
  726. bytes = bug->write_impl.decoded_bytes_per_packet;
  727. if (switch_test_flag(bug, SMBF_WRITE_STREAM)) {
  728. switch_buffer_create_dynamic(&bug->raw_write_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER);
  729. switch_mutex_init(&bug->write_mutex, SWITCH_MUTEX_NESTED, session->pool);
  730. }
  731. if ((bug->flags & SMBF_THREAD_LOCK)) {
  732. bug->thread_id = switch_thread_self();
  733. }
  734. if (switch_test_flag(bug, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM) || switch_test_flag(bug, SMBF_READ_VIDEO_PING) || switch_test_flag(bug, SMBF_WRITE_VIDEO_PING)) {
  735. switch_channel_set_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
  736. if (switch_test_flag(bug, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bug, SMBF_READ_VIDEO_PING)) {
  737. switch_channel_set_flag_recursive(session->channel, CF_VIDEO_READ_TAPPED);
  738. }
  739. if (switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM) || switch_test_flag(bug, SMBF_WRITE_VIDEO_PING)) {
  740. switch_channel_set_flag_recursive(session->channel, CF_VIDEO_WRITE_TAPPED);
  741. }
  742. }
  743. if (switch_test_flag(bug, SMBF_SPY_VIDEO_STREAM) || switch_core_media_bug_test_flag(bug, SMBF_SPY_VIDEO_STREAM_BLEG)) {
  744. switch_queue_create(&bug->spy_video_queue[0], SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
  745. switch_queue_create(&bug->spy_video_queue[1], SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
  746. }
  747. if ((switch_test_flag(bug, SMBF_READ_TEXT_STREAM))) {
  748. switch_buffer_create_dynamic(&bug->text_buffer, 512, 1024, 0);
  749. switch_zmalloc(bug->text_framedata, 1024);
  750. bug->text_framesize = 1024;
  751. }
  752. if ((switch_test_flag(bug, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM))) {
  753. switch_memory_pool_t *pool = switch_core_session_get_pool(session);
  754. if (switch_test_flag(bug, SMBF_READ_VIDEO_STREAM)) {
  755. switch_queue_create(&bug->read_video_queue, SWITCH_CORE_QUEUE_LEN, pool);
  756. }
  757. if (switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM)) {
  758. switch_queue_create(&bug->write_video_queue, SWITCH_CORE_QUEUE_LEN, pool);
  759. }
  760. }
  761. if (bug->callback) {
  762. switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT);
  763. if (result == SWITCH_FALSE) {
  764. switch_core_media_bug_destroy(&bug);
  765. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error attaching BUG to %s\n",
  766. switch_channel_get_name(session->channel));
  767. return SWITCH_STATUS_GENERR;
  768. }
  769. }
  770. bug->ready = 1;
  771. if ((switch_test_flag(bug, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM))) {
  772. switch_threadattr_t *thd_attr = NULL;
  773. switch_memory_pool_t *pool = switch_core_session_get_pool(session);
  774. switch_threadattr_create(&thd_attr, pool);
  775. switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
  776. switch_thread_create(&bug->video_bug_thread, thd_attr, video_bug_thread, bug, pool);
  777. }
  778. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attaching BUG to %s\n", switch_channel_get_name(session->channel));
  779. switch_thread_rwlock_wrlock(session->bug_rwlock);
  780. if (!session->bugs) {
  781. session->bugs = bug;
  782. added = 1;
  783. }
  784. if (!added && switch_test_flag(bug, SMBF_FIRST)) {
  785. bug->next = session->bugs;
  786. session->bugs = bug;
  787. added = 1;
  788. }
  789. for(bp = session->bugs; bp; bp = bp->next) {
  790. if (bp->ready && !switch_test_flag(bp, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp, SMBF_TAP_NATIVE_WRITE)) {
  791. tap_only = 0;
  792. }
  793. if (!added && !bp->next) {
  794. bp->next = bug;
  795. break;
  796. }
  797. }
  798. switch_thread_rwlock_unlock(session->bug_rwlock);
  799. *new_bug = bug;
  800. if (tap_only) {
  801. switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
  802. } else {
  803. switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
  804. }
  805. if (switch_test_flag(bug, SMBF_READ_VIDEO_PATCH) && session->video_read_codec) {
  806. switch_set_flag(session->video_read_codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING);
  807. }
  808. if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_START) == SWITCH_STATUS_SUCCESS) {
  809. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function);
  810. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target);
  811. switch_channel_event_set_data(session->channel, event);
  812. switch_event_fire(&event);
  813. }
  814. switch_core_media_hard_mute(session, SWITCH_FALSE);
  815. return SWITCH_STATUS_SUCCESS;
  816. }
  817. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_flush_all(switch_core_session_t *session)
  818. {
  819. switch_media_bug_t *bp;
  820. if (session->bugs) {
  821. switch_thread_rwlock_wrlock(session->bug_rwlock);
  822. for (bp = session->bugs; bp; bp = bp->next) {
  823. switch_core_media_bug_flush(bp);
  824. }
  825. switch_thread_rwlock_unlock(session->bug_rwlock);
  826. return SWITCH_STATUS_SUCCESS;
  827. }
  828. return SWITCH_STATUS_FALSE;
  829. }
  830. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_callback(switch_core_session_t *orig_session, switch_core_session_t *new_session,
  831. switch_media_bug_callback_t callback, void * (*user_data_dup_func) (switch_core_session_t *, void *))
  832. {
  833. switch_media_bug_t *new_bug = NULL, *cur = NULL, *bp = NULL, *last = NULL, *old_last_next = NULL, *old_bugs = NULL;
  834. int total = 0;
  835. if (!switch_channel_media_ready(new_session->channel)) {
  836. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session), SWITCH_LOG_WARNING, "Cannot transfer media bugs to a channel with no media.\n");
  837. return SWITCH_STATUS_FALSE;
  838. }
  839. switch_thread_rwlock_wrlock(orig_session->bug_rwlock);
  840. bp = orig_session->bugs;
  841. while (bp) {
  842. cur = bp;
  843. bp = bp->next;
  844. if (cur->callback == callback) {
  845. if (last) {
  846. old_last_next = last->next;
  847. last->next = cur->next;
  848. } else {
  849. old_bugs = orig_session->bugs;
  850. orig_session->bugs = cur->next;
  851. }
  852. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session), SWITCH_LOG_DEBUG, "Transfering %s from %s to %s\n", cur->target,
  853. switch_core_session_get_name(orig_session), switch_core_session_get_name(new_session));
  854. if ((switch_core_media_bug_add(new_session, cur->function, cur->target, cur->callback,
  855. user_data_dup_func(new_session, cur->user_data),
  856. cur->stop_time, cur->flags, &new_bug) == SWITCH_STATUS_SUCCESS)) {
  857. switch_core_media_bug_destroy(&cur);
  858. total++;
  859. } else {
  860. /* Call the dup function again to revert to original session */
  861. user_data_dup_func(orig_session, cur->user_data);
  862. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session), SWITCH_LOG_DEBUG, "Adding a bug failed: abort transfering %s from %s to %s\n", cur->target,
  863. switch_core_session_get_name(orig_session), switch_core_session_get_name(new_session));
  864. /* Put the old bug back to the original session's list of bugs */
  865. if (last) {
  866. last->next = old_last_next;
  867. } else {
  868. orig_session->bugs = old_bugs;
  869. }
  870. last = cur;
  871. }
  872. } else {
  873. last = cur;
  874. }
  875. }
  876. if (!orig_session->bugs && switch_core_codec_ready(&orig_session->bug_codec)) {
  877. switch_core_codec_destroy(&orig_session->bug_codec);
  878. }
  879. switch_thread_rwlock_unlock(orig_session->bug_rwlock);
  880. return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
  881. }
  882. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_pop(switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop)
  883. {
  884. switch_media_bug_t *bp;
  885. if (orig_session->bugs) {
  886. switch_thread_rwlock_wrlock(orig_session->bug_rwlock);
  887. for (bp = orig_session->bugs; bp; bp = bp->next) {
  888. if (!strcmp(bp->function, function)) {
  889. switch_set_flag(bp, SMBF_LOCK);
  890. break;
  891. }
  892. }
  893. switch_thread_rwlock_unlock(orig_session->bug_rwlock);
  894. if (bp) {
  895. *pop = bp;
  896. return SWITCH_STATUS_SUCCESS;
  897. } else {
  898. *pop = NULL;
  899. }
  900. }
  901. return SWITCH_STATUS_FALSE;
  902. }
  903. SWITCH_DECLARE(uint32_t) switch_core_media_bug_count(switch_core_session_t *orig_session, const char *function)
  904. {
  905. switch_media_bug_t *bp;
  906. uint32_t x = 0;
  907. if (orig_session->bugs) {
  908. switch_thread_rwlock_rdlock(orig_session->bug_rwlock);
  909. for (bp = orig_session->bugs; bp; bp = bp->next) {
  910. if (!switch_test_flag(bp, SMBF_PRUNE) && !switch_test_flag(bp, SMBF_LOCK) && !strcmp(bp->function, function)) {
  911. x++;
  912. }
  913. }
  914. switch_thread_rwlock_unlock(orig_session->bug_rwlock);
  915. }
  916. return x;
  917. }
  918. SWITCH_DECLARE(uint32_t) switch_core_media_bug_patch_video(switch_core_session_t *orig_session, switch_frame_t *frame)
  919. {
  920. switch_media_bug_t *bp;
  921. uint32_t x = 0, ok = SWITCH_TRUE, prune = 0;
  922. if (orig_session->bugs) {
  923. switch_thread_rwlock_rdlock(orig_session->bug_rwlock);
  924. for (bp = orig_session->bugs; bp; bp = bp->next) {
  925. if (!switch_test_flag(bp, SMBF_PRUNE) && !switch_test_flag(bp, SMBF_LOCK) && !strcmp(bp->function, "patch:video")) {
  926. if (bp->ready && frame->img && switch_test_flag(bp, SMBF_VIDEO_PATCH)) {
  927. bp->video_ping_frame = frame;
  928. if (bp->callback) {
  929. if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_VIDEO_PATCH) == SWITCH_FALSE
  930. || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
  931. ok = SWITCH_FALSE;
  932. }
  933. }
  934. bp->video_ping_frame = NULL;
  935. }
  936. if (ok == SWITCH_FALSE) {
  937. switch_set_flag(bp, SMBF_PRUNE);
  938. prune++;
  939. } else x++;
  940. }
  941. }
  942. switch_thread_rwlock_unlock(orig_session->bug_rwlock);
  943. if (prune) {
  944. switch_core_media_bug_prune(orig_session);
  945. }
  946. }
  947. return x;
  948. }
  949. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_exec_all(switch_core_session_t *orig_session,
  950. const char *function, switch_media_bug_exec_cb_t cb, void *user_data)
  951. {
  952. switch_media_bug_t *bp;
  953. int x = 0;
  954. switch_assert(cb);
  955. if (orig_session->bugs) {
  956. switch_thread_rwlock_wrlock(orig_session->bug_rwlock);
  957. for (bp = orig_session->bugs; bp; bp = bp->next) {
  958. if (!switch_test_flag(bp, SMBF_PRUNE) && !switch_test_flag(bp, SMBF_LOCK) && !strcmp(bp->function, function)) {
  959. cb(bp, user_data);
  960. x++;
  961. }
  962. }
  963. switch_thread_rwlock_unlock(orig_session->bug_rwlock);
  964. }
  965. return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
  966. }
  967. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_enumerate(switch_core_session_t *session, switch_stream_handle_t *stream)
  968. {
  969. switch_media_bug_t *bp;
  970. stream->write_function(stream, "<media-bugs>\n");
  971. if (session->bugs) {
  972. switch_thread_rwlock_rdlock(session->bug_rwlock);
  973. for (bp = session->bugs; bp; bp = bp->next) {
  974. int thread_locked = (bp->thread_id && bp->thread_id == switch_thread_self());
  975. stream->write_function(stream,
  976. " <media-bug>\n"
  977. " <function>%s</function>\n"
  978. " <target>%s</target>\n"
  979. " <thread-locked>%d</thread-locked>\n"
  980. " </media-bug>\n",
  981. bp->function, bp->target, thread_locked);
  982. }
  983. switch_thread_rwlock_unlock(session->bug_rwlock);
  984. }
  985. stream->write_function(stream, "</media-bugs>\n");
  986. return SWITCH_STATUS_SUCCESS;
  987. }
  988. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all_function(switch_core_session_t *session, const char *function)
  989. {
  990. switch_media_bug_t *bp, *last = NULL, *next = NULL;
  991. switch_status_t status = SWITCH_STATUS_FALSE;
  992. switch_media_bug_t *closed = NULL;
  993. switch_thread_rwlock_wrlock(session->bug_rwlock);
  994. if (session->bugs) {
  995. for (bp = session->bugs; bp; bp = next) {
  996. next = bp->next;
  997. if (!switch_test_flag(session, SSF_DESTROYABLE) &&
  998. ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK))) {
  999. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
  1000. last = bp;
  1001. continue;
  1002. }
  1003. if (!zstr(function) && strcmp(bp->function, function)) {
  1004. last = bp;
  1005. continue;
  1006. }
  1007. if (last) {
  1008. last->next = bp->next;
  1009. } else {
  1010. session->bugs = bp->next;
  1011. }
  1012. bp->next = closed;
  1013. closed = bp;
  1014. switch_core_media_bug_close(&bp, SWITCH_FALSE);
  1015. }
  1016. status = SWITCH_STATUS_SUCCESS;
  1017. }
  1018. switch_thread_rwlock_unlock(session->bug_rwlock);
  1019. if (closed) {
  1020. for (bp = closed; bp; bp = next) {
  1021. next = bp->next;
  1022. switch_core_media_bug_destroy(&bp);
  1023. }
  1024. }
  1025. if (switch_core_codec_ready(&session->bug_codec)) {
  1026. switch_core_codec_destroy(&session->bug_codec);
  1027. }
  1028. return status;
  1029. }
  1030. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_close(switch_media_bug_t **bug, switch_bool_t destroy)
  1031. {
  1032. switch_media_bug_t *bp = *bug;
  1033. if (bp) {
  1034. if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)) {
  1035. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(*bug)), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
  1036. return SWITCH_STATUS_FALSE;
  1037. }
  1038. if (bp->callback) {
  1039. bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
  1040. }
  1041. if (switch_test_flag(bp, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bp, SMBF_WRITE_VIDEO_STREAM) || switch_test_flag(bp, SMBF_READ_VIDEO_PING) || switch_test_flag(bp, SMBF_WRITE_VIDEO_PING)) {
  1042. switch_channel_clear_flag_recursive(bp->session->channel, CF_VIDEO_DECODED_READ);
  1043. if (switch_test_flag(bp, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bp, SMBF_READ_VIDEO_PING)) {
  1044. switch_channel_clear_flag_recursive(bp->session->channel, CF_VIDEO_READ_TAPPED);
  1045. }
  1046. if (switch_test_flag(bp, SMBF_WRITE_VIDEO_STREAM) || switch_test_flag(bp, SMBF_WRITE_VIDEO_PING)) {
  1047. switch_channel_clear_flag_recursive(bp->session->channel, CF_VIDEO_WRITE_TAPPED);
  1048. }
  1049. }
  1050. bp->ready = 0;
  1051. if (bp->read_video_queue) {
  1052. switch_queue_push(bp->read_video_queue, NULL);
  1053. }
  1054. if (bp->write_video_queue) {
  1055. switch_queue_push(bp->write_video_queue, NULL);
  1056. }
  1057. switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(*bug)), SWITCH_LOG_DEBUG, "Removing BUG from %s\n",
  1058. switch_channel_get_name(bp->session->channel));
  1059. if (destroy) {
  1060. switch_core_media_bug_destroy(bug);
  1061. }
  1062. return SWITCH_STATUS_SUCCESS;
  1063. }
  1064. return SWITCH_STATUS_FALSE;
  1065. }
  1066. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session_t *session, switch_media_bug_t **bug)
  1067. {
  1068. switch_media_bug_t *bp = NULL, *bp2 = NULL, *last = NULL;
  1069. switch_status_t status = SWITCH_STATUS_FALSE;
  1070. int tap_only = 0;
  1071. if (switch_core_media_bug_test_flag(*bug, SMBF_LOCK)) {
  1072. return status;
  1073. }
  1074. switch_thread_rwlock_wrlock(session->bug_rwlock);
  1075. if (session->bugs) {
  1076. for (bp = session->bugs; bp; bp = bp->next) {
  1077. if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) {
  1078. if (last) {
  1079. last->next = bp->next;
  1080. } else {
  1081. session->bugs = bp->next;
  1082. }
  1083. break;
  1084. }
  1085. last = bp;
  1086. }
  1087. }
  1088. if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
  1089. switch_core_codec_destroy(&session->bug_codec);
  1090. }
  1091. if (session->bugs) {
  1092. for(bp2 = session->bugs; bp2; bp2 = bp2->next) {
  1093. if (bp2->ready && !switch_test_flag(bp2, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp2, SMBF_TAP_NATIVE_WRITE)) {
  1094. tap_only = 0;
  1095. }
  1096. }
  1097. }
  1098. if (tap_only) {
  1099. switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
  1100. } else {
  1101. switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
  1102. }
  1103. switch_thread_rwlock_unlock(session->bug_rwlock);
  1104. if (bp) {
  1105. status = switch_core_media_bug_close(&bp, SWITCH_TRUE);
  1106. }
  1107. return status;
  1108. }
  1109. SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *session)
  1110. {
  1111. switch_media_bug_t *bp = NULL, *last = NULL;
  1112. int ttl = 0;
  1113. top:
  1114. switch_thread_rwlock_wrlock(session->bug_rwlock);
  1115. if (session->bugs) {
  1116. for (bp = session->bugs; bp; bp = bp->next) {
  1117. if (switch_core_media_bug_test_flag(bp, SMBF_PRUNE)) {
  1118. if (last) {
  1119. last->next = bp->next;
  1120. } else {
  1121. session->bugs = bp->next;
  1122. }
  1123. break;
  1124. }
  1125. last = bp;
  1126. }
  1127. }
  1128. if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
  1129. switch_core_codec_destroy(&session->bug_codec);
  1130. }
  1131. switch_thread_rwlock_unlock(session->bug_rwlock);
  1132. if (bp) {
  1133. switch_clear_flag(bp, SMBF_LOCK);
  1134. bp->thread_id = 0;
  1135. switch_core_media_bug_close(&bp, SWITCH_TRUE);
  1136. ttl++;
  1137. goto top;
  1138. }
  1139. return ttl;
  1140. }
  1141. SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_callback(switch_core_session_t *session, switch_media_bug_callback_t callback)
  1142. {
  1143. switch_media_bug_t *cur = NULL, *bp = NULL, *last = NULL, *closed = NULL, *next = NULL;
  1144. int total = 0;
  1145. switch_thread_rwlock_wrlock(session->bug_rwlock);
  1146. if (session->bugs) {
  1147. bp = session->bugs;
  1148. while (bp) {
  1149. cur = bp;
  1150. bp = bp->next;
  1151. if ((!cur->thread_id || cur->thread_id == switch_thread_self()) && cur->ready && cur->callback == callback) {
  1152. if (last) {
  1153. last->next = cur->next;
  1154. } else {
  1155. session->bugs = cur->next;
  1156. }
  1157. if (switch_core_media_bug_close(&cur, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
  1158. total++;
  1159. }
  1160. cur->next = closed;
  1161. closed = cur;
  1162. } else {
  1163. last = cur;
  1164. }
  1165. }
  1166. }
  1167. switch_thread_rwlock_unlock(session->bug_rwlock);
  1168. if (closed) {
  1169. for (bp = closed; bp; bp = next) {
  1170. next = bp->next;
  1171. switch_core_media_bug_destroy(&bp);
  1172. }
  1173. }
  1174. if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
  1175. switch_core_codec_destroy(&session->bug_codec);
  1176. }
  1177. return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
  1178. }
  1179. /* For Emacs:
  1180. * Local Variables:
  1181. * mode:c
  1182. * indent-tabs-mode:t
  1183. * tab-width:4
  1184. * c-basic-offset:4
  1185. * End:
  1186. * For VIM:
  1187. * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
  1188. */