- if (conf.begin_chunk_arg < 0) {
- if (-conf.begin_chunk_arg > afhi->chunks_total)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- first_chunk = afhi->chunks_total + conf.begin_chunk_arg;
- } else
- first_chunk = conf.begin_chunk_arg;
- if (conf.end_chunk_given) {
- if (conf.end_chunk_arg < 0) {
- if (-conf.end_chunk_arg > afhi->chunks_total)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- last_chunk = afhi->chunks_total + conf.end_chunk_arg;
- } else {
- if (conf.end_chunk_arg >= afhi->chunks_total)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- last_chunk = conf.end_chunk_arg;
- }
- } else
- last_chunk = afhi->chunks_total - 1;
- if (first_chunk >= last_chunk)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- if (!afhi->chunks_total)
- return 1;
- /* eliminate the possibility of short writes */
- ret = mark_fd_blocking(STDOUT_FILENO);
- if (ret < 0)
- return ret;
- if (first_chunk > 0 && !conf.no_header_given) {
- afh_get_header(afhi, audio_format_id, audio_file_data, audio_file_size,
- &header, &size);
- if (size > 0) {
- PARA_INFO_LOG("writing header (%zu bytes)\n", size);
- ret = write(STDOUT_FILENO, header, size); /* FIXME */
- afh_free_header(header, audio_format_id);
- if (ret < 0)
- return ret;
- if (ret != size)
- return -E_AFH_SHORT_WRITE;
- }
- }
- PARA_NOTICE_LOG("writing chunks %lu - %lu\n", first_chunk, last_chunk);
- gettimeofday(&stream_start, NULL);
- for (i = first_chunk; i <= last_chunk; i++) {
- struct timeval now, diff, next_chunk;
- afh_get_chunk(i, afhi, audio_file_data, &buf, &size);
- PARA_DEBUG_LOG("chunk %lu: size %zu\n", i, size);
- if (conf.just_in_time_given) {
- compute_chunk_time(i - first_chunk, &afhi->chunk_tv,
- &stream_start, &next_chunk);
- gettimeofday(&now, NULL);
- ret = tv_diff(&next_chunk, &now, &diff);
- if (ret > 0) {
- ret = para_select(1, NULL, NULL, &diff);
- if (ret < 0)
- return ret;
- }
- }
- if (!size)
- continue;
- PARA_INFO_LOG("writing chunk %lu\n", i);
- ret = write_all(STDOUT_FILENO, buf, &size);
- if (ret < 0)
- return ret;
- }
- return 1;