format_h263.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * Asterisk -- A telephony toolkit for Linux.
  3. *
  4. * Save to raw, headerless h263 data.
  5. *
  6. * Copyright (C) 1999, Mark Spencer
  7. *
  8. * Mark Spencer <markster@linux-support.net>
  9. *
  10. * This program is free software, distributed under the terms of
  11. * the GNU General Public License
  12. */
  13. #include <asterisk/lock.h>
  14. #include <asterisk/channel.h>
  15. #include <asterisk/file.h>
  16. #include <asterisk/logger.h>
  17. #include <asterisk/sched.h>
  18. #include <asterisk/module.h>
  19. #include <netinet/in.h>
  20. #include <arpa/inet.h>
  21. #include <stdlib.h>
  22. #include <sys/time.h>
  23. #include <stdio.h>
  24. #include <unistd.h>
  25. #include <errno.h>
  26. #include <string.h>
  27. #ifdef __linux__
  28. #include <endian.h>
  29. #else
  30. #include <machine/endian.h>
  31. #endif
  32. /* Some Ideas for this code came from makeh263e.c by Jeffrey Chilton */
  33. /* Portions of the conversion code are by guido@sienanet.it */
  34. struct ast_filestream {
  35. void *reserved[AST_RESERVED_POINTERS];
  36. /* Believe it or not, we must decode/recode to account for the
  37. weird MS format */
  38. /* This is what a filestream means to us */
  39. int fd; /* Descriptor */
  40. unsigned int lastts;
  41. struct ast_frame fr; /* Frame information */
  42. char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
  43. char empty; /* Empty character */
  44. unsigned char h263[4096]; /* Two Real h263 Frames */
  45. };
  46. AST_MUTEX_DEFINE_STATIC(h263_lock);
  47. static int glistcnt = 0;
  48. static char *name = "h263";
  49. static char *desc = "Raw h263 data";
  50. static char *exts = "h263";
  51. static struct ast_filestream *h263_open(int fd)
  52. {
  53. /* We don't have any header to read or anything really, but
  54. if we did, it would go here. We also might want to check
  55. and be sure it's a valid file. */
  56. struct ast_filestream *tmp;
  57. unsigned int ts;
  58. int res;
  59. if ((res = read(fd, &ts, sizeof(ts))) < sizeof(ts)) {
  60. ast_log(LOG_WARNING, "Empty file!\n");
  61. return NULL;
  62. }
  63. if ((tmp = malloc(sizeof(struct ast_filestream)))) {
  64. memset(tmp, 0, sizeof(struct ast_filestream));
  65. if (ast_mutex_lock(&h263_lock)) {
  66. ast_log(LOG_WARNING, "Unable to lock h263 list\n");
  67. free(tmp);
  68. return NULL;
  69. }
  70. tmp->fd = fd;
  71. tmp->fr.data = tmp->h263;
  72. tmp->fr.frametype = AST_FRAME_VIDEO;
  73. tmp->fr.subclass = AST_FORMAT_H263;
  74. /* datalen will vary for each frame */
  75. tmp->fr.src = name;
  76. tmp->fr.mallocd = 0;
  77. glistcnt++;
  78. ast_mutex_unlock(&h263_lock);
  79. ast_update_use_count();
  80. }
  81. return tmp;
  82. }
  83. static struct ast_filestream *h263_rewrite(int fd, char *comment)
  84. {
  85. /* We don't have any header to read or anything really, but
  86. if we did, it would go here. We also might want to check
  87. and be sure it's a valid file. */
  88. struct ast_filestream *tmp;
  89. if ((tmp = malloc(sizeof(struct ast_filestream)))) {
  90. memset(tmp, 0, sizeof(struct ast_filestream));
  91. if (ast_mutex_lock(&h263_lock)) {
  92. ast_log(LOG_WARNING, "Unable to lock h263 list\n");
  93. free(tmp);
  94. return NULL;
  95. }
  96. tmp->fd = fd;
  97. glistcnt++;
  98. ast_mutex_unlock(&h263_lock);
  99. ast_update_use_count();
  100. } else
  101. ast_log(LOG_WARNING, "Out of memory\n");
  102. return tmp;
  103. }
  104. static void h263_close(struct ast_filestream *s)
  105. {
  106. if (ast_mutex_lock(&h263_lock)) {
  107. ast_log(LOG_WARNING, "Unable to lock h263 list\n");
  108. return;
  109. }
  110. glistcnt--;
  111. ast_mutex_unlock(&h263_lock);
  112. ast_update_use_count();
  113. close(s->fd);
  114. free(s);
  115. s = NULL;
  116. }
  117. static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
  118. {
  119. int res;
  120. int mark=0;
  121. unsigned short len;
  122. unsigned int ts;
  123. /* Send a frame from the file to the appropriate channel */
  124. s->fr.frametype = AST_FRAME_VIDEO;
  125. s->fr.subclass = AST_FORMAT_H263;
  126. s->fr.offset = AST_FRIENDLY_OFFSET;
  127. s->fr.mallocd = 0;
  128. s->fr.data = s->h263;
  129. if ((res = read(s->fd, &len, sizeof(len))) < 1) {
  130. return NULL;
  131. }
  132. len = ntohs(len);
  133. if (len & 0x8000) {
  134. mark = 1;
  135. }
  136. len &= 0x7fff;
  137. if (len > sizeof(s->h263)) {
  138. ast_log(LOG_WARNING, "Length %d is too long\n", len);
  139. }
  140. if ((res = read(s->fd, s->h263, len)) != len) {
  141. if (res)
  142. ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
  143. return NULL;
  144. }
  145. s->fr.samples = s->lastts;
  146. s->fr.datalen = len;
  147. s->fr.subclass |= mark;
  148. if ((res = read(s->fd, &ts, sizeof(ts))) == sizeof(ts)) {
  149. s->lastts = *whennext = ntohl(ts) * 4/45;
  150. } else
  151. *whennext = 0;
  152. return &s->fr;
  153. }
  154. static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
  155. {
  156. int res;
  157. unsigned int ts;
  158. unsigned short len;
  159. int subclass;
  160. int mark=0;
  161. if (f->frametype != AST_FRAME_VIDEO) {
  162. ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
  163. return -1;
  164. }
  165. subclass = f->subclass;
  166. if (subclass & 0x1)
  167. mark=0x8000;
  168. subclass &= ~0x1;
  169. if (subclass != AST_FORMAT_H263) {
  170. ast_log(LOG_WARNING, "Asked to write non-h263 frame (%d)!\n", f->subclass);
  171. return -1;
  172. }
  173. ts = htonl(f->samples);
  174. if ((res = write(fs->fd, &ts, sizeof(ts))) != sizeof(ts)) {
  175. ast_log(LOG_WARNING, "Bad write (%d/4): %s\n", res, strerror(errno));
  176. return -1;
  177. }
  178. len = htons(f->datalen | mark);
  179. if ((res = write(fs->fd, &len, sizeof(len))) != sizeof(len)) {
  180. ast_log(LOG_WARNING, "Bad write (%d/2): %s\n", res, strerror(errno));
  181. return -1;
  182. }
  183. if ((res = write(fs->fd, f->data, f->datalen)) != f->datalen) {
  184. ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
  185. return -1;
  186. }
  187. return 0;
  188. }
  189. static char *h263_getcomment(struct ast_filestream *s)
  190. {
  191. return NULL;
  192. }
  193. static int h263_seek(struct ast_filestream *fs, long sample_offset, int whence)
  194. {
  195. /* No way Jose */
  196. return -1;
  197. }
  198. static int h263_trunc(struct ast_filestream *fs)
  199. {
  200. /* Truncate file to current length */
  201. if (ftruncate(fs->fd, lseek(fs->fd, 0, SEEK_CUR)) < 0)
  202. return -1;
  203. return 0;
  204. }
  205. static long h263_tell(struct ast_filestream *fs)
  206. {
  207. off_t offset;
  208. offset = lseek(fs->fd, 0, SEEK_CUR);
  209. return (offset/20)*160;
  210. }
  211. int load_module()
  212. {
  213. return ast_format_register(name, exts, AST_FORMAT_H263,
  214. h263_open,
  215. h263_rewrite,
  216. h263_write,
  217. h263_seek,
  218. h263_trunc,
  219. h263_tell,
  220. h263_read,
  221. h263_close,
  222. h263_getcomment);
  223. }
  224. int unload_module()
  225. {
  226. return ast_format_unregister(name);
  227. }
  228. int usecount()
  229. {
  230. int res;
  231. if (ast_mutex_lock(&h263_lock)) {
  232. ast_log(LOG_WARNING, "Unable to lock h263 list\n");
  233. return -1;
  234. }
  235. res = glistcnt;
  236. ast_mutex_unlock(&h263_lock);
  237. return res;
  238. }
  239. char *description()
  240. {
  241. return desc;
  242. }
  243. char *key()
  244. {
  245. return ASTERISK_GPL_KEY;
  246. }