switch_core_file.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118
  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. * John Wehle <john@feith.com>
  30. *
  31. *
  32. * switch_core_file.c -- Main Core Library (File I/O Functions)
  33. *
  34. */
  35. #include <switch.h>
  36. #include "private/switch_core_pvt.h"
  37. static switch_status_t get_file_size(switch_file_handle_t *fh, const char **string)
  38. {
  39. switch_status_t status;
  40. switch_file_t *newfile;
  41. switch_size_t size = 0;
  42. switch_assert(string);
  43. status = switch_file_open(&newfile, fh->spool_path ? fh->spool_path : fh->file_path, SWITCH_FOPEN_READ, SWITCH_FPROT_OS_DEFAULT, fh->memory_pool);
  44. if (status != SWITCH_STATUS_SUCCESS) {
  45. return status;
  46. }
  47. size = switch_file_get_size(newfile);
  48. if (size) {
  49. *string = switch_core_sprintf(fh->memory_pool, "%" SWITCH_SIZE_T_FMT, size);
  50. }
  51. status = switch_file_close(newfile);
  52. return status;
  53. }
  54. SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
  55. switch_file_handle_t *fh,
  56. const char *file_path,
  57. uint32_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool)
  58. {
  59. char *ext;
  60. switch_status_t status = SWITCH_STATUS_FALSE;
  61. char stream_name[128] = "";
  62. char *rhs = NULL;
  63. const char *spool_path = NULL;
  64. int is_stream = 0;
  65. char *fp = NULL;
  66. int to = 0;
  67. int force_channels = 0;
  68. uint32_t core_channel_limit;
  69. if (switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  70. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle already open\n");
  71. return SWITCH_STATUS_FALSE;
  72. }
  73. fh->samples_in = 0;
  74. if (!(flags & SWITCH_FILE_FLAG_WRITE)) {
  75. fh->samplerate = 0;
  76. fh->native_rate = 0;
  77. fh->channels = 0;
  78. fh->real_channels = 0;
  79. }
  80. if (!fh->samplerate) {
  81. if (!(fh->samplerate = rate)) {
  82. fh->samplerate = 8000;
  83. }
  84. }
  85. if (zstr(file_path)) {
  86. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Filename\n");
  87. return SWITCH_STATUS_FALSE;
  88. }
  89. fh->flags = flags;
  90. if (pool) {
  91. fh->memory_pool = pool;
  92. } else {
  93. if ((status = switch_core_new_memory_pool(&fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
  94. UNPROTECT_INTERFACE(fh->file_interface);
  95. return status;
  96. }
  97. switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL);
  98. }
  99. switch_mutex_init(&fh->flag_mutex, SWITCH_MUTEX_NESTED, fh->memory_pool);
  100. fh->mm.samplerate = 44100;
  101. fh->mm.channels = 1;
  102. fh->mm.keyint = 60;
  103. fh->mm.ab = 128;
  104. fh->mm.vencspd = SWITCH_VIDEO_ENCODE_SPEED_DEFAULT;
  105. fh->mm.vprofile = SWITCH_VIDEO_PROFILE_BASELINE;
  106. fh->mm.try_hardware_encoder = 1;
  107. if (*file_path == '{') {
  108. char *timeout;
  109. char *modname;
  110. const char *val;
  111. int tmp;
  112. fp = switch_core_strdup(fh->memory_pool, file_path);
  113. while (*fp == '{') {
  114. char *parsed = NULL;
  115. if (switch_event_create_brackets(fp, '{', '}', ',', &fh->params, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
  116. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
  117. goto fail;
  118. }
  119. fp = parsed;
  120. }
  121. file_path = fp;
  122. if ((timeout = switch_event_get_header(fh->params, "timeout"))) {
  123. if ((to = atoi(timeout)) < 1) {
  124. to = 0;
  125. }
  126. }
  127. if ((modname = switch_event_get_header(fh->params, "modname"))) {
  128. fh->modname = switch_core_strdup(fh->memory_pool, modname);
  129. }
  130. if ((val = switch_event_get_header(fh->params, "samplerate"))) {
  131. tmp = atoi(val);
  132. if (tmp >= 8000) {
  133. fh->mm.samplerate = tmp;
  134. }
  135. }
  136. if ((val = switch_event_get_header(fh->params, "force_channels"))) {
  137. tmp = atoi(val);
  138. if (tmp >= 0 && tmp < 3) {
  139. force_channels = tmp;
  140. }
  141. }
  142. if ((val = switch_event_get_header(fh->params, "ab"))) {
  143. tmp = atoi(val);
  144. if (tmp > 16) {
  145. fh->mm.ab = tmp;
  146. }
  147. }
  148. if ((val = switch_event_get_header(fh->params, "cbr"))) {
  149. tmp = switch_true(val);
  150. fh->mm.cbr = tmp;
  151. }
  152. if ((val = switch_event_get_header(fh->params, "vb"))) {
  153. tmp = atoi(val);
  154. if (strrchr(val, 'k')) {
  155. tmp *= 1024;
  156. } else if (strrchr(val, 'm')) {
  157. tmp *= 1048576;
  158. }
  159. fh->mm.vb = tmp;
  160. }
  161. if ((val = switch_event_get_header(fh->params, "vw"))) {
  162. tmp = atoi(val);
  163. if (tmp > 0) {
  164. fh->mm.vw = tmp;
  165. }
  166. }
  167. if ((val = switch_event_get_header(fh->params, "vh"))) {
  168. tmp = atoi(val);
  169. if (tmp > 0) {
  170. fh->mm.vh = tmp;
  171. }
  172. }
  173. if ((val = switch_event_get_header(fh->params, "try_hardware_encoder"))) {
  174. fh->mm.try_hardware_encoder = switch_true(val);
  175. }
  176. if ((val = switch_event_get_header(fh->params, "auth_username"))) {
  177. fh->mm.auth_username = switch_core_strdup(fh->memory_pool, val);
  178. }
  179. if ((val = switch_event_get_header(fh->params, "auth_password"))) {
  180. fh->mm.auth_password = switch_core_strdup(fh->memory_pool, val);
  181. }
  182. if ((val = switch_event_get_header(fh->params, "fps"))) {
  183. float ftmp = atof(val);
  184. if (ftmp > 0.0f) {
  185. fh->mm.fps = ftmp;
  186. }
  187. }
  188. if ((val = switch_event_get_header(fh->params, "vbuf"))) {
  189. tmp = atoi(val);
  190. if (strrchr(val, 'k')) {
  191. tmp *= 1024;
  192. } else if (strrchr(val, 'm')) {
  193. tmp *= 1048576;
  194. }
  195. if (tmp > 0 && tmp < 104857600 /*100mb*/) {
  196. fh->mm.vbuf = tmp;
  197. } else {
  198. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid buffer size: %d\n", tmp);
  199. }
  200. }
  201. if ((val = switch_event_get_header(fh->params, "vencspd"))) {
  202. if (!strcasecmp(val, "slow")) {
  203. fh->mm.vencspd = SWITCH_VIDEO_ENCODE_SPEED_SLOW;
  204. } else if (!strcasecmp(val, "medium")) {
  205. fh->mm.vencspd = SWITCH_VIDEO_ENCODE_SPEED_MEDIUM;
  206. } else if (!strcasecmp(val, "fast")) {
  207. fh->mm.vencspd = SWITCH_VIDEO_ENCODE_SPEED_FAST;
  208. } else {
  209. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid video encode speed: %s\n", val);
  210. }
  211. }
  212. if ((val = switch_event_get_header(fh->params, "vprofile"))) {
  213. if (!strcasecmp(val, "baseline")) {
  214. fh->mm.vprofile = SWITCH_VIDEO_PROFILE_BASELINE;
  215. } else if (!strcasecmp(val, "main")) {
  216. fh->mm.vprofile = SWITCH_VIDEO_PROFILE_MAIN;
  217. } else if (!strcasecmp(val, "high")) {
  218. fh->mm.vprofile = SWITCH_VIDEO_PROFILE_HIGH;
  219. } else {
  220. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid video profile: %s\n", val);
  221. }
  222. }
  223. }
  224. if (switch_directory_exists(file_path, fh->memory_pool) == SWITCH_STATUS_SUCCESS) {
  225. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] is a directory not a file.\n", file_path);
  226. status = SWITCH_STATUS_GENERR;
  227. goto fail;
  228. }
  229. if (!strncasecmp(file_path, "https://", 8) && (switch_stristr("youtube", file_path) || switch_stristr("youtu.be", file_path))) {
  230. char *youtube_root = NULL;
  231. if ((youtube_root = switch_core_get_variable_pdup("youtube_resolver", fh->memory_pool))) {
  232. char *resolve_url, *encoded, *url_buf;
  233. switch_size_t url_buflen = 0;
  234. switch_stream_handle_t stream = { 0 };
  235. const char *video = NULL, *format = "best";
  236. url_buflen = strlen(file_path) * 4;
  237. url_buf = switch_core_alloc(fh->memory_pool, url_buflen);
  238. encoded = switch_url_encode(file_path, url_buf, url_buflen);
  239. if (fh->params && (video = switch_event_get_header(fh->params, "video")) && switch_false(video)) {
  240. format = "bestaudio";
  241. }
  242. resolve_url = switch_core_sprintf(fh->memory_pool, "%s?url=%s&format=%s", youtube_root, encoded, format);
  243. SWITCH_STANDARD_STREAM(stream);
  244. //Depends on mod_curl *shrug*
  245. switch_api_execute("curl", resolve_url, NULL, &stream);
  246. if (stream.data && !strncasecmp("https://", (char *)stream.data, 8)) {
  247. char *url = (char *) stream.data;
  248. while (end_of_p(url) > url && (end_of(url) == '\n' || end_of(url) == '\r')) {
  249. end_of(url) = '\0';
  250. }
  251. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "resolved url to: %s\n", url);
  252. file_path = switch_core_sprintf(fh->memory_pool, "av://%s", url);
  253. } else {
  254. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "YOUTUBE RESOLVER FAIL: %s\n", (char *) stream.data);
  255. }
  256. switch_safe_free(stream.data);
  257. }
  258. }
  259. if ((rhs = strstr(file_path, SWITCH_URL_SEPARATOR))) {
  260. switch_copy_string(stream_name, file_path, (rhs + 1) - file_path);
  261. ext = stream_name;
  262. file_path = rhs + 3;
  263. fh->stream_name = switch_core_strdup(fh->memory_pool, stream_name);
  264. fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
  265. is_stream = 1;
  266. } else {
  267. if ((flags & SWITCH_FILE_FLAG_WRITE)) {
  268. if (fh->params) {
  269. spool_path = switch_event_get_header(fh->params, "spool_path");
  270. }
  271. if (!spool_path) {
  272. spool_path = switch_core_get_variable_pdup(SWITCH_AUDIO_SPOOL_PATH_VARIABLE, fh->memory_pool);
  273. }
  274. }
  275. if ((ext = strrchr(file_path, '.')) == 0) {
  276. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown file Format [%s]\n", file_path);
  277. switch_goto_status(SWITCH_STATUS_FALSE, fail);
  278. }
  279. ext++;
  280. fh->file_path = switch_core_strdup(fh->memory_pool, file_path);
  281. }
  282. if ((fh->file_interface = switch_loadable_module_get_file_interface(ext, fh->modname)) == 0) {
  283. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid file format [%s] for [%s]!\n", ext, file_path);
  284. switch_goto_status(SWITCH_STATUS_GENERR, fail);
  285. }
  286. fh->file = file;
  287. fh->func = func;
  288. fh->line = line;
  289. if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO) && !fh->file_interface->file_read_video) {
  290. switch_clear_flag_locked(fh, SWITCH_FILE_FLAG_VIDEO);
  291. }
  292. if (spool_path) {
  293. char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
  294. switch_uuid_t uuid;
  295. switch_uuid_get(&uuid);
  296. switch_uuid_format(uuid_str, &uuid);
  297. fh->spool_path = switch_core_sprintf(fh->memory_pool, "%s%s%s.%s", spool_path, SWITCH_PATH_SEPARATOR, uuid_str, ext);
  298. } else {
  299. fh->spool_path = NULL;
  300. }
  301. if (rhs) {
  302. fh->handler = switch_core_strdup(fh->memory_pool, rhs);
  303. } else {
  304. fh->handler = NULL;
  305. }
  306. if (force_channels == channels) {
  307. force_channels = 0;
  308. }
  309. if (force_channels && force_channels > 0 && force_channels < 3) {
  310. fh->real_channels = channels ? channels : fh->channels;
  311. fh->channels = force_channels;
  312. fh->mm.channels = fh->channels;
  313. } else {
  314. if (channels) {
  315. fh->channels = channels;
  316. } else {
  317. fh->channels = 1;
  318. }
  319. fh->mm.channels = fh->channels;
  320. }
  321. file_path = fh->spool_path ? fh->spool_path : fh->file_path;
  322. if ((status = fh->file_interface->file_open(fh, file_path)) != SWITCH_STATUS_SUCCESS) {
  323. if (fh->spool_path) {
  324. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Spool dir is set. Make sure [%s] is also a valid path\n", fh->spool_path);
  325. }
  326. UNPROTECT_INTERFACE(fh->file_interface);
  327. goto fail;
  328. }
  329. if (fh->channels > 2) {
  330. /* just show a warning for more than 2 channels, no matter if we allow them or not */
  331. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File [%s] has more than 2 channels: [%u]\n", file_path, fh->channels);
  332. }
  333. core_channel_limit = switch_core_max_audio_channels(0);
  334. if (core_channel_limit && fh->channels > core_channel_limit) {
  335. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File [%s] has more channels (%u) than limit (%u). Closing.\n", file_path, fh->channels, core_channel_limit);
  336. fh->file_interface->file_close(fh);
  337. UNPROTECT_INTERFACE(fh->file_interface);
  338. switch_goto_status(SWITCH_STATUS_FALSE, fail);
  339. }
  340. if (!force_channels && !fh->real_channels) {
  341. fh->real_channels = fh->channels;
  342. if (channels) {
  343. fh->channels = channels;
  344. }
  345. }
  346. if ((flags & SWITCH_FILE_FLAG_WRITE) && !is_stream && (status = switch_file_exists(file_path, fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
  347. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] not created!\n", file_path);
  348. fh->file_interface->file_close(fh);
  349. UNPROTECT_INTERFACE(fh->file_interface);
  350. goto fail;
  351. }
  352. if (to) {
  353. fh->max_samples = (fh->samplerate / 1000) * to;
  354. }
  355. if ((flags & SWITCH_FILE_FLAG_READ)) {
  356. fh->native_rate = fh->samplerate;
  357. } else {
  358. fh->native_rate = rate;
  359. }
  360. if (fh->samplerate && rate && fh->samplerate != rate) {
  361. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "File %s sample rate %d doesn't match requested rate %d\n", file_path, fh->samplerate, rate);
  362. if ((flags & SWITCH_FILE_FLAG_READ)) {
  363. fh->samplerate = rate;
  364. }
  365. }
  366. if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO)) {
  367. fh->pre_buffer_datalen = 0;
  368. }
  369. if (fh->pre_buffer_datalen) {
  370. //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen);
  371. switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen * fh->channels, fh->pre_buffer_datalen * fh->channels, 0);
  372. fh->pre_buffer_data = switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen * fh->channels);
  373. }
  374. if (fh->real_channels != fh->channels && (flags & SWITCH_FILE_FLAG_READ) && !(fh->flags & SWITCH_FILE_NOMUX)) {
  375. fh->cur_channels = fh->real_channels;
  376. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File has %d channels, muxing to %d channel%s will occur.\n", fh->real_channels, fh->channels, fh->channels == 1 ? "" : "s");
  377. }
  378. switch_set_flag_locked(fh, SWITCH_FILE_OPEN);
  379. return status;
  380. fail:
  381. switch_clear_flag_locked(fh, SWITCH_FILE_OPEN);
  382. if (fh->params) {
  383. switch_event_destroy(&fh->params);
  384. }
  385. fh->samples_in = 0;
  386. fh->max_samples = 0;
  387. if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
  388. switch_core_destroy_memory_pool(&fh->memory_pool);
  389. }
  390. return status;
  391. }
  392. SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, void *data, switch_size_t *len)
  393. {
  394. switch_status_t status = SWITCH_STATUS_FALSE;
  395. switch_size_t want, orig_len = *len;
  396. switch_assert(fh != NULL);
  397. switch_assert(fh->file_interface != NULL);
  398. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  399. return SWITCH_STATUS_FALSE;
  400. }
  401. top:
  402. if (fh->max_samples > 0 && fh->samples_in >= (switch_size_t)fh->max_samples) {
  403. *len = 0;
  404. return SWITCH_STATUS_FALSE;
  405. }
  406. if (fh->buffer && switch_buffer_inuse(fh->buffer) >= *len * 2 * fh->channels) {
  407. *len = switch_buffer_read(fh->buffer, data, orig_len * 2 * fh->channels) / 2 / fh->channels;
  408. return *len == 0 ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
  409. }
  410. if (switch_test_flag(fh, SWITCH_FILE_DONE)) {
  411. switch_clear_flag_locked(fh, SWITCH_FILE_DONE);
  412. switch_clear_flag_locked(fh, SWITCH_FILE_BUFFER_DONE);
  413. *len = 0;
  414. return SWITCH_STATUS_FALSE;
  415. }
  416. want = *len;
  417. more:
  418. if (fh->pre_buffer) {
  419. switch_size_t rlen;
  420. int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
  421. if (!switch_test_flag(fh, SWITCH_FILE_BUFFER_DONE)) {
  422. rlen = asis ? fh->pre_buffer_datalen : fh->pre_buffer_datalen / 2 / fh->real_channels;
  423. if (switch_buffer_inuse(fh->pre_buffer) < rlen * 2 * fh->channels) {
  424. if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) == SWITCH_STATUS_BREAK) {
  425. return SWITCH_STATUS_BREAK;
  426. }
  427. if (status != SWITCH_STATUS_SUCCESS || !rlen) {
  428. switch_set_flag_locked(fh, SWITCH_FILE_BUFFER_DONE);
  429. } else {
  430. if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
  431. switch_mux_channels((int16_t *) fh->pre_buffer_data, rlen, fh->real_channels, fh->channels);
  432. }
  433. switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, asis ? rlen : rlen * 2 * fh->channels);
  434. }
  435. }
  436. }
  437. rlen = switch_buffer_read(fh->pre_buffer, data, asis ? *len : *len * 2 * fh->channels);
  438. fh->samples_in += rlen;
  439. *len = asis ? rlen : rlen / 2 / fh->channels;
  440. if (*len == 0) {
  441. switch_set_flag_locked(fh, SWITCH_FILE_DONE);
  442. goto top;
  443. } else {
  444. status = SWITCH_STATUS_SUCCESS;
  445. }
  446. } else {
  447. if ((status = fh->file_interface->file_read(fh, data, len)) == SWITCH_STATUS_BREAK) {
  448. return SWITCH_STATUS_BREAK;
  449. }
  450. if (status != SWITCH_STATUS_SUCCESS || !*len) {
  451. switch_set_flag_locked(fh, SWITCH_FILE_DONE);
  452. goto top;
  453. }
  454. fh->samples_in += *len;
  455. if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
  456. switch_mux_channels((int16_t *) data, *len, fh->real_channels, fh->channels);
  457. }
  458. }
  459. if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
  460. if (!fh->resampler) {
  461. if (switch_resample_create(&fh->resampler,
  462. fh->native_rate, fh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY, fh->channels) != SWITCH_STATUS_SUCCESS) {
  463. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
  464. return SWITCH_STATUS_GENERR;
  465. }
  466. }
  467. switch_resample_process(fh->resampler, data, (uint32_t) *len);
  468. if (fh->resampler->to_len < want || fh->resampler->to_len > orig_len) {
  469. if (!fh->buffer) {
  470. int factor = fh->resampler->to_len * fh->samplerate / 1000;
  471. switch_buffer_create_dynamic(&fh->buffer, factor, factor, 0);
  472. switch_assert(fh->buffer);
  473. }
  474. if (!fh->dbuf || fh->dbuflen < fh->resampler->to_len * 2 * fh->channels) {
  475. void *mem;
  476. fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
  477. mem = realloc(fh->dbuf, fh->dbuflen);
  478. switch_assert(mem);
  479. fh->dbuf = mem;
  480. }
  481. switch_assert(fh->resampler->to_len * 2 * fh->channels <= fh->dbuflen);
  482. memcpy((int16_t *) fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
  483. switch_buffer_write(fh->buffer, fh->dbuf, fh->resampler->to_len * 2 * fh->channels);
  484. if (switch_buffer_inuse(fh->buffer) < want * 2 * fh->channels) {
  485. *len = want;
  486. goto more;
  487. }
  488. *len = switch_buffer_read(fh->buffer, data, orig_len * 2 * fh->channels) / 2 / fh->channels;
  489. } else {
  490. memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
  491. *len = fh->resampler->to_len;
  492. }
  493. }
  494. return status;
  495. }
  496. SWITCH_DECLARE(switch_bool_t) switch_core_file_has_video(switch_file_handle_t *fh, switch_bool_t check_open)
  497. {
  498. return ((!check_open || switch_test_flag(fh, SWITCH_FILE_OPEN)) && switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO)) ? SWITCH_TRUE : SWITCH_FALSE;
  499. }
  500. SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, void *data, switch_size_t *len)
  501. {
  502. switch_size_t orig_len = *len;
  503. switch_assert(fh != NULL);
  504. switch_assert(fh->file_interface != NULL);
  505. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  506. return SWITCH_STATUS_FALSE;
  507. }
  508. if (!fh->file_interface->file_write) {
  509. return SWITCH_STATUS_FALSE;
  510. }
  511. if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
  512. return SWITCH_STATUS_SUCCESS;
  513. }
  514. if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
  515. int need = *len * 2 * (fh->real_channels > fh->channels ? fh->real_channels : fh->channels);
  516. if (need > fh->muxlen) {
  517. fh->muxbuf = realloc(fh->muxbuf, need);
  518. switch_assert(fh->muxbuf);
  519. fh->muxlen = need;
  520. }
  521. if (fh->muxbuf) {
  522. memcpy(fh->muxbuf, data, *len * 2);
  523. data = fh->muxbuf;
  524. }
  525. switch_mux_channels((int16_t *) data, *len, fh->real_channels, fh->channels);
  526. }
  527. if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
  528. if (!fh->resampler) {
  529. if (switch_resample_create(&fh->resampler,
  530. fh->native_rate,
  531. fh->samplerate,
  532. (uint32_t) orig_len * 2 * fh->channels, SWITCH_RESAMPLE_QUALITY, fh->channels) != SWITCH_STATUS_SUCCESS) {
  533. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
  534. return SWITCH_STATUS_GENERR;
  535. }
  536. }
  537. switch_resample_process(fh->resampler, data, (uint32_t) * len);
  538. if (fh->resampler->to_len > orig_len) {
  539. if (!fh->dbuf || (fh->dbuflen < fh->resampler->to_len * 2 * fh->channels)) {
  540. void *mem;
  541. fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
  542. mem = realloc(fh->dbuf, fh->dbuflen);
  543. switch_assert(mem);
  544. fh->dbuf = mem;
  545. }
  546. switch_assert(fh->resampler->to_len * 2 * fh->channels <= fh->dbuflen);
  547. memcpy(fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
  548. data = fh->dbuf;
  549. } else {
  550. memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
  551. }
  552. *len = fh->resampler->to_len;
  553. }
  554. if (!*len) {
  555. return SWITCH_STATUS_SUCCESS;
  556. }
  557. if (fh->pre_buffer) {
  558. switch_size_t rlen, blen;
  559. switch_size_t datalen_adj = fh->pre_buffer_datalen;
  560. switch_status_t status = SWITCH_STATUS_SUCCESS;
  561. int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
  562. switch_buffer_write(fh->pre_buffer, data, (asis ? *len : *len * 2) * fh->channels);
  563. rlen = switch_buffer_inuse(fh->pre_buffer);
  564. if (fh->pre_buffer_datalen % fh->channels) {
  565. datalen_adj = fh->pre_buffer_datalen - (fh->pre_buffer_datalen % fh->channels);
  566. }
  567. if (rlen >= datalen_adj) {
  568. if ((blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, datalen_adj))) {
  569. if (!asis)
  570. blen /= 2;
  571. if (fh->channels > 1)
  572. blen /= fh->channels;
  573. if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) {
  574. *len = 0;
  575. }
  576. }
  577. }
  578. fh->samples_out += orig_len;
  579. return status;
  580. } else {
  581. switch_status_t status;
  582. if ((status = fh->file_interface->file_write(fh, data, len)) == SWITCH_STATUS_SUCCESS) {
  583. fh->samples_out += orig_len;
  584. }
  585. return status;
  586. }
  587. }
  588. SWITCH_DECLARE(switch_status_t) switch_core_file_write_video(switch_file_handle_t *fh, switch_frame_t *frame)
  589. {
  590. switch_assert(fh != NULL);
  591. switch_assert(fh->file_interface != NULL);
  592. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  593. return SWITCH_STATUS_GENERR;
  594. }
  595. if (!fh->file_interface->file_write_video) {
  596. return SWITCH_STATUS_FALSE;
  597. }
  598. if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
  599. return SWITCH_STATUS_SUCCESS;
  600. }
  601. return fh->file_interface->file_write_video(fh, frame);
  602. }
  603. SWITCH_DECLARE(switch_status_t) switch_core_file_read_video(switch_file_handle_t *fh, switch_frame_t *frame, switch_video_read_flag_t flags)
  604. {
  605. switch_status_t status;
  606. switch_assert(fh != NULL);
  607. switch_assert(fh->file_interface != NULL);
  608. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  609. return SWITCH_STATUS_GENERR;
  610. }
  611. if (!fh->file_interface->file_read_video) {
  612. return SWITCH_STATUS_FALSE;
  613. }
  614. status = fh->file_interface->file_read_video(fh, frame, flags);
  615. if (status == SWITCH_STATUS_FALSE) {
  616. switch_cond_next();
  617. }
  618. return status;
  619. }
  620. SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
  621. {
  622. switch_status_t status;
  623. int ok = 1;
  624. switch_assert(fh != NULL);
  625. if (!switch_test_flag(fh, SWITCH_FILE_OPEN) || !fh->file_interface->file_seek) {
  626. ok = 0;
  627. } else if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
  628. if (!(switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(fh, SWITCH_FILE_WRITE_OVER))) {
  629. ok = 0;
  630. }
  631. } else if (!switch_test_flag(fh, SWITCH_FILE_FLAG_READ)) {
  632. ok = 0;
  633. }
  634. if (!ok) {
  635. return SWITCH_STATUS_FALSE;
  636. }
  637. if (fh->buffer) {
  638. switch_buffer_zero(fh->buffer);
  639. }
  640. if (fh->pre_buffer) {
  641. switch_buffer_zero(fh->pre_buffer);
  642. }
  643. if (whence == SWITCH_SEEK_CUR) {
  644. unsigned int cur = 0;
  645. if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
  646. fh->file_interface->file_seek(fh, &cur, fh->samples_out, SEEK_SET);
  647. } else {
  648. fh->file_interface->file_seek(fh, &cur, fh->offset_pos, SEEK_SET);
  649. }
  650. }
  651. switch_set_flag_locked(fh, SWITCH_FILE_SEEK);
  652. status = fh->file_interface->file_seek(fh, cur_pos, samples, whence);
  653. fh->offset_pos = *cur_pos;
  654. if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
  655. fh->samples_out = *cur_pos;
  656. }
  657. return status;
  658. }
  659. SWITCH_DECLARE(switch_status_t) switch_core_file_set_string(switch_file_handle_t *fh, switch_audio_col_t col, const char *string)
  660. {
  661. switch_assert(fh != NULL);
  662. switch_assert(fh->file_interface != NULL);
  663. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  664. return SWITCH_STATUS_FALSE;
  665. }
  666. if (!fh->file_interface->file_set_string) {
  667. return SWITCH_STATUS_FALSE;
  668. }
  669. return fh->file_interface->file_set_string(fh, col, string);
  670. }
  671. SWITCH_DECLARE(switch_status_t) switch_core_file_get_string(switch_file_handle_t *fh, switch_audio_col_t col, const char **string)
  672. {
  673. switch_status_t status;
  674. switch_assert(fh != NULL);
  675. switch_assert(fh->file_interface != NULL);
  676. if (!switch_test_flag(fh, SWITCH_FILE_OPEN) && col < SWITCH_AUDIO_COL_STR_FILE_SIZE) {
  677. return SWITCH_STATUS_FALSE;
  678. }
  679. if (!fh->file_interface->file_get_string) {
  680. if (col == SWITCH_AUDIO_COL_STR_FILE_SIZE) {
  681. return get_file_size(fh, string);
  682. }
  683. return SWITCH_STATUS_FALSE;
  684. }
  685. status = fh->file_interface->file_get_string(fh, col, string);
  686. if (status == SWITCH_STATUS_SUCCESS && string) return status;
  687. if (col == SWITCH_AUDIO_COL_STR_FILE_SIZE) {
  688. return get_file_size(fh, string);
  689. }
  690. return status;
  691. }
  692. SWITCH_DECLARE(switch_status_t) switch_core_file_truncate(switch_file_handle_t *fh, int64_t offset)
  693. {
  694. switch_status_t status;
  695. switch_assert(fh != NULL);
  696. switch_assert(fh->file_interface != NULL);
  697. if (!(switch_test_flag(fh, SWITCH_FILE_OPEN) && switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE))) {
  698. return SWITCH_STATUS_FALSE;
  699. }
  700. if (!fh->file_interface->file_truncate) {
  701. return SWITCH_STATUS_FALSE;
  702. }
  703. if ((status = fh->file_interface->file_truncate(fh, offset)) == SWITCH_STATUS_SUCCESS) {
  704. if (fh->buffer) {
  705. switch_buffer_zero(fh->buffer);
  706. }
  707. if (fh->pre_buffer) {
  708. switch_buffer_zero(fh->pre_buffer);
  709. }
  710. fh->samples_out = 0;
  711. fh->pos = 0;
  712. }
  713. return status;
  714. }
  715. SWITCH_DECLARE(switch_status_t) switch_core_file_command(switch_file_handle_t *fh, switch_file_command_t command)
  716. {
  717. switch_status_t status = SWITCH_STATUS_FALSE;
  718. switch_assert(fh != NULL);
  719. switch_assert(fh->file_interface != NULL);
  720. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  721. return SWITCH_STATUS_FALSE;
  722. }
  723. switch(command) {
  724. case SCFC_FLUSH_AUDIO:
  725. if (fh->pre_buffer) {
  726. switch_buffer_zero(fh->pre_buffer);
  727. }
  728. break;
  729. default:
  730. break;
  731. }
  732. if (fh->file_interface->file_command) {
  733. switch_mutex_lock(fh->flag_mutex);
  734. status = fh->file_interface->file_command(fh, command);
  735. switch_mutex_unlock(fh->flag_mutex);
  736. }
  737. return status;
  738. }
  739. SWITCH_DECLARE(switch_status_t) switch_core_file_pre_close(switch_file_handle_t *fh)
  740. {
  741. switch_status_t status = SWITCH_STATUS_SUCCESS;
  742. switch_assert(fh != NULL);
  743. if (!fh->file_interface) {
  744. return SWITCH_STATUS_FALSE;
  745. }
  746. if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  747. return SWITCH_STATUS_SUCCESS;
  748. }
  749. if (fh->pre_buffer) {
  750. if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
  751. switch_size_t blen;
  752. int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE);
  753. while (switch_buffer_inuse(fh->pre_buffer)) {
  754. if ((blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
  755. if (!asis)
  756. blen /= 2;
  757. if (fh->channels > 1)
  758. blen /= fh->channels;
  759. if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) {
  760. break;
  761. }
  762. }
  763. }
  764. }
  765. switch_buffer_destroy(&fh->pre_buffer);
  766. }
  767. switch_clear_flag_locked(fh, SWITCH_FILE_OPEN);
  768. switch_set_flag_locked(fh, SWITCH_FILE_PRE_CLOSED);
  769. if (fh->file_interface->file_pre_close) {
  770. status = fh->file_interface->file_pre_close(fh);
  771. }
  772. return status;
  773. }
  774. SWITCH_DECLARE(switch_status_t) switch_core_file_handle_dup(switch_file_handle_t *oldfh, switch_file_handle_t **newfh, switch_memory_pool_t *pool)
  775. {
  776. switch_status_t status;
  777. switch_file_handle_t *fh;
  778. uint8_t destroy_pool = 0;
  779. switch_assert(oldfh != NULL);
  780. switch_assert(newfh != NULL);
  781. if (!pool) {
  782. if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
  783. return status;
  784. }
  785. destroy_pool = 1;
  786. }
  787. if (!(fh = switch_core_alloc(pool, sizeof(switch_file_handle_t)))) {
  788. switch_goto_status(SWITCH_STATUS_MEMERR, err);
  789. }
  790. memcpy(fh, oldfh, sizeof(switch_file_handle_t));
  791. if (!destroy_pool) {
  792. switch_clear_flag(fh, SWITCH_FILE_FLAG_FREE_POOL);
  793. } else {
  794. fh->memory_pool = pool;
  795. switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL);
  796. }
  797. if ((status = switch_mutex_init(&fh->flag_mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) {
  798. switch_goto_status(status, err);
  799. }
  800. #define DUP_CHECK(dup) if (oldfh->dup && !(fh->dup = switch_core_strdup(pool, oldfh->dup))) {switch_goto_status(SWITCH_STATUS_MEMERR, err);}
  801. DUP_CHECK(prefix);
  802. DUP_CHECK(modname);
  803. DUP_CHECK(mm.auth_username);
  804. DUP_CHECK(mm.auth_password);
  805. DUP_CHECK(stream_name);
  806. DUP_CHECK(file_path);
  807. DUP_CHECK(handler);
  808. DUP_CHECK(spool_path);
  809. fh->pre_buffer_data = NULL;
  810. if (oldfh->pre_buffer_data) {
  811. switch_size_t pre_buffer_data_size = oldfh->pre_buffer_datalen * oldfh->channels;
  812. if (pre_buffer_data_size) {
  813. if (!(fh->pre_buffer_data = switch_core_alloc(pool, pre_buffer_data_size))) {
  814. switch_goto_status(SWITCH_STATUS_MEMERR, err);
  815. }
  816. memcpy(fh->pre_buffer_data, oldfh->pre_buffer_data, pre_buffer_data_size);
  817. }
  818. }
  819. *newfh = fh;
  820. return SWITCH_STATUS_SUCCESS;
  821. err:
  822. if (destroy_pool) {
  823. switch_core_destroy_memory_pool(&pool);
  824. }
  825. return status;
  826. }
  827. SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
  828. {
  829. switch_status_t status = SWITCH_STATUS_SUCCESS;
  830. if (switch_test_flag(fh, SWITCH_FILE_OPEN)) {
  831. status = switch_core_file_pre_close(fh);
  832. } else if (!switch_test_flag(fh, SWITCH_FILE_PRE_CLOSED)) {
  833. return SWITCH_STATUS_FALSE;
  834. }
  835. switch_clear_flag_locked(fh, SWITCH_FILE_PRE_CLOSED);
  836. fh->file_interface->file_close(fh);
  837. if (fh->params) {
  838. switch_event_destroy(&fh->params);
  839. }
  840. fh->samples_in = 0;
  841. fh->max_samples = 0;
  842. if (fh->buffer) {
  843. switch_buffer_destroy(&fh->buffer);
  844. }
  845. switch_resample_destroy(&fh->resampler);
  846. if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
  847. switch_core_destroy_memory_pool(&fh->memory_pool);
  848. }
  849. fh->memory_pool = NULL;
  850. switch_safe_free(fh->dbuf);
  851. switch_safe_free(fh->muxbuf);
  852. if (fh->spool_path) {
  853. char *command;
  854. #ifdef _MSC_VER
  855. command = switch_mprintf("move %s %s", fh->spool_path, fh->file_path);
  856. #else
  857. command = switch_mprintf("/bin/mv %s %s", fh->spool_path, fh->file_path);
  858. #endif
  859. if (system(command) == -1) {
  860. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to copy spooled file [%s] to [%s] because of a command error : %s\n", fh->spool_path, fh->file_path, command);
  861. } else {
  862. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Copy spooled file [%s] to [%s]\n", fh->spool_path, fh->file_path);
  863. }
  864. free(command);
  865. }
  866. UNPROTECT_INTERFACE(fh->file_interface);
  867. fh->file_interface = NULL;
  868. return status;
  869. }
  870. /* For Emacs:
  871. * Local Variables:
  872. * mode:c
  873. * indent-tabs-mode:t
  874. * tab-width:4
  875. * c-basic-offset:4
  876. * End:
  877. * For VIM:
  878. * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
  879. */