]> git.alsa-project.org Git - alsa-tools.git/commitdiff
Added better period_time setup to the ALSA output code.
authorJaroslav Kysela <perex@perex.cz>
Tue, 8 May 2001 08:55:33 +0000 (08:55 +0000)
committerJaroslav Kysela <perex@perex.cz>
Tue, 8 May 2001 08:55:33 +0000 (08:55 +0000)
Added end-of-file checking to the libac3.

ac3dec/libac3/bitstream.c
ac3dec/libac3/bitstream.h
ac3dec/libac3/decode.c
ac3dec/libac3/parse.c
ac3dec/libac3/parse.h
ac3dec/output.c

index a22b53a99564ec007773e6d75a0896187e9ceec9..ec805001be5d86781623c51f0157382465bc542c 100644 (file)
@@ -41,10 +41,11 @@ uint_32 current_word;
 
 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++);
 }
@@ -54,7 +55,7 @@ uint_8 *bitstream_get_buffer_start(void)
        return buffer_start;
 }
 
-void
+int
 bitstream_buffer_frame(uint_32 frame_size)
 {
   uint_32 bytes_read;
@@ -67,7 +68,8 @@ bitstream_buffer_frame(uint_32 frame_size)
     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;
 
@@ -84,7 +86,8 @@ bitstream_buffer_frame(uint_32 frame_size)
   buffer_start = buffer;
   buffer_end   = buffer + frame_size;
 
-       bits_left = 0;
+  bits_left = 0;
+  return 0;
 }
 
 
index 7602d8acbda6e33758f01f9807c47938b5b9c9c2..2b4dfc55d1fc2d34ffb4ac74a7ee5aca7ed955a7 100644 (file)
@@ -52,10 +52,10 @@ extern uint_32 current_word;
 
 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);
 
index 2b09e56fafa16b927dfe8594ec1c093933bfb8ac..987591999f0ebe756e57d5ec3b5e1b333118a523 100644 (file)
@@ -82,7 +82,8 @@ ac3_decode_frame(void)
        uint_32 i;
 
        //find a syncframe and parse
-       parse_syncinfo(&syncinfo);
+       if (parse_syncinfo(&syncinfo) < 0)
+               return NULL;
        if(error_flag)
                goto error;
 
index 0b16ccb8dd0512efe62ee77ac9904a86350ef1ce..19e896572a892e04fe1868160a959c73052e4438 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <errno.h>
 #include "ac3.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 */
-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;
@@ -128,7 +130,10 @@ parse_syncinfo(syncinfo_t *syncinfo)
        // 
        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;
@@ -138,14 +143,18 @@ parse_syncinfo(syncinfo_t *syncinfo)
        // 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();
@@ -159,11 +168,12 @@ parse_syncinfo(syncinfo_t *syncinfo)
        {
                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;
 }
 
 /*
index 444932681e2b0e228673934961dd5db50e78e8c9..187c714e12eb591b12bfe4b009ce4bdb080d5833 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 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);
index 36934c3d0118f347e3f62ad513d532946ff90eac..a230b3ef0cb37a3afd0d3aacb71965652ab2f631 100644 (file)
@@ -41,8 +41,8 @@ int output_open(output_t *output)
        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(&params);
        snd_pcm_sw_params_alloca(&swparams);
 
@@ -112,11 +112,19 @@ int output_open(output_t *output)
                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;
@@ -205,11 +213,13 @@ int output_play(sint_16* output_samples, uint_32 num_frames)
                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;
 }