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
00027
00028
00029
00030
00031 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00034
00035 #include "asterisk/mod_format.h"
00036 #include "asterisk/module.h"
00037 #include "asterisk/endian.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #define BUF_SIZE 32768
00050
00051 struct h263_desc {
00052 unsigned int lastts;
00053 };
00054
00055
00056 static int h263_open(struct ast_filestream *s)
00057 {
00058 unsigned int ts;
00059 int res;
00060
00061 if ((res = fread(&ts, 1, sizeof(ts), s->f)) < sizeof(ts)) {
00062 ast_log(LOG_WARNING, "Empty file!\n");
00063 return -1;
00064 }
00065 return 0;
00066 }
00067
00068 static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
00069 {
00070 int res;
00071 format_t mark;
00072 unsigned short len;
00073 unsigned int ts;
00074 struct h263_desc *fs = (struct h263_desc *)s->_private;
00075
00076
00077 if ((res = fread(&len, 1, sizeof(len), s->f)) < 1)
00078 return NULL;
00079 len = ntohs(len);
00080 mark = (len & 0x8000) ? 1 : 0;
00081 len &= 0x7fff;
00082 if (len > BUF_SIZE) {
00083 ast_log(LOG_WARNING, "Length %d is too long\n", len);
00084 return NULL;
00085 }
00086 s->fr.frametype = AST_FRAME_VIDEO;
00087 s->fr.subclass.codec = AST_FORMAT_H263;
00088 s->fr.mallocd = 0;
00089 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
00090 if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
00091 if (res)
00092 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00093 return NULL;
00094 }
00095 s->fr.samples = fs->lastts;
00096 s->fr.datalen = len;
00097 s->fr.subclass.codec |= mark;
00098 s->fr.delivery.tv_sec = 0;
00099 s->fr.delivery.tv_usec = 0;
00100 if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
00101 fs->lastts = ntohl(ts);
00102 *whennext = fs->lastts * 4/45;
00103 } else
00104 *whennext = 0;
00105 return &s->fr;
00106 }
00107
00108 static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
00109 {
00110 int res;
00111 unsigned int ts;
00112 unsigned short len;
00113 format_t subclass;
00114 format_t mark=0;
00115 if (f->frametype != AST_FRAME_VIDEO) {
00116 ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
00117 return -1;
00118 }
00119 subclass = f->subclass.codec;
00120 if (subclass & 0x1)
00121 mark=0x8000;
00122 subclass &= ~0x1;
00123 if (subclass != AST_FORMAT_H263) {
00124 ast_log(LOG_WARNING, "Asked to write non-h263 frame (%s)!\n", ast_getformatname(f->subclass.codec));
00125 return -1;
00126 }
00127 ts = htonl(f->samples);
00128 if ((res = fwrite(&ts, 1, sizeof(ts), fs->f)) != sizeof(ts)) {
00129 ast_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
00130 return -1;
00131 }
00132 len = htons(f->datalen | mark);
00133 if ((res = fwrite(&len, 1, sizeof(len), fs->f)) != sizeof(len)) {
00134 ast_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
00135 return -1;
00136 }
00137 if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
00138 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00139 return -1;
00140 }
00141 return 0;
00142 }
00143
00144 static int h263_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
00145 {
00146
00147 return -1;
00148 }
00149
00150 static int h263_trunc(struct ast_filestream *fs)
00151 {
00152
00153 if (ftruncate(fileno(fs->f), ftello(fs->f)) < 0)
00154 return -1;
00155 return 0;
00156 }
00157
00158 static off_t h263_tell(struct ast_filestream *fs)
00159 {
00160 off_t offset = ftello(fs->f);
00161 return offset;
00162 }
00163
00164 static const struct ast_format h263_f = {
00165 .name = "h263",
00166 .exts = "h263",
00167 .format = AST_FORMAT_H263,
00168 .open = h263_open,
00169 .write = h263_write,
00170 .seek = h263_seek,
00171 .trunc = h263_trunc,
00172 .tell = h263_tell,
00173 .read = h263_read,
00174 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
00175 .desc_size = sizeof(struct h263_desc),
00176 };
00177
00178 static int load_module(void)
00179 {
00180 if (ast_format_register(&h263_f))
00181 return AST_MODULE_LOAD_FAILURE;
00182 return AST_MODULE_LOAD_SUCCESS;
00183 }
00184
00185 static int unload_module(void)
00186 {
00187 return ast_format_unregister(h263_f.name);
00188 }
00189
00190 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.263 data",
00191 .load = load_module,
00192 .unload = unload_module,
00193 .load_pri = AST_MODPRI_APP_DEPEND
00194 );