[Ffmpeg-devel] [PATCH] THP PCM decoder (GSoC Qualification)
Baptiste Coudurier
baptiste.coudurier
Mon Apr 2 18:25:14 CEST 2007
Hi
Marco Gerards wrote:
> Hi,
>
> Last week I sent in a patch demuxer for THP files, which was applied
> yesterday. Here is a patch to extend it with a PCM decoder, as
> promised. I have tested it with the files Mike uploaded.
>
> Mike, do you happen to have version THP version 1.1 files? The
> current samples are all THP version 1.0. Both should work, but you
> can't be sure until it is tested ;-).
>
> For now I assumed it is only possible to have THP files with a single
> audio stream. If there are THP files with more than one audio stream,
> please tell me and I will have a look :-).
>
> --
> Marco
>
> Index: libavcodec/allcodecs.c
> ===================================================================
> --- libavcodec/allcodecs.c (revision 8597)
> +++ libavcodec/allcodecs.c (working copy)
> @@ -244,6 +244,7 @@
> REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf);
> REGISTER_ENCDEC (ADPCM_XA, adpcm_xa);
> REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha);
> + REGISTER_DECODER (ADPCM_THP, adpcm_thp);
add it in alphabetical order, and with '(' aligned.
> /* subtitles */
> REGISTER_ENCDEC (DVBSUB, dvbsub);
> Index: libavcodec/Makefile
> ===================================================================
> --- libavcodec/Makefile (revision 8597)
> +++ libavcodec/Makefile (working copy)
> @@ -250,6 +250,7 @@
> OBJS-$(CONFIG_ADPCM_XA_ENCODER) += adpcm.o
> OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o
> OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o
> +OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o
in alphabetical order.
> # external codec libraries
> OBJS-$(CONFIG_LIBA52) += a52dec.o
> Index: libavcodec/avcodec.h
> ===================================================================
> --- libavcodec/avcodec.h (revision 8597)
> +++ libavcodec/avcodec.h (working copy)
> @@ -198,6 +198,7 @@
> CODEC_ID_ADPCM_SBPRO_4,
> CODEC_ID_ADPCM_SBPRO_3,
> CODEC_ID_ADPCM_SBPRO_2,
> + CODEC_ID_ADPCM_THP,
>
> /* AMR */
> CODEC_ID_AMR_NB= 0x12000,
> @@ -2407,6 +2408,7 @@
> PCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf);
> PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
> PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha);
> +PCM_CODEC(CODEC_ID_ADPCM_thp, adpcm_thp);
here too with "thp" in capital.
> #undef PCM_CODEC
>
> Index: libavcodec/adpcm.c
> ===================================================================
> --- libavcodec/adpcm.c (revision 8597)
> +++ libavcodec/adpcm.c (working copy)
> @@ -144,6 +144,7 @@
> int coeff1;
> int coeff2;
> int idelta;
> +
> } ADPCMChannelStatus;
cosmetics.
> typedef struct ADPCMContext {
> @@ -1308,6 +1309,59 @@
> src++;
> }
> break;
> + case CODEC_ID_ADPCM_THP:
> + {
> + GetBitContext gb;
> + float table[16][2];
> + int samplecnt;
> + int prev1[2], prev2[2];
> + int ch;
> +
> + init_get_bits(&gb, src, buf_size);
> + src += buf_size;
> +
> + get_bits(&gb, 32); /* Channel size */
> + samplecnt = get_bits(&gb, 32);
check for input buffer length validity.
> + for (ch = 0; ch < 2; ch++)
> + for (i = 0; i < 16; i++) {
> + /* Read the fixed point entry and store as floating
> + point. */
> + int entry = get_sbits(&gb, 16);
> + table[i][ch] = (float) entry / pow(2, 11);
1<<11
> + }
> +
> + /* Initialize the previous sample. */
> + for (ch = 0; ch < 2; ch++) {
> + prev1[ch] = get_sbits(&gb, 16);
> + prev2[ch] = get_sbits(&gb, 16);
> + }
> +
> + for (ch = 0; ch <= st; ch++) {
> + int sample = samplecnt;
> +
> + /* Read in every sample for this channel. */
> + while (sample > 0) {
> + uint8_t index = get_bits (&gb, 4) & 7;
> + float exp = pow(2, get_bits (&gb, 4));
1<<get_bits(&gb, 4);
> + float factor1 = table[index * 2][ch];
> + float factor2 = table[index * 2 + 1][ch];
> +
> + /* Decode 14 samples. */
> + for (n = 0; n < 14; n++) {
> + int sampledat = get_sbits (&gb, 4);
> + *samples = prev1[ch]*factor1
> + + prev2[ch]*factor2 + sampledat * exp;
> + prev2[ch] = prev1[ch];
> + prev1[ch] = *samples++;
> + sample--;
check for output buffer overflow.
> + }
> + }
> + }
> +
> + break;
> + }
> +
> default:
> return -1;
> }
> @@ -1368,5 +1422,6 @@
> ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4);
> ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3);
> ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2);
> +ADPCM_DECODER(CODEC_ID_ADPCM_THP, adpcm_thp);
use CODEC and dummy return -1 to stay in conformance with others
(see IMA_QT)
> [...]
> + }
> + else {
> + ret = av_get_packet(pb, pkt, thp->audiosize);
> + if (ret != thp->audiosize) {
> + av_free_packet(pkt);
> + return AVERROR_IO;
> + }
> + pkt->stream_index = thp->audio_stream_index;
> + thp->audiosize = 0;
> + thp->frame++;
Can't seek be avoided now ? Does audio follow video in data stream ? If
so Im wondering if reading video + audio in the same time, using buffer
then output audio after, would not be cleaner and simpler.
[...]
--
Baptiste COUDURIER GnuPG Key Id: 0x5C1ABAAA
SMARTJOG S.A. http://www.smartjog.com
Key fingerprint 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
Phone: +33 1 49966312
More information about the ffmpeg-devel
mailing list