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: 364580 $")
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
00060 if (fread(&ts, 1, sizeof(ts), s->f) < sizeof(ts)) {
00061 ast_log(LOG_WARNING, "Empty file!\n");
00062 return -1;
00063 }
00064 return 0;
00065 }
00066
00067 static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
00068 {
00069 int res;
00070 uint32_t mark;
00071 unsigned short len;
00072 unsigned int ts;
00073 struct h263_desc *fs = (struct h263_desc *)s->_private;
00074
00075
00076 if ((res = fread(&len, 1, sizeof(len), s->f)) < 1)
00077 return NULL;
00078 len = ntohs(len);
00079 mark = (len & 0x8000) ? 1 : 0;
00080 len &= 0x7fff;
00081 if (len > BUF_SIZE) {
00082 ast_log(LOG_WARNING, "Length %d is too long\n", len);
00083 return NULL;
00084 }
00085 s->fr.frametype = AST_FRAME_VIDEO;
00086 ast_format_set(&s->fr.subclass.format, AST_FORMAT_H263, 0);
00087 s->fr.mallocd = 0;
00088 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
00089 if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
00090 if (res)
00091 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00092 return NULL;
00093 }
00094 s->fr.samples = fs->lastts;
00095 s->fr.datalen = len;
00096 if (mark) {
00097 ast_format_set_video_mark(&s->fr.subclass.format);
00098 }
00099 s->fr.delivery.tv_sec = 0;
00100 s->fr.delivery.tv_usec = 0;
00101 if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
00102 fs->lastts = ntohl(ts);
00103 *whennext = fs->lastts * 4/45;
00104 } else
00105 *whennext = 0;
00106 return &s->fr;
00107 }
00108
00109 static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
00110 {
00111 int res;
00112 unsigned int ts;
00113 unsigned short len;
00114 uint32_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 mark = ast_format_get_video_mark(&f->subclass.format) ? 0x8000 : 0;
00120 if (f->subclass.format.id != AST_FORMAT_H263) {
00121 ast_log(LOG_WARNING, "Asked to write non-h263 frame (%s)!\n", ast_getformatname(&f->subclass.format));
00122 return -1;
00123 }
00124 ts = htonl(f->samples);
00125 if ((res = fwrite(&ts, 1, sizeof(ts), fs->f)) != sizeof(ts)) {
00126 ast_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
00127 return -1;
00128 }
00129 len = htons(f->datalen | mark);
00130 if ((res = fwrite(&len, 1, sizeof(len), fs->f)) != sizeof(len)) {
00131 ast_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
00132 return -1;
00133 }
00134 if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
00135 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
00136 return -1;
00137 }
00138 return 0;
00139 }
00140
00141 static int h263_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
00142 {
00143
00144 return -1;
00145 }
00146
00147 static int h263_trunc(struct ast_filestream *fs)
00148 {
00149 int fd;
00150 off_t cur;
00151
00152 if ((fd = fileno(fs->f)) < 0) {
00153 ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for h263 filestream %p: %s\n", fs, strerror(errno));
00154 return -1;
00155 }
00156 if ((cur = ftello(fs->f)) < 0) {
00157 ast_log(AST_LOG_WARNING, "Unable to determine current position in h263 filestream %p: %s\n", fs, strerror(errno));
00158 return -1;
00159 }
00160
00161 return ftruncate(fd, cur);
00162 }
00163
00164 static off_t h263_tell(struct ast_filestream *fs)
00165 {
00166 off_t offset = ftello(fs->f);
00167 return offset;
00168 }
00169
00170 static struct ast_format_def h263_f = {
00171 .name = "h263",
00172 .exts = "h263",
00173 .open = h263_open,
00174 .write = h263_write,
00175 .seek = h263_seek,
00176 .trunc = h263_trunc,
00177 .tell = h263_tell,
00178 .read = h263_read,
00179 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
00180 .desc_size = sizeof(struct h263_desc),
00181 };
00182
00183 static int load_module(void)
00184 {
00185 ast_format_set(&h263_f.format, AST_FORMAT_H263, 0);
00186 if (ast_format_def_register(&h263_f))
00187 return AST_MODULE_LOAD_FAILURE;
00188 return AST_MODULE_LOAD_SUCCESS;
00189 }
00190
00191 static int unload_module(void)
00192 {
00193 return ast_format_def_unregister(h263_f.name);
00194 }
00195
00196 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.263 data",
00197 .load = load_module,
00198 .unload = unload_module,
00199 .load_pri = AST_MODPRI_APP_DEPEND
00200 );