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 <unistd.h>
00027 #include <netinet/in.h>
00028 #include <arpa/inet.h>
00029 #include <stdlib.h>
00030 #include <sys/time.h>
00031 #include <stdio.h>
00032 #include <errno.h>
00033 #include <string.h>
00034
00035 #include "asterisk.h"
00036
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00038
00039 #include "asterisk/lock.h"
00040 #include "asterisk/channel.h"
00041 #include "asterisk/file.h"
00042 #include "asterisk/logger.h"
00043 #include "asterisk/sched.h"
00044 #include "asterisk/module.h"
00045 #include "asterisk/endian.h"
00046
00047
00048
00049
00050
00051 struct ast_filestream {
00052 void *reserved[AST_RESERVED_POINTERS];
00053
00054
00055
00056 FILE *f;
00057 unsigned int lastts;
00058 struct ast_frame fr;
00059 char waste[AST_FRIENDLY_OFFSET];
00060 char empty;
00061 unsigned char h263[4096];
00062 };
00063
00064
00065 AST_MUTEX_DEFINE_STATIC(h263_lock);
00066 static int glistcnt = 0;
00067
00068 static char *name = "h263";
00069 static char *desc = "Raw h263 data";
00070 static char *exts = "h263";
00071
00072 static struct ast_filestream *h263_open(FILE *f)
00073 {
00074
00075
00076
00077 struct ast_filestream *tmp;
00078 unsigned int ts;
00079 int res;
00080 if ((res = fread(&ts, 1, sizeof(ts), f)) < sizeof(ts)) {
00081 ast_log(LOG_WARNING, "Empty file!\n");
00082 return NULL;
00083 }
00084
00085 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
00086 memset(tmp, 0, sizeof(struct ast_filestream));
00087 if (ast_mutex_lock(&h263_lock)) {
00088 ast_log(LOG_WARNING, "Unable to lock h263 list\n");
00089 free(tmp);
00090 return NULL;
00091 }
00092 tmp->f = f;
00093 tmp->fr.data = tmp->h263;
00094 tmp->fr.frametype = AST_FRAME_VIDEO;
00095 tmp->fr.subclass = AST_FORMAT_H263;
00096
00097 tmp->fr.src = name;
00098 tmp->fr.mallocd = 0;
00099 glistcnt++;
00100 ast_mutex_unlock(&h263_lock);
00101 ast_update_use_count();
00102 }
00103 return tmp;
00104 }
00105
00106 static struct ast_filestream *h263_rewrite(FILE *f, const char *comment)
00107 {
00108
00109
00110
00111 struct ast_filestream *tmp;
00112 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
00113 memset(tmp, 0, sizeof(struct ast_filestream));
00114 if (ast_mutex_lock(&h263_lock)) {
00115 ast_log(LOG_WARNING, "Unable to lock h263 list\n");
00116 free(tmp);
00117 return NULL;
00118 }
00119 tmp->f = f;
00120 glistcnt++;
00121 ast_mutex_unlock(&h263_lock);
00122 ast_update_use_count();
00123 } else
00124 ast_log(LOG_WARNING, "Out of memory\n");
00125 return tmp;
00126 }
00127
00128 static void h263_close(struct ast_filestream *s)
00129 {
00130 if (ast_mutex_lock(&h263_lock)) {
00131 ast_log(LOG_WARNING, "Unable to lock h263 list\n");
00132 return;
00133 }
00134 glistcnt--;
00135 ast_mutex_unlock(&h263_lock);
00136 ast_update_use_count();
00137 fclose(s->f);
00138 free(s);
00139 s = NULL;
00140 }
00141
00142 static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
00143 {
00144 int res;
00145 int mark=0;
00146 unsigned short len;
00147 unsigned int ts;
00148
00149 s->fr.frametype = AST_FRAME_VIDEO;
00150 s->fr.subclass = AST_FORMAT_H263;
00151 s->fr.offset = AST_FRIENDLY_OFFSET;
00152 s->fr.mallocd = 0;
00153 s->fr.data = s->h263;
00154 if ((res = fread(&len, 1, sizeof(len), s->f)) < 1) {
00155 return NULL;
00156 }
00157 len = ntohs(len);
00158 if (len & 0x8000) {
00159 mark = 1;
00160 }
00161 len &= 0x7fff;
00162 if (len > sizeof(s->h263)) {
00163 ast_log(LOG_WARNING, "Length %d is too long\n", len);
00164 }
00165 if ((res = fread(s->h263, 1, len, s->f)) != len) {
00166 if (res)
00167 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00168 return NULL;
00169 }
00170 s->fr.samples = s->lastts;
00171 s->fr.datalen = len;
00172 s->fr.subclass |= mark;
00173 s->fr.delivery.tv_sec = 0;
00174 s->fr.delivery.tv_usec = 0;
00175 if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
00176 s->lastts = ntohl(ts);
00177 *whennext = s->lastts * 4/45;
00178 } else
00179 *whennext = 0;
00180 return &s->fr;
00181 }
00182
00183 static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
00184 {
00185 int res;
00186 unsigned int ts;
00187 unsigned short len;
00188 int subclass;
00189 int mark=0;
00190 if (f->frametype != AST_FRAME_VIDEO) {
00191 ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
00192 return -1;
00193 }
00194 subclass = f->subclass;
00195 if (subclass & 0x1)
00196 mark=0x8000;
00197 subclass &= ~0x1;
00198 if (subclass != AST_FORMAT_H263) {
00199 ast_log(LOG_WARNING, "Asked to write non-h263 frame (%d)!\n", f->subclass);
00200 return -1;
00201 }
00202 ts = htonl(f->samples);
00203 if ((res = fwrite(&ts, 1, sizeof(ts), fs->f)) != sizeof(ts)) {
00204 ast_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
00205 return -1;
00206 }
00207 len = htons(f->datalen | mark);
00208 if ((res = fwrite(&len, 1, sizeof(len), fs->f)) != sizeof(len)) {
00209 ast_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
00210 return -1;
00211 }
00212 if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
00213 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00214 return -1;
00215 }
00216 return 0;
00217 }
00218
00219 static char *h263_getcomment(struct ast_filestream *s)
00220 {
00221 return NULL;
00222 }
00223
00224 static int h263_seek(struct ast_filestream *fs, long sample_offset, int whence)
00225 {
00226
00227 return -1;
00228 }
00229
00230 static int h263_trunc(struct ast_filestream *fs)
00231 {
00232
00233 if (ftruncate(fileno(fs->f), ftell(fs->f)) < 0)
00234 return -1;
00235 return 0;
00236 }
00237
00238 static long h263_tell(struct ast_filestream *fs)
00239 {
00240
00241 off_t offset;
00242 offset = ftell(fs->f);
00243 return (offset/20)*160;
00244 }
00245
00246 int load_module()
00247 {
00248 return ast_format_register(name, exts, AST_FORMAT_H263,
00249 h263_open,
00250 h263_rewrite,
00251 h263_write,
00252 h263_seek,
00253 h263_trunc,
00254 h263_tell,
00255 h263_read,
00256 h263_close,
00257 h263_getcomment);
00258
00259
00260 }
00261
00262 int unload_module()
00263 {
00264 return ast_format_unregister(name);
00265 }
00266
00267 int usecount()
00268 {
00269 return glistcnt;
00270 }
00271
00272 char *description()
00273 {
00274 return desc;
00275 }
00276
00277
00278 char *key()
00279 {
00280 return ASTERISK_GPL_KEY;
00281 }