Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <errno.h>
  4 #include <string.h>
  5 #include <unistd.h>
  6 #include <dlfcn.h>
  7 
  8 #include "grab-ng.h"
  9 
 10 /* ---------------------------------------------------------------------- */
 11 /* stuff we need from lame.h                                              */
 12 
 13 struct lame_global_struct;
 14 typedef struct lame_global_struct lame_global_flags;
 15 
 16 static lame_global_flags* (*lame_init)(void);
 17 static int (*lame_close)(lame_global_flags *);
 18 
 19 static int (*lame_set_in_samplerate)(lame_global_flags *, int);
 20 static int (*lame_set_num_channels)(lame_global_flags *, int);
 21 static int (*lame_set_quality)(lame_global_flags *, int);
 22 static int (*lame_init_params)(lame_global_flags * const );
 23 
 24 /*
 25  * num_samples = number of samples in the L (or R)
 26  * channel, not the total number of samples in pcm[]  
 27  * returns # of output bytes
 28  * mp3buffer_size_max = 1.25*num_samples + 7200
 29  */
 30 static int (*lame_encode_buffer_interleaved)(
 31     lame_global_flags*  gfp,           /* global context handlei          */
 32     short int           pcm[],         /* PCM data for left and right
 33                                           channel, interleaved            */
 34     int                 num_samples,   /* number of samples per channel,
 35                                           _not_ number of samples in
 36                                           pcm[]                           */
 37     unsigned char*      mp3buf,        /* pointer to encoded MP3 stream   */
 38     int                 mp3buf_size ); /* number of valid octets in this
 39                                           stream                          */
 40 static int (*lame_encode_flush)(
 41     lame_global_flags *  gfp,    /* global context handle                 */
 42     unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */
 43     int                  size);  /* number of valid octets in this stream */
 44 
 45 /* ---------------------------------------------------------------------- */
 46 /* simple, portable dynamic linking (call stuff indirectly using          */
 47 /* function pointers)                                                     */
 48 
 49 #define SYM(symbol) { .func = (void*)(&symbol), .name = #symbol }
 50 static struct {
 51     void   **func;
 52     char   *name;
 53 } symtab[] = {
 54     SYM(lame_init),
 55     SYM(lame_close),
 56     SYM(lame_set_in_samplerate),
 57     SYM(lame_set_num_channels),
 58     SYM(lame_set_quality),
 59     SYM(lame_init_params),
 60     SYM(lame_encode_buffer_interleaved),
 61     SYM(lame_encode_flush),
 62 };
 63 
 64 static int link_lame(void)
 65 {
 66     void *handle;
 67     void *symbol;
 68     unsigned int i;
 69 
 70     handle = dlopen("libmp3lame.so.0",RTLD_NOW);
 71     if (NULL == handle)
 72         return -1;
 73     for (i = 0; i < sizeof(symtab)/sizeof(symtab[0]); i++) {
 74         symbol = dlsym(handle,symtab[i].name);
 75         if (NULL == symbol) {
 76             fprintf(stderr,"dlsym(mp3lame,%s): %s\n",
 77                     symtab[i].name, dlerror());
 78             dlclose(handle);
 79             return -1;
 80         }
 81         *(symtab[i].func) = symbol;
 82     }
 83     return 0;
 84 }
 85 
 86 /* ---------------------------------------------------------------------- */
 87 
 88 struct mp3_enc_state {
 89     lame_global_flags *gf;
 90     int first;
 91 };
 92 
 93 static void* mp3_enc_init(void *priv)
 94 {
 95     struct mp3_enc_state *h;
 96 
 97     h = malloc(sizeof(*h));
 98     if (NULL == h)
 99         return NULL;
100     memset(h,0,sizeof(*h));
101     h->gf    = lame_init();
102     h->first = 1;
103     return h;
104 }
105 
106 static struct ng_audio_buf*
107 mp3_enc_data(void *handle, struct ng_audio_buf *in)
108 {
109     static struct ng_audio_fmt fmt = {
110         .fmtid = AUDIO_MP3,
111         .rate  = 0,
112     };
113     struct mp3_enc_state *h = handle;
114     struct ng_audio_buf *out;
115     int samples, size;
116 
117     if (h->first) {
118         lame_set_in_samplerate(h->gf, in->fmt.rate);
119         lame_set_num_channels(h->gf, ng_afmt_to_channels[in->fmt.fmtid]);
120         lame_set_quality(h->gf, 5 /* FIXME */);
121         lame_init_params(h->gf);
122         h->first = 0;
123     }
124     samples = in->size >> 2;
125     size = 7200 + samples * 5 / 4; /* worst case */
126     out = ng_malloc_audio_buf(&fmt, size);
127 
128     out->size = lame_encode_buffer_interleaved
129         (h->gf, (short int*) in->data, samples, out->data, size);
130     free(in);
131     return out;
132 }
133 
134 static void mp3_enc_fini(void *handle)
135 {
136     struct mp3_enc_state *h = handle;
137 
138     lame_close(h->gf);
139     free(h);
140 }
141 
142 /* ---------------------------------------------------------------------- */
143 
144 static struct ng_audio_conv mp3_list[] = {
145     {
146         /* --- compress --- */
147         init:           mp3_enc_init,
148         frame:          mp3_enc_data,
149         fini:           mp3_enc_fini,
150         fmtid_in:       AUDIO_S16_NATIVE_STEREO,
151         fmtid_out:      AUDIO_MP3,
152         priv:           NULL,
153     }
154 };
155 static const int nconv = sizeof(mp3_list)/sizeof(mp3_list[0]);
156 
157 /* ---------------------------------------------------------------------- */
158 /* init stuff                                                             */
159 
160 extern void ng_plugin_init(void);
161 void ng_plugin_init(void)
162 {
163     if (0 != link_lame())
164         return;
165     ng_aconv_register(NG_PLUGIN_MAGIC,__FILE__,mp3_list,nconv);
166 }
167 
  This page was automatically generated by the LXR engine.