Added end-of-file checking to the libac3.
ssize_t (*bitstream_fill_buffer)(uint_8**,uint_8**);
-uint_8 bitstream_get_byte(void)
+int bitstream_get_byte(void)
{
if(chunk_start == chunk_end)
- bitstream_fill_buffer(&chunk_start,&chunk_end);
+ if (bitstream_fill_buffer(&chunk_start,&chunk_end) <= 0)
+ return EOF;
return (*chunk_start++);
}
return buffer_start;
}
-void
+int
bitstream_buffer_frame(uint_32 frame_size)
{
uint_32 bytes_read;
if(chunk_start > chunk_end)
printf("argh!\n");
if(chunk_start == chunk_end)
- bitstream_fill_buffer(&chunk_start,&chunk_end);
+ if (bitstream_fill_buffer(&chunk_start,&chunk_end) <= 0)
+ return EOF;
num_bytes = chunk_end - chunk_start;
buffer_start = buffer;
buffer_end = buffer + frame_size;
- bits_left = 0;
+ bits_left = 0;
+ return 0;
}
void bitstream_init(ssize_t(*fill_function)(uint_8**,uint_8**));
-uint_8 bitstream_get_byte(void);
+int bitstream_get_byte(void);
uint_8 *bitstream_get_buffer_start(void);
-void bitstream_buffer_frame(uint_32 frame_size);
+int bitstream_buffer_frame(uint_32 frame_size);
uint_32 bitstream_get_bh(uint_32 num_bits);
uint_32 i;
//find a syncframe and parse
- parse_syncinfo(&syncinfo);
+ if (parse_syncinfo(&syncinfo) < 0)
+ return NULL;
if(error_flag)
goto error;
#include <stdlib.h>
#include <stdio.h>
+#include <errno.h>
#include "ac3.h"
#include "ac3_internal.h"
}
/* Parse a syncinfo structure, minus the sync word */
-void
+int
parse_syncinfo(syncinfo_t *syncinfo)
{
+ int byte, idx;
uint_8 data[3];
uint_16 sync_word = 0;
uint_32 time_out = 1<<16;
//
while(time_out--)
{
- sync_word = (sync_word << 8) + bitstream_get_byte();
+ byte = bitstream_get_byte();
+ if (byte < 0)
+ return -ENOENT;
+ sync_word = (sync_word << 8) + byte;
if(sync_word == 0x0b77)
break;
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
// in order to determine how big the frame is
//
- data[0] = bitstream_get_byte();
- data[1] = bitstream_get_byte();
- data[2] = bitstream_get_byte();
+ for (idx = 0; idx < 3; idx++) {
+ byte = bitstream_get_byte();
+ if (byte < 0)
+ return -ENOENT;
+ data[idx] = byte;
+ }
parse_syncinfo_data(syncinfo, data);
// Buffer the entire syncframe
- bitstream_buffer_frame(syncinfo->frame_size * 2 - 5);
+ if (bitstream_buffer_frame(syncinfo->frame_size * 2 - 5) < 0)
+ return -ENOENT;
// Check the crc over the entire frame
crc_init();
{
error_flag = 1;
fprintf(stderr,"** CRC failed - skipping frame **\n");
- return;
+ return 0;
}
if (!(ac3_config.flags & AC3_QUIET))
stats_print_syncinfo(syncinfo);
+ return 0;
}
/*
*/
void parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data);
-void parse_syncinfo(syncinfo_t *syncinfo);
+int parse_syncinfo(syncinfo_t *syncinfo);
void parse_audblk(bsi_t *bsi,audblk_t *audblk);
void parse_bsi(bsi_t *bsi);
void parse_auxdata(syncinfo_t *syncinfo);
snd_pcm_hw_params_t *params;
snd_pcm_sw_params_t *swparams;
snd_pcm_sframes_t buffer_time;
- snd_pcm_sframes_t period_time;
- int err;
+ snd_pcm_sframes_t period_time, tmp;
+ int err, step;
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_sw_params_alloca(&swparams);
fprintf(stderr, "Buffer time not available");
goto __close;
}
- period_time = 100000 * 2;
+ step = 2;
+ period_time = 10000 * 2;
do {
period_time /= 2;
- period_time = snd_pcm_hw_params_set_period_time_near(pcm, params,
+ tmp = snd_pcm_hw_params_set_period_time_near(pcm, params,
+ period_time, 0);
+ if (tmp == period_time) {
+ period_time /= 3;
+ tmp = snd_pcm_hw_params_set_period_time_near(pcm, params,
period_time, 0);
+ if (tmp == period_time)
+ period_time = 10000 * 2;
+ }
if (period_time < 0) {
fprintf(stderr, "Period time not available");
goto __close;
if (res == -EPIPE)
res = snd_pcm_prepare(pcm);
res = res < 0 ? res : snd_pcm_writei(pcm, (void *)output_samples, num_frames);
- } while (res == -EPIPE);
+ if (res > 0) {
+ output_samples += out_config.channels * res;
+ num_frames -= res;
+ }
+ } while (res == -EPIPE || num_frames > 0);
if (res < 0)
fprintf(stderr, "writei returned error: %s\n", snd_strerror(res));
- else if (res != num_frames)
- fprintf(stderr, "writei retured %li (expected %li)\n", res, (long)(num_frames));
return res < 0 ? (int)res : 0;
}