Asterisk - The Open Source Telephony Project  18.5.0
format_g723.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  *
22  * \brief Old-style G.723.1 frame/timestamp format.
23  *
24  * \arg Extensions: g723, g723sf
25  * \ingroup formats
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include "asterisk/mod_format.h"
35 #include "asterisk/module.h"
36 #include "asterisk/format_cache.h"
37 
38 #define G723_MAX_SIZE 1024
39 
40 static struct ast_frame *g723_read(struct ast_filestream *s, int *whennext)
41 {
42  unsigned short size;
43  size_t res;
44  int delay;
45  /* Read the delay for the next packet, and schedule again if necessary */
46  /* XXX is this ignored ? */
47  if (fread(&delay, 1, 4, s->f) == 4)
48  delay = ntohl(delay);
49  else
50  delay = -1;
51  if (fread(&size, 1, 2, s->f) != 2) {
52  /* Out of data, or the file is no longer valid. In any case
53  go ahead and stop the stream */
54  return NULL;
55  }
56  /* Looks like we have a frame to read from here */
57  size = ntohs(size);
58  if (size > G723_MAX_SIZE) {
59  ast_log(LOG_WARNING, "Size %d is invalid\n", size);
60  /* The file is apparently no longer any good, as we
61  shouldn't ever get frames even close to this
62  size. */
63  return NULL;
64  }
65  /* Read the data into the buffer */
67  if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
68  if (res) {
69  ast_log(LOG_WARNING, "Short read of %s data (expected %d bytes, read %zu): %s\n",
71  strerror(errno));
72  }
73  return NULL;
74  }
75  *whennext = s->fr.samples = 240;
76  return &s->fr;
77 }
78 
79 static int g723_write(struct ast_filestream *s, struct ast_frame *f)
80 {
81  uint32_t delay;
82  uint16_t size;
83  int res;
84  /* XXX there used to be a check s->fr means a read stream */
85  delay = 0;
86  if (f->datalen <= 0) {
87  ast_log(LOG_WARNING, "Short frame ignored (%d bytes long?)\n", f->datalen);
88  return 0;
89  }
90  if ((res = fwrite(&delay, 1, 4, s->f)) != 4) {
91  ast_log(LOG_WARNING, "Unable to write delay: res=%d (%s)\n", res, strerror(errno));
92  return -1;
93  }
94  size = htons(f->datalen);
95  if ((res = fwrite(&size, 1, 2, s->f)) != 2) {
96  ast_log(LOG_WARNING, "Unable to write size: res=%d (%s)\n", res, strerror(errno));
97  return -1;
98  }
99  if ((res = fwrite(f->data.ptr, 1, f->datalen, s->f)) != f->datalen) {
100  ast_log(LOG_WARNING, "Unable to write frame: res=%d (%s)\n", res, strerror(errno));
101  return -1;
102  }
103  return 0;
104 }
105 
106 static int g723_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
107 {
108  return -1;
109 }
110 
111 static int g723_trunc(struct ast_filestream *fs)
112 {
113  int fd;
114  off_t cur;
115 
116  if ((fd = fileno(fs->f)) < 0) {
117  ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for g723 filestream %p: %s\n", fs, strerror(errno));
118  return -1;
119  }
120  if ((cur = ftello(fs->f)) < 0) {
121  ast_log(AST_LOG_WARNING, "Unable to determine current position in g723 filestream %p: %s\n", fs, strerror(errno));
122  return -1;
123  }
124  /* Truncate file to current length */
125  return ftruncate(fd, cur);
126 }
127 
128 static off_t g723_tell(struct ast_filestream *fs)
129 {
130  return -1;
131 }
132 
133 static struct ast_format_def g723_1_f = {
134  .name = "g723sf",
135  .exts = "g723|g723sf",
136  .write = g723_write,
137  .seek = g723_seek,
138  .trunc = g723_trunc,
139  .tell = g723_tell,
140  .read = g723_read,
141  .buf_size = G723_MAX_SIZE + AST_FRIENDLY_OFFSET,
142 };
143 
144 static int load_module(void)
145 {
146  g723_1_f.format = ast_format_g723;
147 
148  if (ast_format_def_register(&g723_1_f))
151 }
152 
153 static int unload_module(void)
154 {
155  return ast_format_def_unregister(g723_1_f.name);
156 }
157 
158 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "G.723.1 Simple Timestamp File Format",
159  .support_level = AST_MODULE_SUPPORT_CORE,
160  .load = load_module,
161  .unload = unload_module,
162  .load_pri = AST_MODPRI_APP_DEPEND
163 );
struct ast_format * ast_format_g723
Built-in cached g723.1 format.
Definition: format_cache.c:151
Asterisk main include file. File version handling, generic pbx functions.
static int g723_trunc(struct ast_filestream *fs)
Definition: format_g723.c:111
#define LOG_WARNING
Definition: logger.h:274
#define G723_MAX_SIZE
Definition: format_g723.c:38
#define AST_LOG_WARNING
Definition: logger.h:279
static int g723_write(struct ast_filestream *s, struct ast_frame *f)
Definition: format_g723.c:79
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
Each supported file format is described by the following structure.
Definition: mod_format.h:43
struct ast_frame_subclass subclass
Header for providers of file and format handling routines. Clients of these routines should include "...
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
#define ast_format_def_register(f)
Definition: mod_format.h:136
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
static off_t g723_tell(struct ast_filestream *fs)
Definition: format_g723.c:128
struct ast_format * format
Definition: mod_format.h:48
static int unload_module(void)
Definition: format_g723.c:153
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
static struct ast_frame * g723_read(struct ast_filestream *s, int *whennext)
Definition: format_g723.c:40
int errno
static struct ast_format_def g723_1_f
Definition: format_g723.c:133
char name[80]
Definition: mod_format.h:44
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int load_module(void)
Definition: format_g723.c:144
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int g723_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_g723.c:106
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
Data structure associated with a single frame of data.
union ast_frame::@263 data
struct ast_format * format
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
Media Format Cache API.