00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <string.h>
00027
00028 #include "asterisk.h"
00029
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00031
00032 #include "asterisk/slinfactory.h"
00033 #include "asterisk/logger.h"
00034 #include "asterisk/translate.h"
00035
00036
00037 void ast_slinfactory_init(struct ast_slinfactory *sf)
00038 {
00039 memset(sf, 0, sizeof(struct ast_slinfactory));
00040 sf->offset = sf->hold;
00041 sf->queue = NULL;
00042 }
00043
00044 void ast_slinfactory_destroy(struct ast_slinfactory *sf)
00045 {
00046 struct ast_frame *f;
00047
00048 if (sf->trans) {
00049 ast_translator_free_path(sf->trans);
00050 sf->trans = NULL;
00051 }
00052
00053 while((f = sf->queue)) {
00054 sf->queue = f->next;
00055 ast_frfree(f);
00056 }
00057 }
00058
00059 int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f)
00060 {
00061 struct ast_frame *frame, *frame_ptr;
00062
00063 if (!f) {
00064 return 0;
00065 }
00066
00067 if (f->subclass != AST_FORMAT_SLINEAR) {
00068 if (sf->trans && f->subclass != sf->format) {
00069 ast_translator_free_path(sf->trans);
00070 sf->trans = NULL;
00071 }
00072 if (!sf->trans) {
00073 if ((sf->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
00074 ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(f->subclass));
00075 return 0;
00076 } else {
00077 sf->format = f->subclass;
00078 }
00079 }
00080 }
00081
00082 if (sf->trans) {
00083 frame = ast_translate(sf->trans, f, 0);
00084 } else {
00085 frame = ast_frdup(f);
00086 }
00087
00088 if (frame) {
00089 int x = 0;
00090 for (frame_ptr = sf->queue; frame_ptr && frame_ptr->next; frame_ptr=frame_ptr->next) {
00091 x++;
00092 }
00093 if (frame_ptr) {
00094 frame_ptr->next = frame;
00095 } else {
00096 sf->queue = frame;
00097 }
00098 frame->next = NULL;
00099 sf->size += frame->datalen;
00100 return x;
00101 }
00102
00103 return 0;
00104
00105 }
00106
00107 int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t bytes)
00108 {
00109 struct ast_frame *frame_ptr;
00110 int sofar = 0, ineed, remain;
00111 short *frame_data, *offset = buf;
00112
00113 while (sofar < bytes) {
00114 ineed = bytes - sofar;
00115
00116 if (sf->holdlen) {
00117 if ((sofar + sf->holdlen) <= ineed) {
00118 memcpy(offset, sf->hold, sf->holdlen);
00119 sofar += sf->holdlen;
00120 offset += (sf->holdlen / sizeof(short));
00121 sf->holdlen = 0;
00122 sf->offset = sf->hold;
00123 } else {
00124 remain = sf->holdlen - ineed;
00125 memcpy(offset, sf->offset, ineed);
00126 sofar += ineed;
00127 sf->offset += (ineed / sizeof(short));
00128 sf->holdlen = remain;
00129 }
00130 continue;
00131 }
00132
00133 if ((frame_ptr = sf->queue)) {
00134 sf->queue = frame_ptr->next;
00135 frame_data = frame_ptr->data;
00136
00137 if ((sofar + frame_ptr->datalen) <= ineed) {
00138 memcpy(offset, frame_data, frame_ptr->datalen);
00139 sofar += frame_ptr->datalen;
00140 offset += (frame_ptr->datalen / sizeof(short));
00141 } else {
00142 remain = frame_ptr->datalen - ineed;
00143 memcpy(offset, frame_data, ineed);
00144 sofar += ineed;
00145 frame_data += (ineed / sizeof(short));
00146 memcpy(sf->hold, frame_data, remain);
00147 sf->holdlen = remain;
00148 }
00149 ast_frfree(frame_ptr);
00150 } else {
00151 break;
00152 }
00153 }
00154
00155 sf->size -= sofar;
00156 return sofar;
00157 }
00158
00159
00160
00161