[FFmpeg-devel] [PATCH] G.722 decoder
Michael Niedermayer
michaelni
Wed Sep 8 16:01:50 CEST 2010
On Wed, Sep 08, 2010 at 04:38:36PM +0300, Martin Storsj? wrote:
> On Wed, 8 Sep 2010, Michael Niedermayer wrote:
>
> > On Wed, Sep 08, 2010 at 09:18:21AM +0300, Martin Storsj? wrote:
> > > +static void do_adaptive_prediction(struct G722Band *band, const int cur_diff)
> > > +{
> > > + int sg[2], limit, i, cur_qtzd_reconst;
> > > +
> > > + const int cur_part_reconst = band->s_zero + cur_diff < 0;
> > > +
> > > + sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]];
> > > + sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]];
> > > + band->part_reconst_mem[1] = band->part_reconst_mem[0];
> > > + band->part_reconst_mem[0] = cur_part_reconst;
> > > +
> > > + band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) +
> > > + (sg[1] << 7) + (band->pole_mem[1] * 127 >> 7), -12288, 12288);
> > > +
> > > + limit = 15360 - band->pole_mem[1];
> > > + band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit);
> > > +
> > > +
> > > + if (cur_diff) {
> > > + for (i = 0; i < 6; i++)
> > > + band->zero_mem[i] = ((band->zero_mem[i]*255) >> 8) +
> > > + ((band->diff_mem[i]^cur_diff) < 0 ? -128 : 128);
> > > + } else
> >
> > > + for (i = 0; i < 6; i++)
> > > + band->zero_mem[i] = (band->zero_mem[i]*255) >> 8;
> >
> > > +
> > > + for (i = 5; i > 0; i--)
> > > + band->diff_mem[i] = band->diff_mem[i-1];
> > > + band->diff_mem[0] = av_clip_int16(cur_diff << 1);
> > > +
> > > + band->s_zero = 0;
> > > + for (i = 5; i >= 0; i--)
> > > + band->s_zero += (band->zero_mem[i]*band->diff_mem[i]) >> 15;
> > > +
> > > +
> > > + cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) << 1);
> > > + band->s_predictor = av_clip_int16(band->s_zero +
> > > + (band->pole_mem[0] * cur_qtzd_reconst >> 15) +
> > > + (band->pole_mem[1] * band->prev_qtzd_reconst >> 15));
> > > + band->prev_qtzd_reconst = cur_qtzd_reconst;
> > > +}
> >
> > somehow iam feeling this function should return s_predictor and not void
>
> Yes, that would perhaps be logical, however, in this codec, the updated
> predictor value isn't used until decoding the next sample, due to the
> scalable bitrate design (where different inv quant tables are used for
> decoding the actual samples, but the one same lower precision one always
> is used for updating the predictor internally, regardless which way it is
> decoded). So making this return the predictor wouldn't really help
> anything in this implementation.
>
> > > +static int inline linear_scale_factor(const int log_factor, int shift)
> > > +{
> > > + const int wd1 = inv_log2_table[(log_factor >> 6) & 31];
> > > + shift -= log_factor >> 11;
> > > + return (shift < 0 ? wd1 << -shift : wd1 >> shift) << 2;
> > > +}
> >
> > the shift parameter can be droped and instead a constant added to the
> > log_factor param for each call
>
> Yes, dropped this parameter.
>
> > also the <<2 can be removed, scale_factor be scaled down by 4 thus and a
> > few shifts readjusted in uses of it
>
> Hmm, I'm not sure I'm following you here. Do you mean that I should
> premultiply inv_log2_table by 4 and skip the final right shift? Or just
> add/subtract 2 from the 'shift' variable? I tried that (the former, but
> the latter would have the same effect), but it doesn't give bitexact
> output, since the codec relies on truncating the values when doing the
> right shift.
ive meant making scale_factor= scale_factor/4 and simplifying all code that
reads or writes it. This seems possible, am i missing something?
>
> > > +static av_cold int g722_init(AVCodecContext * avctx)
> > > +{
> > > + G722Context *c = avctx->priv_data;
> > > +
> > > + if (avctx->channels != 1) {
> > > + av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n");
> > > + return AVERROR_INVALIDDATA;
> > > + }
> > > + avctx->sample_fmt = SAMPLE_FMT_S16;
> > > +
> > > + switch (avctx->bit_rate) {
> > > + case 64000:
> > > + case 56000:
> > > + case 48000:
> > > + c->bits_per_sample = avctx->bit_rate/8000;
> > > + break;
> >
> > theres a problem here
> > bitrate is the bitrate of the bitstream in libavcodec
> > thus a lower bitrate stream + trash bits has 64000 too you cant distinguish
> > them like this
>
> Yes, this is a problem. Do you have any other suggestion for how to signal
> the lower bitrate variants? Would AVCodecContext->bits_per_coded_sample
> perhaps be suitable for this?
maybe
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The misfortune of the wise is better than the prosperity of the fool.
-- Epicurus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100908/bd5b660b/attachment.pgp>
More information about the ffmpeg-devel
mailing list