~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/codec/encoder-jpeg.cc

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /*
  2  * encoder-jpeg.cc --
  3  *
  4  *      Motion Jpeg video encoder
  5  *
  6  * Copyright (c) 1994-2002 The Regents of the University of California.
  7  * All rights reserved.
  8  *
  9  * Redistribution and use in source and binary forms, with or without
 10  * modification, are permitted provided that the following conditions are met:
 11  *
 12  * A. Redistributions of source code must retain the above copyright notice,
 13  *    this list of conditions and the following disclaimer.
 14  * B. Redistributions in binary form must reproduce the above copyright notice,
 15  *    this list of conditions and the following disclaimer in the documentation
 16  *    and/or other materials provided with the distribution.
 17  * C. Neither the names of the copyright holders nor the names of its
 18  *    contributors may be used to endorse or promote products derived from this
 19  *    software without specific prior written permission.
 20  *
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 22  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  */
 33 
 34 static const char rcsid[] =
 35 "@(#) $Header: /usr/mash/src/repository/mash/mash-1/codec/encoder-jpeg.cc,v 1.20 2003/11/19 19:20:17 aswan Exp $";
 36 
 37 #include <stdio.h>
 38 #include <errno.h>
 39 #include "rtp/inet.h"
 40 #include "rtp/rtp.h"
 41 #include "codec/dct.h"
 42 #include "misc/bsd-endian.h"
 43 #include "rtp/pktbuf-rtp.h"
 44 #include "codec/module-list.h"
 45 
 46 #include "codec/encoder-jpeg.h"
 47 
 48 
 49 static class JpegEncoderClass : public TclClass {
 50         public:
 51                 JpegEncoderClass() : TclClass("Module/VideoEncoder/Pixel/JPEG") {}
 52                 TclObject* create(int, const char*const*) {
 53                         return (new JpegEncoder);
 54                 }
 55 } jpeg_encoder_class;
 56 
 57 #define HDRSIZE (sizeof(rtphdr) + 8)
 58 
 59 //
 60 // STORE_BITS
 61 //
 62 // This macro copies bb (a 32 or 64-bit number) into the buffer pointed by 
 63 // bc. It escapes any byte-aligned 0xff with 0xff00
 64 //
 65 #if NBIT == 64
 66 #define STORE_BITS(bb, bc)                                              \
 67 {                                                                       \
 68     u_char t = bb>>56;                                                  \
 69     *bc++ = t;                                                          \
 70     if (t == 0xff) *bc++ = 0;                                           \
 71     t = bb>>48;                                                         \
 72     *bc++ = t;                                                          \
 73     if (t == 0xff) *bc++ = 0;                                           \
 74     t = bb>>40;                                                         \
 75     *bc++ = t;                                                          \
 76     if (t == 0xff) *bc++ = 0;                                           \
 77     t = bb>>32;                                                         \
 78     *bc++ = t;                                                          \
 79     if (t == 0xff) *bc++ = 0;                                           \
 80     t = bb>>24;                                                         \
 81     *bc++ = t;                                                          \
 82     if (t == 0xff) *bc++ = 0;                                           \
 83     t = bb>>16;                                                         \
 84     *bc++ = t;                                                          \
 85     if (t == 0xff) *bc++ = 0;                                           \
 86     t = bb>>8;                                                          \
 87     *bc++ = t;                                                          \
 88     if (t == 0xff) *bc++ = 0;                                           \
 89     t = bb;                                                             \
 90     *bc++ = t;                                                          \
 91     if (t == 0xff) *bc++ = 0;                                           \
 92 }
 93 
 94 #else
 95 
 96 #define STORE_BITS(bb, bc)                                              \
 97 {                                                                       \
 98     u_char t = bb>>24;                                                  \
 99     *bc++ = t;                                                          \
100     if (t == 0xff) *bc++ = 0;                                           \
101     t = bb>>16;                                                         \
102     *bc++ = t;                                                          \
103     if (t == 0xff) *bc++ = 0;                                           \
104     t = bb>>8;                                                          \
105     *bc++ = t;                                                          \
106     if (t == 0xff) *bc++ = 0;                                           \
107     t = bb;                                                             \
108     *bc++ = t;                                                          \
109     if (t == 0xff) *bc++ = 0;                                           \
110 }
111 
112 #endif
113 
114 //
115 // PUT_BITS
116 //
117 // This macro stores "n" bits located at "bits" into the buffer pointed 
118 // by bc. It uses bb:nbb to cache bits in order to write an integer number 
119 // of sizeof(NBITS).
120 //
121 //   bits: the bits we want to write
122 //   n:    number of useful bits in "bits"
123 //   bb:   the NBIT-length cache integer
124 //   nbb:  occupied bits in bb so far
125 //   bc:   final buffer
126 //
127 
128 #define PUT_BITS(bits, n, nbb, bb, bc)                                  \
129 {                                                                       \
130     nbb += (n);                                                         \
131     if (nbb > NBIT)  {                                                  \
132         u_int extra = (nbb) - NBIT;                                     \
133         bb |= (BB_INT)(bits) >> extra;                                  \
134         STORE_BITS(bb, bc)                                              \
135         bb = (BB_INT)(bits) << (NBIT - extra);                          \
136         nbb = extra;                                                    \
137     } else                                                              \
138         bb |= (BB_INT)(bits) << (NBIT - (nbb));                         \
139 }
140 
141 
142 //
143 // JPEG tables definition
144 //
145 static const int stdlqt[] = {
146     16, 11, 10, 16, 24, 40, 51, 61,
147     12, 12, 14, 19, 26, 58, 60, 55,
148     14, 13, 16, 24, 40, 57, 69, 56,
149     14, 17, 22, 29, 51, 87, 80, 62,
150     18, 22, 37, 56, 68, 109, 103, 77,
151     24, 35, 55, 64, 81, 104, 113, 92,
152     49, 64, 78, 87, 103, 121, 120, 101,
153     72, 92, 95, 98, 112, 100, 103, 99 };
154 
155 static const int stdcqt[] = {
156     17, 18, 24, 47, 99, 99, 99, 99,
157     18, 21, 26, 66, 99, 99, 99, 99,
158     24, 26, 56, 99, 99, 99, 99, 99,
159     47, 66, 99, 99, 99, 99, 99, 99,
160     99, 99, 99, 99, 99, 99, 99, 99,
161     99, 99, 99, 99, 99, 99, 99, 99,
162     99, 99, 99, 99, 99, 99, 99, 99,
163     99, 99, 99, 99, 99, 99, 99, 99 };
164 
165 static struct JpegEncoder::huffentry ldht[] = {
166     {0x0, 2}, {0x2, 3}, {0x3, 3}, {0x4, 3}, {0x5, 3}, {0x6, 3},
167     {0xe, 4}, {0x1e, 5}, {0x3e, 6}, {0x7e, 7}, {0xfe, 8}, {0x1fe, 9}};
168 
169 static struct JpegEncoder::huffentry cdht[] = {
170     {0x0, 2}, {0x1, 2}, {0x2, 2}, {0x6, 3}, {0xe, 4}, {0x1e, 5}, {0x3e, 6},
171     {0x7e, 7}, {0xfe, 8}, {0x1fe, 9}, {0x3fe, 10}, {0x7fe, 11}};
172 
173 static struct JpegEncoder::huffentry laht[] = {
174     {0x0a, 4}, {0x00, 2}, {0x01, 2}, {0x04, 3},
175     {0x0b, 4}, {0x1a, 5}, {0x78, 7}, {0xf8, 8},
176     {0x3f6, 10}, {0xff82, 16}, {0xff83, 16}, {0x00, 0},
177     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
178     {0x00, 0}, {0x0c, 4}, {0x1b, 5}, {0x79, 7},
179     {0x1f6, 9}, {0x7f6, 11}, {0xff84, 16}, {0xff85, 16},
180     {0xff86, 16}, {0xff87, 16}, {0xff88, 16}, {0x00, 0},
181     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
182     {0x00, 0}, {0x1c, 5}, {0xf9, 8}, {0x3f7, 10},
183     {0xff4, 12}, {0xff89, 16}, {0xff8a, 16}, {0xff8b, 16},
184     {0xff8c, 16}, {0xff8d, 16}, {0xff8e, 16}, {0x00, 0},
185     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
186     {0x00, 0}, {0x3a, 6}, {0x1f7, 9}, {0xff5, 12},
187     {0xff8f, 16}, {0xff90, 16}, {0xff91, 16}, {0xff92, 16},
188     {0xff93, 16}, {0xff94, 16}, {0xff95, 16}, {0x00, 0},
189     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
190     {0x00, 0}, {0x3b, 6}, {0x3f8, 10}, {0xff96, 16},
191     {0xff97, 16}, {0xff98, 16}, {0xff99, 16}, {0xff9a, 16},
192     {0xff9b, 16}, {0xff9c, 16}, {0xff9d, 16}, {0x00, 0},
193     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
194     {0x00, 0}, {0x7a, 7}, {0x7f7, 11}, {0xff9e, 16},
195     {0xff9f, 16}, {0xffa0, 16}, {0xffa1, 16}, {0xffa2, 16},
196     {0xffa3, 16}, {0xffa4, 16}, {0xffa5, 16}, {0x00, 0},
197     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
198     {0x00, 0}, {0x7b, 7}, {0xff6, 12}, {0xffa6, 16},
199     {0xffa7, 16}, {0xffa8, 16}, {0xffa9, 16}, {0xffaa, 16},
200     {0xffab, 16}, {0xffac, 16}, {0xffad, 16}, {0x00, 0},
201     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
202     {0x00, 0}, {0xfa, 8}, {0xff7, 12}, {0xffae, 16},
203     {0xffaf, 16}, {0xffb0, 16}, {0xffb1, 16}, {0xffb2, 16},
204     {0xffb3, 16}, {0xffb4, 16}, {0xffb5, 16}, {0x00, 0},
205     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
206     {0x00, 0}, {0x1f8, 9}, {0x7fc0, 15}, {0xffb6, 16},
207     {0xffb7, 16}, {0xffb8, 16}, {0xffb9, 16}, {0xffba, 16},
208     {0xffbb, 16}, {0xffbc, 16}, {0xffbd, 16}, {0x00, 0},
209     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
210     {0x00, 0}, {0x1f9, 9}, {0xffbe, 16}, {0xffbf, 16},
211     {0xffc0, 16}, {0xffc1, 16}, {0xffc2, 16}, {0xffc3, 16},
212     {0xffc4, 16}, {0xffc5, 16}, {0xffc6, 16}, {0x00, 0},
213     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
214     {0x00, 0}, {0x1fa, 9}, {0xffc7, 16}, {0xffc8, 16},
215     {0xffc9, 16}, {0xffca, 16}, {0xffcb, 16}, {0xffcc, 16},
216     {0xffcd, 16}, {0xffce, 16}, {0xffcf, 16}, {0x00, 0},
217     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
218     {0x00, 0}, {0x3f9, 10}, {0xffd0, 16}, {0xffd1, 16},
219     {0xffd2, 16}, {0xffd3, 16}, {0xffd4, 16}, {0xffd5, 16},
220     {0xffd6, 16}, {0xffd7, 16}, {0xffd8, 16}, {0x00, 0},
221     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
222     {0x00, 0}, {0x3fa, 10}, {0xffd9, 16}, {0xffda, 16},
223     {0xffdb, 16}, {0xffdc, 16}, {0xffdd, 16}, {0xffde, 16},
224     {0xffdf, 16}, {0xffe0, 16}, {0xffe1, 16}, {0x00, 0},
225     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
226     {0x00, 0}, {0x7f8, 11}, {0xffe2, 16}, {0xffe3, 16},
227     {0xffe4, 16}, {0xffe5, 16}, {0xffe6, 16}, {0xffe7, 16},
228     {0xffe8, 16}, {0xffe9, 16}, {0xffea, 16}, {0x00, 0},
229     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
230     {0x00, 0}, {0xffeb, 16}, {0xffec, 16}, {0xffed, 16},
231     {0xffee, 16}, {0xffef, 16}, {0xfff0, 16}, {0xfff1, 16},
232     {0xfff2, 16}, {0xfff3, 16}, {0xfff4, 16}, {0x00, 0},
233     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
234     {0x7f9, 11}, {0xfff5, 16}, {0xfff6, 16}, {0xfff7, 16},
235     {0xfff8, 16}, {0xfff9, 16}, {0xfffa, 16}, {0xfffb, 16},
236     {0xfffc, 16}, {0xfffd, 16}, {0xfffe, 16}, {0x00, 0},
237     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0} };
238 
239 static struct JpegEncoder::huffentry caht[] = {
240     {0x00, 2}, {0x01, 2}, {0x04, 3}, {0x0a, 4},
241     {0x18, 5}, {0x19, 5}, {0x38, 6}, {0x78, 7},
242     {0x1f4, 9}, {0x3f6, 10}, {0xff4, 12}, {0x00, 0},
243     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
244     {0x00, 0}, {0x0b, 4}, {0x39, 6}, {0xf6, 8},
245     {0x1f5, 9}, {0x7f6, 11}, {0xff5, 12}, {0xff88, 16},
246     {0xff89, 16}, {0xff8a, 16}, {0xff8b, 16}, {0x00, 0},
247     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
248     {0x00, 0}, {0x1a, 5}, {0xf7, 8}, {0x3f7, 10},
249     {0xff6, 12}, {0x7fc2, 15}, {0xff8c, 16}, {0xff8d, 16},
250     {0xff8e, 16}, {0xff8f, 16}, {0xff90, 16}, {0x00, 0},
251     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
252     {0x00, 0}, {0x1b, 5}, {0xf8, 8}, {0x3f8, 10},
253     {0xff7, 12}, {0xff91, 16}, {0xff92, 16}, {0xff93, 16},
254     {0xff94, 16}, {0xff95, 16}, {0xff96, 16}, {0x00, 0},
255     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
256     {0x00, 0}, {0x3a, 6}, {0x1f6, 9}, {0xff97, 16},
257     {0xff98, 16}, {0xff99, 16}, {0xff9a, 16}, {0xff9b, 16},
258     {0xff9c, 16}, {0xff9d, 16}, {0xff9e, 16}, {0x00, 0},
259     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
260     {0x00, 0}, {0x3b, 6}, {0x3f9, 10}, {0xff9f, 16},
261     {0xffa0, 16}, {0xffa1, 16}, {0xffa2, 16}, {0xffa3, 16},
262     {0xffa4, 16}, {0xffa5, 16}, {0xffa6, 16}, {0x00, 0},
263     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
264     {0x00, 0}, {0x79, 7}, {0x7f7, 11}, {0xffa7, 16},
265     {0xffa8, 16}, {0xffa9, 16}, {0xffaa, 16}, {0xffab, 16},
266     {0xffac, 16}, {0xffad, 16}, {0xffae, 16}, {0x00, 0},
267     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
268     {0x00, 0}, {0x7a, 7}, {0x7f8, 11}, {0xffaf, 16},
269     {0xffb0, 16}, {0xffb1, 16}, {0xffb2, 16}, {0xffb3, 16},
270     {0xffb4, 16}, {0xffb5, 16}, {0xffb6, 16}, {0x00, 0},
271     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
272     {0x00, 0}, {0xf9, 8}, {0xffb7, 16}, {0xffb8, 16},
273     {0xffb9, 16}, {0xffba, 16}, {0xffbb, 16}, {0xffbc, 16},
274     {0xffbd, 16}, {0xffbe, 16}, {0xffbf, 16}, {0x00, 0},
275     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
276     {0x00, 0}, {0x1f7, 9}, {0xffc0, 16}, {0xffc1, 16},
277     {0xffc2, 16}, {0xffc3, 16}, {0xffc4, 16}, {0xffc5, 16},
278     {0xffc6, 16}, {0xffc7, 16}, {0xffc8, 16}, {0x00, 0},
279     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
280     {0x00, 0}, {0x1f8, 9}, {0xffc9, 16}, {0xffca, 16},
281     {0xffcb, 16}, {0xffcc, 16}, {0xffcd, 16}, {0xffce, 16},
282     {0xffcf, 16}, {0xffd0, 16}, {0xffd1, 16}, {0x00, 0},
283     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
284     {0x00, 0}, {0x1f9, 9}, {0xffd2, 16}, {0xffd3, 16},
285     {0xffd4, 16}, {0xffd5, 16}, {0xffd6, 16}, {0xffd7, 16},
286     {0xffd8, 16}, {0xffd9, 16}, {0xffda, 16}, {0x00, 0},
287     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
288     {0x00, 0}, {0x1fa, 9}, {0xffdb, 16}, {0xffdc, 16},
289     {0xffdd, 16}, {0xffde, 16}, {0xffdf, 16}, {0xffe0, 16},
290     {0xffe1, 16}, {0xffe2, 16}, {0xffe3, 16}, {0x00, 0},
291     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
292     {0x00, 0}, {0x7f9, 11}, {0xffe4, 16}, {0xffe5, 16},
293     {0xffe6, 16}, {0xffe7, 16}, {0xffe8, 16}, {0xffe9, 16},
294     {0xffea, 16}, {0xffeb, 16}, {0xffec, 16}, {0x00, 0},
295     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
296     {0x00, 0}, {0x3fe0, 14}, {0xffed, 16}, {0xffee, 16},
297     {0xffef, 16}, {0xfff0, 16}, {0xfff1, 16}, {0xfff2, 16},
298     {0xfff3, 16}, {0xfff4, 16}, {0xfff5, 16}, {0x00, 0},
299     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
300     {0x3fa, 10}, {0x7fc3, 15}, {0xfff6, 16}, {0xfff7, 16},
301     {0xfff8, 16}, {0xfff9, 16}, {0xfffa, 16}, {0xfffb, 16},
302     {0xfffc, 16}, {0xfffd, 16}, {0xfffe, 16}, {0x00, 0},
303     {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0} };
304 
305 static const char ss[] = {
306     0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
307     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
308     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
309     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
310     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
311     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
312     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
313     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
314     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
315     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
316     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
317     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
318     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
319     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
320     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
321     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
322 
323 
324 
325 //
326 // JpegEncoder
327 //
328 JpegEncoder::JpegEncoder() : EncoderModule(),
329                 bb_(0), nbb_(0), bs_(0), bc_(0), quant_(0),
330                 lpred_(0), crpred_(0), cbpred_(0), nmcu_(0), w_(0), h_(0)
331 {
332         setq(30);
333 }
334 
335 
336 void JpegEncoder::setq(int q)
337 {
338         int lqt[64], cqt[64];
339         quant_ = q;
340 
341         int s = (q>50) ? 200-q*2 : 5000/q;
342         for (int i=0; i<64; i++) {
343                 int v = (stdlqt[i] * s + 50)/ 100;
344                 if (v < 1) {
345                         lqt[i] = 1;
346                 } else if (v > 255) {
347                         lqt[i] = 255;
348                 } else {
349                         lqt[i] = v;
350                 }
351 
352                 v = (stdcqt[i] * s + 50)/ 100;
353                 if (v < 1) {
354                         cqt[i] = 1;
355                 } else if (v > 255) {
356                         cqt[i] = 255;
357                 } else {
358                         cqt[i] = v;
359                 }
360         }
361         fdct_fold_q(lqt, lqt_);
362         fdct_fold_q(cqt, cqt_);
363 }
364 
365 
366 void JpegEncoder::size(int w, int h)
367 {
368         FrameModule::size(w, h);
369         if ((w & 0xf) || (h & 0xf)) {
370                 fprintf(stderr, "JpegEncoder: bad geometry: %dx%d\n", w, h);
371                 exit(1);
372         }
373         w_ = w>>3;
374         h_ = h>>3;
375         nmcu_ = (w_>>1) * h_;
376 }
377 
378 
379 int JpegEncoder::command(int argc, const char*const* argv)
380 {
381         // let the encoder choose the color-subsampling scheme
382         if (argc == 2 && strcmp(argv[1], "frame-format") == 0) {
383                 Tcl& tcl = Tcl::instance();
384                 tcl.result("422");
385                 return (TCL_OK);
386         }
387 
388         if (argc == 3 && strcmp(argv[1], "q") == 0) {
389                 setq(atoi(argv[2]));
390                 return (TCL_OK);
391         }
392         return (EncoderModule::command(argc, argv));
393 }
394 
395 
396 void JpegEncoder::recv(Buffer* bp)
397 {
398         YuvFrame* vf = (YuvFrame*)bp;
399         if (!samesize(vf)) {
400                 size(vf->width_, vf->height_);
401         }
402 
403         encode(vf);
404 }
405 
406 
407 //
408 //      JpegEncoder::flush
409 //
410 // Description: This method prepares the format-specific RTP header and 
411 //      sends it to PacketModule::recv() in order to be sent
412 //
413 int JpegEncoder::flush(pktbuf* pb, int nbit, pktbuf* npb)
414 {
415         u_char* obc = bc_;
416 
417         /* flush bit buffer */
418         STORE_BITS(bb_, bc_);
419 
420         int cc = (nbit + 7) >> 3;
421 
422         /*FIXME*/
423         if ((cc == 0) && (npb != 0)) {
424                 abort();
425         }
426 
427         pb->len = cc + HDRSIZE;
428         rtphdr* rh = (rtphdr*)pb->data;
429         if (npb == 0) {
430                 rh->rh_flags |= htons(RTP_M);
431         }
432 
433         if (npb != 0) {
434                 u_char* nbs = &npb->data[HDRSIZE];
435                 int extra = obc - (bs_ + (nbit >> 3));
436                 if (extra > 0) {
437                         memcpy(nbs, bs_ + (nbit >> 3), extra);
438                 }
439                 bs_ = nbs;
440                 bc_ = nbs + extra;
441         }
442 
443         // do send the packet
444         pb->attach();
445         target_->recv(pb);
446 
447         Module * target;
448         target = target_list_->first_;
449         while (target != NULL) {
450             pb->attach();
451             target->recv(pb);
452             target = target->next();
453         }
454         pb->release();
455 
456         return (cc + HDRSIZE);
457 }
458 
459 #define SSSS(n) (((n)&~0xff) ? (8+ss[(n)>>8]) : ss[n])
460 
461 
462 void JpegEncoder::encode_blk(const short* blk, short* dcpred,
463                 struct huffentry* dcht, struct huffentry* acht)
464 {
465         BB_INT bb = bb_;
466         u_int nbb = nbb_;
467         u_char* bc = bc_;
468 
469         /* code dc */
470         short diff = blk[0] - *dcpred;
471         *dcpred = blk[0];
472 
473         u_char len;
474 
475         if (diff < 0){
476                 len = SSSS(-diff);
477                 huffentry e = dcht[len];
478                 PUT_BITS(e.val, e.nb, nbb, bb, bc);
479                 PUT_BITS((diff-1)&(~(-1<<len)), len, nbb, bb, bc);
480         } else {
481                 len = SSSS(diff);
482                 huffentry e = dcht[len];
483                 PUT_BITS(e.val, e.nb, nbb, bb, bc);
484                 PUT_BITS(diff, len, nbb, bb, bc);
485         }
486 
487         /* code ac terms */
488         int run = 0;
489         const u_char* colzag = &COLZAG[0];
490         for (int zag; (zag = *++colzag) != 0; ) {
491                 int level = blk[zag];
492                 if (level != 0) {
493                         if (level < 0) {
494                                 len = SSSS(-level);
495                                 while (run & ~0xf) {
496                                         huffentry e = acht[0xf0];
497                                         PUT_BITS(e.val, e.nb, nbb, bb, bc);
498                                         run -= 16;
499                                 }
500                                 huffentry e = acht[(run<<4) | len];
501                                 PUT_BITS(e.val, e.nb, nbb, bb, bc);
502                                 PUT_BITS((level-1)&(~(-1<<len)), len, nbb, bb, bc);
503                         } else {
504                                 len = SSSS(level);
505                                 while (run & ~0xf) {
506                                         huffentry e = acht[0xf0];
507                                         PUT_BITS(e.val, e.nb, nbb, bb, bc);
508                                         run -= 16;
509                                 }
510                                 huffentry e = acht[(run<<4) | len];
511                                 PUT_BITS(e.val, e.nb, nbb, bb, bc);
512                                 PUT_BITS(level, len, nbb, bb, bc);
513                         }
514                         run = 0;
515                 } else {
516                         run++;
517                 }
518         }
519 
520         if (run > 0) {
521                 /* EOB */
522                 huffentry e = acht[0];
523                 PUT_BITS(e.val, e.nb, nbb, bb, bc);
524         }
525 
526         bb_ = bb;
527         nbb_ = nbb;
528         bc_ = bc;
529 }
530 
531 
532 void JpegEncoder::encode_mcu(u_int mcu, const u_char* frm)
533 {
534         short blk[64];
535         register int stride = w_ << 3;
536 
537         u_char mx = mcu % (w_ >> 1);
538         u_char my = mcu / (w_ >> 1);
539 
540         /* luminance */
541         const u_char* p = &frm[8*stride*my + 16*mx];
542         fdct(p, stride, blk, lqt_);
543         encode_blk(blk, &lpred_, ldht, laht);
544 
545         p += 8;
546         fdct(p, stride, blk, lqt_);
547         encode_blk(blk, &lpred_, ldht, laht);
548 
549         /* chrominance */
550         stride >>= 1;
551         int fs = framesize_;
552         p = &frm[fs + 8*stride*my + 8*mx];
553         fdct(p, stride, blk, cqt_);
554         encode_blk(blk, &crpred_, cdht, caht);
555 
556         p += (fs>>1);
557         fdct(p, stride, blk, cqt_);
558         encode_blk(blk, &cbpred_, cdht, caht);
559 }
560 
561 
562 int JpegEncoder::encode(const VideoFrame* vf)
563 {
564         if (!pool_) {
565             printf("WARNING no buffer pool installed for encoder");
566             return 0;
567         }
568         pktbuf* pb = pool_->alloc(vf->ts_, RTP_PT_JPEG);
569         bs_ = &pb->data[HDRSIZE];
570         bc_ = bs_;
571         int fragsize = mtu_ - HDRSIZE;
572 
573         bb_ = 0;
574         nbb_ = 0;
575         lpred_ = 0;
576         crpred_ = 0;
577         cbpred_ = 0;
578         u_int offset = 0;
579         
580         /* RTP/JPEG header */
581         rtphdr* rh = (rtphdr*)pb->data;
582         u_int* h = (u_int*)(rh+1);
583         h[0] = htonl(offset);
584         h[1] = htonl(quant_ << 16 | w_ << 8 | h_);
585 
586         int cc = 0;
587 
588         u_int8_t* frm = vf->bp_;
589         for (u_int mcu = 0; mcu < nmcu_; mcu++) {
590                 encode_mcu(mcu, frm);
591                 int cbytes = bc_ - bs_;
592                 if (cbytes > fragsize) {
593                         pktbuf* npb = pool_->alloc(vf->ts_, RTP_PT_JPEG);
594                         cc += flush(pb, fragsize<<3, npb);
595                         offset += fragsize;
596                         pb = npb;
597 
598                         /* RTP/JPEG header */
599                         rh = (rtphdr*)pb->data;
600                         u_int* h = (u_int*)(rh+1);
601                         h[0] = htonl(offset);
602                         h[1] = htonl(quant_ << 16 | w_ << 8 | h_);
603                 }
604         }
605 
606         cc += flush(pb, ((bc_ - bs_)<<3) + nbb_, 0);
607         return (cc);
608 }
609 
610 
611 /*
612  * fdct() from dct.cc slightly modified to fold in the jpeg 128 bias.
613  */
614 #define FA1 (0.707106781f)
615 #define FA2 (0.541196100f)
616 #define FA3 FA1
617 #define FA4 (1.306562965f)
618 #define FA5 (0.382683433f)
619 #define FWD_DandQ(v, iq) short((v) * qt[iq] + 0.5)
620 
621 
622 void JpegEncoder::fdct(const u_char* in, int stride, short* out, 
623                 const float* qt)
624 {
625         float tmp[64];
626         float* tp = tmp;
627 
628         int i;
629         for (i = 8; --i >= 0; ) {
630                 float x0, x1, x2, x3, t0, t1, t2, t3, t4, t5, t6, t7;
631                 t0 = float(in[0] + in[7] - 256);
632                 t7 = float(in[0] - in[7]);
633                 t1 = float(in[1] + in[6] - 256);
634                 t6 = float(in[1] - in[6]);
635                 t2 = float(in[2] + in[5] - 256);
636                 t5 = float(in[2] - in[5]);
637                 t3 = float(in[3] + in[4] - 256);
638                 t4 = float(in[3] - in[4]);
639 
640                 /* even part */
641                 x0 = t0 + t3;
642                 x2 = t1 + t2;
643                 tp[8*0] = x0 + x2;
644                 tp[8*4] = x0 - x2;
645 
646                 x1 = t0 - t3;
647                 x3 = t1 - t2;
648                 t0 = (x1 + x3) * FA1;
649                 tp[8*2] = x1 + t0;
650                 tp[8*6] = x1 - t0;
651 
652                 /* odd part */
653                 x0 = t4 + t5;
654                 x1 = t5 + t6;
655                 x2 = t6 + t7;
656 
657                 t3 = x1 * FA1;
658                 t4 = t7 - t3;
659 
660                 t0 = (x0 - x2) * FA5;
661                 t1 = x0 * FA2 + t0;
662                 tp[8*3] = t4 - t1;
663                 tp[8*5] = t4 + t1;
664 
665                 t7 += t3;
666                 t2 = x2 * FA4 + t0;
667                 tp[8*1] = t7 + t2;
668                 tp[8*7] = t7 - t2;
669 
670                 in += stride;
671                 tp += 1;
672         }
673         tp -= 8;
674 
675         for (i = 8; --i >= 0; ) {
676                 float x0, x1, x2, x3, t0, t1, t2, t3, t4, t5, t6, t7;
677                 t0 = tp[0] + tp[7];
678                 t7 = tp[0] - tp[7];
679                 t1 = tp[1] + tp[6];
680                 t6 = tp[1] - tp[6];
681                 t2 = tp[2] + tp[5];
682                 t5 = tp[2] - tp[5];
683                 t3 = tp[3] + tp[4];
684                 t4 = tp[3] - tp[4];
685 
686                 /* even part */
687                 x0 = t0 + t3;
688                 x2 = t1 + t2;
689                 out[0] = FWD_DandQ(x0 + x2, 0);
690                 out[4] = FWD_DandQ(x0 - x2, 4);
691 
692                 x1 = t0 - t3;
693                 x3 = t1 - t2;
694                 t0 = (x1 + x3) * FA1;
695                 out[2] = FWD_DandQ(x1 + t0, 2);
696                 out[6] = FWD_DandQ(x1 - t0, 6);
697 
698                 /* odd part */
699                 x0 = t4 + t5;
700                 x1 = t5 + t6;
701                 x2 = t6 + t7;
702 
703                 t3 = x1 * FA1;
704                 t4 = t7 - t3;
705 
706                 t0 = (x0 - x2) * FA5;
707                 t1 = x0 * FA2 + t0;
708                 out[3] = FWD_DandQ(t4 - t1, 3);
709                 out[5] = FWD_DandQ(t4 + t1, 5);
710 
711                 t7 += t3;
712                 t2 = x2 * FA4 + t0;
713                 out[1] = FWD_DandQ(t7 + t2, 1);
714                 out[7] = FWD_DandQ(t7 - t2, 7);
715 
716                 out += 8;
717                 tp += 8;
718                 qt += 8;
719         }
720 }
721 
722 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.