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: 364578 $")
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 int fd;
00153 off_t cur;
00154
00155 if ((fd = fileno(fs->f)) < 0) {
00156 ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for h263 filestream %p: %s\n", fs, strerror(errno));
00157 return -1;
00158 }
00159 if ((cur = ftello(fs->f)) < 0) {
00160 ast_log(AST_LOG_WARNING, "Unable to determine current position in h263 filestream %p: %s\n", fs, strerror(errno));
00161 return -1;
00162 }
00163
00164 return ftruncate(fd, cur);
00165 }
00166
00167 static off_t h263_tell(struct ast_filestream *fs)
00168 {
00169 off_t offset = ftello(fs->f);
00170 return offset;
00171 }
00172
00173 static const struct ast_format h263_f = {
00174 .name = "h263",
00175 .exts = "h263",
00176 .format = AST_FORMAT_H263,
00177 .open = h263_open,
00178 .write = h263_write,
00179 .seek = h263_seek,
00180 .trunc = h263_trunc,
00181 .tell = h263_tell,
00182 .read = h263_read,
00183 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
00184 .desc_size = sizeof(struct h263_desc),
00185 };
00186
00187 static int load_module(void)
00188 {
00189 if (ast_format_register(&h263_f))
00190 return AST_MODULE_LOAD_FAILURE;
00191 return AST_MODULE_LOAD_SUCCESS;
00192 }
00193
00194 static int unload_module(void)
00195 {
00196 return ast_format_unregister(h263_f.name);
00197 }
00198
00199 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.263 data",
00200 .load = load_module,
00201 .unload = unload_module,
00202 .load_pri = AST_MODPRI_APP_DEPEND
00203 );