From e93047ad816cce52b937e8ccf8a57937e373a431 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Mar 2007 18:53:32 +0000 Subject: [PATCH] these aren't the droids you're looking for.... git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4591 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/formats/mod_shout/Makefile | 3 +- src/mod/formats/mod_shout/common.c | 18 ++--- src/mod/formats/mod_shout/decode_ntom.c | 6 +- src/mod/formats/mod_shout/interface.c | 13 ++- src/mod/formats/mod_shout/layer3.c | 18 ++--- src/mod/formats/mod_shout/mod_shout.c | 102 +++++++++++++++++++++--- src/mod/formats/mod_shout/mpglib.h | 5 ++ 7 files changed, 127 insertions(+), 38 deletions(-) diff --git a/src/mod/formats/mod_shout/Makefile b/src/mod/formats/mod_shout/Makefile index b85ba7fd23..1a4a364e2f 100644 --- a/src/mod/formats/mod_shout/Makefile +++ b/src/mod/formats/mod_shout/Makefile @@ -1,3 +1,4 @@ +BASE=../../../.. MODNAME=mod_shout LAME=lame-3.97 SHOUT=libshout-2.2.2 @@ -12,7 +13,7 @@ SHOUTLA=$(SHOUT_DIR)/src/libshout.la CURLLA=$(CURL_DIR)/lib/libcurl.la LOCAL_CFLAGS=-I$(CURL_DIR)/include -I$(SHOUT_DIR)/include -I$(LAME_DIR)/include -LOCAL_LIBADD=$(LAMELA) $(SHOUTLA) $(CURLLA) +LOCAL_LIBADD=$(LAMELA) $(SHOUTLA) -lcurl MP3OBJS=common.o dct64_i386.o decode_ntom.o layer3.o tabinit.o interface.o LOCAL_OBJS=$(MP3OBJS) diff --git a/src/mod/formats/mod_shout/common.c b/src/mod/formats/mod_shout/common.c index 026c2a76ee..987d6d28a8 100644 --- a/src/mod/formats/mod_shout/common.c +++ b/src/mod/formats/mod_shout/common.c @@ -88,7 +88,7 @@ int decode_header(struct frame *fr,unsigned long newhead) fr->lay = 4-((newhead>>17)&3); if( ((newhead>>10)&0x3) == 0x3) { - //printf("Stream error\n"); + debug_printf("%d Stream error\n", __LINE__); return (0); } if(fr->mpeg25) { @@ -114,7 +114,7 @@ int decode_header(struct frame *fr,unsigned long newhead) if(!fr->bitrate_index) { - //printf("Free format not supported.\n"); + debug_printf("%d Free format not supported.\n", __LINE__); return (0); } @@ -129,7 +129,7 @@ int decode_header(struct frame *fr,unsigned long newhead) fr->framesize /= freqs[fr->sampling_frequency]; fr->framesize = ((fr->framesize+fr->padding)<<2)-4; #else - //printf("Layer 1 not supported!\n"); + debug_printf("%d Layer 1 not supported!\n", __LINE__); #endif break; case 2: @@ -142,7 +142,7 @@ int decode_header(struct frame *fr,unsigned long newhead) fr->framesize /= freqs[fr->sampling_frequency]; fr->framesize += fr->padding - 4; #else - //printf("Layer 2 not supported!\n"); + debug_printf("%d Layer 2 not supported!\n", __LINE__); #endif break; case 3: @@ -163,7 +163,7 @@ int decode_header(struct frame *fr,unsigned long newhead) fr->framesize = fr->framesize + fr->padding - 4; break; default: - //printf("Sorry, unknown layer type.\n"); + debug_printf("%d Sorry, unknown layer type.\n", __LINE__); return (0); } return 1; @@ -175,15 +175,15 @@ void print_header(struct frame *fr) static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" }; static char *layers[4] = { "Unknown" , "I", "II", "III" }; - //printf("MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n", + debug_printf("MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n", fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"), layers[fr->lay],freqs[fr->sampling_frequency], modes[fr->mode],fr->mode_ext,fr->framesize+4); - //printf("Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n", + debug_printf("Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n", fr->stereo,fr->copyright?"Yes":"No", fr->original?"Yes":"No",fr->error_protection?"Yes":"No", fr->emphasis); - //printf("Bitrate: %d Kbits/s, Extension value: %d\n", + debug_printf("Bitrate: %d Kbits/s, Extension value: %d\n", tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],fr->extension); } @@ -192,7 +192,7 @@ void print_header_compact(struct frame *fr) static char *modes[4] = { "stereo", "joint-stereo", "dual-channel", "mono" }; static char *layers[4] = { "Unknown" , "I", "II", "III" }; - //printf("MPEG %s layer %s, %d kbit/s, %ld Hz %s\n", + debug_printf("MPEG %s layer %s, %d kbit/s, %ld Hz %s\n", fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"), layers[fr->lay], tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index], diff --git a/src/mod/formats/mod_shout/decode_ntom.c b/src/mod/formats/mod_shout/decode_ntom.c index 5f06674bfa..a8ad097929 100644 --- a/src/mod/formats/mod_shout/decode_ntom.c +++ b/src/mod/formats/mod_shout/decode_ntom.c @@ -28,10 +28,10 @@ static unsigned long ntom_step = NTOM_MUL; int synth_ntom_set_step(long m,long n) { if(param.verbose > 1) - //printf("Init rate converter: %ld->%ld\n",m,n); + debug_printf("Init rate converter: %ld->%ld\n",m,n); if(n >= 96000 || m >= 96000 || m == 0 || n == 0) { - //printf("NtoM converter: illegal rates\n"); + debug_printf("NtoM converter: %d illegal rates\n", __LINE__); return (1); } @@ -39,7 +39,7 @@ int synth_ntom_set_step(long m,long n) ntom_step = n / m; if(ntom_step > 8*NTOM_MUL) { - //printf("max. 1:8 conversion allowed!\n"); + debug_printf("%d max. 1:8 conversion allowed!\n", __LINE__); return (1); } diff --git a/src/mod/formats/mod_shout/interface.c b/src/mod/formats/mod_shout/interface.c index 3bb4acd98d..7aabb1f55c 100644 --- a/src/mod/formats/mod_shout/interface.c +++ b/src/mod/formats/mod_shout/interface.c @@ -5,7 +5,6 @@ #include "mpg123.h" #include "mpglib.h" - void InitMP3Constants(void) { init_layer3_const(); @@ -55,7 +54,7 @@ static struct buf *addbuf(struct mpstr *mp,char *buf,int size) nbuf = malloc( sizeof(struct buf) ); if(!nbuf) { - //printf("Out of memory!\n"); + debug_printf("%d Out of memory!\n", __LINE__); return NULL; } nbuf->pnt = malloc(size); @@ -109,7 +108,7 @@ static int read_buf_byte(int *error, struct mpstr *mp) if(!mp->tail) { /* We may pick up this error a few times*/ /* But things have gone pear shaped */ - //printf("Fatal Buffer error!\n"); + debug_printf("%d Fatal Buffer error!\n", __LINE__); *error = 1; return (0); } @@ -190,7 +189,7 @@ int decodeMP3(struct mpstr *mp,char *in,int isize,char *out, int down_sample_sblimit; if(osize < 4608) { - //printf("To less out space\n"); + debug_printf("%d To less out space\n", __LINE__); return MP3_ERR; } @@ -211,7 +210,7 @@ int decodeMP3(struct mpstr *mp,char *in,int isize,char *out, if(!head_check(mp->header) ) { int i; - //printf("Junk at the beginning of frame %08lx\n",mp->header); + debug_printf("Junk at the beginning of frame %08lx\n",mp->header); /* step in byte steps through next 64K */ for(i=0;i<65536;i++) { @@ -225,7 +224,7 @@ int decodeMP3(struct mpstr *mp,char *in,int isize,char *out, break; } if(i == 65536) { - //printf("Giving up searching valid MPEG header\n"); + debug_printf("%d Giving up searching valid MPEG header\n", __LINE__); return MP3_ERR; } } @@ -305,7 +304,7 @@ int set_pointer(struct mpstr *mp, long backstep) { unsigned char *bsbufold; if(mp->fsizeold < 0 && backstep > 0) { - //printf("Can't step back %ld!\n",backstep); + debug_printf("Can't step back %ld!\n",backstep); return MP3_ERR; } bsbufold = mp->bsspace[mp->bsnum] + 512; diff --git a/src/mod/formats/mod_shout/layer3.c b/src/mod/formats/mod_shout/layer3.c index b39e206f8e..33f58ef1f3 100644 --- a/src/mod/formats/mod_shout/layer3.c +++ b/src/mod/formats/mod_shout/layer3.c @@ -324,7 +324,7 @@ static int III_get_side_info_1(struct mpstr *mp, struct III_sideinfo *si,int ste gr_info->part2_3_length = getbits(mp, 12); gr_info->big_values = getbits_fast(mp, 9); if(gr_info->big_values > 288) { - //printf("big_values too large!\n"); + debug_printf("%d big_values too large!\n", __LINE__); gr_info->big_values = 288; } gr_info->pow2gain = gainpow2+256 - getbits_fast(mp, 8) + powdiff; @@ -348,7 +348,7 @@ static int III_get_side_info_1(struct mpstr *mp, struct III_sideinfo *si,int ste gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(mp, 3)<<3); if(gr_info->block_type == 0) { - //printf("Blocktype == 0 and window-switching == 1 not allowed.\n"); + debug_printf("%d Blocktype == 0 and window-switching == 1 not allowed.\n", __LINE__); return (1); } /* region_count/start parameters are implicit in this case. */ @@ -399,7 +399,7 @@ static int III_get_side_info_2(struct mpstr *mp, struct III_sideinfo *si,int ste gr_info->part2_3_length = getbits(mp, 12); gr_info->big_values = getbits_fast(mp, 9); if(gr_info->big_values > 288) { - //printf("big_values too large!\n"); + debug_printf("%d big_values too large!\n", __LINE__); gr_info->big_values = 288; } gr_info->pow2gain = gainpow2+256 - getbits_fast(mp, 8) + powdiff; @@ -423,7 +423,7 @@ static int III_get_side_info_2(struct mpstr *mp, struct III_sideinfo *si,int ste gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(mp, 3)<<3); if(gr_info->block_type == 0) { - //printf("Blocktype == 0 and window-switching == 1 not allowed.\n"); + debug_printf("%d Blocktype == 0 and window-switching == 1 not allowed.\n", __LINE__); return (1); } /* region_count/start parameters are implicit in this case. */ @@ -963,7 +963,7 @@ static int III_dequantize_sample(struct mpstr *mp, real xr[SBLIMIT][SSLIMIT],int if(part2remain > 0) getbits(mp, part2remain); else if(part2remain < 0) { - //printf("mpg123: Can't rewind stream by %d bits!\n",-part2remain); + debug_printf("mpg123: %d Can't rewind stream by %d bits!\n",-part2remain, __LINE__); return 1; /* -> error */ } return 0; @@ -1374,7 +1374,7 @@ static int III_dequantize_sample_ms(real xr[2][SBLIMIT][SSLIMIT],int *scf, if(part2remain > 0 ) getbits(mp, part2remain); else if(part2remain < 0) { - //printf("mpg123_ms: Can't rewind stream by %d bits!\n",-part2remain); + debug_printf("mpg123_ms: %d: Can't rewind stream by %d bits!\n",-part2remain, __LINE__); return 1; /* -> error */ } return 0; @@ -1920,7 +1920,7 @@ int do_layer3(struct mpstr *mp,unsigned char *pcm_sample,int *pcm_point) return (MP3_ERR); #else - //printf("Not supported\n"); + debug_printf("%d Not supported\n", __LINE__); #endif } @@ -1941,7 +1941,7 @@ int do_layer3(struct mpstr *mp,unsigned char *pcm_sample,int *pcm_point) #ifdef MPEG1 part2bits = III_get_scale_factors_1(mp, scalefacs,gr_info); #else - //printf("Not supported\n"); + debug_printf("%d Not supported\n", __LINE__); #endif } if(III_dequantize_sample(mp, hybridIn[0], scalefacs,gr_info,sfreq,part2bits)) @@ -1956,7 +1956,7 @@ int do_layer3(struct mpstr *mp,unsigned char *pcm_sample,int *pcm_point) #ifdef MPEG1 part2bits = III_get_scale_factors_1(mp, scalefacs,gr_info); #else - //printf("Not supported\n"); + debug_printf("%d Not supported\n", __LINE__); #endif } diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 64e9c468c7..deb9ed7631 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -39,7 +39,8 @@ #define OUTSCALE 4096 -#define MP3BUFLEN OUTSCALE * 2 +#define MP3_SCACHE 16384 +#define MP3_DCACHE 8192 static const char modname[] = "mod_shout"; @@ -51,10 +52,15 @@ struct shout_context { lame_global_flags *gfp; char *stream_url; switch_mutex_t *audio_mutex; + switch_mutex_t *mp3_mutex; switch_buffer_t *audio_buffer; + switch_buffer_t *mp3_buffer; switch_memory_pool_t *memory_pool; - char decode_buf[MP3BUFLEN]; + //char encode_buf[MP3_SCACHE]; + char decode_buf[MP3_DCACHE]; struct mpstr mp; + int err; + int dlen; }; typedef struct shout_context shout_context_t; @@ -63,7 +69,13 @@ static inline void free_context(shout_context_t *context) { if (context) { if (context->audio_buffer) { + switch_mutex_lock(context->audio_mutex); switch_buffer_destroy(&context->audio_buffer); + switch_mutex_unlock(context->audio_mutex); + } + + if (context->mp3_buffer) { + switch_buffer_destroy(&context->mp3_buffer); } if (context->shout) { @@ -158,17 +170,65 @@ static void log_msg(char const *fmt, va_list ap) } +static int wtf = -1; + static size_t stream_callback(void *ptr, size_t size, size_t nmemb, void *data) { register unsigned int realsize = (unsigned int)(size * nmemb); shout_context_t *context = data; - int dlen; - - decodeMP3(&context->mp, data, realsize, context->decode_buf, sizeof(context->decode_buf), &dlen); + int rlen; + char grr[1024]; + char *ass; + int decode_status = 0; + int dlen = 0; + int offset = 0; + int x = 0; + char *in; + int inlen; + char *out; + int outlen; + int usedlen; + + + in = ptr; + inlen = realsize; + out = context->decode_buf; + outlen = sizeof(context->decode_buf); + usedlen = 0; + + do { + decode_status = decodeMP3(&context->mp, in, inlen, out, outlen, &dlen); + + if (!x) { + in = NULL; + inlen = 0; + x++; + } + + if (decode_status == MP3_ERR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error!\n"); + context->err++; + return 0; + } + + usedlen += dlen; + out += dlen; + outlen -= dlen; + dlen = 0; + } while (decode_status != MP3_NEED_MORE); + + printf("WRITE %d\n", usedlen); switch_mutex_lock(context->audio_mutex); - switch_buffer_write(context->audio_buffer, context->decode_buf, dlen); + switch_buffer_write(context->audio_buffer, context->decode_buf, usedlen); switch_mutex_unlock(context->audio_mutex); + out = context->decode_buf; + outlen = sizeof(context->decode_buf); + + printf("doh\n"); + + + return realsize; } @@ -181,6 +241,7 @@ static void *SWITCH_THREAD_FUNC stream_thread(switch_thread_t *thread, void *obj CURL *curl_handle = NULL; shout_context_t *context = (shout_context_t *) obj; + curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, context->stream_url); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, stream_callback); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)context); @@ -244,7 +305,12 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, char *path) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); goto error; } + if (switch_buffer_create_dynamic(&context->mp3_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); + goto error; + } switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->memory_pool); + switch_mutex_init(&context->mp3_mutex, SWITCH_MUTEX_NESTED, context->memory_pool); InitMP3(&context->mp, OUTSCALE); context->stream_url = switch_core_sprintf(context->memory_pool, "http://%s", path); launch_stream_thread(context); @@ -354,13 +420,30 @@ static switch_status_t shout_file_seek(switch_file_handle_t *handle, unsigned in static switch_status_t shout_file_read(switch_file_handle_t *handle, void *data, size_t *len) { shout_context_t *context = handle->private_info; - size_t bytes = *len; + size_t rb = 0, bytes = *len * sizeof(int16_t); + + *len = 0; switch_mutex_lock(context->audio_mutex); - *len = switch_buffer_read(context->audio_buffer, data, bytes); + if (context->audio_buffer) { + rb = switch_buffer_read(context->audio_buffer, data, bytes); + } else { + context->err++; + } switch_mutex_unlock(context->audio_mutex); - return SWITCH_STATUS_FALSE; + if (context->err) { + return SWITCH_STATUS_FALSE; + } + + if (rb) { + *len = rb / sizeof(int16_t); + } else { + memset(data, 255, bytes); + *len = bytes / sizeof(int16_t); + } + + return SWITCH_STATUS_SUCCESS; } static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data, size_t *len) @@ -455,6 +538,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod *module_interface = &shout_module_interface; shout_init(); + InitMP3Constants(); /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/formats/mod_shout/mpglib.h b/src/mod/formats/mod_shout/mpglib.h index 0613222e66..38b60f7bd1 100644 --- a/src/mod/formats/mod_shout/mpglib.h +++ b/src/mod/formats/mod_shout/mpglib.h @@ -1,3 +1,8 @@ +#ifndef DEBUG_MP3 +#define debug_printf(fmt,...) printf(fmt, ##__VA_ARGS__); +#else +#define debug_printf; +#endif struct buf { unsigned char *pnt;