[albeu at free.fr: [Ffmpeg-devel] [Ffmpeg-devel-old] [PATCH] Limit number of processed sample with pcm codecs and a libgsm warper]

Diego Biurrun diego
Sun May 22 18:29:38 CEST 2005


A ghost has resurfaced :)
I thought I'd forward this here before it gets lost...

----- Forwarded message from Alban Bedel <albeu at free.fr> -----

From: Alban Bedel <albeu at free.fr>
Date: Thu, 19 May 2005 01:44:15 +0200
To: ffmpeg-devel at lists.sourceforge.net
Cc: 
Subject: [Ffmpeg-devel] [Ffmpeg-devel-old] [PATCH] Limit number of processed
 sample with pcm codecs and a libgsm warper
X-Newsreader: Sylpheed version 1.0.3 (GTK+ 1.2.10; i686-pc-linux-gnu)


Hi all,

i'm hacking a little voip prog that use lavc. However i run into a small
problem with the pcm formats and g726. The encoder encode as much data
as there is space in the output buffer. One can hack a bit with pcm
and alaw,ulaw. But then with g726 that's start to be messy.

The patch add a max_samples field to the avctx, if non 0 the pcm and g726
encoder and decoder will only process at most that many samples in a run.

Then i'm needing gsm, so i made a little warper to libgsm. Dunno if a
"native lavc" gsm enc/decoder is planned but for now that fill the gap.
I also attached a patch for ffmpeg configure.

	Albeu

----- End forwarded message -----
-------------- next part --------------
Index: avcodec.h
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/avcodec.h,v
retrieving revision 1.398
diff -u -r1.398 avcodec.h
--- avcodec.h	17 May 2005 22:47:34 -0000	1.398
+++ avcodec.h	18 May 2005 21:57:44 -0000
@@ -1789,6 +1789,14 @@
      * - decoding: unused
      */
     int me_penalty_compensation;
+
+    /**
+     * encode/decode only up to a given number of samples, used by non framed
+     * audio codec.
+     * - encoding: set by user.
+     * - decoding: set by user.
+     */
+    int max_samples;
 } AVCodecContext;
 
 
Index: g726.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/g726.c,v
retrieving revision 1.6
diff -u -r1.6 g726.c
--- g726.c	8 May 2005 20:15:42 -0000	1.6
+++ g726.c	18 May 2005 21:57:44 -0000
@@ -359,8 +359,13 @@
 
     init_put_bits(&pb, dst, 1024*1024);
 
-    for (; buf_size; buf_size--)
-       put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++));
+    if(avctx->max_samples) {
+        int max = avctx->max_samples;
+        for (; max && buf_size; buf_size--, max--)
+            put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++));
+    } else
+        for (; buf_size; buf_size--)
+            put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++));
 
     flush_put_bits(&pb);
 
@@ -376,6 +381,7 @@
     uint8_t code;
     uint8_t mask;
     GetBitContext gb; 
+    int max_samples = avctx->max_samples;
    
     if (!buf_size)
         goto out;
@@ -386,10 +392,17 @@
         int s = c->code_size - c->bits_left;;
 	code = (c->bit_buffer << s) | get_bits(&gb, s);
 	*samples++ = g726_decode(&c->c, code & mask);
+        if(max_samples) max_samples--;
     }
     
-    while (get_bits_count(&gb) + c->code_size <= buf_size*8)
-	*samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask);
+    if(avctx->max_samples)
+        while (get_bits_count(&gb) + c->code_size <= buf_size*8 && max_samples > 0) {
+            *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask);
+            max_samples--;
+        }
+    else
+        while (get_bits_count(&gb) + c->code_size <= buf_size*8)
+            *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask);
     
     c->bits_left = buf_size*8 - get_bits_count(&gb);
     c->bit_buffer = get_bits(&gb, c->bits_left);
Index: pcm.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/pcm.c,v
retrieving revision 1.15
diff -u -r1.15 pcm.c
--- pcm.c	13 Feb 2005 23:36:04 -0000	1.15
+++ pcm.c	18 May 2005 21:57:45 -0000
@@ -189,6 +189,8 @@
         break;
     }
     n = buf_size / sample_size;
+    if(avctx->max_samples && n > avctx->max_samples)
+        n = avctx->max_samples;
     samples = data;
     dst = frame;
 
@@ -305,6 +307,8 @@
     switch(avctx->codec->id) {
     case CODEC_ID_PCM_S16LE:
         n = buf_size >> 1;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = src[0] | (src[1] << 8);
             src += 2;
@@ -312,6 +316,8 @@
         break;
     case CODEC_ID_PCM_S16BE:
         n = buf_size >> 1;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = (src[0] << 8) | src[1];
             src += 2;
@@ -319,6 +325,8 @@
         break;
     case CODEC_ID_PCM_U16LE:
         n = buf_size >> 1;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = (src[0] | (src[1] << 8)) - 0x8000;
             src += 2;
@@ -326,6 +334,8 @@
         break;
     case CODEC_ID_PCM_U16BE:
         n = buf_size >> 1;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = ((src[0] << 8) | src[1]) - 0x8000;
             src += 2;
@@ -333,6 +343,8 @@
         break;
     case CODEC_ID_PCM_S8:
         n = buf_size;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = src[0] << 8;
             src++;
@@ -340,6 +352,8 @@
         break;
     case CODEC_ID_PCM_U8:
         n = buf_size;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = ((int)src[0] - 128) << 8;
             src++;
@@ -348,6 +362,8 @@
     case CODEC_ID_PCM_ALAW:
     case CODEC_ID_PCM_MULAW:
         n = buf_size;
+        if(avctx->max_samples && n > avctx->max_samples)
+            n = avctx->max_samples;
         for(;n>0;n--) {
             *samples++ = s->table[src[0]];
             src++;
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/Makefile,v
retrieving revision 1.189
diff -u -r1.189 Makefile
--- Makefile	18 May 2005 14:05:16 -0000	1.189
+++ Makefile	18 May 2005 21:57:44 -0000
@@ -18,7 +18,7 @@
       fft.o mdct.o raw.o golomb.o cabac.o\
       dpcm.o adx.o rational.o faandct.o parser.o g726.o \
       vp3dsp.o integer.o h264idct.o rangecoder.o pnm.o h263.o msmpeg4.o h263dec.o
-      
+
 ifeq ($(CONFIG_AASC_DECODER),yes)
     OBJS+= aasc.o
 endif
@@ -178,8 +178,8 @@
 ifeq ($(CONFIG_XL_DECODER),yes)
     OBJS+= xl.o
 endif
-      
-      
+
+
 AMROBJS=
 ifeq ($(AMR_NB),yes)
 ifeq ($(AMR_NB_FIXED),yes)
@@ -291,6 +291,11 @@
 EXTRALIBS += -logg
 endif
 
+ifeq ($(CONFIG_LIBGSM),yes)
+OBJS += libgsm.o
+EXTRALIBS += -lgsm
+endif
+
 ifeq ($(TARGET_GPROF),yes)
 CFLAGS+=-p
 LDFLAGS+=-p
Index: allcodecs.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/allcodecs.c,v
retrieving revision 1.105
diff -u -r1.105 allcodecs.c
--- allcodecs.c	17 May 2005 22:47:34 -0000	1.105
+++ allcodecs.c	18 May 2005 21:57:44 -0000
@@ -186,6 +186,9 @@
     register_avcodec(&x264_encoder);
 #endif //CONFIG_X264_ENCODER
 #endif
+#ifdef CONFIG_LIBGSM
+    register_avcodec(&libgsm_encoder);
+#endif //CONFIG_LIBGSM
 #endif /* CONFIG_ENCODERS */
 #ifdef CONFIG_RAWVIDEO_ENCODER
     register_avcodec(&rawvideo_encoder);
@@ -482,6 +485,9 @@
 #ifdef CONFIG_VORBIS_DECODER
     register_avcodec(&vorbis_decoder);
 #endif
+#ifdef CONFIG_LIBGSM
+    register_avcodec(&libgsm_decoder);
+#endif //CONFIG_LIBGSM
 #endif /* CONFIG_DECODERS */
 
 #ifdef AMR_NB
Index: avcodec.h
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/avcodec.h,v
retrieving revision 1.398
diff -u -r1.398 avcodec.h
--- avcodec.h	17 May 2005 22:47:34 -0000	1.398
+++ avcodec.h	18 May 2005 21:57:44 -0000
@@ -172,6 +172,7 @@
     CODEC_ID_SHORTEN,
     CODEC_ID_ALAC,
     CODEC_ID_WESTWOOD_SND1,
+    CODEC_ID_GSM,    
     
     CODEC_ID_OGGTHEORA= 0x16000, 
     
@@ -2029,6 +2030,8 @@
 extern AVCodec indeo2_decoder;
 extern AVCodec vorbis_decoder;
 extern AVCodec fraps_decoder;
+extern AVCodec libgsm_encoder;
+extern AVCodec libgsm_decoder;
 
 /* pcm codecs */
 #define PCM_CODEC(id, name) \
--- /dev/null	2003-12-20 14:44:57.000000000 +0100
+++ libgsm.c	2005-05-18 22:24:23.000000000 +0200
@@ -0,0 +1,95 @@
+/*
+ * Interface to libgsm for gsm encoding/decoding
+ * Copyright (c) 2005 Alban Bedel <albeu at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ 
+/**
+ * @file libgsm.c
+ * Interface to libgsm for gsm encoding/decoding
+ */
+
+#include "avcodec.h"
+#include <gsm.h>
+
+// gsm.h miss some essential constants
+#define GSM_BLOCK_SIZE 33
+#define GSM_FRAME_SIZE 160
+
+static int libgsm_init(AVCodecContext *avctx) {
+    if (avctx->channels > 1 || avctx->sample_rate != 8000)
+        return -1;
+
+    avctx->frame_size = GSM_FRAME_SIZE;
+    avctx->block_align = GSM_BLOCK_SIZE;
+
+    avctx->priv_data = gsm_create();
+    
+    avctx->coded_frame= avcodec_alloc_frame();
+    avctx->coded_frame->key_frame= 1;
+    
+    return 0;
+}
+
+static int libgsm_close(AVCodecContext *avctx) {
+    gsm_destroy(avctx->priv_data);
+    avctx->priv_data = NULL;
+    return 0;
+}
+
+static int libgsm_encode_frame(AVCodecContext *avctx,
+                               unsigned char *frame, int buf_size, void *data) {
+    // we need a full block
+    if(buf_size < GSM_BLOCK_SIZE) return 0;
+
+    gsm_encode(avctx->priv_data,data,frame);
+
+    return GSM_BLOCK_SIZE;
+}
+
+
+AVCodec libgsm_encoder = {
+    "gsm",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_GSM,
+    0,
+    libgsm_init,
+    libgsm_encode_frame,
+    libgsm_close,
+};
+
+static int libgsm_decode_frame(AVCodecContext *avctx,
+                               void *data, int *data_size,
+                               uint8_t *buf, int buf_size) {
+
+    if(buf_size < GSM_BLOCK_SIZE) return 0;
+
+    if(gsm_decode(avctx->priv_data,buf,data)) return -1;
+
+    *data_size = GSM_FRAME_SIZE*2;
+    return GSM_BLOCK_SIZE;
+}
+
+AVCodec libgsm_decoder = {
+    "gsm",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_GSM,
+    0,
+    libgsm_init,
+    NULL,
+    libgsm_close,
+    libgsm_decode_frame,
+};
-------------- next part --------------
--- configure	2005-05-17 00:49:28.000000000 +0200
+++ /home/alban/aphx/configure	2005-05-18 21:29:42.000000000 +0200
@@ -22,6 +22,7 @@
 echo "  --enable-faad            enable faad support via libfaad [default=no]"
 echo "  --enable-faadbin         build faad support with runtime linking [default=no]"
 echo "  --enable-faac            enable faac support via libfaac [default=no]"
+echo "  --enable-libgsm          enable gsm support via libgsm [default=no]"
 echo "  --enable-xvid            enable xvid support via xvidcore [default=no]"
 echo "  --enable-x264            enable H.264 encoding via x264 [default=no]"
 echo "  --enable-mingw32         enable mingw32 native/cross windows compile"
@@ -158,6 +159,7 @@
 dc1394="no"
 network="yes"
 zlib="yes"
+libgsm="no"
 mp3lame="no"
 libogg="no"
 vorbis="no"
@@ -447,6 +449,8 @@
   ;;
   --enable-shared-pp) shared_pp="yes"
   ;;
+  --enable-libgsm) libgsm="yes"
+  ;;
   --enable-mp3lame) mp3lame="yes"
   ;;
   --enable-libogg) libogg="yes"
@@ -1123,6 +1127,7 @@
 fi
 echo "gprof enabled    $gprof"
 echo "zlib enabled     $zlib"
+echo "libgsm enabled   $libgsm"
 echo "mp3lame enabled  $mp3lame"
 echo "libogg enabled   $libogg"
 echo "vorbis enabled   $vorbis"
@@ -1420,6 +1425,11 @@
   echo "CONFIG_ZLIB=yes" >> config.mak
 fi
 
+if test "$libgsm" = "yes" ; then
+  echo "#define CONFIG_LIBGSM 1" >> $TMPH
+  echo "CONFIG_LIBGSM=yes" >> config.mak
+fi
+
 if test "$mp3lame" = "yes" ; then
   echo "#define CONFIG_MP3LAME 1" >> $TMPH
   echo "CONFIG_MP3LAME=yes" >> config.mak



More information about the ffmpeg-devel mailing list