Changeset 288
- Timestamp:
- Mar 5, 2006 1:37:19 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/file_port.c
r277 r288 23 23 #include <pj/file_access.h> 24 24 #include <pj/file_io.h> 25 #include <pj/log.h> 25 26 #include <pj/pool.h> 26 27 #include <pj/string.h> 28 29 30 #define THIS_FILE "file_port.c" 31 32 33 #ifndef PJMEDIA_FILE_PORT_BUFSIZE 34 # define PJMEDIA_FILE_PORT_BUFSIZE 4000 35 #endif 27 36 28 37 … … 35 44 char *buf; 36 45 char *readpos; 46 47 pj_off_t fsize; 48 pj_off_t fpos; 49 pj_oshandle_t fd; 50 37 51 }; 38 52 … … 77 91 78 92 /* 93 * Fill buffer. 94 */ 95 static pj_status_t fill_buffer(struct file_port *fport) 96 { 97 pj_ssize_t size_left = fport->bufsize; 98 unsigned size_to_read; 99 pj_ssize_t size; 100 pj_status_t status; 101 102 while (size_left > 0) { 103 104 /* Calculate how many bytes to read in this run. */ 105 size = size_to_read = size_left; 106 status = pj_file_read(fport->fd, 107 &fport->buf[fport->bufsize-size_left], 108 &size); 109 if (status != PJ_SUCCESS) 110 return status; 111 if (size < 0) { 112 /* Should return more appropriate error code here.. */ 113 return PJ_ECANCELLED; 114 } 115 116 size_left -= size; 117 fport->fpos += size; 118 119 /* If size is less than size_to_read, it indicates that we've 120 * encountered EOF. Rewind the file. 121 */ 122 if (size < (pj_ssize_t)size_to_read) { 123 PJ_LOG(5,(THIS_FILE, "File port %.*s EOF, rewinding..", 124 (int)fport->base.info.name.slen, 125 fport->base.info.name.ptr)); 126 fport->fpos = sizeof(struct pjmedia_wave_hdr); 127 pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET); 128 } 129 } 130 131 return PJ_SUCCESS; 132 } 133 134 /* 79 135 * Create WAVE player port. 80 136 */ … … 86 142 pjmedia_port **p_port ) 87 143 { 88 pj_off_t file_size;89 pj_oshandle_t fd = NULL;90 144 pjmedia_wave_hdr wave_hdr; 91 145 pj_ssize_t size_read; 92 struct file_port *f ile_port;146 struct file_port *fport; 93 147 pj_status_t status; 94 148 … … 105 159 } 106 160 161 /* Create fport instance. */ 162 fport = create_file_port(pool); 163 if (!fport) { 164 return PJ_ENOMEM; 165 } 166 167 107 168 /* Get the file size. */ 108 f ile_size = pj_file_size(filename);169 fport->fsize = pj_file_size(filename); 109 170 110 171 /* Size must be more than WAVE header size */ 111 if (f ile_size <= sizeof(pjmedia_wave_hdr)) {172 if (fport->fsize <= sizeof(pjmedia_wave_hdr)) { 112 173 return PJMEDIA_ENOTVALIDWAVE; 113 174 } 114 175 115 176 /* Open file. */ 116 status = pj_file_open( pool, filename, PJ_O_RDONLY, &f d);177 status = pj_file_open( pool, filename, PJ_O_RDONLY, &fport->fd); 117 178 if (status != PJ_SUCCESS) 118 179 return status; … … 120 181 /* Read the WAVE header. */ 121 182 size_read = sizeof(wave_hdr); 122 status = pj_file_read( f d, &wave_hdr, &size_read);183 status = pj_file_read( fport->fd, &wave_hdr, &size_read); 123 184 if (status != PJ_SUCCESS) { 124 pj_file_close(f d);185 pj_file_close(fport->fd); 125 186 return status; 126 187 } 127 188 if (size_read != sizeof(wave_hdr)) { 128 pj_file_close(f d);189 pj_file_close(fport->fd); 129 190 return PJMEDIA_ENOTVALIDWAVE; 130 191 } … … 135 196 wave_hdr.fmt_hdr.fmt != PJMEDIA_FMT_TAG) 136 197 { 137 pj_file_close(f d);198 pj_file_close(fport->fd); 138 199 return PJMEDIA_ENOTVALIDWAVE; 139 200 } … … 144 205 wave_hdr.fmt_hdr.block_align != 2) 145 206 { 146 pj_file_close(f d);207 pj_file_close(fport->fd); 147 208 return PJMEDIA_EWAVEUNSUPP; 148 209 } 149 210 150 211 /* Validate length. */ 151 if (wave_hdr.data_hdr.len != f ile_size-sizeof(pjmedia_wave_hdr)) {152 pj_file_close(f d);212 if (wave_hdr.data_hdr.len != fport->fsize-sizeof(pjmedia_wave_hdr)) { 213 pj_file_close(fport->fd); 153 214 return PJMEDIA_EWAVEUNSUPP; 154 215 } 155 216 if (wave_hdr.data_hdr.len < 400) { 156 pj_file_close(f d);217 pj_file_close(fport->fd); 157 218 return PJMEDIA_EWAVETOOSHORT; 158 219 } … … 160 221 /* It seems like we have a valid WAVE file. */ 161 222 162 /* Create file_port instance. */ 163 file_port = create_file_port(pool); 164 if (!file_port) { 165 pj_file_close(fd); 223 /* Initialize */ 224 fport->base.user_data = user_data; 225 226 /* Update port info. */ 227 fport->base.info.sample_rate = wave_hdr.fmt_hdr.sample_rate; 228 fport->base.info.bits_per_sample = wave_hdr.fmt_hdr.bits_per_sample; 229 fport->base.info.samples_per_frame = fport->base.info.sample_rate * 230 20 / 1000; 231 fport->base.info.bytes_per_frame = 232 fport->base.info.samples_per_frame * 233 fport->base.info.bits_per_sample / 8; 234 235 pj_strdup2(pool, &fport->base.info.name, filename); 236 237 /* Create file buffer. 238 */ 239 fport->bufsize = PJMEDIA_FILE_PORT_BUFSIZE; 240 241 242 /* Create buffer. */ 243 fport->buf = pj_pool_alloc(pool, fport->bufsize); 244 if (!fport->buf) { 245 pj_file_close(fport->fd); 166 246 return PJ_ENOMEM; 167 247 } 168 248 169 /* Initialize */ 170 file_port->base.user_data = user_data; 171 172 /* Update port info. */ 173 file_port->base.info.sample_rate = wave_hdr.fmt_hdr.sample_rate; 174 file_port->base.info.bits_per_sample = wave_hdr.fmt_hdr.bits_per_sample; 175 file_port->base.info.samples_per_frame = file_port->base.info.sample_rate * 176 20 / 1000; 177 file_port->base.info.bytes_per_frame = 178 file_port->base.info.samples_per_frame * 179 file_port->base.info.bits_per_sample / 8; 180 181 182 /* For this version, we only support reading the whole 183 * contents of the file. 184 */ 185 file_port->bufsize = wave_hdr.data_hdr.len - 8; 186 187 /* Create buffer. */ 188 file_port->buf = pj_pool_alloc(pool, file_port->bufsize); 189 if (!file_port->buf) { 190 pj_file_close(fd); 191 return PJ_ENOMEM; 192 } 193 194 file_port->readpos = file_port->buf; 195 196 /* Read the the file. */ 197 size_read = file_port->bufsize; 198 status = pj_file_read(fd, file_port->buf, &size_read); 249 fport->readpos = fport->buf; 250 251 /* Set initial position of the file. */ 252 fport->fpos = sizeof(struct pjmedia_wave_hdr); 253 254 /* Fill up the buffer. */ 255 status = fill_buffer(fport); 199 256 if (status != PJ_SUCCESS) { 200 pj_file_close(f d);257 pj_file_close(fport->fd); 201 258 return status; 202 259 } 203 260 204 if (size_read != (pj_ssize_t)file_port->bufsize) {205 pj_file_close(fd);206 return PJMEDIA_ENOTVALIDWAVE;207 }208 209 210 261 /* Done. */ 211 pj_file_close(fd); 212 213 *p_port = &file_port->base; 262 263 *p_port = &fport->base; 264 265 266 PJ_LOG(4,(THIS_FILE, 267 "File port '%.*s' created: clock=%dKHz, bufsize=%uKB, " 268 "filesize=%luKB", 269 (int)fport->base.info.name.slen, 270 fport->base.info.name.ptr, 271 fport->base.info.sample_rate/1000, 272 fport->bufsize / 1000, 273 (unsigned long)(fport->fsize / 1000))); 214 274 215 275 return PJ_SUCCESS; … … 234 294 pjmedia_frame *frame) 235 295 { 236 struct file_port * port = (struct file_port*)this_port;296 struct file_port *fport = (struct file_port*)this_port; 237 297 unsigned frame_size; 238 pj_assert(port->base.info.signature == SIGNATURE); 239 240 frame_size = port->base.info.bytes_per_frame; 298 pj_status_t status; 299 300 pj_assert(fport->base.info.signature == SIGNATURE); 301 302 frame_size = fport->base.info.bytes_per_frame; 303 pj_assert(frame->size == frame_size); 241 304 242 305 /* Copy frame from buffer. */ … … 245 308 frame->timestamp.u64 = 0; 246 309 247 if (port->readpos + frame_size <= port->buf + port->bufsize) { 248 pj_memcpy(frame->buf, port->readpos, frame_size); 249 port->readpos += frame_size; 250 if (port->readpos == port->buf + port->bufsize) 251 port->readpos = port->buf; 310 if (fport->readpos + frame_size <= fport->buf + fport->bufsize) { 311 312 /* Read contiguous buffer. */ 313 pj_memcpy(frame->buf, fport->readpos, frame_size); 314 315 /* Fill up the buffer if all has been read. */ 316 fport->readpos += frame_size; 317 if (fport->readpos == fport->buf + fport->bufsize) { 318 fport->readpos = fport->buf; 319 320 status = fill_buffer(fport); 321 if (status != PJ_SUCCESS) 322 return status; 323 } 252 324 } else { 253 325 unsigned endread; 254 326 255 endread = (port->buf+port->bufsize) - port->readpos; 256 pj_memcpy(frame->buf, port->readpos, endread); 257 pj_memcpy(((char*)frame->buf)+endread, port->buf, frame_size-endread); 258 port->readpos = port->buf + (frame_size - endread); 327 /* Split read. 328 * First stage: read until end of buffer. 329 */ 330 endread = (fport->buf+fport->bufsize) - fport->readpos; 331 pj_memcpy(frame->buf, fport->readpos, endread); 332 333 /* Second stage: fill up buffer, and read from the start of buffer. */ 334 status = fill_buffer(fport); 335 if (status != PJ_SUCCESS) { 336 pj_memset(((char*)frame->buf)+endread, 0, frame_size-endread); 337 return status; 338 } 339 340 pj_memcpy(((char*)frame->buf)+endread, fport->buf, frame_size-endread); 341 fport->readpos = fport->buf + (frame_size - endread); 259 342 } 260 343 … … 267 350 static pj_status_t file_on_destroy(pjmedia_port *this_port) 268 351 { 269 PJ_UNUSED_ARG(this_port);352 struct file_port *fport = (struct file_port*) this_port; 270 353 271 354 pj_assert(this_port->info.signature == SIGNATURE); 272 355 356 pj_file_close(fport->fd); 273 357 return PJ_SUCCESS; 274 358 }
Note: See TracChangeset
for help on using the changeset viewer.