diff --git a/build/modules.conf.in b/build/modules.conf.in index 76f192308c1..de87399e748 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -29,8 +29,6 @@ applications/mod_httapi #applications/mod_lcr #applications/mod_memcache #applications/mod_mongo -#applications/mod_mp4 -#applications/mod_mp4v2 #applications/mod_nibblebill #applications/mod_oreka #applications/mod_osp @@ -69,7 +67,6 @@ codecs/mod_g729 codecs/mod_h26x #codecs/mod_ilbc #codecs/mod_isac -#codecs/mod_mp4v codecs/mod_opus #codecs/mod_silk #codecs/mod_siren diff --git a/build/modules.conf.most b/build/modules.conf.most index 943ff713367..ad14f0bb7a1 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -29,7 +29,6 @@ applications/mod_http_cache applications/mod_lcr applications/mod_memcache applications/mod_mongo -applications/mod_mp4 applications/mod_nibblebill applications/mod_oreka #applications/mod_osp @@ -67,7 +66,6 @@ codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac -codecs/mod_mp4v codecs/mod_opus codecs/mod_silk codecs/mod_siren diff --git a/ci.sh b/ci.sh index d7322c44326..26947f6a70b 100755 --- a/ci.sh +++ b/ci.sh @@ -93,7 +93,6 @@ configure_freeswitch() sed -i \ -e '/mod_ilbc/s/^/#/g' \ -e '/mod_isac/s/^/#/g' \ - -e '/mod_mp4/s/^/#/g' \ -e '/mod_mongo/s/^/#/g' \ -e '/mod_pocketsphinx/s/^/#/g' \ -e '/mod_siren/s/^/#/g' \ diff --git a/configure.ac b/configure.ac index e56bc72e9d3..4b908715406 100755 --- a/configure.ac +++ b/configure.ac @@ -2119,8 +2119,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_limit/Makefile src/mod/applications/mod_memcache/Makefile src/mod/applications/mod_mongo/Makefile - src/mod/applications/mod_mp4/Makefile - src/mod/applications/mod_mp4v2/Makefile src/mod/applications/mod_nibblebill/Makefile src/mod/applications/mod_oreka/Makefile src/mod/applications/mod_osp/Makefile @@ -2160,7 +2158,6 @@ AC_CONFIG_FILES([Makefile src/mod/codecs/mod_h26x/Makefile src/mod/codecs/mod_ilbc/Makefile src/mod/codecs/mod_isac/Makefile - src/mod/codecs/mod_mp4v/Makefile src/mod/codecs/mod_opus/Makefile src/mod/codecs/mod_openh264/Makefile src/mod/codecs/mod_silk/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index d3a00c7071b..d77ca48d3fa 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -35,8 +35,6 @@ supported_distros="$supported_debian_distros $supported_ubuntu_distros" avoid_mods=( applications/mod_limit applications/mod_mongo - applications/mod_mp4 - applications/mod_mp4v2 applications/mod_osp applications/mod_rad_auth applications/mod_skel @@ -712,7 +710,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g729 (= \${binary:Version}), freeswitch-mod-h26x (= \${binary:Version}), freeswitch-mod-isac (= \${binary:Version}), - freeswitch-mod-mp4v (= \${binary:Version}), freeswitch-mod-opus (= \${binary:Version}), freeswitch-mod-silk (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), @@ -738,7 +735,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g729-dbg (= \${binary:Version}), freeswitch-mod-h26x-dbg (= \${binary:Version}), freeswitch-mod-isac-dbg (= \${binary:Version}), - freeswitch-mod-mp4v-dbg (= \${binary:Version}), freeswitch-mod-opus-dbg (= \${binary:Version}), freeswitch-mod-silk-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index b11dc100059..2261416c47d 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -149,16 +149,6 @@ Description: MongoDB This module provides an interface to MongoDB. Build-Depends: libmongoc-dev -Module: applications/mod_mp4 -Section: contrib/comm -Description: MP4 video support - This module adds support for MP4 video playback. -Build-Depends: libmp4v2-dev - -Module: applications/mod_mp4v2 -Description: Adds mod_mp4v2 - Adds mod_mp4v2. - Module: applications/mod_nibblebill Description: Nibblebill This module allows for real-time accounting of a cash balance and @@ -333,10 +323,6 @@ Module: codecs/mod_isac Description: mod_isac Adds mod_isac. -Module: codecs/mod_mp4v -Description: mod_mp4v - Adds mod_mp4v. - Module: codecs/mod_openh264 Description: Adds mod_openh264 Adds mod_openh264. diff --git a/freeswitch.spec b/freeswitch.spec index 773b8784c78..8761ca2365a 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -722,14 +722,6 @@ Requires: %{name} = %{version}-%{release} %description codec-vpx iSAC Codec support for FreeSWITCH open source telephony platform -%package codec-mp4v -Summary: MP4V Video Codec support for FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description codec-mp4v -MP4V Video Codec support for FreeSWITCH open source telephony platform - %package codec-opus Summary: Opus Codec support for FreeSWITCH open source telephony platform Group: System/Libraries @@ -1351,7 +1343,7 @@ ASR_TTS_MODULES="asr_tts/mod_flite asr_tts/mod_pocketsphinx asr_tts/mod_tts_comm # ###################################################################################################################### CODECS_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_bv codecs/mod_codec2 codecs/mod_g723_1 \ - codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_mp4v codecs/mod_opus codecs/mod_silk \ + codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_opus codecs/mod_silk \ codecs/mod_siren codecs/mod_theora" # @@ -2075,9 +2067,6 @@ fi %files codec-isac %{MODINSTDIR}/mod_isac.so* -%files codec-mp4v -%{MODINSTDIR}/mod_mp4v.so* - %files codec-opus %{MODINSTDIR}/mod_opus.so* %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opus.conf.xml diff --git a/src/mod/applications/mod_mp4/Makefile.am b/src/mod/applications/mod_mp4/Makefile.am deleted file mode 100644 index 46d3f78dfa8..00000000000 --- a/src/mod/applications/mod_mp4/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4 - -mod_LTLIBRARIES = mod_mp4.la -mod_mp4_la_SOURCES = mod_mp4.cpp mp4_helper.cpp -mod_mp4_la_CFLAGS = $(AM_CFLAGS) -mod_mp4_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lmp4v2 diff --git a/src/mod/applications/mod_mp4/exception.hpp b/src/mod/applications/mod_mp4/exception.hpp deleted file mode 100644 index 75f84989a2d..00000000000 --- a/src/mod/applications/mod_mp4/exception.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - -The contents of this file are subject to the Mozilla Public License -Version 1.1 (the "License"); you may not use this file except in -compliance with the License. You may obtain a copy of the License at -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -License for the specific language governing rights and limitations -under the License. - -The Original Code is MP4 Helper Library to Freeswitch MP4 module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -*/ - -#ifndef EXCEPTION_HPP_ -#define EXCEPTION_HPP_ - -#include -#include - -class Exception: public std::exception { - public: - Exception() - { - } - - Exception(const std::string & message): message_(message) - { - } - - Exception(const std::exception & e): message_(e.what()) - { - } - - Exception(const Exception & e): message_(e.message_) - { - } - - virtual ~Exception() throw() - { - } - - const char * what() const throw() - { - return message_.c_str(); - } - - private: - std::string message_; -}; - -#endif \ No newline at end of file diff --git a/src/mod/applications/mod_mp4/mod_mp4.cpp b/src/mod/applications/mod_mp4/mod_mp4.cpp deleted file mode 100644 index 433642d8167..00000000000 --- a/src/mod/applications/mod_mp4/mod_mp4.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Paulo Rogério Panhoto - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * mod_mp4 -- MP4 File Format support for video apps. - * - */ - -#include -#include "mp4_helper.hpp" -#include "exception.hpp" - - -#ifndef min -#define min(x, y) ((x) < (y) ? (x) : (y)) -#endif - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4_load); -SWITCH_MODULE_DEFINITION(mod_mp4, mod_mp4_load, NULL, NULL); - -#define VID_BIT (1 << 31) -#define VERSION 4201 - -#ifdef MP4_RECORD -struct file_header { - int32_t version; - char video_codec_name[32]; - char video_fmtp[128]; - uint32_t audio_rate; - uint32_t audio_ptime; - switch_time_t created; -}; - -struct record_helper { - switch_core_session_t *session; - switch_mutex_t *mutex; - int fd; - int up; -}; -#endif - -struct AVParams { - switch_core_session_t * session; - switch_channel_t * channel; - switch_timer_t * timer; - switch_frame_t * frame; - switch_mutex_t * mutex; - bool video; - switch_payload_t pt; - MP4::Context * vc; - bool done; - bool * quit; -}; - -static void *SWITCH_THREAD_FUNC record_video_thread(switch_thread_t *thread, void *obj) -{ -#ifdef MP4_RECORD - record_helper *eh = reinterpret_cast(obj); - switch_core_session_t *session = eh->session; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status; - switch_frame_t *read_frame; - int bytes; - - eh->up = 1; - while (switch_channel_ready(channel)) { - status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; - } - - if (switch_test_flag(read_frame, SFF_CNG)) { - continue; - } - - bytes = read_frame->packetlen | VID_BIT; - - switch_mutex_lock(eh->mutex); - - if (write(eh->fd, &bytes, sizeof(bytes)) != (int) sizeof(bytes)) { - switch_mutex_unlock(eh->mutex); - break; - } - - if (write(eh->fd, read_frame->packet, read_frame->packetlen) != (int) read_frame->packetlen) { - switch_mutex_unlock(eh->mutex); - break; - } - - switch_mutex_unlock(eh->mutex); - - switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); - } - eh->up = 0; -#endif - return NULL; -} - -SWITCH_STANDARD_APP(record_mp4_function) -{ -#ifdef MP4_RECORD - switch_status_t status; - switch_frame_t *read_frame; - switch_channel_t *channel = switch_core_session_get_channel(session); - struct record_helper eh = { 0 }; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - int fd; - switch_mutex_t *mutex = NULL; - switch_codec_t codec, *vid_codec; - switch_codec_implementation_t read_impl = { }; - int count = 0, sanity = 30; - - switch_core_session_get_read_impl(session, &read_impl); - switch_channel_answer(channel); - - - while (switch_channel_up(channel) && !switch_channel_test_flag(channel, CF_VIDEO)) { - switch_yield(10000); - - if (count) count--; - - if (count == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s waiting for video.\n", switch_channel_get_name(channel)); - count = 100; - if (!--sanity) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s timeout waiting for video.\n", - switch_channel_get_name(channel)); - return; - } - } - } - - if (!switch_channel_ready(channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s not ready.\n", switch_channel_get_name(channel)); - return; - } - -/* - if ((fd = open((char *) data, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data); - return; - } -*/ - - MP4::Context ctx(reinterpret_cast(data), true); - - if (switch_core_codec_init(&codec, - "L16", - NULL, - NULL, - read_impl.samples_per_second, - read_impl.microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); - goto end; - } - - switch_core_session_set_read_codec(session, &codec); - - if (switch_channel_test_flag(channel, CF_VIDEO)) { - struct file_header h; - memset(&h, 0, sizeof(h)); - vid_codec = switch_core_session_get_video_read_codec(session); - - h.version = VERSION; - h.created = switch_micro_time_now(); - switch_set_string(h.video_codec_name, vid_codec->implementation->iananame); - if (vid_codec->fmtp_in) { - switch_set_string(h.video_fmtp, vid_codec->fmtp_in); - } - h.audio_rate = read_impl.samples_per_second; - h.audio_ptime = read_impl.microseconds_per_packet / 1000; - - if (write(fd, &h, sizeof(h)) != sizeof(h)) { - goto end; - } - - switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - eh.mutex = mutex; - eh.fd = fd; - eh.session = session; - switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, record_video_thread, &eh, switch_core_session_get_pool(session)); - } - - - while (switch_channel_ready(channel)) { - - status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; - } - - if (switch_test_flag(read_frame, SFF_CNG)) { - continue; - } - - if (mutex) { - switch_mutex_lock(mutex); - } - - if (write(fd, &read_frame->datalen, sizeof(read_frame->datalen)) != sizeof(read_frame->datalen)) { - if (mutex) { - switch_mutex_unlock(mutex); - } - break; - } - - if (write(fd, read_frame->data, read_frame->datalen) != (int) read_frame->datalen) { - if (mutex) { - switch_mutex_unlock(mutex); - } - break; - } - - if (mutex) { - switch_mutex_unlock(mutex); - } - } - - - end: - - if (eh.up) { - while (eh.up) { - switch_cond_next(); - } - } - - switch_core_session_set_read_codec(session, NULL); - switch_core_codec_destroy(&codec); -#endif -} - -static void *SWITCH_THREAD_FUNC play_video_function(switch_thread_t *thread, void *obj) -{ - AVParams * pt = reinterpret_cast(obj); - u_int next = 0, first = 0xffffffff; - uint64_t ts = 0, control = 0; - - bool ok; - bool sent = true; - pt->done = false; - switch_time_t start = switch_time_now(); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Video thread Started\n"); - while (!*pt->quit && switch_channel_ready(pt->channel)) { - if (pt->video) { - if (sent) { - switch_mutex_lock(pt->mutex); - pt->frame->packetlen = pt->frame->buflen; - ok = pt->vc->getVideoPacket(pt->frame->packet, pt->frame->packetlen, next); - switch_mutex_unlock(pt->mutex); - sent = false; - if (ok) { - switch_rtp_hdr_t *hdr = reinterpret_cast(pt->frame->packet); - if(first == 0xffffffff) first = next; - next -= first; - control = next * 90000LL / pt->vc->videoTrack().track.clock; - control -= first; - hdr->ts = htonl(control); - control = control * 1000 / 90; - if (pt->pt) - hdr->pt = pt->pt; - } else break; - } - - ts = switch_time_now() - start; - int64_t wait = control > ts ? (control - ts) : 0; - - if (wait > 0) { - switch_cond_next(); - // wait the time for the next Video frame - switch_sleep(wait); - } - - if (switch_channel_test_flag(pt->channel, CF_VIDEO)) { - switch_byte_t *data = (switch_byte_t *) pt->frame->packet; - - pt->frame->data = data + 12; - pt->frame->datalen = pt->frame->packetlen - 12; - switch_core_session_write_video_frame(pt->session, pt->frame, SWITCH_IO_FLAG_NONE, 0); - sent = true; - } - - } - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Video thread ended\n"); - pt->done = true; - return NULL; -} - -static void *SWITCH_THREAD_FUNC play_audio_function(switch_thread_t *thread, void *obj) -{ - AVParams * pt = reinterpret_cast(obj); - u_int next = 0, first = 0xffffffff; - uint64_t ts = 0, control = 0; - - bool ok; - bool sent = true; - switch_dtmf_t dtmf = {0}; - pt->done = false; - switch_frame_t * read_frame; - - while (!*pt->quit && switch_channel_ready(pt->channel)) { - // event processing. - // -- SEE switch_ivr_play_say.c:1231 && mod_dptools.c:1428 && mod_dptools.c:1919 - switch_core_session_read_frame(pt->session, &read_frame, SWITCH_IO_FLAG_SINGLE_READ, 0); - - if (switch_channel_test_flag(pt->channel, CF_BREAK)) { - switch_channel_clear_flag(pt->channel, CF_BREAK); - break; - } - - switch_ivr_parse_all_events(pt->session); - - if (switch_channel_has_dtmf(pt->channel)) { - switch_channel_dequeue_dtmf(pt->channel, &dtmf); - const char * terminators = switch_channel_get_variable(pt->channel, SWITCH_PLAYBACK_TERMINATORS_VARIABLE); - if (terminators && !strcasecmp(terminators, "none")) terminators = NULL; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Digit %c\n", dtmf.digit); - if (terminators && strchr(terminators, dtmf.digit)) { - std::string digit(&dtmf.digit, 0, 1); - switch_channel_set_variable(pt->channel, SWITCH_PLAYBACK_TERMINATOR_USED, digit.c_str()); - break; - } - } - - switch_mutex_lock(pt->mutex); - pt->frame->datalen = pt->frame->buflen; - ok = pt->vc->getAudioPacket(pt->frame->data, pt->frame->datalen, next); - switch_mutex_unlock(pt->mutex); - - if (ok) { - if (pt->frame->datalen > (int) pt->frame->buflen) - pt->frame->datalen = pt->frame->buflen; - - switch_core_session_write_frame(pt->session, pt->frame, SWITCH_IO_FLAG_NONE, 0); - switch_core_timer_next(pt->timer); - } - else break; - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Audio done\n"); - *pt->quit = pt->done = true; - return NULL; -} - -SWITCH_STANDARD_APP(play_mp4_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_frame_t write_frame = { 0 }, vid_frame = {0}; - switch_codec_t codec = { 0 }, vid_codec = {0}, *read_vid_codec; - unsigned char *aud_buffer; - unsigned char *vid_buffer; - switch_timer_t timer = { 0 }; - switch_codec_implementation_t read_impl = {}; - bool done = false; - - try { - MP4::Context vc((char *) data); - - switch_payload_t pt = 0; - - switch_core_session_get_read_impl(session, &read_impl); - - aud_buffer = (unsigned char *) switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); - vid_buffer = (unsigned char *) switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); - - /* - if (!vc.isOpen()) - { - char msgbuf[1024]; - sprintf(msgbuf, "PLAYBACK ERROR (%s): FILE NOT FOUND.", (char*) data); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, msgbuf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data); - return; - } - - if(!vc.isSupported()) - { - char msgbuf[1024]; - sprintf(msgbuf, "PLAYBACK ERROR (%s): UNSUPPORTED FORMAT OR FILE NOT HINTED.", (char*) data); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, msgbuf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, - "Error reading track info. Maybe this file is not hinted.\n"); - throw 1; - } - */ - - switch_channel_set_variable(channel, "rtp_force_video_fmtp", vc.videoTrack().fmtp.c_str()); - switch_channel_answer(channel); - - if ((read_vid_codec = switch_core_session_get_video_read_codec(session))) { - pt = read_vid_codec->agreed_pt; - } - - write_frame.codec = &codec; - write_frame.data = aud_buffer; - write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; - - vid_frame.codec = &vid_codec; - vid_frame.packet = vid_buffer; - vid_frame.data = vid_buffer + 12; - vid_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE - 12; - switch_set_flag((&vid_frame), SFF_RAW_RTP); - switch_set_flag((&vid_frame), SFF_PROXY_PACKET); - - if (switch_core_timer_init(&timer, "soft", read_impl.microseconds_per_packet / 1000, - read_impl.samples_per_packet, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Timer Activation Fail\n"); - throw 2; - } - - if (switch_core_codec_init(&codec, - vc.audioTrack().codecName, - NULL, - NULL, - vc.audioTrack().clock, - vc.audioTrack().packetLength, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - throw Exception("Audio Codec Activation Fail"); - } - - if (switch_core_codec_init(&vid_codec, - vc.videoTrack().track.codecName, - NULL, - NULL, - 0, - 0, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Activation Success\n"); - } else - { - throw Exception("Video Codec Activation Fail"); - } - switch_core_session_set_read_codec(session, &codec); - - AVParams vpt; - vpt.session = session; - vpt.channel = channel; - vpt.frame = &vid_frame; - vpt.timer = &timer; - vpt.video = true; - vpt.pt = pt; - vpt.vc = &vc; - switch_mutex_init(&vpt.mutex, SWITCH_MUTEX_DEFAULT, switch_core_session_get_pool(session)); - vpt.quit = &done; - - switch_threadattr_t * thd_attr; - switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_t *thread; - switch_thread_create(&thread, thd_attr, play_video_function, (void*)&vpt, switch_core_session_get_pool(session)); - - AVParams apt; - apt.session = session; - apt.channel = channel; - apt.frame = &write_frame; - apt.timer = &timer; - apt.video = false; - apt.vc = &vc; - apt.mutex = vpt.mutex; - apt.quit = &done; - play_audio_function(NULL, &apt); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Waiting for video thread to join.\n"); - while (!vpt.done) { - switch_cond_next(); - } - - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE PLAYED"); - } catch(const std::exception & e) - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s\n", e.what()); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, - (std::string("PLAYBACK_FAILED - ") + e.what()).c_str()); - }catch(...) - { - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK_FAILED - See FS logs for detail."); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Exception caught.\n"); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "All done.\n"); - if (timer.interval) switch_core_timer_destroy(&timer); - - switch_core_session_set_read_codec(session, NULL); - - if (switch_core_codec_ready(&codec)) switch_core_codec_destroy(&codec); - - if (switch_core_codec_ready(&vid_codec)) switch_core_codec_destroy(&vid_codec); -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4_load) -{ - switch_application_interface_t *app_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "play_mp4", "play an MP4 file", "play an MP4 file", play_mp4_function, "", SAF_NONE); - //SWITCH_ADD_APP(app_interface, "record_mp4", "record an MP4 file", "record an MP4 file", record_mp4_function, "", SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/applications/mod_mp4/mp4_helper.cpp b/src/mod/applications/mod_mp4/mp4_helper.cpp deleted file mode 100644 index 0904cafd675..00000000000 --- a/src/mod/applications/mod_mp4/mp4_helper.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - -The contents of this file are subject to the Mozilla Public License -Version 1.1 (the "License"); you may not use this file except in -compliance with the License. You may obtain a copy of the License at -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -License for the specific language governing rights and limitations -under the License. - -The Original Code is MP4 Helper Library to the Freeswitch MP4 Module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -Contributors: - - Seven Du -*/ - -#include -#include "mp4_helper.hpp" - -namespace MP4 -{ - - Context::Context(const char * file, bool newFile) - { - if(newFile) create(file); - else open(file); - } - - Context::~Context() - { - close(); - } - - void Context::open(const char * file) - { - fh = MP4Read(file); - if (fh == MP4_INVALID_FILE_HANDLE) throw Exception(file, "Open failed"); - getTracks(file); - } - - void Context::create(const char * file) - { - fh = MP4Create(file); - if (fh == MP4_INVALID_FILE_HANDLE) throw Exception(file, "Create file failed"); - } - - void Context::close() - { - if (!isOpen()) return; - MP4Close(fh); - } - - void Context::getTracks(const char * file) - { - int i = 0; - bool audioTrack = false, videoTrack = false; - - if (!isOpen()) throw Exception(file, "File is closed."); - - for (;;) - { - TrackProperties track; - if((track.hint = MP4FindTrackId(fh, i++, MP4_HINT_TRACK_TYPE, 0)) == MP4_INVALID_TRACK_ID) break; - - MP4GetHintTrackRtpPayload(fh, track.hint, &track.codecName, &track.payload, NULL, NULL); - - track.track = MP4GetHintTrackReferenceTrackId(fh, track.hint); - if(track.track == MP4_INVALID_TRACK_ID) continue; - track.clock = MP4GetTrackTimeScale(fh, track.hint); - - if (!strcmp(MP4GetTrackType(fh, track.track), MP4_AUDIO_TRACK_TYPE)) { - audioTrack = true; - - if(!strncmp(track.codecName, "PCM", 3)) - track.packetLength = 20; - else - track.packetLength = track.clock = 0; - - audio = track; - } else if (!strcmp(MP4GetTrackType(fh, track.track), MP4_VIDEO_TRACK_TYPE)) { - videoTrack = true; - - const char * sdp = MP4GetHintTrackSdp(fh, track.hint); - const char * fmtp = strstr(sdp, "fmtp"); - - if (fmtp) { - // finds beginning of 'fmtp' value; - for(fmtp += 5; *fmtp != ' '; ++fmtp); - ++fmtp; - - const char * eol = fmtp; - for(;*eol != '\r' && *eol != '\n'; ++eol); - video.fmtp = std::string(fmtp, eol); - } - video.track = track; - } - } - - if (!audioTrack || !videoTrack) throw Exception(file, "Missing audio/video track."); - } - - bool Context::getVideoPacket(void * buffer, u_int & size, u_int & ts) - { - return getPacket(video.track.hint, video.track.runtime, true, buffer, size, ts); - } - - bool Context::getAudioPacket(void * buffer, u_int & size, u_int & ts) - { - return getPacket(audio.hint, audio.runtime, false, buffer, size, ts); - } - - bool Context::getPacket(MP4TrackId hint, RuntimeProperties & rt, - bool header, void * buffer, u_int & size, u_int & ts) - { - if (rt.frame == 0 || rt.packet == rt.packetsPerFrame) { - ++rt.frame; - if(!MP4ReadRtpHint(fh, hint, rt.frame, &rt.packetsPerFrame)) - return false; - rt.packet = 0; - rt.last_frame = MP4GetSampleTime(fh, hint, rt.frame); - } - - ts = rt.last_frame; - if (!MP4ReadRtpPacket(fh, hint, rt.packet, (uint8_t **) &buffer, &size, 0, header, true)) return false; - ++rt.packet; - return true; - } -} diff --git a/src/mod/applications/mod_mp4/mp4_helper.hpp b/src/mod/applications/mod_mp4/mp4_helper.hpp deleted file mode 100644 index 8f61cd6c6b5..00000000000 --- a/src/mod/applications/mod_mp4/mp4_helper.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - -The contents of this file are subject to the Mozilla Public License -Version 1.1 (the "License"); you may not use this file except in -compliance with the License. You may obtain a copy of the License at -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -License for the specific language governing rights and limitations -under the License. - -The Original Code is MP4 Helper Library to Freeswitch MP4 module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -Contributor(s): - - Seven Du - -*/ - -#ifndef MP4_HELPER_HPP_ -#define MP4_HELPER_HPP_ - -#include -#include -#include -#include - -typedef unsigned int u_int; - -namespace MP4 -{ - class Exception: public std::exception { - public: - Exception(const std::string & file, const std::string & error) - : description_(file + ':' + error) - { - } - - const char * what() const throw() - { - return description_.c_str(); - } - - ~Exception() throw() - { - } - - private: - std::string description_; - }; - - struct RuntimeProperties { - uint32_t frame; // sampleID - uint16_t packetsPerFrame; - uint16_t packet; // packetID - uint32_t last_frame; // timestamp - - RuntimeProperties(): frame(0), packetsPerFrame(0), packet(0) - { - } - }; - - - struct TrackProperties { - MP4TrackId hint; - MP4TrackId track; - - char * codecName; - uint8_t payload; - uint32_t clock; - uint32_t packetLength; // packet Length in time (ms) - - RuntimeProperties runtime; - - TrackProperties(): hint(MP4_INVALID_TRACK_ID), track(MP4_INVALID_TRACK_ID), - codecName(NULL), payload(0), clock(0), packetLength(0) - { - } - }; - - typedef TrackProperties AudioProperties; - - struct VideoProperties { - TrackProperties track; - std::string fmtp; - - VideoProperties() - { - } - - VideoProperties(const TrackProperties & rhs): track(rhs) - { - } - }; - - class Context { - public: - - Context(const char * file, bool create = false); - ~Context(); - - void open(const char * file); - - void create(const char * file); - - void close(); - - // returns: TRUE = has more data, FALSE = end-of-stream or failure - bool getVideoPacket(void * buffer, u_int & size, u_int & ts); - - // returns: TRUE = has more data, FALSE = end-of-stream or failure - bool getAudioPacket(void * buffer, u_int & size, u_int & ts); - - bool isOpen() const { return fh != MP4_INVALID_FILE_HANDLE; } - - bool isSupported() const { return audio.track != MP4_INVALID_TRACK_ID && video.track.track != MP4_INVALID_TRACK_ID; } - - const AudioProperties & audioTrack() const { return audio; } - - const VideoProperties & videoTrack() const { return video; } - - private: - MP4FileHandle fh; - AudioProperties audio; - - VideoProperties video; - - // Prevent copy construction. - Context(const Context &); - - bool getPacket(MP4TrackId hint, RuntimeProperties & rt, - bool header, void * buffer, u_int & size, u_int & ts); - - void getTracks(const char * file); - }; -} -#endif diff --git a/src/mod/applications/mod_mp4v2/Makefile.am b/src/mod/applications/mod_mp4v2/Makefile.am deleted file mode 100644 index f8b8bec05a7..00000000000 --- a/src/mod/applications/mod_mp4v2/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4v2 - -mod_LTLIBRARIES = mod_mp4v2.la -mod_mp4v2_la_SOURCES = mod_mp4v2.c -mod_mp4v2_la_CFLAGS = $(AM_CFLAGS) -mod_mp4v2_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4v2_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lmp4v2 diff --git a/src/mod/applications/mod_mp4v2/mod_mp4v2.c b/src/mod/applications/mod_mp4v2/mod_mp4v2.c deleted file mode 100644 index 8faccc4e02c..00000000000 --- a/src/mod/applications/mod_mp4v2/mod_mp4v2.c +++ /dev/null @@ -1,772 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2015, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Seven Du - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * - * mod_mp4v2 -- MP4 File Format for FreeSWITCH - * - * - * status: For write, codec is hard coded to PCMU for audio and H264 for video - * tested with lib mp4v2-2.0.0 - * Read from mp4 is not supported yet. - */ - -#include - -#include - -#define TIMESCALE 1000 -#define SampleLenFieldSize 4 -#define PTIME 20 -// #define HAS_SPS_PARSER - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v2_load); -SWITCH_MODULE_DEFINITION(mod_mp4v2, mod_mp4v2_load, NULL, NULL); - -struct record_helper { - switch_core_session_t *session; - switch_mutex_t *mutex; - MP4FileHandle fd; - MP4TrackId video_track; - MP4TrackId audio_track; - switch_timer_t timer; - int up; - uint64_t last_pts; -}; - -#ifdef HAS_SPS_PARSER -#include "bs.h" -static void parse_sps_video_size(uint8_t *sps_buffer, int len, int *width, int *height) -{ - sps_t sps = { 0 }; - bs_t b = { 0 }; - - bs_init(&b, sps_buffer, len); - read_sps(&sps, &b); - - *width = ((sps.pic_width_in_mbs_minus1 +1)*16) - sps.frame_crop_left_offset*2 - sps.frame_crop_right_offset*2; - *height= ((2 - sps.frame_mbs_only_flag)* (sps.pic_height_in_map_units_minus1 +1) * 16) - (sps.frame_crop_top_offset * 2) - (sps.frame_crop_bottom_offset * 2); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "H264 Profile: %d size: %dx%d\n", sps.profile_idc, *width, *height); -} -#else -// use hardcoded value -static void parse_sps_video_size(uint8_t *sps_buffer, int len, int *width, int *height) -{ - *width = 1280; - *height = 720; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "We have no idea about the video size without decoding the video or actually parse the SPS, using hardcoded %dx%d\n", *width, *height); -} -#endif - -static void init_video_track(MP4FileHandle mp4, MP4TrackId *video, switch_frame_t *frame) -{ - int width = 0; - int height = 0; - uint8_t *sps_buffer = frame->data; - uint32_t sps_bytes = frame->datalen; - - sps_buffer++; - - if (frame->img) { - width = frame->img->d_w; - height = frame->img->d_h; - } else { - parse_sps_video_size(sps_buffer, sps_bytes, &width, &height); - } - - MP4SetTimeScale(mp4, TIMESCALE); - - *video = MP4AddH264VideoTrack(mp4, TIMESCALE, MP4_INVALID_DURATION, width, height, *(sps_buffer), *(sps_buffer+1), *(sps_buffer+2), SampleLenFieldSize - 1); - - if (*video == MP4_INVALID_TRACK_ID) { - return; - } - - MP4AddH264SequenceParameterSet(mp4, *video, --sps_buffer, sps_bytes); - - /* - MP4SetVideoProfileLevel sets the minumum profile/level of MPEG-4 video support necessary to render the contents of the file. - - ISO/IEC 14496-1:2001 MPEG-4 Systems defines the following values: - 0x00 Reserved - 0x01 Simple Profile @ Level 3 - 0x02 Simple Profile @ Level 2 - 0x03 Simple Profile @ Level 1 - 0x04 Simple Scalable Profile @ Level 2 - 0x05 Simple Scalable Profile @ Level 1 - 0x06 Core Profile @ Level 2 - 0x07 Core Profile @ Level 1 - 0x08 Main Profile @ Level 4 - 0x09 Main Profile @ Level 3 - 0x0A Main Profile @ Level 2 - 0x0B N-Bit Profile @ Level 2 - 0x0C Hybrid Profile @ Level 2 - 0x0D Hybrid Profile @ Level 1 - 0x0E Basic Animated Texture @ Level 2 - 0x0F Basic Animated Texture @ Level 1 - 0x10 Scalable Texture @ Level 3 - 0x11 Scalable Texture @ Level 2 - 0x12 Scalable Texture @ Level 1 - 0x13 Simple Face Animation @ Level 2 - 0x14 Simple Face Animation @ Level 1 - 0x15-0x7F Reserved - 0x80-0xFD User private - 0xFE No audio profile specified - 0xFF No audio required - */ - MP4SetVideoProfileLevel(mp4, 0x7F); -} - -static inline char *get_audio_codec_name(uint8_t audio_type) -{ - switch (audio_type) { - case MP4_MP3_AUDIO_TYPE: - return "MP3"; - case MP4_ULAW_AUDIO_TYPE: - return "PCMU"; - case MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE: - return "L16"; - case MP4_MPEG4_AUDIO_TYPE: - return "AAC"; - default: - return "ERROR"; - } -} - -static int get_aac_sample_rate_index(unsigned int sampleRate) -{ - if (92017 <= sampleRate) return 0; - if (75132 <= sampleRate) return 1; - if (55426 <= sampleRate) return 2; - if (46009 <= sampleRate) return 3; - if (37566 <= sampleRate) return 4; - if (27713 <= sampleRate) return 5; - if (23004 <= sampleRate) return 6; - if (18783 <= sampleRate) return 7; - if (13856 <= sampleRate) return 8; - if (11502 <= sampleRate) return 9; - if (9391 <= sampleRate) return 10; - - return 11; -} - -struct mp4_file_context { - switch_file_handle_t *handle; - switch_memory_pool_t *pool; - MP4FileHandle fd; - MP4TrackId audio; - MP4TrackId video; - uint32_t audio_frame_size; - switch_codec_t audio_codec; - switch_codec_t video_codec; - switch_mutex_t *mutex; - switch_buffer_t *buf; - uint32_t last_chunk_size; - int sps_set; - int pps_set; - switch_timer_t timer; - uint64_t last_pts; - int offset; - int audio_start; - uint8_t audio_type; // MP4 Audio Type - MP4Duration audio_duration; - switch_thread_t *video_thread; - switch_queue_t *video_queue; -}; - -typedef struct mp4_file_context mp4_file_context_t; - -static switch_status_t do_write_video(switch_file_handle_t *handle, switch_frame_t *frame); - -static void *SWITCH_THREAD_FUNC video_write_thread_run(switch_thread_t *thread, void *obj) -{ - mp4_file_context_t *context = (mp4_file_context_t *)obj; - void *pop = NULL; - switch_image_t *last_img = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_status_t encode_status = SWITCH_STATUS_SUCCESS; - uint8_t data[SWITCH_DEFAULT_VIDEO_SIZE]; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video_write_thread start\n"); - - while (switch_queue_pop(context->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { - switch_frame_t frame = { 0 }; - - if (!pop) break; - - if (!last_img) { // first img - last_img = (switch_image_t *)pop; - continue; - } - - frame.data = data; - frame.img = last_img; - // switch_set_flag(&frame, SFF_DYNAMIC); - - do { - frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE; - encode_status = switch_core_codec_encode_video(&context->video_codec, &frame); - - if (encode_status == SWITCH_STATUS_SUCCESS || encode_status == SWITCH_STATUS_MORE_DATA) { - switch_assert((encode_status == SWITCH_STATUS_SUCCESS && frame.m) || !frame.m); - - if (frame.datalen == 0) break; - - status = do_write_video(context->handle, &frame); - } - } while(status == SWITCH_STATUS_SUCCESS && encode_status == SWITCH_STATUS_MORE_DATA); - - switch_img_free(&last_img); - last_img = (switch_image_t *)pop; - } - - switch_img_free(&last_img); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video_write_thread done\n"); - - return NULL; -} - -static void launch_video_write_thread(mp4_file_context_t *context, switch_memory_pool_t *pool) -{ - //switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - // switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&context->video_thread, thd_attr, video_write_thread_run, context, pool); -} - - -static int flush_video_queue(switch_queue_t *q, int min) -{ - void *pop; - - if (switch_queue_size(q) > min) { - while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { - switch_image_t *img = (switch_image_t *) pop; - switch_img_free(&img); - if (min && switch_queue_size(q) <= min) { - break; - } - } - } - - return switch_queue_size(q); -} - -static switch_status_t mp4_file_open(switch_file_handle_t *handle, const char *path) -{ - mp4_file_context_t *context; - char *ext; - unsigned int flags = 0; - const char *tmp = NULL; - - if ((ext = strrchr(path, '.')) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); - return SWITCH_STATUS_GENERR; - } - ext++; - - if ((context = switch_core_alloc(handle->memory_pool, sizeof(mp4_file_context_t))) == 0) { - return SWITCH_STATUS_MEMERR; - } - - memset(context, 0, sizeof(mp4_file_context_t)); - - context->handle = handle; - context->offset = 0; - - if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_video_offset"))) { - context->offset = atoi(tmp); - } - - context->audio_type = MP4_ULAW_AUDIO_TYPE; // default - - if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_audio_codec"))) { - if (!strcasecmp(tmp, "PCMU")) { - context->audio_type = MP4_ULAW_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "MP3")) { - context->audio_type = MP4_MP3_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "AAC")) { - context->audio_type = MP4_MPEG4_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "L16")) { - context->audio_type = MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE; - } - } - - switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - flags |= SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE; - if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(handle, SWITCH_FILE_WRITE_OVER)) { - flags |= SWITCH_FOPEN_READ; - } else { - flags |= SWITCH_FOPEN_TRUNCATE; - } - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) { - flags |= SWITCH_FOPEN_READ; - } - - if (handle->mm.samplerate) { - handle->samplerate = handle->mm.samplerate; - } else { - handle->mm.samplerate = handle->samplerate; - } - - if (!handle->mm.ab) { - handle->mm.ab = 128; - } - - if (!handle->mm.vb) { - handle->mm.vb = switch_calc_bitrate(handle->mm.vw, handle->mm.vh, 1, handle->mm.fps); - } - - // MP4_CREATE_64BIT_DATA if file > 4G - - if ((context->fd = MP4CreateEx(path, 0, 1, 1, NULL, 0, NULL, 0)) == MP4_INVALID_FILE_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening file %s\n", path); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sample rate: %d, channels: %d\n", handle->samplerate, handle->channels); - - if (context->audio_type == MP4_ULAW_AUDIO_TYPE) { - context->audio = MP4AddULawAudioTrack(context->fd, handle->samplerate); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.sampleSize", 8); - } else if (context->audio_type == MP4_MP3_AUDIO_TYPE) { - // handle->samplerate = 44100; - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_MP3_AUDIO_TYPE); - MP4SetTrackName(context->fd, context->audio, ".mp3"); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - // MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd..mp3.channels", handle->channels); - } else if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) { - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE); - MP4SetTrackName(context->fd, context->audio, "lpcm"); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.sampleSize", 16); - } else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) { - /* AAC object types */ - #define AAC_MAIN 1 - #define AAC_LOW 2 - #define AAC_SSR 3 - #define AAC_LTP 4 - - uint16_t info = 0; - - info |= AAC_LOW << 11; // aacObjectType (5bit) - info |= get_aac_sample_rate_index(handle->samplerate) << 7; //(4bit) - info |= handle->channels << 3; //(4bit) - info = htons(info); - - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, 1024, MP4_MPEG4_AUDIO_TYPE); - MP4SetTrackESConfiguration(context->fd, context->audio, (uint8_t *)&info, sizeof(info)); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - } - - handle->format = 0; - handle->sections = 0; - handle->seekable = 0; - handle->speed = 0; - handle->pos = 0; - handle->private_info = context; - context->pool = handle->memory_pool; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n", - path, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : ""); - - if (switch_core_codec_init(&context->audio_codec, - get_audio_codec_name(context->audio_type), - NULL, - NULL, - handle->samplerate, - PTIME,//ms - handle->channels, SWITCH_CODEC_FLAG_ENCODE, - NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); - goto end; - } - - if (context->audio_type == MP4_MP3_AUDIO_TYPE) { // fetch frame size - uint32_t size; - uint32_t flag = 0xFFFFFFFF; - - switch_core_codec_encode(&context->audio_codec, NULL, &flag, 0, 0, - (void *)&context->audio_frame_size, &size, NULL, &flag); - } else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) { - context->audio_frame_size = 1024; - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { - switch_codec_settings_t codec_settings = {{ 0 }}; - codec_settings.video.bandwidth = handle->mm.vb; - codec_settings.video.fps = handle->mm.fps; - - if (switch_core_codec_init(&context->video_codec, - "H264", - NULL, - NULL, - 90000, - 0,//ms - 1, SWITCH_CODEC_FLAG_ENCODE, - &codec_settings, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Codec H264 Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video Codec H264 Activation Fail\n"); - goto end; - } - - switch_queue_create(&context->video_queue, 60, handle->memory_pool); - launch_video_write_thread(context, handle->memory_pool); - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - MP4SetAudioProfileLevel(context->fd, 0x7F); - } - - switch_buffer_create_dynamic(&context->buf, 512, 512, 1024000); - - return SWITCH_STATUS_SUCCESS; - -end: - if (context->fd) { - MP4Close(context->fd, 0); - context->fd = NULL; - } - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_truncate(switch_file_handle_t *handle, int64_t offset) -{ - mp4_file_context_t *context = handle->private_info; - switch_status_t status; - - if ((status = switch_file_trunc(context->fd, offset)) == SWITCH_STATUS_SUCCESS) { - handle->pos = 0; - } - - return status; - -} - -static switch_status_t mp4_file_close(switch_file_handle_t *handle) -{ - mp4_file_context_t *context = handle->private_info; - switch_status_t status; - - if (context->fd) { - MP4Close(context->fd, MP4_CLOSE_DO_NOT_COMPUTE_BITRATE); - context->fd = NULL; - } - - if (switch_core_codec_ready(&context->audio_codec)) switch_core_codec_destroy(&context->audio_codec); - if (switch_core_codec_ready(&context->video_codec)) switch_core_codec_destroy(&context->video_codec); - - if (context->timer.interval) { - switch_core_timer_destroy(&context->timer); - } - - if (context->video_queue) { - switch_queue_term(context->video_queue); - flush_video_queue(context->video_queue, 0); - } - - if (context->video_thread) { - switch_thread_join(&status, context->video_thread); - } - - switch_buffer_destroy(&context->buf); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t mp4_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "seek not implemented\n"); - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read not implemented\n"); - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_write(switch_file_handle_t *handle, void *data, size_t *len) -{ - uint32_t datalen = *len * 2 * handle->channels; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - uint32_t encoded_rate; - mp4_file_context_t *context = handle->private_info; - uint32_t size = 0; - uint32_t flag = 0; - - if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) { - size = datalen; - memcpy(buf, data, datalen); - } else { - switch_core_codec_encode(&context->audio_codec, NULL, - data, datalen, - handle->samplerate, - buf, &size, &encoded_rate, &flag); - } - - switch_mutex_lock(context->mutex); - - if (!context->timer.interval) { - switch_core_timer_init(&context->timer, "soft", 1, 1, context->pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); - } - - if (size > 0) { - MP4WriteSample(context->fd, context->audio, buf, size, context->audio_frame_size ? context->audio_frame_size : *len, 0, 1); - } - - context->audio_duration += *len; - - switch_mutex_unlock(context->mutex); - - return status; -} - -static switch_status_t mp4_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t do_write_video(switch_file_handle_t *handle, switch_frame_t *frame) -{ - uint32_t datalen = frame->datalen; - switch_status_t status = SWITCH_STATUS_SUCCESS; - int is_iframe = 0; - uint32_t size; - uint8_t *hdr = NULL; - uint8_t fragment_type; - uint8_t nal_type; - uint8_t start_bit; - uint8_t end_bit; - mp4_file_context_t *context = handle->private_info; - - hdr = (uint8_t *)frame->data; - fragment_type = hdr[0] & 0x1f; - nal_type = hdr[1] & 0x1f; - start_bit = hdr[1] & 0x80; - end_bit = hdr[1] & 0x40; - - is_iframe = fragment_type == 5 || (fragment_type == 28 && nal_type == 5); - - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x | len:%d m:%d st:%d i:%d\n", hdr[0], hdr[1], hdr[2], datalen, frame->m, start_bit, is_iframe); - - if (fragment_type == 7 && !context->sps_set) { //sps - context->sps_set = 1; - - init_video_track(context->fd, &context->video, frame); - if (context->video == MP4_INVALID_TRACK_ID) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error add video track!\n"); - return SWITCH_STATUS_FALSE; - } - } else if (fragment_type == 8 && context->sps_set && !context->pps_set) { //pps - MP4AddH264PictureParameterSet(context->fd, context->video, hdr, datalen); - context->pps_set = 1; - } - - if (fragment_type == 28) { - if (start_bit && end_bit) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF?\n"); - } - - if (start_bit) { - nal_type |= (hdr[0] & 0x60); - - size = htonl(datalen); - switch_buffer_write(context->buf, &size, 4); - switch_buffer_write(context->buf, &nal_type, 1); - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size = datalen - 1; - } else if (end_bit) { - uint32_t used; - const void *data; - uint32_t *chunk_size = NULL; - - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size += datalen - 2; - used = switch_buffer_inuse(context->buf); - switch_buffer_peek_zerocopy(context->buf, &data); - chunk_size = (uint32_t *)((uint8_t *)data + used - context->last_chunk_size - 4); - *chunk_size = htonl(context->last_chunk_size); - } else { - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size += datalen - 2; - } - } else { - size = htonl(datalen); - switch_buffer_write(context->buf, &size, 4); - switch_buffer_write(context->buf, hdr, datalen); - } - - if (!frame->m) { - return SWITCH_STATUS_SUCCESS; - } - - switch_mutex_lock(context->mutex); - - if (context->sps_set && context->pps_set) { - uint32_t used = switch_buffer_inuse(context->buf); - const void *data; - int duration = 0; - int ts = 0; - - if (frame->img && frame->img->user_priv) { - ts = *(int *)frame->img->user_priv; - } else { - switch_core_timer_sync(&context->timer); - ts = context->timer.samplecount; - } - - duration = ts - context->last_pts; - - if (duration <= 0) duration = 1; - - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "samplecount: %u, duration: %u\n", context->timer.samplecount, duration); - switch_buffer_peek_zerocopy(context->buf, &data); - - context->last_pts = ts; - - MP4WriteSample(context->fd, context->video, data, used, duration, 0, is_iframe); - switch_buffer_zero(context->buf); - } - - switch_mutex_unlock(context->mutex); - - { - int delta = context->timer.samplecount * (handle->samplerate / 1000) - context->audio_duration; - - if (delta > (int)handle->samplerate) { - uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; - size_t samples = handle->samplerate / 1000 * PTIME; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missed audio %d samples at %d\n", delta, (int)context->audio_duration / (handle->samplerate / 1000)); - - while ((delta -= samples) > 0) { - mp4_file_write(handle, data, &samples); - samples = handle->samplerate / 1000 * PTIME; - } - } - } - - return status; -} - -static switch_status_t mp4_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) -{ - mp4_file_context_t *context = handle->private_info; - - if (!frame->img) { - return do_write_video(handle, frame); - } else { - switch_image_t *img = NULL; - - if (!context->timer.interval) { - switch_mutex_lock(context->mutex); - switch_core_timer_init(&context->timer, "soft", 1, 1, context->pool); - switch_mutex_unlock(context->mutex); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); - } else { - switch_mutex_lock(context->mutex); - switch_core_timer_sync(&context->timer); - switch_mutex_unlock(context->mutex); - } - - switch_img_copy(frame->img, &img); - switch_assert(img); - img->user_priv = malloc(sizeof(int)); - *(int *)img->user_priv = context->timer.samplecount; - - if (switch_queue_trypush(context->video_queue, img) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "video queue full, discard one frame\n"); - } - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t mp4_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string) -{ - return SWITCH_STATUS_FALSE; -} - -static char *supported_formats[3] = { 0 }; - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v2_load) -{ - switch_file_interface_t *file_interface; - - supported_formats[0] = "mp4v2"; - supported_formats[1] = "mp4"; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = modname; - file_interface->extens = supported_formats; - file_interface->file_open = mp4_file_open; - file_interface->file_close = mp4_file_close; - file_interface->file_truncate = mp4_file_truncate; - file_interface->file_read = mp4_file_read; - file_interface->file_write = mp4_file_write; - file_interface->file_read_video = mp4_file_read_video; - file_interface->file_write_video = mp4_file_write_video; - file_interface->file_seek = mp4_file_seek; - file_interface->file_set_string = mp4_file_set_string; - file_interface->file_get_string = mp4_file_get_string; - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/codecs/mod_mp4v/Makefile.am b/src/mod/codecs/mod_mp4v/Makefile.am deleted file mode 100644 index 59f9fa41efc..00000000000 --- a/src/mod/codecs/mod_mp4v/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4v - -mod_LTLIBRARIES = mod_mp4v.la -mod_mp4v_la_SOURCES = mod_mp4v.c -mod_mp4v_la_CFLAGS = $(AM_CFLAGS) -mod_mp4v_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4v_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/codecs/mod_mp4v/mod_mp4v.c b/src/mod/codecs/mod_mp4v/mod_mp4v.c deleted file mode 100644 index 685e6756c7c..00000000000 --- a/src/mod/codecs/mod_mp4v/mod_mp4v.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_mp4v.c -- MP4V Video Codec - * - */ - -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load); -SWITCH_MODULE_DEFINITION(mod_mp4v, mod_mp4v_load, NULL, NULL); - -static switch_status_t switch_mp4v_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - int encoding, decoding; - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - if (!(encoding || decoding)) { - return SWITCH_STATUS_FALSE; - } else { - if (codec->fmtp_in) { - codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); - } - return SWITCH_STATUS_SUCCESS; - } -} - -static switch_status_t switch_mp4v_encode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *decoded_data, - uint32_t decoded_data_len, - uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, - unsigned int *flag) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t switch_mp4v_decode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *encoded_data, - uint32_t encoded_data_len, - uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, - unsigned int *flag) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t switch_mp4v_destroy(switch_codec_t *codec) -{ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load) -{ - switch_codec_interface_t *codec_interface; - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - SWITCH_ADD_CODEC(codec_interface, "MP4V Video (passthru)"); - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_VIDEO, 99, "MP4V-ES", NULL, 90000, 90000, 0, - 0, 0, 0, 0, 1, 1, switch_mp4v_init, switch_mp4v_encode, switch_mp4v_decode, switch_mp4v_destroy); - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */