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