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

Open Mash Cross Reference
mash/codec/video/transcoder-nv.cc

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

  1 /*
  2  * transcoder-nv.cc --
  3  *
  4  *      Netvideo Transcoder
  5  */
  6 
  7 /*
  8  * This module was originally derived from:
  9  *
 10  * Netvideo version 3.2
 11  * Written by Ron Frederick <frederick@parc.xerox.com>
 12  *
 13  * Video decode routines
 14  *
 15  * Copyright (c) Xerox Corporation 1992. All rights reserved.
 16  *
 17  * License is granted to copy, to use, and to make and to use derivative
 18  * works for research and evaluation purposes, provided that Xerox is
 19  * acknowledged in all documentation pertaining to any such copy or derivative
 20  * work. Xerox grants no other licenses expressed or implied. The Xerox trade
 21  * name should not be used in any advertising without its written permission.
 22  *
 23  * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
 24  * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
 25  * FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
 26  * express or implied warranty of any kind.
 27  *
 28  * These notices must be retained in any copies of any part of this software.
 29  */
 30 
 31 static const char rcsid[] =
 32     "@(#) $Header: /usr/mash/src/repository/mash/mash-1/codec/video/transcoder-nv.cc,v 1.7 2002/03/16 02:56:43 chema Exp $";
 33 
 34 #include <stdio.h>
 35 #include <string.h>
 36 #include <sys/param.h>
 37 #include "config.h"
 38 #include "inet.h"
 39 #include "rtp.h"
 40 #include "transcoder.h"
 41 #include "transmitter.h"
 42 #include "encoder.h"
 43 #include "crdef.h"
 44 
 45 #ifdef INFOPAD
 46 #include "encoder-ipadvq.h"
 47 #include "ipadchan.h"
 48 #endif /* INFOPAD */
 49 
 50 class NvTranscoder : public VideoTranscoder {
 51 public:
 52         NvTranscoder();
 53         int recv(const rtphdr* rh, const u_char* bp, int cc, Transmitter& tx);
 54 protected:
 55         void process_hdr(const nvhdr*);
 56         virtual void configure();
 57         void info(char* wrk) const;
 58         const u_char* decode_run(const u_char* data, const u_char* end,
 59                                  int color, int mark);
 60         void VidTransform_Rev(u_int* inp, u_char* yp, char* up, char* vp,
 61                               int width);
 62         void NVDCT_RevTransform(u_int* inp, u_char *yp,
 63                                 char* up, char* vp, int width);
 64         int compute_margins(void);
 65         struct margin {
 66                 int top;
 67                 int right;
 68                 int left;
 69         } margin_;
 70         int rcrop_;
 71         int lcrop_;
 72         int topcrop_;
 73         int botcrop_;
 74 
 75         int outw_;
 76         int outh_;
 77         int use_dct_;
 78         u_char* frm_;
 79         int color_;
 80 };
 81 
 82 static class NvTranscoderMatcher : public Matcher {
 83 public:
 84         NvTranscoderMatcher() : Matcher("transcoder") {}
 85         TclObject* match(const char* id) {
 86                 if (strcmp(id, "nv") == 0)
 87                         return (new NvTranscoder());
 88                 return (0);
 89         }
 90 } nv_transcoder_matcher;
 91 
 92 NvTranscoder::NvTranscoder()
 93              :VideoTranscoder(sizeof(nvhdr)), use_dct_(0), frm_(0), color_(1)
 94 {}
 95 
 96 void NvTranscoder::configure()
 97 {
 98         if (compute_margins() != 0)
 99                 fprintf(stderr, "NvTranscoder: Couldn't compute margins.\n");
100         delete frm_;
101         int size = outw_ * outh_ * 2;
102         frm_ = new u_char[size];
103         memset(frm_, 0x80, size);
104         crinit(outw_, outh_);
105 }
106 
107 int NvTranscoder::compute_margins()
108 {
109         /*
110          * Embed one image size in a bigger one.
111          * (extra areas will already be gray from init() )
112          */
113         margin& m = margin_;
114         m.top = m.left = m.right = 0;
115         lcrop_ = 0;
116         rcrop_ = inw_ >> 3;
117         topcrop_ = 0;
118         botcrop_ = inh_ >> 3;
119 
120         int dx = outw_ - inw_;
121         int dy = outh_ - inh_;
122 
123         /*
124          * If output size is smaller that intput, crop input image to fit
125          * output size, otherwise try and center the image in the larger
126          * frame, making sure to align on macroblock (16x16) boundaries.
127          */
128         if (dx < 0) {
129                 dx = -dx;
130                 /* Bail if can't align on block boundary. */
131                 if (dx % 8 != 0)
132                         return (-1);
133 
134                 int q = dx / 16;
135                 if (q % 2 != 0)
136                         /* Can't center crop horizontally */
137                         lcrop_ = (dx - 16) / 2;
138                 else
139                         /* Center crop horizontally */
140                         lcrop_ = dx / 2;
141 
142                 lcrop_ >>= 3;
143                 rcrop_ -= lcrop_;
144         } else {
145                 if (dx % 8 != 0)
146                         return (-1);
147 
148                 /* Know dx is multiple of 8 at least */
149                 if (dx % 16 == 8) {
150                         /* crop one block and bias dx */
151                         rcrop_--;
152                         dx -= 8;
153                 }
154 
155                 int q = dx / 16;
156                 if (q % 2 != 0) {
157                         /* Can't center horizontally */
158                         m.right = ((dx - 16) / 2) >> 3;
159                         m.left = ((dx + 16) / 2) >> 3;
160                 } else
161                         /* Center horizontally */
162                         m.right = m.left = (dx / 2) >> 3;
163         }
164 
165         if (dy < 0) {
166                 dy = -dy;
167                 /* Bail if can't align on block boundary. */
168                 if (dy % 8 != 0)
169                         return (-1);
170                 int q = dy / 16;
171                 if (q % 2 != 0)
172                         /* Can't center crop vertically */
173                         topcrop_ = (dy - 16) / 2;
174                 else
175                         /* Center crop vertically */
176                         topcrop_ = dy / 2;
177                 topcrop_ >>= 3;
178                 botcrop_ -= topcrop_;
179         } else {
180                 /* Bail if can't align on block boundary. */
181                 if (dy % 8 != 0)
182                         return (-1);
183 
184                 /* Know dy is multiple of 8 at least */
185                 if (dy % 16 == 8) {
186                         /* crop one block and bias dy */
187                         botcrop_--;
188                         dy -= 8;
189                 }
190 
191                 int q = dy / 16;
192                 if (q % 2 != 0)
193                         /* Can't center vertically */
194                         m.top = ((dy - 16) / 2) >> 3;
195                 else
196                         /* Center vertically */
197                         m.top = (dy / 2) >> 3;
198         }
199         return (0);
200 }
201 
202 void NvTranscoder::info(char* wrk) const
203 {
204         strcpy(wrk, use_dct_ ? "[dct]" : "[haar]");
205 }
206 
207 /* Sick little macro which will limit x to [0..255] with logical ops */
208 #define UCLIMIT(x) ((t = (x)), (t &= ~(t>>31)), (t | ~((t-256) >> 31)))
209 /* A variant of above which will limit x to [-128..127] */
210 #define SCLIMIT(x) (UCLIMIT((x)+128)-128)
211 
212 void NvTranscoder::VidTransform_Rev(u_int* inp, u_char *yp,
213                                  char* up, char* vp, int width)
214 {
215     register int i, t, t0, t1, t2, t3, t4, t5, *dataptr;
216     register int width2=2*width, width6=6*width;
217     register signed char *inpcptr=(signed char *)inp;
218     static int block[64];
219 #define SIGN_EXTEND(c) c
220 
221     dataptr = block;
222     for (i=0; i<8; i++) {
223         if ((inp[0] << 8) == 0) {
224             t2 = t3 = t4 = t5 = SIGN_EXTEND(inpcptr[0]);
225         } else {
226             t4 = SIGN_EXTEND(inpcptr[0]);
227             t5 = SIGN_EXTEND(inpcptr[1]);
228             t0 = t4 - t5;
229             t1 = t4 + t5;
230 
231             t4 = SIGN_EXTEND(inpcptr[2]);
232             t5 = SIGN_EXTEND(inpcptr[3]);
233             t2 = t0 - t4;
234             t3 = t0 + t4;
235             t4 = t1 - t5;
236             t5 = t1 + t5;
237         }
238 
239         if (inp[1] == 0) {
240             dataptr[0] = dataptr[1] = t2;
241             dataptr[2] = dataptr[3] = t3;
242             dataptr[4] = dataptr[5] = t4;
243             dataptr[6] = dataptr[7] = t5;
244         } else {
245             t0 = SIGN_EXTEND(inpcptr[4]);
246             t1 = SIGN_EXTEND(inpcptr[5]);
247             dataptr[0] = t2 - t0;
248             dataptr[1] = t2 + t0;
249             dataptr[2] = t3 - t1;
250             dataptr[3] = t3 + t1;
251 
252             t0 = SIGN_EXTEND(inpcptr[6]);
253             t1 = SIGN_EXTEND(inpcptr[7]);
254             dataptr[4] = t4 - t0;
255             dataptr[5] = t4 + t0;
256             dataptr[6] = t5 - t1;
257             dataptr[7] = t5 + t1;
258         }
259 
260         inp += 2;
261         inpcptr += 8;
262         dataptr += 8;
263     }
264 
265     dataptr = block;
266     for (i=0; i<8; i++) {
267         t4 = dataptr[0] + 128; /* Add back DC offset */
268         t5 = dataptr[8];
269         t0 = t4 - t5;
270         t1 = t4 + t5;
271 
272         t4 = dataptr[16];
273         t5 = dataptr[24];
274         t2 = t0 - t4;
275         t3 = t0 + t4;
276         t4 = t1 - t5;
277         t5 = t1 + t5;
278 
279         t0 = dataptr[32];
280         t1 = dataptr[40];
281         yp[0] = UCLIMIT(t2 - t0);
282         yp[width] = UCLIMIT(t2 + t0);
283         yp += width2;
284         yp[0] = UCLIMIT(t3 - t1);
285         yp[width] = UCLIMIT(t3 + t1);
286         yp += width2;
287 
288         t0 = dataptr[48];
289         t1 = dataptr[56];
290         yp[0] = UCLIMIT(t4 - t0);
291         yp[width] = UCLIMIT(t4 + t0);
292         yp += width2;
293         yp[0] = UCLIMIT(t5 - t1);
294         yp[width] = UCLIMIT(t5 + t1);
295         yp -= width6;
296 
297         yp++;
298         dataptr++;
299     }
300 
301     if (up) {
302         int uswitch = 1;
303         signed char* p = (signed char*)up++;
304         dataptr = block;
305         for (i=0; i<8; i++) {
306             if ((inp[0] << 16) == 0) {
307                 t2 = t3 = SIGN_EXTEND(inpcptr[0]);
308                 t4 = t5 = SIGN_EXTEND(inpcptr[1]);
309             } else {
310                 t0 = SIGN_EXTEND(inpcptr[0]);
311                 t1 = SIGN_EXTEND(inpcptr[1]);
312 
313                 t4 = SIGN_EXTEND(inpcptr[2]);
314                 t5 = SIGN_EXTEND(inpcptr[3]);
315                 t2 = t0 - t4;
316                 t3 = t0 + t4;
317                 t4 = t1 - t5;
318                 t5 = t1 + t5;
319             }
320 
321             if (inp[1] == 0) {
322                 dataptr[0] = dataptr[2] = t2;
323                 dataptr[4] = dataptr[6] = t3;
324                 dataptr[1] = dataptr[3] = t4;
325                 dataptr[5] = dataptr[7] = t5;
326             } else {
327                 t0 = SIGN_EXTEND(inpcptr[4]);
328                 t1 = SIGN_EXTEND(inpcptr[5]);
329                 dataptr[0] = t2 - t0;
330                 dataptr[2] = t2 + t0;
331                 dataptr[4] = t3 - t1;
332                 dataptr[6] = t3 + t1;
333 
334                 t0 = SIGN_EXTEND(inpcptr[6]);
335                 t1 = SIGN_EXTEND(inpcptr[7]);
336                 dataptr[1] = t4 - t0;
337                 dataptr[3] = t4 + t0;
338                 dataptr[5] = t5 - t1;
339                 dataptr[7] = t5 + t1;
340             }
341 
342             inp += 2;
343             inpcptr += 8;
344             dataptr += 8;
345         }
346 
347         dataptr = block;
348         for (i=0; i<8; i++) {
349             t4 = dataptr[0];
350             t5 = dataptr[8];
351             t0 = t4 - t5;
352             t1 = t4 + t5;
353 
354             t4 = dataptr[16];
355             t5 = dataptr[24];
356             t2 = t0 - t4;
357             t3 = t0 + t4;
358             t4 = t1 - t5;
359             t5 = t1 + t5;
360 
361             t0 = dataptr[32];
362             t1 = dataptr[40];
363 
364             *p = SCLIMIT(t2 - t0) + 0x80;
365             p += width / 2;
366             *p = SCLIMIT(t2 + t0) + 0x80;
367             p += width / 2;
368             *p = SCLIMIT(t3 - t1) + 0x80;
369             p += width / 2;
370             *p = SCLIMIT(t3 + t1) + 0x80;
371             p += width / 2;
372 
373             t0 = dataptr[48];
374             t1 = dataptr[56];
375             *p = SCLIMIT(t4 - t0) + 0x80;
376             p += width / 2;
377             *p = SCLIMIT(t4 + t0) + 0x80;
378             p += width / 2;
379             *p = SCLIMIT(t5 - t1) + 0x80;
380             p += width / 2;
381             *p = SCLIMIT(t5 + t1) + 0x80;
382             p += width / 2;
383 
384             if (uswitch) {
385                     uswitch = 0;
386                     p = (signed char*)vp++;
387             } else {
388                     uswitch = 1;
389                     p = (signed char*)up++;
390             }
391             dataptr++;
392         }
393     }
394 }
395 
396 void NvTranscoder::NVDCT_RevTransform(u_int* inp, u_char *yp,
397                                    char* up, char* vp, int width)
398 {
399     int i, t, *dataptr;
400     int a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3;
401     int8_t *inpcptr=(int8_t *)inp;
402     static int block[64];
403 
404     dataptr = block;
405     for (i=0; i<8; i++) {
406         if ((inp[0]|inp[1]) == 0) {
407             dataptr[0] = dataptr[1] = dataptr[2] = dataptr[3] =
408                 dataptr[4] = dataptr[5] = dataptr[6] = dataptr[7] = 0;
409         } else {
410             b0 = inpcptr[0] << 4;
411             b1 = inpcptr[4] << 4;
412             b2 = inpcptr[2] << 4;
413             b3 = inpcptr[6] << 4;
414 
415             a0 = (362 * (b0+b1)) >> 9;
416             a1 = (362 * (b0-b1)) >> 9;
417             a2 = (196*b2 - 473*b3) >> 9;
418             a3 = (473*b2 + 196*b3) >> 9;
419 
420             b0 = a0+a3;
421             b1 = a1+a2;
422             b2 = a1-a2;
423             b3 = a0-a3;
424 
425             a0 = inpcptr[1] << 4;
426             a1 = inpcptr[3] << 4;
427             a2 = inpcptr[5] << 4;
428             a3 = inpcptr[7] << 4;
429 
430             c0 = (100*a0 - 502*a3) >> 9;
431             c1 = (426*a2 - 284*a1) >> 9;
432             c2 = (426*a1 + 284*a2) >> 9;
433             c3 = (502*a0 + 100*a3) >> 9;
434 
435             a0 = c0+c1;
436             a1 = c0-c1;
437             a2 = c3-c2;
438             a3 = c3+c2;
439 
440             c0 = a0;
441             c1 = (362 * (a2-a1)) >> 9;
442             c2 = (362 * (a1+a2)) >> 9;
443             c3 = a3;
444 
445             dataptr[0] = b0+c3;
446             dataptr[1] = b1+c2;
447             dataptr[2] = b2+c1;
448             dataptr[3] = b3+c0;
449             dataptr[4] = b3-c0;
450             dataptr[5] = b2-c1;
451             dataptr[6] = b1-c2;
452             dataptr[7] = b0-c3;
453         }
454 
455         inp += 2;
456         inpcptr += 8;
457         dataptr += 8;
458     }
459 
460     dataptr = block;
461     for (i=0; i<8; i++) {
462         b0 = dataptr[0]+1448; /* Add back DC offset */
463         b1 = dataptr[32];
464         b2 = dataptr[16];
465         b3 = dataptr[48];
466 
467         a0 = (362 * (b0+b1)) >> 9;
468         a1 = (362 * (b0-b1)) >> 9;
469         a2 = (196*b2 - 473*b3) >> 9;
470         a3 = (473*b2 + 196*b3) >> 9;
471 
472         b0 = a0+a3;
473         b1 = a1+a2;
474         b2 = a1-a2;
475         b3 = a0-a3;
476 
477         a0 = dataptr[8];
478         a1 = dataptr[24];
479         a2 = dataptr[40];
480         a3 = dataptr[56];
481 
482         c0 = (100*a0 - 502*a3) >> 9;
483         c1 = (426*a2 - 284*a1) >> 9;
484         c2 = (426*a1 + 284*a2) >> 9;
485         c3 = (502*a0 + 100*a3) >> 9;
486 
487         a0 = c0+c1;
488         a1 = c0-c1;
489         a2 = c3-c2;
490         a3 = c3+c2;
491 
492         c0 = a0;
493         c1 = (362 * (a2-a1)) >> 9;
494         c2 = (362 * (a2+a1)) >> 9;
495         c3 = a3;
496 
497         yp[0]     = UCLIMIT((b0+c3+4) >> 3);
498         yp[width] = UCLIMIT((b1+c2+4) >> 3);
499         yp += 2*width;
500 
501         yp[0]     = UCLIMIT((b2+c1+4) >> 3);
502         yp[width] = UCLIMIT((b3+c0+4) >> 3);
503         yp += 2*width;
504 
505         yp[0]     = UCLIMIT((b3-c0+4) >> 3);
506         yp[width] = UCLIMIT((b2-c1+4) >> 3);
507         yp += 2*width;
508 
509         yp[0]     = UCLIMIT((b1-c2+4) >> 3);
510         yp[width] = UCLIMIT((b0-c3+4) >> 3);
511         yp -= 6*width;
512 
513         yp++;
514         dataptr++;
515     }
516 
517     if (up) {
518         u_int8_t uvblk[64];
519         u_int8_t* uvp = uvblk;
520 #define width 8
521         dataptr = block;
522         for (i=0; i<8; i++) {
523             if ((inp[0]|inp[1]) == 0) {
524                 dataptr[0] = dataptr[1] = dataptr[2] = dataptr[3] =
525                     dataptr[4] = dataptr[5] = dataptr[6] = dataptr[7] = 0;
526             } else {
527                 b0 = inpcptr[0] << 4;
528                 b2 = inpcptr[2] << 4;
529                 b1 = inpcptr[4] << 4;
530                 b3 = inpcptr[6] << 4;
531 
532                 a0 = (362 * (b0+b1)) >> 9;
533                 a1 = (362 * (b0-b1)) >> 9;
534                 a2 = (196*b2 - 473*b3) >> 9;
535                 a3 = (473*b2 + 196*b3) >> 9;
536 
537                 dataptr[0] = a0+a3;
538                 dataptr[2] = a1+a2;
539                 dataptr[4] = a1-a2;
540                 dataptr[6] = a0-a3;
541 
542                 b0 = inpcptr[1] << 4;
543                 b2 = inpcptr[3] << 4;
544                 b1 = inpcptr[5] << 4;
545                 b3 = inpcptr[7] << 4;
546 
547                 a0 = (362 * (b0+b1)) >> 9;
548                 a1 = (362 * (b0-b1)) >> 9;
549                 a2 = (196*b2 - 473*b3) >> 9;
550                 a3 = (473*b2 + 196*b3) >> 9;
551 
552                 dataptr[1] = a0+a3;
553                 dataptr[3] = a1+a2;
554                 dataptr[5] = a1-a2;
555                 dataptr[7] = a0-a3;
556             }
557 
558             inp += 2;
559             inpcptr += 8;
560             dataptr += 8;
561         }
562 
563         dataptr = block;
564         for (i=0; i<8; i++) {
565             b0 = dataptr[0];
566             b1 = dataptr[32];
567             b2 = dataptr[16];
568             b3 = dataptr[48];
569 
570             a0 = (362 * (b0+b1)) >> 9;
571             a1 = (362 * (b0-b1)) >> 9;
572             a2 = (196*b2 - 473*b3) >> 9;
573             a3 = (473*b2 + 196*b3) >> 9;
574 
575             b0 = a0+a3;
576             b1 = a1+a2;
577             b2 = a1-a2;
578             b3 = a0-a3;
579 
580             a0 = dataptr[8];
581             a1 = dataptr[24];
582             a2 = dataptr[40];
583             a3 = dataptr[56];
584 
585             c0 = (100*a0 - 502*a3) >> 9;
586             c1 = (426*a2 - 284*a1) >> 9;
587             c2 = (426*a1 + 284*a2) >> 9;
588             c3 = (502*a0 + 100*a3) >> 9;
589 
590             a0 = c0+c1;
591             a1 = c0-c1;
592             a2 = c3-c2;
593             a3 = c3+c2;
594 
595             c0 = a0;
596             c1 = (362 * (a2-a1)) >> 9;
597             c2 = (362 * (a2+a1)) >> 9;
598             c3 = a3;
599 
600             uvp[0]     = SCLIMIT((b0+c3+4) >> 3);
601             uvp[width] = SCLIMIT((b1+c2+4) >> 3);
602             uvp += 2*width;
603 
604             uvp[0]     = SCLIMIT((b2+c1+4) >> 3);
605             uvp[width] = SCLIMIT((b3+c0+4) >> 3);
606             uvp += 2*width;
607 
608             uvp[0]     = SCLIMIT((b3-c0+4) >> 3);
609             uvp[width] = SCLIMIT((b2-c1+4) >> 3);
610             uvp += 2*width;
611 
612             uvp[0]     = SCLIMIT((b1-c2+4) >> 3);
613             uvp[width] = SCLIMIT((b0-c3+4) >> 3);
614             uvp -= 6*width;
615 
616             uvp++;
617             dataptr++;
618         }
619 #undef width
620         uvp = uvblk;
621         for (i = 0; i < 8; ++i) {
622                 up[0] = uvp[0] + 0x80;
623                 vp[0] = uvp[1] + 0x80;
624                 up[1] = uvp[2] + 0x80;
625                 vp[1] = uvp[3] + 0x80;
626                 up[2] = uvp[4] + 0x80;
627                 vp[2] = uvp[5] + 0x80;
628                 up[3] = uvp[6] + 0x80;
629                 vp[3] = uvp[7] + 0x80;
630                 up += width >> 1;
631                 vp += width >> 1;
632                 uvp += 8;
633         }
634     }
635 }
636 
637 #define VIDCODE_COLORFLAG 0x8000
638 #define VIDCODE_WIDTHMASK 0x0fff
639 
640 const u_char* NvTranscoder::decode_run(const u_char* data, const u_char* end,
641                                     int color, int mark)
642 {
643         if (end - data < 3)
644                 return (end);
645 
646         int w0, w;
647         w0 = w = *data++;
648         int x0 = *data++;
649         int y0 = *data++;
650 
651         margin& m = margin_;
652         if ((x0+w > inw_/8) || (y0 >= inh_/8))
653                 return (end);
654 
655         /* Remember original coords */
656         int y = y0;
657         int x = x0;
658 
659         /* Skip margins */
660         y0 += m.top;
661         x0 += m.left;
662 
663         /* Adjust for crops */
664         y0 -= topcrop_;
665         x0 -= lcrop_;
666 
667         int offset = y0 * outw_;
668 #ifdef notdef
669         u_char* ts = &rvts_[(offset >> 3) + x0];
670 #endif
671         u_char* crv = &crvec_[(offset >> 3) + x0];
672 
673         offset = (offset << 3) + (x0 << 3);
674         u_char* yp = &frm_[offset];
675         int s = outw_ * outh_;/* FIXME */
676         u_char* up = frm_ + s + (offset >> 1);
677         u_char* vp = up + (s >> 1);
678         while (w-- > 0) {
679                 if (data >= end) {
680                         return (end);
681                 }
682                 static u_int block[32];
683                 int lim=color? 128 : 64;
684                 for (int i=0; i<lim; ) {
685                         int run = *data++;
686                         int j = run >> 6;
687                         int k = run & 0x3f;
688                         if (i+j+k > lim) {
689                                 return (end);
690                         }
691                         char* blkp = (char*)block;
692                         while (j--) blkp[i++] = (char) *data++;
693                         while (k--) blkp[i++] = 0;
694                 }
695                 if (y >= topcrop_ && y < botcrop_ && x >= lcrop_ &&
696                     x < rcrop_) {
697                         if (use_dct_)
698                                 NVDCT_RevTransform(block, yp, (char*)up,
699                                                    (char*)vp, outw_);
700                         else
701                                 VidTransform_Rev(block, yp, (char*)up,
702                                                  (char*)vp, outw_);
703                         *crv = mark;
704                 }
705 
706                 crv += 1;
707                 yp += 8;
708                 x++;
709                 if (up) {
710                         up += 4;
711                         vp += 4;
712                 }
713 #ifdef notdef
714                 *ts++ = now_;
715 #endif
716         }
717         return (data);
718 }
719 
720 void NvTranscoder::process_hdr(const nvhdr* ph)
721 {
722         int reconfig = 0;
723 
724         int h = ntohs(ph->height);
725         int w = ntohs(ph->width);
726         color_ = w >> 15;
727         w &= 0xfff;
728         int fmt = h >> 12;
729         h &= 0xfff;
730         if (fmt == 0)
731                 use_dct_ = 0;
732         else if (fmt == 1)
733                 use_dct_ = 1;
734 #ifdef notyet
735         if (color != color_)
736                 /*FIXME should do this by invoking tcl command */
737                 setcolor(color);
738 #endif
739         if (w != inw_ || h != inh_) {
740                 if ((unsigned)w > 1000 || (unsigned)h > 1000) {
741                         /*FIXME*/
742                         w = 320;
743                         h = 240;
744                 }
745                 inw_ = w;
746                 inh_ = h;
747                 encoder_->framesize(inw_, inh_, outw_, outh_);
748                 reconfig = 1;
749         }
750         if (reconfig)
751                 configure();
752 
753 }
754 
755 int NvTranscoder::recv(const rtphdr* rh, const u_char* bp, int cc,
756                        Transmitter& tx)
757 {
758         const nvhdr* ph = (nvhdr*)(rh + 1);
759         process_hdr(ph);
760 
761         bp += sizeof(nvhdr);
762         cc -= sizeof(nvhdr);
763         const u_char* end = bp + cc;
764         while (bp < end)
765                 bp = decode_run(bp, end, color_, CR_SEND|CR_MOTION);
766 
767         if (!(ntohs(rh->rh_flags) & RTP_M))
768                 return (0);
769         /*
770          * Have a frame.
771          */
772         if (tx.bps() == 0)
773                 return (1);
774 
775         double now = gettimeofday();
776         if (fc_ <= now) {
777                 /* If we have fallen behind (>200ms), re-sync. */
778                 if (now - fc_ > 200000.)
779                         fc_ = now;
780                 VideoFrame vf(ntohl(rh->rh_ts), frm_, outw_, outh_, 0, 422);
781                 int ecc = encoder_->consume(&vf, tx);
782                 age_blocks();
783                 double bits = 8 * double(ecc);
784                 fc_ += 1e6 * bits / tx.bps();
785         }
786         return (1);
787 }
788 
789 #ifdef INFOPAD
790 void NvIpadVQTranscoder::configure(const u_char* p, Network* n)
791 {
792         NvTranscoder::configure(p, n);
793 
794         IpadChannel* c = (IpadChannel*)n;
795         encoder_ = new IpadVQEncoder(c, outw_, outh_, 422, 0);
796 }
797 
798 void NvIpadVQTranscoder::resize(int w, int h)
799 {
800         outw_ = inw_ = w;
801         outh_ = inh_ = h;
802         /* FIXME */
803         u_int bps = encoder_->bps();
804         delete encoder_;
805         encoder_ = new IpadVQEncoder((IpadChannel*)net_, outw_, outh_, 422, 0);
806         encoder_->bps(bps);
807 }
808 
809 int NvIpadVQTranscoder::recv(const rtphdr* rh, const u_char* bp, int cc, int)
810 {
811         const nvhdr* ph = (nvhdr*)(rh + 1);
812         int reconfig = process_hdr(ph);
813         if (reconfig)
814                 reconfigure();
815 
816         bp += sizeof(nvhdr);
817         cc -= sizeof(nvhdr);
818         const u_char* end = bp + cc;
819         while (bp < end)
820                 bp = decode_run(bp, end, color_, CR_SEND|CR_MOTION);
821 
822         if (!(ntohs(rh->rh_flags) & RTP_M))
823                 return (0);
824         /*
825          * Have a frame.
826          */
827         if (bps() == 0)
828                 return (1);
829         double now = gettimeofday();
830         if (fc_ <= now) {
831                 /* If we have fallen behind (>200ms), re-sync. */
832                 if (now - fc_ > 200000.)
833                         fc_ = now;
834                 int ecc = encoder()->encode(frm_, outw_, outh_, 0);
835                 age_blocks();
836                 double bits = 8 * double(ecc);
837                 obits_ += int(bits);
838                 ofrms_ += 1;
839                 opkts_ = encoder()->np();
840                 fc_ += 1e6 * bits / double(bps());
841         }
842         return (1);
843 }
844 #endif /* INFOPAD */
845 
846 

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