On piÄ…tek, 21 marca 2008, Justin Ruggles wrote:
> > - add argument to sync,  AAC parser will need some changes then,
> > - change sync, so that it won't use long list of arguments but a new
> > defined structure (in the future there will be need to get
> > substream_id...), or
>
> Either of these 2 would be fine with me.

Here is my idea of changing ac3 parser, so that it will send in one package to 
decoder all frames concerning one part of time.
It works like that: it buffers all frames until next independent frame.
The problem is that the last frame never leaves the buffer. Any ideas how to 
solve it?
I send new ffmpeg.patch (patch of patch isn't easily readable, but it's easy 
to tell if the change concerns >5.1 or not)

-- 
Bartlomiej Wolowiec
Index: libavcodec/Makefile
===================================================================
--- libavcodec/Makefile	(revision 12191)
+++ libavcodec/Makefile	(working copy)
@@ -33,7 +33,7 @@
 HEADERS = avcodec.h opt.h
 
 OBJS-$(CONFIG_AASC_DECODER)            += aasc.o
-OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3tab.o ac3.o mdct.o fft.o
+OBJS-$(CONFIG_AC3_DECODER)             += eac3dec.o ac3dec.o ac3tab.o ac3.o mdct.o fft.o ac3_parser.o ac3dec_data.o
 OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc.o ac3tab.o ac3.o
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o
 OBJS-$(CONFIG_AMV_DECODER)             += sp5xdec.o mjpegdec.o mjpeg.o
Index: libavcodec/ac3_parser.c
===================================================================
--- libavcodec/ac3_parser.c	(revision 12191)
+++ libavcodec/ac3_parser.c	(working copy)
@@ -38,7 +38,6 @@
 {
     GetBitContext gbc;
     int frame_size_code;
-    int num_blocks;
 
     memset(hdr, 0, sizeof(*hdr));
 
@@ -84,10 +83,11 @@
         hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift;
         hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
         hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2;
+        hdr->num_blocks = 6;
     } else {
         /* Enhanced AC-3 */
         hdr->crc1 = 0;
-        skip_bits(&gbc, 2); // skip stream type
+        hdr->stream_type = get_bits(&gbc, 2);
         skip_bits(&gbc, 3); // skip substream id
 
         hdr->frame_size = (get_bits(&gbc, 11) + 1) << 1;
@@ -101,9 +101,9 @@
                 return AC3_PARSE_ERROR_SAMPLE_RATE;
             hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2;
             hdr->sr_shift = 1;
-            num_blocks = 6;
+            hdr->num_blocks = 6;
         } else {
-            num_blocks = eac3_blocks[get_bits(&gbc, 2)];
+            hdr->num_blocks = eac3_blocks[get_bits(&gbc, 2)];
             hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code];
             hdr->sr_shift = 0;
         }
@@ -112,34 +112,35 @@
         hdr->lfe_on = get_bits1(&gbc);
 
         hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate /
-                        (num_blocks * 256.0));
+                        (hdr->num_blocks * 256.0));
         hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
     }
 
     return 0;
 }
 
-static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
-                    int *bit_rate, int *samples)
+static int ac3_sync(AACAC3HeaderInfo *hdr_info)
 {
     int err;
     AC3HeaderInfo hdr;
 
-    err = ff_ac3_parse_header(buf, &hdr);
+    err = ff_ac3_parse_header(hdr_info->buf, &hdr);
 
     if(err < 0)
         return 0;
 
-    *sample_rate = hdr.sample_rate;
-    *bit_rate = hdr.bit_rate;
-    *channels = hdr.channels;
-    *samples = AC3_FRAME_SIZE;
+    hdr_info->sample_rate = hdr.sample_rate;
+    hdr_info->bit_rate = hdr.bit_rate;
+    hdr_info->channels = hdr.channels;
+    hdr_info->samples = hdr.num_blocks * 256;
+    hdr_info->stream_type = hdr.stream_type;
     return hdr.frame_size;
 }
 
 static int ac3_parse_init(AVCodecParserContext *s1)
 {
     AACAC3ParseContext *s = s1->priv_data;
+    s->inbuf = s->inbuf_tab;
     s->inbuf_ptr = s->inbuf;
     s->header_size = AC3_HEADER_SIZE;
     s->sync = ac3_sync;
Index: libavcodec/ac3.c
===================================================================
--- libavcodec/ac3.c	(revision 12191)
+++ libavcodec/ac3.c	(working copy)
@@ -173,7 +173,8 @@
 }
 
 void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
-                               int snr_offset, int floor, uint8_t *bap)
+                               int snr_offset, int floor,
+                               const uint8_t *bap_tab, uint8_t *bap)
 {
     int i, j, k, end1, v, address;
 
@@ -190,7 +191,7 @@
         end1 = FFMIN(band_start_tab[j] + ff_ac3_critical_band_size_tab[j], end);
         for (k = i; k < end1; k++) {
             address = av_clip((psd[i] - v) >> 5, 0, 63);
-            bap[i] = ff_ac3_bap_tab[address];
+            bap[i] = bap_tab[address];
             i++;
         }
     } while (end > band_start_tab[j++]);
@@ -215,7 +216,8 @@
                                dba_mode, dba_nsegs, dba_offsets, dba_lengths, dba_values,
                                mask);
 
-    ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor, bap);
+    ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor,
+                              ff_ac3_bap_tab, bap);
 }
 
 /**
Index: libavcodec/ac3.h
===================================================================
--- libavcodec/ac3.h	(revision 12191)
+++ libavcodec/ac3.h	(working copy)
@@ -63,6 +63,7 @@
     AC3_CHMODE_3F2R
 } AC3ChannelMode;
 
+
 typedef struct AC3BitAllocParameters {
     int sr_code;
     int sr_shift;
@@ -84,6 +85,7 @@
     uint8_t bitstream_id;
     uint8_t channel_mode;
     uint8_t lfe_on;
+    uint8_t stream_type;
     /** @} */
 
     /** @defgroup derived Derived values
@@ -94,6 +96,7 @@
     uint32_t bit_rate;
     uint8_t channels;
     uint16_t frame_size;
+    uint8_t num_blocks;
     /** @} */
 } AC3HeaderInfo;
 
@@ -156,10 +159,12 @@
  * @param[in]  end        ending bin location
  * @param[in]  snr_offset SNR adjustment
  * @param[in]  floor      noise floor
+ * @param[in]  bap_tab    look-up table for bit allocation pointers
  * @param[out] bap        bit allocation pointers
  */
 void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
-                               int snr_offset, int floor, uint8_t *bap);
+                               int snr_offset, int floor,
+                               const uint8_t *bap_tab, uint8_t *bap);
 
 void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
                                    int8_t *exp, int start, int end,
Index: libavcodec/ac3enc.c
===================================================================
--- libavcodec/ac3enc.c	(revision 12191)
+++ libavcodec/ac3enc.c	(working copy)
@@ -463,7 +463,8 @@
         for(ch=0;ch<s->nb_all_channels;ch++) {
             ff_ac3_bit_alloc_calc_bap(mask[i][ch], psd[i][ch], 0,
                                       s->nb_coefs[ch], snr_offset,
-                                      s->bit_alloc.floor, bap[i][ch]);
+                                      s->bit_alloc.floor, ff_ac3_bap_tab,
+                                      bap[i][ch]);
             frame_bits += compute_mantissa_size(s, bap[i][ch],
                                                  s->nb_coefs[ch]);
         }
Index: libavcodec/aac_ac3_parser.c
===================================================================
--- libavcodec/aac_ac3_parser.c	(revision 12191)
+++ libavcodec/aac_ac3_parser.c	(working copy)
@@ -23,6 +23,7 @@
 #include "parser.h"
 #include "aac_ac3_parser.h"
 
+// TODO check s->inbuf_tab size
 int ff_aac_ac3_parse(AVCodecParserContext *s1,
                      AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
@@ -30,12 +31,19 @@
 {
     AACAC3ParseContext *s = s1->priv_data;
     const uint8_t *buf_ptr;
-    int len, sample_rate, bit_rate, channels, samples;
+    int len;
 
     *poutbuf = NULL;
     *poutbuf_size = 0;
 
     buf_ptr = buf;
+
+    if(s->inbuf_ptr < s->inbuf) {
+        //after sending package of data in the end there was one new header
+        memcpy(s->inbuf_tab, s->inbuf, s->header_size);
+        s->inbuf = s->inbuf_tab;
+        s->inbuf_ptr = s->inbuf_tab + s->header_size;
+    }
     while (buf_size > 0) {
         int size_needed= s->frame_size ? s->frame_size : s->header_size;
         len = s->inbuf_ptr - s->inbuf;
@@ -50,38 +58,42 @@
 
         if (s->frame_size == 0) {
             if ((s->inbuf_ptr - s->inbuf) == s->header_size) {
-                len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate,
-                              &samples);
+                s->hdr.buf = s->inbuf;
+                len = s->sync(&s->hdr);
                 if (len == 0) {
                     /* no sync found : move by one byte (inefficient, but simple!) */
                     memmove(s->inbuf, s->inbuf + 1, s->header_size - 1);
                     s->inbuf_ptr--;
                 } else {
-                    s->frame_size = len;
+                    if(!s->hdr.stream_type) {
+                        if(s->inbuf != s->inbuf_tab) {
+                            *poutbuf = s->inbuf_tab;
+                            *poutbuf_size = s->inbuf - s->inbuf_tab;
+                            s->inbuf_ptr = s->inbuf_tab;
+                            s->frame_size = 0;
+                            break;
+                        }
                     /* update codec info */
-                    avctx->sample_rate = sample_rate;
+                    avctx->sample_rate = s->hdr.sample_rate;
                     /* allow downmixing to stereo (or mono for AC3) */
                     if(avctx->request_channels > 0 &&
-                            avctx->request_channels < channels &&
+                            avctx->request_channels < s->hdr.channels &&
                             (avctx->request_channels <= 2 ||
                             (avctx->request_channels == 1 &&
                             avctx->codec_id == CODEC_ID_AC3))) {
                         avctx->channels = avctx->request_channels;
                     } else {
-                        avctx->channels = channels;
+                        avctx->channels = s->hdr.channels;
                     }
-                    avctx->bit_rate = bit_rate;
-                    avctx->frame_size = samples;
+                    avctx->bit_rate = s->hdr.bit_rate;
+                    avctx->frame_size = s->hdr.samples;
+                    } else {
+                        //TODO update bit_rate
+                        avctx->frame_size += s->hdr.samples;
+                    }
+                    s->frame_size = len;
                 }
             }
-        } else {
-            if(s->inbuf_ptr - s->inbuf == s->frame_size){
-                *poutbuf = s->inbuf;
-                *poutbuf_size = s->frame_size;
-                s->inbuf_ptr = s->inbuf;
-                s->frame_size = 0;
-                break;
-            }
         }
     }
     return buf_ptr - buf;
Index: libavcodec/aac_ac3_parser.h
===================================================================
--- libavcodec/aac_ac3_parser.h	(revision 12191)
+++ libavcodec/aac_ac3_parser.h	(working copy)
@@ -26,13 +26,23 @@
 #include <stdint.h>
 #include "avcodec.h"
 
+typedef struct AACAC3HeaderInfo {
+    const uint8_t *buf;
+    int channels;
+    int sample_rate;
+    int bit_rate;
+    int samples;
+    int stream_type;
+} AACAC3HeaderInfo;
+
 typedef struct AACAC3ParseContext {
-    uint8_t *inbuf_ptr;
+    uint8_t *inbuf_ptr; ///< not read part of frame
+    uint8_t *inbuf; ///< beginning of current frame
     int frame_size;
     int header_size;
-    int (*sync)(const uint8_t *buf, int *channels, int *sample_rate,
-                int *bit_rate, int *samples);
-    uint8_t inbuf[8192]; /* input buffer */
+    int (*sync)(AACAC3HeaderInfo *hdr_info);
+    uint8_t inbuf_tab[8192]; /* input buffer */
+    AACAC3HeaderInfo hdr;
 } AACAC3ParseContext;
 
 int ff_aac_ac3_parse(AVCodecParserContext *s1,
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to