Added better period_time setup to the ALSA output code.

Added end-of-file checking to the libac3.
This commit is contained in:
Jaroslav Kysela 2001-05-08 08:55:33 +00:00
parent 3d1998857a
commit c40c3b5623
6 changed files with 47 additions and 23 deletions

View file

@ -41,10 +41,11 @@ uint_32 current_word;
ssize_t (*bitstream_fill_buffer)(uint_8**,uint_8**); 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) 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 (*chunk_start++);
} }
@ -54,7 +55,7 @@ uint_8 *bitstream_get_buffer_start(void)
return buffer_start; return buffer_start;
} }
void int
bitstream_buffer_frame(uint_32 frame_size) bitstream_buffer_frame(uint_32 frame_size)
{ {
uint_32 bytes_read; uint_32 bytes_read;
@ -67,7 +68,8 @@ bitstream_buffer_frame(uint_32 frame_size)
if(chunk_start > chunk_end) if(chunk_start > chunk_end)
printf("argh!\n"); printf("argh!\n");
if(chunk_start == chunk_end) 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; num_bytes = chunk_end - chunk_start;
@ -84,7 +86,8 @@ bitstream_buffer_frame(uint_32 frame_size)
buffer_start = buffer; buffer_start = buffer;
buffer_end = buffer + frame_size; buffer_end = buffer + frame_size;
bits_left = 0; bits_left = 0;
return 0;
} }

View file

@ -52,10 +52,10 @@ extern uint_32 current_word;
void bitstream_init(ssize_t(*fill_function)(uint_8**,uint_8**)); 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); 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 bitstream_get_bh(uint_32 num_bits);

View file

@ -82,7 +82,8 @@ ac3_decode_frame(void)
uint_32 i; uint_32 i;
//find a syncframe and parse //find a syncframe and parse
parse_syncinfo(&syncinfo); if (parse_syncinfo(&syncinfo) < 0)
return NULL;
if(error_flag) if(error_flag)
goto error; goto error;

View file

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#include "ac3.h" #include "ac3.h"
#include "ac3_internal.h" #include "ac3_internal.h"
@ -114,9 +115,10 @@ parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data)
} }
/* Parse a syncinfo structure, minus the sync word */ /* Parse a syncinfo structure, minus the sync word */
void int
parse_syncinfo(syncinfo_t *syncinfo) parse_syncinfo(syncinfo_t *syncinfo)
{ {
int byte, idx;
uint_8 data[3]; uint_8 data[3];
uint_16 sync_word = 0; uint_16 sync_word = 0;
uint_32 time_out = 1<<16; uint_32 time_out = 1<<16;
@ -128,7 +130,10 @@ parse_syncinfo(syncinfo_t *syncinfo)
// //
while(time_out--) 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) if(sync_word == 0x0b77)
break; break;
@ -138,14 +143,18 @@ parse_syncinfo(syncinfo_t *syncinfo)
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits) // We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
// in order to determine how big the frame is // in order to determine how big the frame is
// //
data[0] = bitstream_get_byte(); for (idx = 0; idx < 3; idx++) {
data[1] = bitstream_get_byte(); byte = bitstream_get_byte();
data[2] = bitstream_get_byte(); if (byte < 0)
return -ENOENT;
data[idx] = byte;
}
parse_syncinfo_data(syncinfo, data); parse_syncinfo_data(syncinfo, data);
// Buffer the entire syncframe // 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 // Check the crc over the entire frame
crc_init(); crc_init();
@ -159,11 +168,12 @@ parse_syncinfo(syncinfo_t *syncinfo)
{ {
error_flag = 1; error_flag = 1;
fprintf(stderr,"** CRC failed - skipping frame **\n"); fprintf(stderr,"** CRC failed - skipping frame **\n");
return; return 0;
} }
if (!(ac3_config.flags & AC3_QUIET)) if (!(ac3_config.flags & AC3_QUIET))
stats_print_syncinfo(syncinfo); stats_print_syncinfo(syncinfo);
return 0;
} }
/* /*

View file

@ -22,7 +22,7 @@
*/ */
void parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data); 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_audblk(bsi_t *bsi,audblk_t *audblk);
void parse_bsi(bsi_t *bsi); void parse_bsi(bsi_t *bsi);
void parse_auxdata(syncinfo_t *syncinfo); void parse_auxdata(syncinfo_t *syncinfo);

View file

@ -41,8 +41,8 @@ int output_open(output_t *output)
snd_pcm_hw_params_t *params; snd_pcm_hw_params_t *params;
snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_t *swparams;
snd_pcm_sframes_t buffer_time; snd_pcm_sframes_t buffer_time;
snd_pcm_sframes_t period_time; snd_pcm_sframes_t period_time, tmp;
int err; int err, step;
snd_pcm_hw_params_alloca(&params); snd_pcm_hw_params_alloca(&params);
snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_alloca(&swparams);
@ -112,11 +112,19 @@ int output_open(output_t *output)
fprintf(stderr, "Buffer time not available"); fprintf(stderr, "Buffer time not available");
goto __close; goto __close;
} }
period_time = 100000 * 2; step = 2;
period_time = 10000 * 2;
do { do {
period_time /= 2; 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); period_time, 0);
if (tmp == period_time)
period_time = 10000 * 2;
}
if (period_time < 0) { if (period_time < 0) {
fprintf(stderr, "Period time not available"); fprintf(stderr, "Period time not available");
goto __close; goto __close;
@ -205,11 +213,13 @@ int output_play(sint_16* output_samples, uint_32 num_frames)
if (res == -EPIPE) if (res == -EPIPE)
res = snd_pcm_prepare(pcm); res = snd_pcm_prepare(pcm);
res = res < 0 ? res : snd_pcm_writei(pcm, (void *)output_samples, num_frames); 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) if (res < 0)
fprintf(stderr, "writei returned error: %s\n", snd_strerror(res)); 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; return res < 0 ? (int)res : 0;
} }