FS-7519: merge mod_avcodec and mod_avformat into mod_av

This commit is contained in:
Anthony Minessale 2015-05-21 15:48:48 -05:00 committed by Michael Jerris
parent 3a8c6c3803
commit e8fed1a47f
9 changed files with 61 additions and 2198 deletions

View File

@ -1701,7 +1701,6 @@ AC_CONFIG_FILES([Makefile
src/mod/asr_tts/mod_unimrcp/Makefile
src/mod/codecs/mod_amr/Makefile
src/mod/codecs/mod_amrwb/Makefile
src/mod/codecs/mod_avcodec/Makefile
src/mod/codecs/mod_b64/Makefile
src/mod/codecs/mod_bv/Makefile
src/mod/codecs/mod_codec2/Makefile
@ -1757,7 +1756,6 @@ AC_CONFIG_FILES([Makefile
src/mod/event_handlers/mod_rayo/Makefile
src/mod/event_handlers/mod_snmp/Makefile
src/mod/event_handlers/mod_event_zmq/Makefile
src/mod/formats/mod_avformat/Makefile
src/mod/formats/mod_imagick/Makefile
src/mod/formats/mod_local_stream/Makefile
src/mod/formats/mod_native_file/Makefile

View File

@ -1,9 +1,18 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_av
mod_LTLIBRARIES = mod_av.la
mod_av_la_SOURCES = mod_av.c
mod_av_la_CFLAGS = $(AM_CFLAGS)
mod_av_la_LIBADD = $(switch_builddir)/libfreeswitch.la
mod_av_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lavformat -lavcodec -lavutil -lswresample -lx264
if HAVE_AVFORMAT
mod_LTLIBRARIES = mod_av.la
mod_av_la_SOURCES = mod_av.c avformat.c avcodec.c
mod_av_la_CFLAGS = $(AM_CFLAGS) $(AVFORMAT_CFLAGS) $(AVCODEC_CFLAGS) $(SWSCALE_CFLAGS) $(AVUTIL_CFLAGS) $(AVRESAMPLE_CFALGS)
mod_av_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(AVFORMAT_LIBS) $(AVCODEC_LIBS) $(SWSCALE_LIBS) $(AVUTIL_LIBS) $(AVRESAMPLE_LIBS)
mod_av_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
else
install: error
all: error
error:
$(error You must install libavformat-dev to build mod_av)
endif

View File

@ -24,6 +24,7 @@
* Contributor(s):
*
* Seven Du <dujinfang@gmail.com>
* Anthony Minessale <anthm@freeswitch.org>
*
* mod_avcodec -- Codec with libav.org
*
@ -35,19 +36,10 @@
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
/* use libx264 by default, comment out to use the ffmpeg/avcodec wrapper */
// #define H264_CODEC_USE_LIBX264
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
#ifdef H264_CODEC_USE_LIBX264
#include <x264.h>
#endif
#define FPS 30 // frame rate
#define FPS 15 // frame rate
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
SWITCH_MODULE_DEFINITION(mod_avcodec, mod_avcodec_load, NULL, NULL);
/* ff_avc_find_startcode is not exposed in the ffmpeg lib but you can use it
Either include the avc.h which available in the ffmpeg source, or
@ -132,159 +124,12 @@ typedef struct h264_codec_context_s {
int change_bandwidth;
unsigned int bandwidth;
switch_codec_settings_t codec_settings;
#ifndef H264_CODEC_USE_LIBX264
AVCodecContext *encoder_ctx;
AVFrame *encoder_avframe;
AVPacket encoder_avpacket;
our_h264_nalu_t nalus[MAX_NALUS];
#else
/*x264*/
x264_t *x264_handle;
x264_param_t x264_params;
x264_nal_t *x264_nals;
int x264_nal_count;
int cur_nalu_index;
#endif
} h264_codec_context_t;
#ifdef H264_CODEC_USE_LIBX264
static switch_status_t init_x264(h264_codec_context_t *context, uint32_t width, uint32_t height)
{
x264_t *xh = context->x264_handle;
x264_param_t *xp = &context->x264_params;
//int ret = 0;
if (width && height) {
context->codec_settings.video.width = width;
context->codec_settings.video.height = height;
}
if (!context->codec_settings.video.width) {
context->codec_settings.video.width = 1280;
}
if (!context->codec_settings.video.height) {
context->codec_settings.video.height = 720;
}
if (context->codec_settings.video.bandwidth) {
context->bandwidth = context->codec_settings.video.bandwidth;
} else {
context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 0, 0);
}
if (context->bandwidth > 5120) {
context->bandwidth = 5120;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "initializing x264 handle %dx%d bw:%d\n", context->codec_settings.video.width, context->codec_settings.video.height, context->bandwidth);
if (xh) {
x264_encoder_close(context->x264_handle);
context->x264_handle = xh = NULL;
switch_buffer_zero(context->nalu_buffer);
//xp->i_width = width;
//xp->i_height = height;
//ret = x264_encoder_reconfig(xh, xp);
//if (ret == 0) return SWITCH_STATUS_SUCCESS;
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Reset error:%d\n", ret);
//return SWITCH_STATUS_FALSE;
}
// x264_param_default(xp);
x264_param_default_preset(xp, "veryfast", "zerolatency");
// xp->i_level_idc = 31; // baseline
// CPU Flags
// xp->i_threads = 1;//X264_SYNC_LOOKAHEAD_AUTO;
// xp->i_lookahead_threads = X264_SYNC_LOOKAHEAD_AUTO;
// Video Properties
xp->i_width = context->codec_settings.video.width;
xp->i_height = context->codec_settings.video.height;
xp->i_frame_total = 0;
xp->i_keyint_max = FPS * 10;
// Bitstream parameters
xp->i_bframe = 0;
// xp->i_frame_reference = 0;
// xp->b_open_gop = 0;
// xp->i_bframe_pyramid = 0;
// xp->i_bframe_adaptive = X264_B_ADAPT_NONE;
//xp->vui.i_sar_width = 1080;
//xp->vui.i_sar_height = 720;
// xp->i_log_level = X264_LOG_DEBUG;
xp->i_log_level = X264_LOG_NONE;
// Rate control Parameters
xp->rc.i_bitrate = context->bandwidth;
// Muxing parameters
//xp->i_fps_den = 1;
//xp->i_fps_num = FPS;
xp->i_timebase_den = xp->i_fps_num;
xp->i_timebase_num = xp->i_fps_den;
xp->i_slice_max_size = SLICE_SIZE;
//Set Profile 0=baseline other than 1=MainProfile
x264_param_apply_profile(xp, x264_profile_names[0]);
xh = x264_encoder_open(xp);
if (!xh) return SWITCH_STATUS_FALSE;
// copy params back to xp;
x264_encoder_parameters(xh, xp);
context->x264_handle = xh;
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t nalu_slice(h264_codec_context_t *context, switch_frame_t *frame)
{
int nalu_len;
uint8_t *buffer;
int start_code_len = 3;
x264_nal_t *nal = &context->x264_nals[context->cur_nalu_index];
switch_status_t status = SWITCH_STATUS_SUCCESS;
frame->m = 0;
if (context->cur_nalu_index >= context->x264_nal_count) {
frame->datalen = 0;
frame->m = 0;
context->cur_nalu_index = 0;
return SWITCH_STATUS_NOTFOUND;
}
if (nal->b_long_startcode) start_code_len++;
nalu_len = nal->i_payload - start_code_len;
buffer = nal->p_payload + start_code_len;
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "nalu:%d/%d nalu_len:%d\n",
// context->cur_nalu_index, context->x264_nal_count, nalu_len);
switch_assert(nalu_len > 0);
// if ((*buffer & 0x1f) == 7) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Got SPS | %02x %02x %02x\n", *(buffer+1), *(buffer+2), *(buffer+3));
memcpy(frame->data, buffer, nalu_len);
frame->datalen = nalu_len;
if (context->cur_nalu_index == context->x264_nal_count - 1) {
frame->m = 1;
} else {
status = SWITCH_STATUS_MORE_DATA;
}
context->cur_nalu_index++;
return status;
}
#endif
static uint8_t ff_input_buffer_padding[FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
static switch_status_t buffer_h264_nalu(h264_codec_context_t *context, switch_frame_t *frame)
@ -356,7 +201,7 @@ static switch_status_t buffer_h264_nalu(h264_codec_context_t *context, switch_fr
return SWITCH_STATUS_SUCCESS;
}
#ifndef H264_CODEC_USE_LIBX264
static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame)
{
@ -466,8 +311,8 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt
}
context->encoder_ctx->bit_rate = context->bandwidth * 1024;
context->encoder_ctx->width = width;
context->encoder_ctx->height = height;
context->encoder_ctx->width = context->codec_settings.video.width;
context->encoder_ctx->height = context->codec_settings.video.height;
/* frames per second */
context->encoder_ctx->time_base = (AVRational){1, FPS};
context->encoder_ctx->gop_size = FPS * 3; /* emit one intra frame every 3 seconds */
@ -489,7 +334,6 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt
return SWITCH_STATUS_SUCCESS;
}
#endif
static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
@ -567,8 +411,6 @@ static void __attribute__((unused)) fill_avframe(AVFrame *pict, switch_image_t *
}
#ifndef H264_CODEC_USE_LIBX264
static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t *frame)
{
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
@ -645,6 +487,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
avframe->format = avctx->pix_fmt;
avframe->width = avctx->width;
avframe->height = avctx->height;
avframe->pts = frame->timestamp / 90;
ret = av_frame_get_buffer(avframe, 32);
@ -670,7 +513,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
fill_avframe(avframe, img);
avframe->pts = context->pts++;
//avframe->pts = context->pts++;
if (context->need_key_frame) {
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NEED Refresh\n");
@ -727,131 +570,6 @@ error:
return SWITCH_STATUS_FALSE;
}
#endif
#ifdef H264_CODEC_USE_LIBX264
static switch_status_t switch_h264_encode(switch_codec_t *codec,
switch_frame_t *frame)
{
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
uint32_t width = 0;
uint32_t height = 0;
x264_picture_t pic = { 0 }, pic_out = { 0 };
int result;
switch_image_t *img = frame->img;
void *encoded_data = frame->data;
uint32_t *encoded_data_len = &frame->datalen;
//unsigned int *flag = &frame->flags;
//if (*flag & SFF_WAIT_KEY_FRAME) context->need_key_frame = 1;
//if (*encoded_data_len < SWITCH_DEFAULT_VIDEO_SIZE) return SWITCH_STATUS_FALSE;
if (!context) return SWITCH_STATUS_FALSE;
if (context->change_bandwidth) {
context->codec_settings.video.bandwidth = context->change_bandwidth;
context->change_bandwidth = 0;
if (init_x264(context, 0, 0) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
}
if (!context->x264_handle) {
if (init_x264(context, width, height) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
}
if (frame->flags & SFF_SAME_IMAGE) {
return nalu_slice(context, frame);
}
width = img->d_w;
height = img->d_h;
if (context->x264_params.i_width != width || context->x264_params.i_height != height) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "picture size changed from %dx%d to %dx%d, reinitializing encoder\n",
context->x264_params.i_width, context->x264_params.i_height, width, height);
if (init_x264(context, width, height) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
}
switch_assert(encoded_data);
x264_picture_init(&pic);
pic.img.i_csp = X264_CSP_I420;
pic.img.i_plane = 3;
if (context->encimg && (context->encimg->d_w != width || context->encimg->d_h != height)) {
switch_img_free(&context->encimg);
}
if (!context->encimg) {
context->encimg = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, width, height, 1);
}
switch_img_copy(img, &context->encimg);
pic.img.i_stride[0] = context->encimg->stride[0];
pic.img.i_stride[1] = context->encimg->stride[1];
pic.img.i_stride[2] = context->encimg->stride[2];
pic.img.plane[0] = context->encimg->planes[0];
pic.img.plane[1] = context->encimg->planes[1];
pic.img.plane[2] = context->encimg->planes[2];
// pic.i_pts = (context->pts++);
// pic.i_pts = (context->pts+=90000/FPS);
pic.i_pts = 0;
if (context->need_key_frame) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "H264 KEYFRAME GENERATED\n");
//pic.i_type = X264_TYPE_IDR;
pic.i_type = X264_TYPE_KEYFRAME;
context->need_key_frame = 0;
}
result = x264_encoder_encode(context->x264_handle, &context->x264_nals, &context->x264_nal_count, &pic, &pic_out);
if (result < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "encode error\n");
goto error;
}
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "encode result:%d nal_count:%d daylayed: %d, max_delayed: %d\n", result, context->x264_nal_count, x264_encoder_delayed_frames(context->x264_handle), x264_encoder_maximum_delayed_frames(context->x264_handle));
if (0) { //debug
int i;
x264_nal_t *nals = context->x264_nals;
for (i = 0; i < context->x264_nal_count; i++) {
// int start_code_len = 3 + nals[i].b_long_startcode;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "encoded: %d %d %d %d| %d %d %d %x %x %x %x %x %x\n",
nals[i].i_type, nals[i].i_ref_idc, nals[i].i_payload, nals[i].b_long_startcode, *(nals[i].p_payload), *(nals[i].p_payload + 1), *(nals[i].p_payload + 2), *(nals[i].p_payload+3), *(nals[i].p_payload + 4), *(nals[i].p_payload + 5), *(nals[i].p_payload + 6), *(nals[i].p_payload + 7), *(nals[i].p_payload + 8));
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got ACL count : %d, Encoder output dts:%ld\n", context->x264_nal_count, (long)pic_out.i_dts);
}
context->cur_nalu_index = 0;
return nalu_slice(context, frame);
error:
*encoded_data_len = 0;
return SWITCH_STATUS_NOTFOUND;
}
#endif
static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t *frame)
{
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
@ -1008,7 +726,6 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
switch_img_free(&context->img);
#ifndef H264_CODEC_USE_LIBX264
if (context->encoder_ctx) {
if (avcodec_is_open(context->encoder_ctx)) avcodec_close(context->encoder_ctx);
av_free(context->encoder_ctx);
@ -1017,11 +734,6 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
if (context->encoder_avframe) {
av_frame_free(&context->encoder_avframe);
}
#else
if (context->x264_handle) {
x264_encoder_close(context->x264_handle);
}
#endif
return SWITCH_STATUS_SUCCESS;
}
@ -1093,81 +805,6 @@ static void print_codecs_for_id(switch_stream_handle_t *stream, enum AVCodecID i
stream->write_function(stream, ")");
}
static int is_device(const AVClass *avclass)
{
#if 0
if (!avclass) return 0;
return avclass->category == AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ||
avclass->category == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ||
avclass->category == AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ||
avclass->category == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ||
avclass->category == AV_CLASS_CATEGORY_DEVICE_OUTPUT ||
avclass->category == AV_CLASS_CATEGORY_DEVICE_INPUT;
#endif
return 0;
}
void show_formats(switch_stream_handle_t *stream) {
AVInputFormat *ifmt = NULL;
AVOutputFormat *ofmt = NULL;
const char *last_name;
// int is_dev;
stream->write_function(stream, "============= File Formats ==============================:\n"
" D. = Demuxing supported\n"
" .M = Muxing supported\n"
"----------------------\n");
last_name = "000";
for (;;) {
int decode = 0;
int encode = 0;
int is_dev = 0;
const char *name = NULL;
const char *long_name = NULL;
while ((ofmt = av_oformat_next(ofmt))) {
is_dev = is_device(ofmt->priv_class);
if ((name == NULL || strcmp(ofmt->name, name) < 0) &&
strcmp(ofmt->name, last_name) > 0) {
name = ofmt->name;
long_name = ofmt->long_name;
encode = 1;
}
}
while ((ifmt = av_iformat_next(ifmt))) {
is_dev = is_device(ifmt->priv_class);
if ((name == NULL || strcmp(ifmt->name, name) < 0) &&
strcmp(ifmt->name, last_name) > 0) {
name = ifmt->name;
long_name = ifmt->long_name;
encode = 0;
}
if (name && strcmp(ifmt->name, name) == 0) decode = 1;
}
if (name == NULL) break;
last_name = name;
stream->write_function(stream, "%s%s%s %-15s %s\n",
is_dev ? "*" : " ",
decode ? "D" : " ",
encode ? "M" : " ",
name, long_name ? long_name:" ");
}
}
void show_codecs(switch_stream_handle_t *stream)
{
const AVCodecDescriptor **codecs = NULL;
@ -1222,6 +859,7 @@ void show_codecs(switch_stream_handle_t *stream)
av_free(codecs);
}
SWITCH_STANDARD_API(av_codec_api_function)
{
show_codecs(stream);
@ -1229,49 +867,19 @@ SWITCH_STANDARD_API(av_codec_api_function)
return SWITCH_STATUS_SUCCESS;
}
static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
{
switch_log_level_t switch_level = SWITCH_LOG_DEBUG;
/* naggy messages */
if (level == AV_LOG_DEBUG || level == AV_LOG_WARNING) return;
switch(level) {
case AV_LOG_QUIET: switch_level = SWITCH_LOG_CONSOLE; break;
case AV_LOG_PANIC: switch_level = SWITCH_LOG_DEBUG2; break;
case AV_LOG_FATAL: switch_level = SWITCH_LOG_DEBUG2; break;
case AV_LOG_ERROR: switch_level = SWITCH_LOG_DEBUG2; break;
case AV_LOG_WARNING: switch_level = SWITCH_LOG_WARNING; break;
case AV_LOG_INFO: switch_level = SWITCH_LOG_INFO; break;
case AV_LOG_VERBOSE: switch_level = SWITCH_LOG_INFO; break;
case AV_LOG_DEBUG: switch_level = SWITCH_LOG_DEBUG; break;
default: break;
}
// switch_level = SWITCH_LOG_ERROR; // hardcoded for debug
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, switch_level, fmt, vl);
}
static const char modname[] = "mod_av";
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load)
{
switch_codec_interface_t *codec_interface;
switch_api_interface_t *api_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, "H264 Video");
switch_core_codec_add_video_implementation(pool, codec_interface, 99, "H264", NULL,
switch_h264_init, switch_h264_encode, switch_h264_decode, switch_h264_control, switch_h264_destroy);
SWITCH_ADD_API(api_interface, "av_codec", "av_codec information", av_codec_api_function, "");
av_log_set_callback(log_callback);
av_log_set_level(AV_LOG_DEBUG);
av_register_all();
av_log(NULL, AV_LOG_INFO, "%s %d\n", "av_log callback installed, level=", av_log_get_level());
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -24,8 +24,9 @@
* Contributor(s):
*
* Seven Du <dujinfang@gmail.com>
* Anthony Minessale <anthm@freeswitch.org>
*
* mod_avformat -- FS Video File Format using libav.org
* mod_avformat -- File Formats with libav.org
*
*/
@ -36,7 +37,6 @@
#include <libavutil/imgutils.h>
#include <libavutil/avstring.h>
#include <libavutil/channel_layout.h>
// #include <libavutil/timestamp.h>
#include <libavresample/avresample.h>
#include <libswscale/swscale.h>
@ -44,7 +44,6 @@
#define DFT_RECORD_OFFSET 350
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
SWITCH_MODULE_DEFINITION(mod_avformat, mod_avformat_load, NULL, NULL);
static char *const get_error_text(const int error)
{
@ -906,74 +905,9 @@ SWITCH_STANDARD_APP(record_av_function)
/* API interface */
static char get_media_type_char(enum AVMediaType type)
{
switch (type) {
case AVMEDIA_TYPE_VIDEO: return 'V';
case AVMEDIA_TYPE_AUDIO: return 'A';
case AVMEDIA_TYPE_DATA: return 'D';
case AVMEDIA_TYPE_SUBTITLE: return 'S';
case AVMEDIA_TYPE_ATTACHMENT:return 'T';
default: return '?';
}
}
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
int encoder)
{
while ((prev = av_codec_next(prev))) {
if (prev->id == id &&
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
return prev;
}
return NULL;
}
static int compare_codec_desc(const void *a, const void *b)
{
const AVCodecDescriptor * const *da = a;
const AVCodecDescriptor * const *db = b;
return (*da)->type != (*db)->type ? (*da)->type - (*db)->type :
strcmp((*da)->name, (*db)->name);
}
static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
{
const AVCodecDescriptor *desc = NULL;
const AVCodecDescriptor **codecs;
unsigned nb_codecs = 0, i = 0;
while ((desc = avcodec_descriptor_next(desc)))
nb_codecs++;
if (!(codecs = av_malloc(nb_codecs * sizeof(*codecs)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MEM Error!\n");
return 0;
}
desc = NULL;
while ((desc = avcodec_descriptor_next(desc)))
codecs[i++] = desc;
switch_assert(i == nb_codecs);
qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
*rcodecs = codecs;
return nb_codecs;
}
static void print_codecs_for_id(switch_stream_handle_t *stream, enum AVCodecID id, int encoder)
{
const AVCodec *codec = NULL;
stream->write_function(stream, " (%s: ", encoder ? "encoders" : "decoders");
while ((codec = next_codec_for_id(id, codec, encoder)))
stream->write_function(stream, "%s ", codec->name);
stream->write_function(stream, ")");
}
static int is_device(const AVClass *avclass)
{
#if 0
#if defined (AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT)
if (!avclass) return 0;
@ -1046,59 +980,7 @@ void show_formats(switch_stream_handle_t *stream) {
}
void show_codecs(switch_stream_handle_t *stream)
{
const AVCodecDescriptor **codecs = NULL;
unsigned i, nb_codecs = get_codecs_sorted(&codecs);
stream->write_function(stream, "================ Codecs ===============================:\n"
" V..... = Video\n"
" A..... = Audio\n"
" S..... = Subtitle\n"
" .F.... = Frame-level multithreading\n"
" ..S... = Slice-level multithreading\n"
" ...X.. = Codec is experimental\n"
" ....B. = Supports draw_horiz_band\n"
" .....D = Supports direct rendering method 1\n"
" ----------------------------------------------\n\n");
for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL;
stream->write_function(stream, " ");
stream->write_function(stream, avcodec_find_decoder(desc->id) ? "D" : ".");
stream->write_function(stream, avcodec_find_encoder(desc->id) ? "E" : ".");
stream->write_function(stream, "%c", get_media_type_char(desc->type));
stream->write_function(stream, (desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
stream->write_function(stream, (desc->props & AV_CODEC_PROP_LOSSY) ? "L" : ".");
stream->write_function(stream, (desc->props & AV_CODEC_PROP_LOSSLESS) ? "S" : ".");
stream->write_function(stream, " %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
/* print decoders/encoders when there's more than one or their
* names are different from codec name */
while ((codec = next_codec_for_id(desc->id, codec, 0))) {
if (strcmp(codec->name, desc->name)) {
print_codecs_for_id(stream ,desc->id, 0);
break;
}
}
codec = NULL;
while ((codec = next_codec_for_id(desc->id, codec, 1))) {
if (strcmp(codec->name, desc->name)) {
print_codecs_for_id(stream, desc->id, 1);
break;
}
}
stream->write_function(stream, "\n");
}
av_free(codecs);
}
void show_codecs(switch_stream_handle_t *stream);
SWITCH_STANDARD_API(av_format_api_function)
{
@ -1119,29 +1001,6 @@ SWITCH_STANDARD_API(av_format_api_function)
return SWITCH_STATUS_SUCCESS;
}
static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
{
switch_log_level_t switch_level = SWITCH_LOG_DEBUG;
/* naggy messages */
if (level == AV_LOG_DEBUG || level == AV_LOG_WARNING) return;
switch(level) {
case AV_LOG_QUIET: switch_level = SWITCH_LOG_CONSOLE; break;
case AV_LOG_PANIC: switch_level = SWITCH_LOG_DEBUG2; break;
case AV_LOG_FATAL: switch_level = SWITCH_LOG_DEBUG2; break;
case AV_LOG_ERROR: switch_level = SWITCH_LOG_DEBUG2; break;
case AV_LOG_WARNING: switch_level = SWITCH_LOG_WARNING; break;
case AV_LOG_INFO: switch_level = SWITCH_LOG_INFO; break;
case AV_LOG_VERBOSE: switch_level = SWITCH_LOG_INFO; break;
case AV_LOG_DEBUG: switch_level = SWITCH_LOG_DEBUG; break;
default: break;
}
// switch_level = SWITCH_LOG_ERROR; // hardcoded for debug
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, switch_level, fmt, vl);
}
/* file interface */
struct av_file_context {
@ -1438,7 +1297,7 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo
// }
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "this block is not tested samples: %d\n", in_frame.nb_samples);
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "this block is not tested samples: %d\n", in_frame.nb_samples);
switch_mutex_lock(context->mutex);
switch_buffer_write(context->audio_buffer, in_frame.data[0], in_frame.nb_samples * 2 * context->audio_st.channels);
switch_mutex_unlock(context->mutex);
@ -2031,9 +1890,10 @@ static switch_status_t av_file_get_string(switch_file_handle_t *handle, switch_a
return SWITCH_STATUS_FALSE;
}
static char *supported_formats[SWITCH_MAX_CODECS] = { 0 };
static const char modname[] = "mod_av";
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load)
{
switch_api_interface_t *api_interface;
@ -2046,8 +1906,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load)
supported_formats[i++] = "mp4";
supported_formats[i++] = "mov";
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
file_interface = (switch_file_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface->interface_name = modname;
@ -2067,13 +1925,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load)
SWITCH_ADD_APP(app_interface, "record_av", "record video using libavformat", "record video using libavformat", record_av_function, "<file>", SAF_NONE);
av_log_set_callback(log_callback);
av_log_set_level(AV_LOG_INFO);
avformat_network_init();
av_register_all();
av_log(NULL, AV_LOG_INFO, "%s %d\n", "av_log callback installed, level=", av_log_get_level());
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +0,0 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_avcodec
if HAVE_AVCODEC
mod_LTLIBRARIES = mod_avcodec.la
mod_avcodec_la_SOURCES = mod_avcodec.c
mod_avcodec_la_CFLAGS = $(AM_CFLAGS) $(AVCODEC_CFLAGS) $(AVUTIL_CFLAGS) $(X264_CFLAGS)
mod_avcodec_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(X264_LIBS)
mod_avcodec_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
else
install: error
all: error
error:
$(error You must install libavcodec-dev to build mod_avcodec)
endif

View File

@ -1,7 +0,0 @@
LOCAL_LDFLAGS=-L/opt/av/lib -lavformat -lavcodec -lavutil -lavresample -lx264
LOCAL_CFLAGS=-I/opt/av/include
LOCAL_LIBADD=
BASE=../../../..
include $(BASE)/build/modmake.rules

View File

@ -1,18 +0,0 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_avformat
if HAVE_AVFORMAT
mod_LTLIBRARIES = mod_avformat.la
mod_avformat_la_SOURCES = mod_avformat.c
mod_avformat_la_CFLAGS = $(AM_CFLAGS) $(AVFORMAT_CFLAGS) $(AVCODEC_CFLAGS) $(SWSCALE_CFLAGS) $(AVUTIL_CFLAGS) $(AVRESAMPLE_CFALGS)
mod_avformat_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(AVFORMAT_LIBS) $(AVCODEC_LIBS) $(SWSCALE_LIBS) $(AVUTIL_LIBS) $(AVRESAMPLE_LIBS)
mod_avformat_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
else
install: error
all: error
error:
$(error You must install libavformat-dev to build mod_avformat)
endif

View File

@ -1,6 +0,0 @@
LOCAL_LDFLAGS=-L/opt/av/lib -lavformat -lavcodec -lavutil -lavresample -lswscale
LOCAL_CFLAGS=-I/opt/av/include
LOCAL_LIBADD=
BASE=../../../..
include $(BASE)/build/modmake.rules