int file_test(void) { int rc = file_test_internal(); /* Delete test file if exists. */ if (pj_file_exists(FILENAME)) pj_file_delete(FILENAME); return rc; }
// // Check file existance. // static bool file_exists(const char *filename) { return pj_file_exists(filename) != 0; }
static int file_test_internal(void) { enum { FILE_MAX_AGE = 1000 }; pj_oshandle_t fd = 0; pj_status_t status; char readbuf[sizeof(buffer)+16]; pj_file_stat stat; pj_time_val start_time; pj_ssize_t size; pj_off_t pos; PJ_LOG(3,("", "..file io test..")); /* Get time. */ pj_gettimeofday(&start_time); /* Delete original file if exists. */ if (pj_file_exists(FILENAME)) pj_file_delete(FILENAME); /* * Write data to the file. */ status = pj_file_open(NULL, FILENAME, PJ_O_WRONLY, &fd); if (status != PJ_SUCCESS) { app_perror("...file_open() error", status); return -10; } size = sizeof(buffer); status = pj_file_write(fd, buffer, &size); if (status != PJ_SUCCESS) { app_perror("...file_write() error", status); pj_file_close(fd); return -20; } if (size != sizeof(buffer)) return -25; status = pj_file_close(fd); if (status != PJ_SUCCESS) { app_perror("...file_close() error", status); return -30; } /* Check the file existance and size. */ if (!pj_file_exists(FILENAME)) return -40; if (pj_file_size(FILENAME) != sizeof(buffer)) return -50; /* Get file stat. */ status = pj_file_getstat(FILENAME, &stat); if (status != PJ_SUCCESS) return -60; /* Check stat size. */ if (stat.size != sizeof(buffer)) return -70; #if INCLUDE_FILE_TIME_TEST /* Check file creation time >= start_time. */ if (!PJ_TIME_VAL_GTE(stat.ctime, start_time)) return -80; /* Check file creation time is not much later. */ PJ_TIME_VAL_SUB(stat.ctime, start_time); if (stat.ctime.sec > FILE_MAX_AGE) return -90; /* Check file modification time >= start_time. */ if (!PJ_TIME_VAL_GTE(stat.mtime, start_time)) return -80; /* Check file modification time is not much later. */ PJ_TIME_VAL_SUB(stat.mtime, start_time); if (stat.mtime.sec > FILE_MAX_AGE) return -90; /* Check file access time >= start_time. */ if (!PJ_TIME_VAL_GTE(stat.atime, start_time)) return -80; /* Check file access time is not much later. */ PJ_TIME_VAL_SUB(stat.atime, start_time); if (stat.atime.sec > FILE_MAX_AGE) return -90; #endif /* * Re-open the file and read data. */ status = pj_file_open(NULL, FILENAME, PJ_O_RDONLY, &fd); if (status != PJ_SUCCESS) { app_perror("...file_open() error", status); return -100; } size = 0; while (size < (pj_ssize_t)sizeof(readbuf)) { pj_ssize_t read; read = 1; status = pj_file_read(fd, &readbuf[size], &read); if (status != PJ_SUCCESS) { PJ_LOG(3,("", "...error reading file after %d bytes (error follows)", size)); app_perror("...error", status); return -110; } if (read == 0) { // EOF break; } size += read; } if (size != sizeof(buffer)) return -120; /* if (!pj_file_eof(fd, PJ_O_RDONLY)) return -130; */ if (pj_memcmp(readbuf, buffer, size) != 0) return -140; /* Seek test. */ status = pj_file_setpos(fd, 4, PJ_SEEK_SET); if (status != PJ_SUCCESS) { app_perror("...file_setpos() error", status); return -141; } /* getpos test. */ status = pj_file_getpos(fd, &pos); if (status != PJ_SUCCESS) { app_perror("...file_getpos() error", status); return -142; } if (pos != 4) return -143; status = pj_file_close(fd); if (status != PJ_SUCCESS) { app_perror("...file_close() error", status); return -150; } /* * Rename test. */ status = pj_file_move(FILENAME, NEWNAME); if (status != PJ_SUCCESS) { app_perror("...file_move() error", status); return -160; } if (pj_file_exists(FILENAME)) return -170; if (!pj_file_exists(NEWNAME)) return -180; if (pj_file_size(NEWNAME) != sizeof(buffer)) return -190; /* Delete test. */ status = pj_file_delete(NEWNAME); if (status != PJ_SUCCESS) { app_perror("...file_delete() error", status); return -200; } if (pj_file_exists(NEWNAME)) return -210; PJ_LOG(3,("", "...success")); return PJ_SUCCESS; }
int codec_test_vectors(void) { pjmedia_endpt *endpt; pjmedia_codec_mgr *mgr; int rc, rc_final = 0; struct enc_vectors { char *codec_name; unsigned bit_rate; const char *wav_file; const char *ref_encoded_file; } enc_vectors[] = { #if PJMEDIA_HAS_G7221_CODEC { "G7221/16000/1", 24000, "../src/test/vectors/g722_1_enc_in.wav", "../src/test/vectors/g722_1_enc_out_24000_be.pak" }, { "G7221/16000/1", 32000, "../src/test/vectors/g722_1_enc_in.wav", "../src/test/vectors/g722_1_enc_out_32000_be.pak" }, #endif { NULL } }; struct dec_vectors { char *codec_name; unsigned bit_rate; unsigned encoded_frame_len; void (*manip)(short *pcm, unsigned count); const char *enc_file; const char *ref_pcm_file; } dec_vectors[] = { #if PJMEDIA_HAS_G7221_CODEC { "G7221/16000/1", 24000, 60, &g7221_pcm_manip, "../src/test/vectors/g722_1_enc_out_24000_be.pak", "../src/test/vectors/g722_1_dec_out_24000.pcm" }, { "G7221/16000/1", 32000, 80, &g7221_pcm_manip, "../src/test/vectors/g722_1_enc_out_32000_be.pak", "../src/test/vectors/g722_1_dec_out_32000.pcm" }, { "G7221/16000/1", 24000, 60, &g7221_pcm_manip, "../src/test/vectors/g722_1_dec_in_24000_fe.itu", "../src/test/vectors/g722_1_dec_out_24000_fe.pcm" }, { "G7221/16000/1", 32000, 80, &g7221_pcm_manip, "../src/test/vectors/g722_1_dec_in_32000_fe.itu", "../src/test/vectors/g722_1_dec_out_32000_fe.pcm" }, #endif { NULL } }; unsigned i; pj_status_t status; status = pjmedia_endpt_create(mem, NULL, 0, &endpt); if (status != PJ_SUCCESS) return -5; mgr = pjmedia_endpt_get_codec_mgr(endpt); #if PJMEDIA_HAS_G7221_CODEC status = pjmedia_codec_g7221_init(endpt); if (status != PJ_SUCCESS) { pjmedia_endpt_destroy(endpt); return -7; } /* Set shift value to zero for the test vectors */ pjmedia_codec_g7221_set_pcm_shift(0); #endif PJ_LOG(3,(THIS_FILE," encode tests:")); for (i=0; i<PJ_ARRAY_SIZE(enc_vectors); ++i) { if (!enc_vectors[i].codec_name) continue; PJ_LOG(3,(THIS_FILE," %s @%d bps %s ==> %s", enc_vectors[i].codec_name, enc_vectors[i].bit_rate, enc_vectors[i].wav_file, enc_vectors[i].ref_encoded_file)); rc = codec_test_encode(mgr, enc_vectors[i].codec_name, enc_vectors[i].bit_rate, enc_vectors[i].wav_file, enc_vectors[i].ref_encoded_file); if (rc != 0) rc_final = rc; } PJ_LOG(3,(THIS_FILE," decode tests:")); for (i=0; i<PJ_ARRAY_SIZE(dec_vectors); ++i) { if (!dec_vectors[i].codec_name) continue; PJ_LOG(3,(THIS_FILE," %s @%d bps %s ==> %s", dec_vectors[i].codec_name, dec_vectors[i].bit_rate, dec_vectors[i].enc_file, dec_vectors[i].ref_pcm_file)); rc = codec_test_decode(mgr, dec_vectors[i].codec_name, dec_vectors[i].bit_rate, dec_vectors[i].encoded_frame_len, dec_vectors[i].enc_file, dec_vectors[i].ref_pcm_file, dec_vectors[i].manip); if (rc != 0) rc_final = rc; } if (pj_file_exists(TMP_OUT)) pj_file_delete(TMP_OUT); pjmedia_endpt_destroy(endpt); return rc_final; }
/* Scan V4L2 devices */ static pj_status_t v4l2_scan_devs(vid4lin_factory *f) { vid4lin_dev_info vdi[V4L2_MAX_DEVS]; char dev_name[32]; unsigned i, old_count; pj_status_t status; if (f->dev_pool) { pj_pool_release(f->dev_pool); f->dev_pool = NULL; } pj_bzero(vdi, sizeof(vdi)); old_count = f->dev_count; f->dev_count = 0; f->dev_pool = pj_pool_create(f->pf, DRIVER_NAME, 500, 500, NULL); for (i=0; i<V4L2_MAX_DEVS && f->dev_count < V4L2_MAX_DEVS; ++i) { int fd; vid4lin_dev_info *pdi; pj_uint32_t fmt_cap[8]; int j, fmt_cnt=0; pdi = &vdi[f->dev_count]; snprintf(dev_name, sizeof(dev_name), "/dev/video%d", i); if (!pj_file_exists(dev_name)) continue; fd = v4l2_open(dev_name, O_RDWR, 0); if (fd == -1) continue; status = xioctl(fd, VIDIOC_QUERYCAP, &pdi->v4l2_cap); if (status != PJ_SUCCESS) { PJ_PERROR(4,(THIS_FILE, status, "Error querying %s", dev_name)); v4l2_close(fd); continue; } if ((pdi->v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { v4l2_close(fd); continue; } PJ_LOG(5,(THIS_FILE, "Found capture device %s", pdi->v4l2_cap.card)); PJ_LOG(5,(THIS_FILE, " Enumerating formats:")); for (j=0; fmt_cnt<PJ_ARRAY_SIZE(fmt_cap); ++j) { struct v4l2_fmtdesc fdesc; unsigned k; pj_bzero(&fdesc, sizeof(fdesc)); fdesc.index = j; fdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; status = xioctl(fd, VIDIOC_ENUM_FMT, &fdesc); if (status != PJ_SUCCESS) break; for (k=0; k<PJ_ARRAY_SIZE(v4l2_fmt_maps); ++k) { if (v4l2_fmt_maps[k].v4l2_fmt_id == fdesc.pixelformat) { fmt_cap[fmt_cnt++] = v4l2_fmt_maps[k].pjmedia_fmt_id; PJ_LOG(5,(THIS_FILE, " Supported: %s", fdesc.description)); break; } } if (k==PJ_ARRAY_SIZE(v4l2_fmt_maps)) { PJ_LOG(5,(THIS_FILE, " Unsupported: %s", fdesc.description)); } } v4l2_close(fd); if (fmt_cnt==0) { PJ_LOG(5,(THIS_FILE, " Found no common format")); continue; } strncpy(pdi->dev_name, dev_name, sizeof(pdi->dev_name)); pdi->dev_name[sizeof(pdi->dev_name)-1] = '\0'; strncpy(pdi->info.name, (char*)pdi->v4l2_cap.card, sizeof(pdi->info.name)); pdi->info.name[sizeof(pdi->info.name)-1] = '\0'; strncpy(pdi->info.driver, DRIVER_NAME, sizeof(pdi->info.driver)); pdi->info.driver[sizeof(pdi->info.driver)-1] = '\0'; pdi->info.dir = PJMEDIA_DIR_CAPTURE; pdi->info.has_callback = PJ_FALSE; pdi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT; pdi->info.fmt_cnt = fmt_cnt; for (j=0; j<fmt_cnt; ++j) { pjmedia_format_init_video(&pdi->info.fmt[j], fmt_cap[j], DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FPS, 1); } if (j < fmt_cnt) continue; f->dev_count++; } if (f->dev_count == 0) return PJ_SUCCESS; if (f->dev_count > old_count || f->dev_info == NULL) { f->dev_info = (vid4lin_dev_info*) pj_pool_calloc(f->dev_pool, f->dev_count, sizeof(vid4lin_dev_info)); } pj_memcpy(f->dev_info, vdi, f->dev_count * sizeof(vid4lin_dev_info)); return PJ_SUCCESS; }
/* * Create wave list player. */ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool, const pj_str_t *port_label, const pj_str_t file_list[], int file_count, unsigned ptime, unsigned options, pj_ssize_t buff_size, pjmedia_port **p_port) { struct playlist_port *fport; pj_off_t pos; pj_status_t status; int index; pj_bool_t has_wave_info = PJ_FALSE; pj_str_t tmp_port_label; char filename[PJ_MAXPATH]; /* filename for open operations. */ /* Check arguments. */ PJ_ASSERT_RETURN(pool && file_list && file_count && p_port, PJ_EINVAL); /* Normalize port_label */ if (port_label == NULL || port_label->slen == 0) { tmp_port_label = pj_str("WAV playlist"); port_label = &tmp_port_label; } /* Be sure all files exist */ for (index=0; index<file_count; index++) { PJ_ASSERT_RETURN(file_list[index].slen < PJ_MAXPATH, PJ_ENAMETOOLONG); pj_memcpy(filename, file_list[index].ptr, file_list[index].slen); filename[file_list[index].slen] = '\0'; /* Check the file really exists. */ if (!pj_file_exists(filename)) { PJ_LOG(4,(THIS_FILE, "WAV playlist error: file '%s' not found", filename)); return PJ_ENOTFOUND; } } /* Normalize ptime */ if (ptime == 0) ptime = 20; /* Create fport instance. */ fport = create_file_list_port(pool, port_label); if (!fport) { return PJ_ENOMEM; } /* start with the first file. */ fport->current_file = 0; fport->max_file = file_count; /* Create file descriptor list */ fport->fd_list = pj_pool_zalloc(pool, sizeof(pj_oshandle_t)*file_count); if (!fport->fd_list) { return PJ_ENOMEM; } /* Create file size list */ fport->fsize_list = pj_pool_alloc(pool, sizeof(pj_off_t)*file_count); if (!fport->fsize_list) { return PJ_ENOMEM; } /* Create start of WAVE data list */ fport->start_data_list = pj_pool_alloc(pool, sizeof(unsigned)*file_count); if (!fport->start_data_list) { return PJ_ENOMEM; } /* Create file position list */ fport->fpos_list = pj_pool_alloc(pool, sizeof(pj_off_t)*file_count); if (!fport->fpos_list) { return PJ_ENOMEM; } /* Create file buffer once for this operation. */ if (buff_size < 1) buff_size = PJMEDIA_FILE_PORT_BUFSIZE; fport->bufsize = buff_size; /* Create buffer. */ fport->buf = pj_pool_alloc(pool, fport->bufsize); if (!fport->buf) { return PJ_ENOMEM; } /* Initialize port */ fport->options = options; fport->readpos = fport->buf; /* ok run this for all files to be sure all are good for playback. */ for (index=file_count-1; index>=0; index--) { pjmedia_wave_hdr wavehdr; pj_ssize_t size_to_read, size_read; /* we end with the last one so we are good to go if still in function*/ pj_memcpy(filename, file_list[index].ptr, file_list[index].slen); filename[file_list[index].slen] = '\0'; /* Get the file size. */ fport->current_file = index; fport->fsize_list[index] = pj_file_size(filename); /* Size must be more than WAVE header size */ if (fport->fsize_list[index] <= sizeof(pjmedia_wave_hdr)) { status = PJMEDIA_ENOTVALIDWAVE; goto on_error; } /* Open file. */ status = pj_file_open( pool, filename, PJ_O_RDONLY, &fport->fd_list[index]); if (status != PJ_SUCCESS) goto on_error; /* Read the file header plus fmt header only. */ size_read = size_to_read = sizeof(wavehdr) - 8; status = pj_file_read( fport->fd_list[index], &wavehdr, &size_read); if (status != PJ_SUCCESS) { goto on_error; } if (size_read != size_to_read) { status = PJMEDIA_ENOTVALIDWAVE; goto on_error; } /* Normalize WAVE header fields values from little-endian to host * byte order. */ pjmedia_wave_hdr_file_to_host(&wavehdr); /* Validate WAVE file. */ if (wavehdr.riff_hdr.riff != PJMEDIA_RIFF_TAG || wavehdr.riff_hdr.wave != PJMEDIA_WAVE_TAG || wavehdr.fmt_hdr.fmt != PJMEDIA_FMT_TAG) { TRACE_((THIS_FILE, "actual value|expected riff=%x|%x, wave=%x|%x fmt=%x|%x", wavehdr.riff_hdr.riff, PJMEDIA_RIFF_TAG, wavehdr.riff_hdr.wave, PJMEDIA_WAVE_TAG, wavehdr.fmt_hdr.fmt, PJMEDIA_FMT_TAG)); status = PJMEDIA_ENOTVALIDWAVE; goto on_error; } /* Must be PCM with 16bits per sample */ if (wavehdr.fmt_hdr.fmt_tag != 1 || wavehdr.fmt_hdr.bits_per_sample != 16) { status = PJMEDIA_EWAVEUNSUPP; goto on_error; } /* Block align must be 2*nchannels */ if (wavehdr.fmt_hdr.block_align != wavehdr.fmt_hdr.nchan * BYTES_PER_SAMPLE) { status = PJMEDIA_EWAVEUNSUPP; goto on_error; } /* If length of fmt_header is greater than 16, skip the remaining * fmt header data. */ if (wavehdr.fmt_hdr.len > 16) { size_to_read = wavehdr.fmt_hdr.len - 16; status = pj_file_setpos(fport->fd_list[index], size_to_read, PJ_SEEK_CUR); if (status != PJ_SUCCESS) { goto on_error; } } /* Repeat reading the WAVE file until we have 'data' chunk */ for (;;) { pjmedia_wave_subchunk subchunk; size_read = 8; status = pj_file_read(fport->fd_list[index], &subchunk, &size_read); if (status != PJ_SUCCESS || size_read != 8) { status = PJMEDIA_EWAVETOOSHORT; goto on_error; } /* Normalize endianness */ PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(&subchunk); /* Break if this is "data" chunk */ if (subchunk.id == PJMEDIA_DATA_TAG) { wavehdr.data_hdr.data = PJMEDIA_DATA_TAG; wavehdr.data_hdr.len = subchunk.len; break; } /* Otherwise skip the chunk contents */ size_to_read = subchunk.len; status = pj_file_setpos(fport->fd_list[index], size_to_read, PJ_SEEK_CUR); if (status != PJ_SUCCESS) { goto on_error; } } /* Current file position now points to start of data */ status = pj_file_getpos(fport->fd_list[index], &pos); fport->start_data_list[index] = (unsigned)pos; /* Validate length. */ if (wavehdr.data_hdr.len != fport->fsize_list[index] - fport->start_data_list[index]) { status = PJMEDIA_EWAVEUNSUPP; goto on_error; } if (wavehdr.data_hdr.len < 400) { status = PJMEDIA_EWAVETOOSHORT; goto on_error; } /* It seems like we have a valid WAVE file. */ /* Update port info if we don't have one, otherwise check * that the WAV file has the same attributes as previous files. */ if (!has_wave_info) { fport->base.info.channel_count = wavehdr.fmt_hdr.nchan; fport->base.info.clock_rate = wavehdr.fmt_hdr.sample_rate; fport->base.info.bits_per_sample = wavehdr.fmt_hdr.bits_per_sample; fport->base.info.samples_per_frame = fport->base.info.clock_rate * wavehdr.fmt_hdr.nchan * ptime / 1000; fport->base.info.bytes_per_frame = fport->base.info.samples_per_frame * fport->base.info.bits_per_sample / 8; has_wave_info = PJ_TRUE; } else { /* Check that this file has the same characteristics as the other * files. */ if (wavehdr.fmt_hdr.nchan != fport->base.info.channel_count || wavehdr.fmt_hdr.sample_rate != fport->base.info.clock_rate || wavehdr.fmt_hdr.bits_per_sample != fport->base.info.bits_per_sample) { /* This file has different characteristics than the other * files. */ PJ_LOG(4,(THIS_FILE, "WAV playlist error: file '%s' has differrent number" " of channels, sample rate, or bits per sample", filename)); status = PJMEDIA_EWAVEUNSUPP; goto on_error; } } /* Set initial position of the file. */ fport->fpos_list[index] = fport->start_data_list[index]; } /* Fill up the buffer. */ status = file_fill_buffer(fport); if (status != PJ_SUCCESS) { goto on_error; } /* Done. */ *p_port = &fport->base; PJ_LOG(4,(THIS_FILE, "WAV playlist '%.*s' created: samp.rate=%d, ch=%d, bufsize=%uKB", (int)port_label->slen, port_label->ptr, fport->base.info.clock_rate, fport->base.info.channel_count, fport->bufsize / 1000)); return PJ_SUCCESS; on_error: for (index=0; index<file_count; ++index) { if (fport->fd_list[index] != 0) pj_file_close(fport->fd_list[index]); } return status; }