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

Open Mash Cross Reference
mash/tgw/combiner.cc

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

  1 /*
  2  * combiner.cc --
  3  *
  4  *      FIXME: This file needs a description here.
  5  *
  6  * Copyright (c) 2001-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 #include "combiner.h"
 35 
 36 // this file has the code for combining two (or more hypothetically) RTP
 37 // streams into one stream whose frames are the glued images of both the
 38 // incoming streams. Then it gives the output to a Real encoding engine
 39 
 40 // Constructor for our list node...
 41 CombinerSourceNode::CombinerSourceNode(char* s, int p): pos(p),width(0),height(0),next(0) {
 42   strcpy(source,s);
 43 }
 44 
 45 // =======================
 46 
 47 // Wrapper for the OTcl object...
 48 static class CombinerSourceClass : public TclClass {
 49 public:
 50   CombinerSourceClass() : TclClass ("CombinerSource") {};
 51   TclObject* create(int argc, const char*const* argv) {
 52     return (new CombinerSource((Combiner*)TclObject::lookup(argv[4]),argv[5],atoi(argv[6])));
 53   };
 54 } combiner_source;
 55 
 56 CombinerSource::CombinerSource(Combiner* destination, const char* s, int c): dest(destination),colorModel(c) {
 57   strcpy(src, s);
 58 }
 59 
 60 // this is the whole reason we need this class, so that it can tell the
 61 // combiner which source the image came from.
 62 void CombinerSource::recv(Buffer* b) {
 63   dest->recv(b, src, colorModel);
 64 }
 65 
 66 // ==========================
 67 
 68 // Wrapper for the OTcl object...
 69 static class CombinerClass : public TclClass {
 70 public:
 71   CombinerClass() : TclClass ("Combiner") {};
 72   TclObject* create(int argc, const char*const* argv) {
 73     return (new Combiner());
 74   };
 75 } combiner;
 76 
 77 
 78 Combiner::Combiner(): destination(0),width(0),height(0),sources(0),frame_(0),frame_data_(0) {
 79 }
 80 
 81 Combiner::~Combiner() {
 82 };
 83 
 84 // this does all the work of gluing the two images together and handing it off.
 85 void Combiner::recv(Buffer* b, char* source, int colorModel) {
 86   YuvFrame* in_frame_ = (YuvFrame*)b;
 87   u_int8_t* dest;
 88   u_int8_t* src;
 89   int rownum;
 90   CombinerSourceNode* temp;
 91   
 92   if (frame_ == 0) {
 93     // search the list to see if dimensions were entered yet...
 94     for (temp=sources; temp != 0; temp=temp->next) {
 95       if (strcmp(temp->source, source) == 0) {
 96         temp->width = in_frame_->width_;
 97         temp->height = in_frame_->height_;
 98         break;
 99       }
100     }
101     // wait until we have at least two sources...
102     if (sources !=0 && sources->next != 0) {
103       // sort them so that they are in the right left to right order (currently only works for 2 sources)
104       if (sources->pos == 2) {
105         temp = sources;
106         sources = sources->next;
107         temp->next = 0;
108         sources->next = temp;
109       }
110 
111       if ((sources->width != 0) && (sources->next->width != 0)) {
112         // gather the total size of the output frame
113         for(temp=sources; temp != 0; temp=temp->next) {
114           width += temp->width;
115           if (height < temp->height)
116             height = temp->height;
117         }
118         // FIXME -- should check to make sure the size is a multiple of 8.
119         // allocate the data structure to store the frame data...
120         frame_data_ = new u_int8_t[(width*height*3)/2];
121         frame_ = new YuvFrame(0,frame_data_,0,width,height, 0);
122       } else
123         return;
124     } else
125       return;
126   }
127 
128   // check to see if it is a frame we are going to use...
129   if ((strcmp(sources->source,source) != 0) && (strcmp(sources->next->source,source) != 0))
130     return;
131   
132   dest = frame_data_;
133   src = in_frame_->bp_;
134   // determine if this is the second source and then put the
135   // dest (destination) pointer to the appropriate offset in the frame.
136   if (strcmp(source,sources->source) != 0)
137     dest = &(dest[sources->width]);
138 
139   // copy the Luninescence
140   for(rownum=0;rownum<in_frame_->height_;rownum++)
141     memcpy(&(dest[(rownum*width)]),&(src[rownum*(in_frame_->width_)]),in_frame_->width_);
142 
143   dest = &(frame_data_[width*height]);
144   src = &((in_frame_->bp_)[in_frame_->width_*in_frame_->height_]);
145   // once again, determine the proper destination in the frame (like above)
146   if (strcmp(source,sources->source) != 0)
147     dest = &(dest[(sources->width)/2]);
148 
149   // copy the chrominence (the U component)
150   if (colorModel == 422) {
151     for(rownum=0;rownum<((in_frame_->height_)/2);rownum++)
152       memcpy(&(dest[(rownum*width)/2]),&(src[rownum*in_frame_->width_]),(in_frame_->width_)/2);
153   } else {
154     for(rownum=0;rownum<((in_frame_->height_)/2);rownum++)
155       memcpy(&(dest[(rownum*width)/2]),&(src[(rownum*(in_frame_->width_))/2]),(in_frame_->width_)/2);
156   }
157 
158   dest = &(frame_data_[(width*height*5)/4]);
159   if (colorModel == 422)
160     src = &((in_frame_->bp_)[(in_frame_->width_*in_frame_->height_*3)/2]);
161   else
162     src = &((in_frame_->bp_)[(in_frame_->width_*in_frame_->height_*5)/4]);
163   // once again, determine the proper destination in the frame (like above)
164   if (strcmp(source,sources->source) != 0)
165     dest = &(dest[(sources->width)/2]);
166 
167   // copy the chrominence (the V component)
168   if (colorModel == 422) {
169     for(rownum=0;rownum<((in_frame_->height_)/2);rownum++)
170       memcpy(&(dest[(rownum*width)/2]),&(src[rownum*in_frame_->width_]),(in_frame_->width_)/2);
171   } else {
172     for(rownum=0;rownum<((in_frame_->height_)/2);rownum++)
173       memcpy(&(dest[(rownum*width)/2]),&(src[(rownum*(in_frame_->width_))/2]),(in_frame_->width_)/2);
174   }
175 
176   // hand it off to the Real Encoder.
177   if (destination != 0)
178     destination->recv(frame_, 0, 0);
179 }
180 
181 // For Tcl commands to call from Tcl space...
182 int Combiner::command(int argc, const char*const* argv) {
183   Tcl& tcl = Tcl::instance();
184   if (argc == 2) {
185     if (strcmp(argv[1], "unlinkEncoder") == 0) {
186       destination = 0;
187       return (TCL_OK);
188     } else if (strcmp(argv[1], "ready") == 0) {
189       if ((sources != 0) && (sources->next != 0))
190         tcl.resultf("yes");
191       else
192         tcl.resultf("no");
193       return (TCL_OK);
194     }
195   } else if (argc == 3) {
196     if (strcmp(argv[1], "linkEncoder") == 0) {
197       destination = (Renderer*)TclObject::lookup(argv[2]);
198       return (TCL_OK);
199     }
200   } else if (argc == 4) {
201     if (strcmp(argv[1], "setSide") == 0) {
202       // check to see if the source is already there...
203       for (CombinerSourceNode* temp=sources; temp != 0; temp=temp->next) {
204         if (strcmp(temp->source, argv[3]) == 0) {
205           temp->pos = atoi(argv[2]);
206           return (TCL_OK);
207         }
208       }
209       CombinerSourceNode* head = sources;
210       sources = new CombinerSourceNode((char*)(argv[3]),atoi(argv[2]));
211       sources->next = head;
212       return (TCL_OK);
213     }
214   }
215   
216   return (TclObject::command(argc, argv));
217 }
218 

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