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.
|