--- format_mp3.c.orig 2006-04-14 11:09:42.000000000 +0400 +++ format_mp3.c 2006-05-10 09:37:58.000000000 +0400 @@ -43,18 +43,13 @@ /* Based on format_wav.c */ -struct ast_filestream { - void *reserved[AST_RESERVED_POINTERS]; - /* This is what a filestream means to us */ - FILE *f; /* Descriptor */ - struct ast_frame fr; /* Frame information */ +struct mp3_private { char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */ - char empty; /* Empty character */ + char empty; /* Empty character */ int lasttimeout; int maxlen; struct timeval last; struct mpstr mp; - char buf[MP3_BUFLEN]; char sbuf[MP3_SCACHE]; char dbuf[MP3_DCACHE]; int buflen; @@ -67,13 +62,8 @@ long seek; }; - -AST_MUTEX_DEFINE_STATIC(mp3_lock); -static int glistcnt = 0; - static char *name = "mp3"; static char *desc = "MP3 format [Any rate but 8000hz mono optimal]"; -static char *exts = "mp3"; #define BLOCKSIZE 160 #define OUTSCALE 4096 @@ -103,92 +93,80 @@ #endif -static struct ast_filestream *mp3_open(FILE *f) +static int mp3_open(struct ast_filestream *s) { - struct ast_filestream *tmp; - if ((tmp = malloc(sizeof(struct ast_filestream)))) { - memset(tmp, 0, sizeof(struct ast_filestream)); - if (ast_mutex_lock(&mp3_lock)) { - ast_log(LOG_WARNING, "Unable to lock mp3 list\n"); - free(tmp); - return NULL; - } - InitMP3(&tmp->mp, OUTSCALE); - tmp->dbuflen = 0; - tmp->f = f; - tmp->fr.data = tmp->buf; - tmp->fr.frametype = AST_FRAME_VOICE; - tmp->fr.subclass = AST_FORMAT_SLINEAR; - /* datalen will vary for each frame */ - tmp->fr.src = name; - tmp->fr.mallocd = 0; - tmp->offset = 0; - glistcnt++; - ast_mutex_unlock(&mp3_lock); - ast_update_use_count(); - } - return tmp; + struct mp3_private *p = s->private; + + InitMP3(&p->mp, OUTSCALE); + p->dbuflen = 0; + s->fr.data = s->buf; + s->fr.frametype = AST_FRAME_VOICE; + s->fr.subclass = AST_FORMAT_SLINEAR; + /* datalen will vary for each frame */ + s->fr.src = name; + s->fr.mallocd = 0; + p->offset = 0; + return 0; } static void mp3_close(struct ast_filestream *s) { - if (ast_mutex_lock(&mp3_lock)) { - ast_log(LOG_WARNING, "Unable to lock mp3 list\n"); - return; - } - - ExitMP3(&s->mp); + struct mp3_private *p = s->private; - glistcnt--; - ast_mutex_unlock(&mp3_lock); - ast_update_use_count(); - fclose(s->f); - free(s); - s = NULL; - + ExitMP3(&p->mp); + return; } static int mp3_squeue(struct ast_filestream *s) { + struct mp3_private *p = s->private; int res=0; - s->lastseek = ftell(s->f); - s->sbuflen = fread(s->sbuf, 1, MP3_SCACHE, s->f); - if(s->sbuflen < 0) { - ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", s->sbuflen, strerror(errno)); + + p->lastseek = ftell(s->f); + p->sbuflen = fread(p->sbuf, 1, MP3_SCACHE, s->f); + if(p->sbuflen < 0) { + ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", p->sbuflen, strerror(errno)); return -1; } - res = decodeMP3(&s->mp,s->sbuf,s->sbuflen,s->dbuf,MP3_DCACHE,&s->dbuflen); + res = decodeMP3(&p->mp,p->sbuf,p->sbuflen,p->dbuf,MP3_DCACHE,&p->dbuflen); if(res != MP3_OK) return -1; - s->sbuflen -= s->dbuflen; - s->dbufoffset = 0; + p->sbuflen -= p->dbuflen; + p->dbufoffset = 0; return 0; } + static int mp3_dqueue(struct ast_filestream *s) { + struct mp3_private *p = s->private; int res=0; - if((res = decodeMP3(&s->mp,NULL,0,s->dbuf,MP3_DCACHE,&s->dbuflen)) == MP3_OK) { - s->sbuflen -= s->dbuflen; - s->dbufoffset = 0; + + if((res = decodeMP3(&p->mp,NULL,0,p->dbuf,MP3_DCACHE,&p->dbuflen)) == MP3_OK) { + p->sbuflen -= p->dbuflen; + p->dbufoffset = 0; } return res; } -static int mp3_queue(struct ast_filestream *s) { + +static int mp3_queue(struct ast_filestream *s) +{ + struct mp3_private *p = s->private; int res = 0, bytes = 0; - if(s->seek) { - ExitMP3(&s->mp); - InitMP3(&s->mp, OUTSCALE); + + if(p->seek) { + ExitMP3(&p->mp); + InitMP3(&p->mp, OUTSCALE); fseek(s->f, 0, SEEK_SET); - s->sbuflen = s->dbuflen = s->offset = 0; - while(s->offset < s->seek) { + p->sbuflen = p->dbuflen = p->offset = 0; + while(p->offset < p->seek) { if(mp3_squeue(s)) return -1; - while(s->offset < s->seek && ((res = mp3_dqueue(s))) == MP3_OK) { - for(bytes = 0 ; bytes < s->dbuflen ; bytes++) { - s->dbufoffset++; - s->offset++; - if(s->offset >= s->seek) + while(p->offset < p->seek && ((res = mp3_dqueue(s))) == MP3_OK) { + for(bytes = 0 ; bytes < p->dbuflen ; bytes++) { + p->dbufoffset++; + p->offset++; + if(p->offset >= p->seek) break; } } @@ -196,16 +174,16 @@ return -1; } - s->seek = 0; + p->seek = 0; return 0; } - if(s->dbuflen == 0) { - if(s->sbuflen) { + if(p->dbuflen == 0) { + if(p->sbuflen) { res = mp3_dqueue(s); if(res == MP3_ERR) return -1; } - if(! s->sbuflen || res != MP3_OK) { + if(! p->sbuflen || res != MP3_OK) { if(mp3_squeue(s)) return -1; } @@ -218,6 +196,7 @@ static struct ast_frame *mp3_read(struct ast_filestream *s, int *whennext) { + struct mp3_private *p = s->private; int delay =0; int save=0; @@ -226,35 +205,35 @@ if(mp3_queue(s)) return NULL; - if(s->dbuflen) { - for(s->buflen=0; s->buflen < MP3_BUFLEN && s->buflen < s->dbuflen; s->buflen++) { - s->buf[s->buflen] = s->dbuf[s->buflen+s->dbufoffset]; - s->sbufoffset++; + if(p->dbuflen) { + for(p->buflen=0; p->buflen < MP3_BUFLEN && p->buflen < p->dbuflen; p->buflen++) { + s->buf[p->buflen] = p->dbuf[p->buflen+p->dbufoffset]; + p->sbufoffset++; } - s->dbufoffset += s->buflen; - s->dbuflen -= s->buflen; + p->dbufoffset += p->buflen; + p->dbuflen -= p->buflen; - if(s->buflen < MP3_BUFLEN) { + if(p->buflen < MP3_BUFLEN) { if(mp3_queue(s)) return NULL; - for(save = s->buflen; s->buflen < MP3_BUFLEN; s->buflen++) { - s->buf[s->buflen] = s->dbuf[(s->buflen-save)+s->dbufoffset]; - s->sbufoffset++; + for(save = p->buflen; p->buflen < MP3_BUFLEN; p->buflen++) { + s->buf[p->buflen] = p->dbuf[(p->buflen-save)+p->dbufoffset]; + p->sbufoffset++; } - s->dbufoffset += (MP3_BUFLEN - save); - s->dbuflen -= (MP3_BUFLEN - save); + p->dbufoffset += (MP3_BUFLEN - save); + p->dbuflen -= (MP3_BUFLEN - save); } } - s->offset += s->buflen; - delay = s->buflen/2; + p->offset += p->buflen; + delay = p->buflen/2; s->fr.frametype = AST_FRAME_VOICE; s->fr.subclass = AST_FORMAT_SLINEAR; s->fr.offset = AST_FRIENDLY_OFFSET; - s->fr.datalen = s->buflen; + s->fr.datalen = p->buflen; s->fr.data = s->buf; s->fr.mallocd = 0; s->fr.samples = delay; @@ -271,17 +250,17 @@ } -static int mp3_seek(struct ast_filestream *fs, long sample_offset, int whence) +static int mp3_seek(struct ast_filestream *s, long sample_offset, int whence) { - + struct mp3_private *p = s->private; off_t min,max,cur; long offset=0,samples; samples = sample_offset * 2; min = 0; - fseek(fs->f, 0, SEEK_END); - max = ftell(fs->f) * 100; - cur = fs->offset; + fseek(s->f, 0, SEEK_END); + max = ftell(s->f) * 100; + cur = p->offset; if (whence == SEEK_SET) offset = samples + min; @@ -293,27 +272,29 @@ offset = (offset > max)?max:offset; } - fs->seek = offset; - return fs->seek; + p->seek = offset; + return p->seek; } -static struct ast_filestream *mp3_rewrite(FILE *f, const char *comment) +static int mp3_rewrite(struct ast_filestream *s, const char *comment) { ast_log(LOG_ERROR,"I Can't write MP3 only read them.\n"); - return NULL; + return -1; } -static int mp3_trunc(struct ast_filestream *fs) +static int mp3_trunc(struct ast_filestream *s) { ast_log(LOG_ERROR,"I Can't write MP3 only read them.\n"); return -1; } -static long mp3_tell(struct ast_filestream *fs) +static long mp3_tell(struct ast_filestream *s) { - return fs->offset/2; + struct mp3_private *p = s->private; + + return p->offset/2; } static char *mp3_getcomment(struct ast_filestream *s) @@ -321,47 +302,45 @@ return NULL; } -int load_module() +static const struct ast_format mp3_f = { + .name = "mp3", + .exts = "mp3", + .format = AST_FORMAT_SLINEAR, + .open = mp3_open, + .write = mp3_write, + .rewrite = mp3_rewrite, + .seek = mp3_seek, + .trunc = mp3_trunc, + .tell = mp3_tell, + .read = mp3_read, + .close = mp3_close, + .getcomment = mp3_getcomment, + .buf_size = MP3_BUFLEN + AST_FRIENDLY_OFFSET, + .desc_size = sizeof(struct mp3_private), + .module = &mod_data, +}; + + +static int load_module(void *mod) { InitMP3Constants(); - return ast_format_register(name, exts, AST_FORMAT_SLINEAR, - mp3_open, - mp3_rewrite, - mp3_write, - mp3_seek, - mp3_trunc, - mp3_tell, - mp3_read, - mp3_close, - mp3_getcomment); - - + return ast_format_register(&mp3_f); } -int unload_module() +static int unload_module(void *mod) { return ast_format_unregister(name); } -int usecount() -{ - int res; - if (ast_mutex_lock(&mp3_lock)) { - ast_log(LOG_WARNING, "Unable to lock mp3 list\n"); - return -1; - } - res = glistcnt; - ast_mutex_unlock(&mp3_lock); - return res; -} - -char *description() +static const char *description(void) { return desc; } -char *key() +static const char *key(void) { return ASTERISK_GPL_KEY; } + +STD_MOD1;