[FFmpeg-soc] [Patch] Maxis EA XA decoder - GSoC Task
Robert Marston
rmarston at gmail.com
Tue Apr 8 21:29:41 CEST 2008
On Tue, Apr 8, 2008 at 8:11 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Tue, Apr 08, 2008 at 04:43:25PM +0200, Robert Marston wrote:
> [...]
>
>
>
>
> >
> >
> > >
> > >
> > > [...]
> > > > static int xa_read_header(AVFormatContext *s,
> > > > AVFormatParameters *ap)
> > > > {
> > > > MaxisXADemuxContext *xa = s->priv_data;
> > > > AVStream *st;
> > > >
> > > > /* Extract Header Information from xa file */
> > > > if (!xa_extract_header_info(s))
> > > > return AVERROR(EIO);
> > > >
> > > > /*Set up the XA Audio Decoder*/
> > > > st = av_new_stream(s, 0);
> > > > if (!st)
> > > > return AVERROR(ENOMEM);
> > >
> > > > av_set_pts_info(st, 33, 1, xa->sampleRate);
> > >
> > > i doubt 33 is correct
> >
> >
> > I am not entirely sure what the wrap bits is and what its value should be, I
> > copied that from the original ADPCM EA in electronicarts.c
>
> Its the number of bits in the pts, mpeg stores them in 33 bits people
> copied that all over the place without undestanding it ...
>
Set this to 64 then?
>
> [...]
>
> > >
> > >
> > > > if (ret != packet_size) {
> > > > av_log(s, AV_LOG_WARNING, "Size mismatch");
> > > > return AVERROR(EIO);
> > > > }
> > >
> > > memleak
> > >
> >
> > Added a av_free for pkt here. The test files seem to have an extra few
> > samples but according to the description the samples are contained in blocks
> > of 14 bytes for each channel and so I am not sure why there are these extra
> > samples in the file.
>
> Probably because the source did not contain a multiple of 28 samples, it
> would be nice if tha last incomplete packet would be decoded as well.
> Assuming iam guessing correct that it is actual audio at all instead of
> junk.
>
Will check this.
>
> [...]
> > typedef struct ADPCMContext {
> > int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */
> > ADPCMChannelStatus status[6];
> > + int32_t mxa_current_left_sample; /*Needed to keep track of left and right samples for Maxis EA XA */
> > + int32_t mxa_previous_left_sample;
> > + int32_t mxa_current_right_sample;
> > + int32_t mxa_previous_right_sample;
> > } ADPCMContext;
> >
> > /* XXX: implement encoding */
>
> unneeded
>
Not sure why unneeded since for each block the previous blocks prev
and curr samples need to be remembered and are not present in the
stream.
>
> [...]
> > @@ -1235,6 +1246,53 @@
>
> > }
> > }
> > break;
> > + case CODEC_ID_ADPCM_EA_MAXIS_XA:
> > + channel = avctx->channels;
> > +
> > + if(channel > 2) {
> > + av_log(avctx, AV_LOG_ERROR, "Only 1 or 2 channels supported");
> > + return -1;
> > + }
> > +
>
> > + coeff1l = ea_adpcm_table[(*src >> 4) & 0x0F];
> > + coeff2l = ea_adpcm_table[((*src >> 4) & 0x0F) + 4];
> > + shift_left = (*src & 0x0F) + 8;
> > + src++;
> > +
> > + if(st) {
> > + coeff1r = ea_adpcm_table[(*src >> 4) & 0x0F];
> > + coeff2r = ea_adpcm_table[((*src >> 4) & 0x0F) + 4];
> > + shift_right = (*src & 0x0F) + 8;
> > + src++;
> > + }
>
> duplicate
>
Not sure what the duplication refers too? If statement has duplicate
code to what precedes it or duplicate to already implemented EA ADPCM?
>
>
> > +
> > + for (count1 = 0; count1 < 14 ; count1++) {
> > + for(count2 = 4; count2 >= 0; count2-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */
>
> > + next_left_sample = ((((*src >> count2) & 0x0F) << 0x1C) >> shift_left);
>
> > + next_left_sample = (next_left_sample +
> > + (c->mxa_current_left_sample * coeff1l) +
> > + (c->mxa_previous_left_sample * coeff2l) + 0x80) >> 8;
> > + c->mxa_previous_left_sample = c->mxa_current_left_sample;
> > + c->mxa_current_left_sample = av_clip_int16(next_left_sample);
> > + *samples++ = (unsigned short)c->mxa_current_left_sample;
> > +
> > + if(st) {
> > + src++;
> > + next_right_sample = ((((*src >> count2) & 0x0F) << 0x1C) >> shift_right);
>
> > + next_right_sample = (next_right_sample +
> > + (c->mxa_current_right_sample * coeff1r) +
> > + (c->mxa_previous_right_sample * coeff2r) + 0x80) >> 8;
> > + c->mxa_previous_right_sample = c->mxa_current_right_sample;
> > + c->mxa_current_right_sample = av_clip_int16(next_right_sample);
> > + *samples++ = (unsigned short)c->mxa_current_right_sample;
> > + src--;
> > + }
>
> duplicate
>
ditto
> [...]
>
> > +static int xa_read_header(AVFormatContext *s,
>
> > + AVFormatParameters *ap)
> > +{
> > + MaxisXADemuxContext *xa = s->priv_data;
> > + AVStream *st;
> > +
> > + /* Extract Header Information from xa file */
> > + if (!xa_extract_header_info(s))
> > + return AVERROR(EIO);
> > +
> > + /*Set up the XA Audio Decoder*/
> > + st = av_new_stream(s, 0);
> > + if (!st)
> > + return AVERROR(ENOMEM);
> > + av_set_pts_info(st, 33, 1, xa->sampleRate);
> > + st->codec->codec_type = CODEC_TYPE_AUDIO;
>
> > + st->codec->codec_id = CODEC_ID_ADPCM_EA_MAXIS_XA;
> > + st->codec->bits_per_sample = xa->bits;
>
> > + st->codec->block_align = (xa->bits/8) * xa->channels;
>
> This is wrong.
>
>
> [...]
> > + packet_size = 15*xa->channels;/* 1 byte header and 14 bytes worth of samples * number channels per block */
> > + if (av_get_packet(pb, pkt, packet_size) != packet_size) {
> > + av_log(s, AV_LOG_WARNING, "Size mismatch when reading data from file\n");
> > + av_free_packet(pkt);
> > + return AVERROR(EIO);
> > + }
>
> This is wrong as well
>
What are you referring to when you say this is wrong?
>
> > + else {
>
> > + pkt->stream_index = xa->audio_stream_index;
> > + pkt->pts = 90000;
> > + pkt->pts *= xa->audio_frame_counter;
> > + pkt->pts /= xa->sampleRate;
> > + xa->audio_frame_counter += (14 * xa->channels); /* 14 Samples per channel */
>
> to quote the documentation
> "int64_t pts; ///< presentation time stamp in time_base units"
>
> This is not what you set it to
>
>
Is this then number_samples per packet / sample rate?
> [...]
>
More information about the FFmpeg-soc
mailing list