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