Changeset 6
- Timestamp:
- 06/24/07 22:31:43
(1 year ago)
- Author:
- sip
- Message:
New mosaic struture.
Resize of incoming frames.
Change composition type on the fly.
Fixed participant hangup.
Modified Makefile and added install option.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r5 |
r6 |
|
| 2 | 2 | mkdir -p bin |
|---|
| 3 | 3 | make -C media |
|---|
| | 4 | clean: |
|---|
| | 5 | make -C media clean |
|---|
| | 6 | rm -rf bin |
|---|
| | 7 | install: |
|---|
| | 8 | make -C media install |
|---|
| r4 |
r6 |
|
| 1 | 1 | ################################# |
|---|
| 2 | | # Tipo de plataforma: |
|---|
| 3 | | # PLATFORM: linux,win32 |
|---|
| 4 | | # OS: linux,win32 |
|---|
| | 2 | # Config file |
|---|
| 5 | 3 | ################################## |
|---|
| 6 | 4 | LOG = yes |
|---|
| 7 | 5 | DEBUG = yes |
|---|
| 8 | | SRCDIR = /root/mcu |
|---|
| | 6 | SRCDIR = /usr/mcu |
|---|
| | 7 | TARGET = /usr/local |
|---|
| r4 |
r6 |
|
| 36 | 36 | GSMOBJ=gsmcodec.o |
|---|
| 37 | 37 | |
|---|
| 38 | | OBJS=mcu.o multiconf.o participant.o videomixer.o audiomixer.o main.o xmlrpcserver.o xmlhandler.o statushandler.o xmlrpcmcu.o tools.o rtpsession.o audiostream.o videostream.o pipeaudioinput.o pipeaudiooutput.o pipevideoinput.o pipevideooutput.o |
|---|
| | 38 | OBJS=mcu.o multiconf.o participant.o videomixer.o audiomixer.o main.o xmlrpcserver.o xmlhandler.o statushandler.o xmlrpcmcu.o tools.o rtpsession.o audiostream.o videostream.o pipeaudioinput.o pipeaudiooutput.o pipevideoinput.o pipevideooutput.o framescaler.o mosaic.o partedmosaic.o |
|---|
| 39 | 39 | OBJS+= $(G711OBJ) $(H263OBJ) $(GSMOBJ) |
|---|
| 40 | | OBJSCLIENTE = xmlrpcclient.o xmlrpcmcuclient.o |
|---|
| | 40 | OBJSCLIENT = xmlrpcclient.o xmlrpcmcuclient.o |
|---|
| 41 | 41 | |
|---|
| 42 | 42 | BUILDOBJS= $(addprefix $(BUILD)/,$(OBJS)) |
|---|
| 43 | | BUILDOBJSCLIENTE= $(addprefix $(BUILD)/,$(OBJSCLIENTE)) |
|---|
| | 43 | BUILDOBJSCLIENT= $(addprefix $(BUILD)/,$(OBJSCLIENT)) |
|---|
| 44 | 44 | |
|---|
| 45 | 45 | ################################### |
|---|
| … | … | |
| 74 | 74 | #Targets |
|---|
| 75 | 75 | ############################################ |
|---|
| 76 | | all: mkdirs mcu cliente test |
|---|
| | 76 | all: mkdirs mcu client test |
|---|
| 77 | 77 | |
|---|
| 78 | 78 | mkdirs: |
|---|
| … | … | |
| 81 | 81 | clean: |
|---|
| 82 | 82 | rm -f $(BUILDOBJS) |
|---|
| 83 | | rm -f $(BUILDOBJSCLIENTE) |
|---|
| | 83 | rm -f $(BUILDOBJSCLIENT) |
|---|
| 84 | 84 | rm -f "$(BIN)/mcu" |
|---|
| 85 | | rm -f "$(BIN)/libmcucliente.so" |
|---|
| | 85 | rm -f "$(BIN)/libmcuclient.so" |
|---|
| 86 | 86 | rm -f "$(BIN)/test" |
|---|
| | 87 | |
|---|
| | 88 | install: |
|---|
| | 89 | mkdir -p $(TARGET)/lib |
|---|
| | 90 | mkdir -p $(TARGET)/include/mcu |
|---|
| | 91 | cp $(BIN)/libmcuclient.so $(TARGET)/lib/libmcuclient.so |
|---|
| | 92 | cp $(SRCDIR)/media/include/xmlrpcmcuclient.h $(TARGET)/include/mcu |
|---|
| | 93 | |
|---|
| 87 | 94 | |
|---|
| 88 | 95 | ############################################ |
|---|
| … | … | |
| 93 | 100 | $(CXX) $(LDFLAGS) -o $(BIN)/$@ $(BUILDOBJS) |
|---|
| 94 | 101 | |
|---|
| 95 | | cliente: $(OBJSCLIENTE) |
|---|
| 96 | | $(CXX) $(LDXMLFLAGS) -lpthread -lcurl -shared -o $(BIN)/libmcucliente.so $(BUILDOBJSCLIENTE) |
|---|
| | 102 | client: $(OBJSCLIENT) |
|---|
| | 103 | $(CXX) $(LDXMLFLAGS) -lpthread -lcurl -shared -o $(BIN)/libmcuclient.so $(BUILDOBJSCLIENT) |
|---|
| 97 | 104 | |
|---|
| 98 | | test: cliente.o |
|---|
| 99 | | $(CXX) $(LDXMLFLAGS) -lpthread -lcurl -o $(BIN)/test -lmcucliente -L$(BIN) $(BUILD)/cliente.o |
|---|
| | 105 | test: client.o |
|---|
| | 106 | $(CXX) $(LDXMLFLAGS) -lpthread -lcurl -o $(BIN)/test -lmcuclient -L$(BIN) $(BUILD)/client.o |
|---|
| r4 |
r6 |
|
| 24 | 24 | int Init(); |
|---|
| 25 | 25 | int CreateMixer(int id); |
|---|
| 26 | | //int InitMixer(int id); |
|---|
| 27 | | //int EndMixer(int id); |
|---|
| | 26 | int InitMixer(int id); |
|---|
| | 27 | int EndMixer(int id); |
|---|
| 28 | 28 | int DeleteMixer(int id); |
|---|
| 29 | 29 | AudioInput* GetInput(int id); |
|---|
| r4 |
r6 |
|
| 9 | 9 | #define H261 31 |
|---|
| 10 | 10 | #define H263_1996 34 |
|---|
| 11 | | #define H263_1998 96 |
|---|
| 12 | | #define MPEG4 35 |
|---|
| | 11 | #define H263_1998 103 |
|---|
| | 12 | #define MPEG4 104 |
|---|
| 13 | 13 | |
|---|
| 14 | 14 | class AudioCodec |
|---|
| r2 |
r6 |
|
| 17 | 17 | int Init(); |
|---|
| 18 | 18 | int CreateParticipant(); |
|---|
| | 19 | int SetCompositionType(int comp,int size); |
|---|
| 19 | 20 | |
|---|
| 20 | 21 | //Video |
|---|
| r1 |
r6 |
|
| 14 | 14 | virtual int StartRecording(); |
|---|
| 15 | 15 | virtual int StopRecording(); |
|---|
| 16 | | // int Init(); |
|---|
| | 16 | int Init(); |
|---|
| 17 | 17 | int PutSamples(WORD *buffer,DWORD size); |
|---|
| 18 | | // int End(); |
|---|
| | 18 | int End(); |
|---|
| 19 | 19 | |
|---|
| 20 | 20 | private: |
|---|
| … | … | |
| 26 | 26 | fifo<WORD,2048> fifoBuffer; |
|---|
| 27 | 27 | int recording; |
|---|
| | 28 | int inited; |
|---|
| 28 | 29 | |
|---|
| 29 | 30 | |
|---|
| r1 |
r6 |
|
| 17 | 17 | |
|---|
| 18 | 18 | int GetSamples(WORD *buffer,DWORD size); |
|---|
| 19 | | //int Int(); |
|---|
| 20 | | //int End(); |
|---|
| | 19 | int Init(); |
|---|
| | 20 | int End(); |
|---|
| 21 | 21 | private: |
|---|
| 22 | 22 | //Mutex |
|---|
| … | … | |
| 25 | 25 | //Members |
|---|
| 26 | 26 | fifo<WORD,2048> fifoBuffer; |
|---|
| | 27 | int inited; |
|---|
| 27 | 28 | |
|---|
| 28 | 29 | |
|---|
| r1 |
r6 |
|
| 17 | 17 | virtual int StopVideoCapture(); |
|---|
| 18 | 18 | |
|---|
| 19 | | //int Init(); |
|---|
| | 19 | int Init(); |
|---|
| 20 | 20 | int SetFrame(BYTE * buffer, int height, int width); |
|---|
| 21 | | //int End(); |
|---|
| | 21 | int End(); |
|---|
| 22 | 22 | |
|---|
| 23 | 23 | private: |
|---|
| … | … | |
| 28 | 28 | int imgPos; |
|---|
| 29 | 29 | int imgNew; |
|---|
| 30 | | //int inited; |
|---|
| | 30 | int inited; |
|---|
| 31 | 31 | int capturing; |
|---|
| 32 | 32 | BYTE *imgBuffer[2]; |
|---|
| r1 |
r6 |
|
| 18 | 18 | int GetWidth(){return videoWidth;}; |
|---|
| 19 | 19 | int GetHeight(){return videoHeight;}; |
|---|
| 20 | | //int Init(); |
|---|
| 21 | | //int End(); |
|---|
| | 20 | int Init(); |
|---|
| | 21 | int End(); |
|---|
| 22 | 22 | private: |
|---|
| 23 | 23 | BYTE* buffer; |
|---|
| … | … | |
| 26 | 26 | int videoHeight; |
|---|
| 27 | 27 | int isChanged; |
|---|
| | 28 | int inited; |
|---|
| 28 | 29 | |
|---|
| 29 | 30 | pthread_mutex_t* videoMixerMutex; |
|---|
| r1 |
r6 |
|
| 6 | 6 | #include "pipevideoinput.h" |
|---|
| 7 | 7 | #include "pipevideooutput.h" |
|---|
| | 8 | #include "mosaic.h" |
|---|
| 8 | 9 | #include <map> |
|---|
| 9 | 10 | using namespace std; |
|---|
| | 11 | |
|---|
| | 12 | typedef enum |
|---|
| | 13 | { |
|---|
| | 14 | mosaic1x1 = 0, |
|---|
| | 15 | mosaic2x2 = 1, |
|---|
| | 16 | mosaic3x3 = 2 |
|---|
| | 17 | } CompositionType; |
|---|
| 10 | 18 | |
|---|
| 11 | 19 | class VideoMixer |
|---|
| … | … | |
| 13 | 21 | public: |
|---|
| 14 | 22 | // Los valores indican el número de mosaicos por composicion |
|---|
| 15 | | enum CompositionType {mosaic1x1, mosaic2x1, mosaic2x2}; |
|---|
| 16 | 23 | |
|---|
| 17 | 24 | VideoMixer(); |
|---|
| … | … | |
| 20 | 27 | int Init(); |
|---|
| 21 | 28 | int CreateMixer(int id); |
|---|
| 22 | | // int InitMixer(int id); |
|---|
| 23 | | // int EndMixer(int id); |
|---|
| | 29 | int InitMixer(int id); |
|---|
| | 30 | int EndMixer(int id); |
|---|
| 24 | 31 | int DeleteMixer(int id); |
|---|
| 25 | 32 | VideoInput* GetInput(int id); |
|---|
| 26 | 33 | VideoOutput* GetOutput(int id); |
|---|
| 27 | | int SetCompositionType(CompositionType comp,int type); |
|---|
| 28 | | CompositionType GetCompositionType(); |
|---|
| | 34 | int GetCompositionType(); |
|---|
| | 35 | int SetCompositionType(CompositionType comp,int size); |
|---|
| 29 | 36 | int End(); |
|---|
| 30 | 37 | |
|---|
| … | … | |
| 34 | 41 | private: |
|---|
| 35 | 42 | static void * startMixingVideo(void *par); |
|---|
| 36 | | int UpdatePosition(int pos, BYTE *image, int imgWidth, int imgHeight); |
|---|
| 37 | 43 | |
|---|
| 38 | 44 | private: |
|---|
| … | … | |
| 52 | 58 | //Las propiedades del mosaico |
|---|
| 53 | 59 | CompositionType compositionType; |
|---|
| 54 | | int mosaicCols; |
|---|
| 55 | | int mosaicRows; |
|---|
| 56 | | int mosaicNum; |
|---|
| 57 | | int mosaicWidth; |
|---|
| 58 | | int mosaicHeight; |
|---|
| 59 | | int mosaicTotalWidth; |
|---|
| 60 | | int mosaicTotalHeight; |
|---|
| 61 | | int mosaicSize; |
|---|
| 62 | | int logoSize; |
|---|
| 63 | | BYTE *mosaic; |
|---|
| 64 | 60 | BYTE *logo; |
|---|
| | 61 | Mosaic *mosaic; |
|---|
| 65 | 62 | |
|---|
| 66 | 63 | //Threads, mutex y condiciones |
|---|
| r1 |
r6 |
|
| 29 | 29 | xmlrpc_value* IsReceivingAudio(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data); |
|---|
| 30 | 30 | xmlrpc_value* DeleteParticipant(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data); |
|---|
| | 31 | xmlrpc_value* SetCompositionType(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data); |
|---|
| 31 | 32 | |
|---|
| 32 | 33 | |
|---|
| r4 |
r6 |
|
| 1 | 1 | #ifndef _XMLRPCMCUCLIENT_H_ |
|---|
| 2 | 2 | #define _XMLRPCMCUCLIENT_H_ |
|---|
| | 3 | |
|---|
| | 4 | #define PCMA 8 |
|---|
| | 5 | #define PCMU 0 |
|---|
| | 6 | #define GSM 3 |
|---|
| | 7 | #define H261 31 |
|---|
| | 8 | #define H263 103 |
|---|
| | 9 | #define MPEG4 104 |
|---|
| | 10 | |
|---|
| | 11 | #define MOSAIC1x1 0 |
|---|
| | 12 | #define MOSAIC2x2 1 |
|---|
| | 13 | #define MOSAIC3x3 2 |
|---|
| | 14 | |
|---|
| | 15 | #define CIF 0 |
|---|
| | 16 | #define QCIF 1 |
|---|
| 3 | 17 | |
|---|
| 4 | 18 | #ifdef __cplusplus |
|---|
| … | … | |
| 16 | 30 | int CreateConference(char *name); |
|---|
| 17 | 31 | int CreateParticipant(int confId); |
|---|
| | 32 | int SetCompositionType(int confId,int comp,int size); |
|---|
| 18 | 33 | |
|---|
| 19 | 34 | //Video |
|---|
| … | … | |
| 57 | 72 | int CreateParticipant(void *mcu,int confId) |
|---|
| 58 | 73 | { return ((XmlRpcMcuClient*)mcu)->CreateParticipant(confId); } |
|---|
| | 74 | int SetCompositionType(void *mcu,int confId,int comp,int size) |
|---|
| | 75 | { return ((XmlRpcMcuClient*)mcu)->SetCompositionType(confId,comp,size); } |
|---|
| 59 | 76 | |
|---|
| 60 | 77 | //Video |
|---|
| … | … | |
| 102 | 119 | int CreateConference(void *mcu,char *name); |
|---|
| 103 | 120 | int CreateParticipant(void *mcu,int confId); |
|---|
| | 121 | int SetCompositionType(void *mcu,int confId,int comp,int size); |
|---|
| 104 | 122 | |
|---|
| 105 | 123 | //Video |
|---|
| r1 |
r6 |
|
| 13 | 13 | int InitConference(int confId); |
|---|
| 14 | 14 | int CreateParticipant(int confId); |
|---|
| | 15 | int SetCompositionType(int confId,int comp,int size); |
|---|
| 15 | 16 | |
|---|
| 16 | 17 | //Video |
|---|
| r1 |
r6 |
|
| 302 | 302 | } |
|---|
| 303 | 303 | |
|---|
| 304 | | #if 0 |
|---|
| 305 | 304 | /*********************** |
|---|
| 306 | 305 | * InitMixer |
|---|
| … | … | |
| 330 | 329 | |
|---|
| 331 | 330 | //INiciamos los pipes |
|---|
| 332 | | //audio->input->Init(); |
|---|
| 333 | | //audio->output->Init(); |
|---|
| | 331 | audio->input->Init(); |
|---|
| | 332 | audio->output->Init(); |
|---|
| 334 | 333 | |
|---|
| 335 | 334 | //Desprotegemos |
|---|
| … | … | |
| 368 | 367 | |
|---|
| 369 | 368 | //Terminamos |
|---|
| 370 | | //audio->input->End(); |
|---|
| 371 | | //audio->output->End(); |
|---|
| | 369 | audio->input->End(); |
|---|
| | 370 | audio->output->End(); |
|---|
| 372 | 371 | |
|---|
| 373 | 372 | //Desprotegemos |
|---|
| … | … | |
| 377 | 376 | return true;; |
|---|
| 378 | 377 | } |
|---|
| 379 | | #endif |
|---|
| 380 | 378 | |
|---|
| 381 | 379 | /*********************** |
|---|
| r4 |
r6 |
|
| 2 | 2 | #include <xmlrpc.h> |
|---|
| 3 | 3 | #include "xmlrpcmcuclient.h" |
|---|
| 4 | | |
|---|
| 5 | | #define PCMA 8 |
|---|
| 6 | | #define PCMU 0 |
|---|
| 7 | | #define GSM 3 |
|---|
| 8 | | #define H261 31 |
|---|
| 9 | | #define H263 96 |
|---|
| 10 | | #define MPEG4 35 |
|---|
| 11 | | |
|---|
| 12 | | #define CIF 0 |
|---|
| 13 | | #define QCIF 1 |
|---|
| 14 | 4 | |
|---|
| 15 | 5 | int main() |
|---|
| … | … | |
| 30 | 20 | mcu.StartReceivingVideo(confId,partId,&port); |
|---|
| 31 | 21 | printf("%d",port); |
|---|
| | 22 | |
|---|
| | 23 | mcu.SetCompositionType(confId,0,0); |
|---|
| 32 | 24 | } |
|---|
| 33 | 25 | |
|---|
| r4 |
r6 |
|
| 38 | 38 | Log("-Init multiconf\n"); |
|---|
| 39 | 39 | |
|---|
| 40 | | //POnemos el tipo de video mixer |
|---|
| 41 | | videoMixer.SetCompositionType(VideoMixer::mosaic2x2,CIF); |
|---|
| | 40 | //Set default composition |
|---|
| | 41 | SetCompositionType(mosaic2x2,CIF); |
|---|
| 42 | 42 | |
|---|
| 43 | 43 | //INiciamos los mixers |
|---|
| … | … | |
| 49 | 49 | |
|---|
| 50 | 50 | return 1; |
|---|
| | 51 | } |
|---|
| | 52 | |
|---|
| | 53 | /************************ |
|---|
| | 54 | * SetCompositionType |
|---|
| | 55 | * Set mosaic type and size |
|---|
| | 56 | *************************/ |
|---|
| | 57 | int MultiConf::SetCompositionType(int comp,int size) |
|---|
| | 58 | { |
|---|
| | 59 | Log("-SetCompositionType [%d,%d]\n",comp,size); |
|---|
| | 60 | |
|---|
| | 61 | //POnemos el tipo de video mixer |
|---|
| | 62 | return videoMixer.SetCompositionType((CompositionType)comp,size); |
|---|
| 51 | 63 | } |
|---|
| 52 | 64 | |
|---|
| … | … | |
| 87 | 99 | part->audio.SetAudioCodec(GSM); |
|---|
| 88 | 100 | |
|---|
| 89 | | //E iniciamos el mixer |
|---|
| 90 | | //videoMixer.InitMixer(partId); |
|---|
| 91 | | //audioMixer.InitMixer(partId); |
|---|
| 92 | | |
|---|
| 93 | 101 | //Iniciamos el audio y video |
|---|
| 94 | 102 | part->video.Init(videoMixer.GetInput(partId),videoMixer.GetOutput(partId)); |
|---|
| 95 | 103 | part->audio.Init(audioMixer.GetInput(partId),audioMixer.GetOutput(partId)); |
|---|
| 96 | 104 | |
|---|
| | 105 | //E iniciamos el mixer |
|---|
| | 106 | videoMixer.InitMixer(partId); |
|---|
| | 107 | audioMixer.InitMixer(partId); |
|---|
| 97 | 108 | |
|---|
| 98 | 109 | //Lo insertamos en el map |
|---|
| … | … | |
| 120 | 131 | |
|---|
| 121 | 132 | //Paramos el mixer |
|---|
| 122 | | //videoMixer.EndMixer(id); |
|---|
| 123 | | //audioMixer.EndMixer(id); |
|---|
| | 133 | videoMixer.EndMixer(id); |
|---|
| | 134 | audioMixer.EndMixer(id); |
|---|
| 124 | 135 | |
|---|
| 125 | 136 | //LO obtenemos |
|---|
| r1 |
r6 |
|
| 120 | 120 | } |
|---|
| 121 | 121 | |
|---|
| 122 | | #if 0 |
|---|
| 123 | 122 | int PipeAudioInput::Init() |
|---|
| 124 | 123 | { |
|---|
| … | … | |
| 152 | 151 | return true; |
|---|
| 153 | 152 | } |
|---|
| 154 | | #endif |
|---|
| r1 |
r6 |
|
| 62 | 62 | return len; |
|---|
| 63 | 63 | } |
|---|
| | 64 | int PipeAudioOutput::Init() |
|---|
| | 65 | { |
|---|
| | 66 | Log("PipeAudioOutput init\n"); |
|---|
| | 67 | |
|---|
| | 68 | //Protegemos |
|---|
| | 69 | pthread_mutex_lock(&mutex); |
|---|
| | 70 | |
|---|
| | 71 | //Iniciamos |
|---|
| | 72 | inited = true; |
|---|
| | 73 | |
|---|
| | 74 | //Protegemos |
|---|
| | 75 | pthread_mutex_unlock(&mutex); |
|---|
| | 76 | |
|---|
| | 77 | return true; |
|---|
| | 78 | } |
|---|
| | 79 | |
|---|
| | 80 | int PipeAudioOutput::End() |
|---|
| | 81 | { |
|---|
| | 82 | //Protegemos |
|---|
| | 83 | pthread_mutex_lock(&mutex); |
|---|
| | 84 | |
|---|
| | 85 | //Terminamos |
|---|
| | 86 | inited = false; |
|---|
| | 87 | |
|---|
| | 88 | //Señalizamos la condicion |
|---|
| | 89 | //pthread_cond_signal(&newPicCond); |
|---|
| | 90 | |
|---|
| | 91 | //Protegemos |
|---|
| | 92 | pthread_mutex_unlock(&mutex); |
|---|
| | 93 | |
|---|
| | 94 | return true; |
|---|
| | 95 | } |
|---|
| r4 |
r6 |
|
| 22 | 22 | } |
|---|
| 23 | 23 | |
|---|
| 24 | | #if 0 |
|---|
| 25 | 24 | int PipeVideoInput::Init() |
|---|
| 26 | 25 | { |
|---|
| … | … | |
| 55 | 54 | return true; |
|---|
| 56 | 55 | } |
|---|
| 57 | | |
|---|
| 58 | | #endif |
|---|
| 59 | 56 | |
|---|
| 60 | 57 | int PipeVideoInput::StartVideoCapture(int width,int height,int fps) |
|---|
| … | … | |
| 152 | 149 | int PipeVideoInput::SetFrame(BYTE * buffer, int width, int height) |
|---|
| 153 | 150 | { |
|---|
| 154 | | Log("-SetFrame [%d]\n",capturing); |
|---|
| 155 | | |
|---|
| 156 | 151 | //Protegemos |
|---|
| 157 | 152 | pthread_mutex_lock(&newPicMutex); |
|---|
| r1 |
r6 |
|
| 17 | 17 | videoWidth = 0; |
|---|
| 18 | 18 | videoHeight = 0; |
|---|
| 19 | | |
|---|
| 20 | 19 | } |
|---|
| 21 | 20 | |
|---|
| … | … | |
| 27 | 26 | free(buffer); |
|---|
| 28 | 27 | } |
|---|
| 29 | | |
|---|
| 30 | | /* |
|---|
| 31 | | int PipeVideoOutput::Init() |
|---|
| 32 | | { |
|---|
| 33 | | return 1; |
|---|
| 34 | | } |
|---|
| 35 | | |
|---|
| 36 | | int PipeVideoOutput::End() |
|---|
| 37 | | { |
|---|
| 38 | | return 1; |
|---|
| 39 | | } |
|---|
| 40 | | */ |
|---|
| 41 | 28 | |
|---|
| 42 | 29 | int PipeVideoOutput::NextFrame(BYTE *pic) |
|---|
| … | … | |
| 88 | 75 | } |
|---|
| 89 | 76 | |
|---|
| | 77 | int PipeVideoOutput::Init() |
|---|
| | 78 | { |
|---|
| | 79 | Log("PipeVideoOutput init\n"); |
|---|
| | 80 | |
|---|
| | 81 | //Protegemos |
|---|
| | 82 | pthread_mutex_lock(videoMixerMutex); |
|---|
| | 83 | |
|---|
| | 84 | //Iniciamos |
|---|
| | 85 | inited = true; |
|---|
| | 86 | |
|---|
| | 87 | //Protegemos |
|---|
| | 88 | pthread_mutex_unlock(videoMixerMutex); |
|---|
| | 89 | |
|---|
| | 90 | return true; |
|---|
| | 91 | } |
|---|
| | 92 | |
|---|
| | 93 | int PipeVideoOutput::End() |
|---|
| | 94 | { |
|---|
| | 95 | //Protegemos |
|---|
| | 96 | pthread_mutex_lock(videoMixerMutex); |
|---|
| | 97 | |
|---|
| | 98 | //Terminamos |
|---|
| | 99 | inited = false; |
|---|
| | 100 | |
|---|
| | 101 | //Señalizamos la condicion |
|---|
| | 102 | pthread_cond_signal(videoMixerCond); |
|---|
| | 103 | |
|---|
| | 104 | //Protegemos |
|---|
| | 105 | pthread_mutex_unlock(videoMixerMutex); |
|---|
| | 106 | |
|---|
| | 107 | return true; |
|---|
| | 108 | } |
|---|
| r4 |
r6 |
|
| 3 | 3 | #include <pipevideoinput.h> |
|---|
| 4 | 4 | #include <pipevideooutput.h> |
|---|
| | 5 | #include <partedmosaic.h> |
|---|
| 5 | 6 | |
|---|
| 6 | 7 | /*********************** |
|---|
| … | … | |
| 11 | 12 | { |
|---|
| 12 | 13 | //Incializamos a cero |
|---|
| 13 | | mosaicSize = 0; |
|---|
| 14 | | mosaicWidth = 0; |
|---|
| 15 | | mosaicHeight = 0; |
|---|
| 16 | | mosaicNum = 0; |
|---|
| 17 | | mosaicCols = 0; |
|---|
| 18 | | mosaicRows = 0; |
|---|
| | 14 | mosaic = NULL; |
|---|
| 19 | 15 | |
|---|
| 20 | 16 | //Inciamos lso mutex y la condicion |
|---|
| … | … | |
| 59 | 55 | { |
|---|
| 60 | 56 | int id; |
|---|
| 61 | | int mosaicChanged = true; |
|---|
| 62 | 57 | VideoSource *video; |
|---|
| 63 | 58 | |
|---|
| … | … | |
| 74 | 69 | |
|---|
| 75 | 70 | //Si no ha cambiado el frame volvemos al principio |
|---|
| 76 | | if (mosaicChanged) |
|---|
| | 71 | if (mosaic->HasChanged()) |
|---|
| 77 | 72 | { |
|---|
| 78 | | Log("-Updating\n"); |
|---|
| 79 | | |
|---|
| 80 | 73 | //Nos recorremos los videos |
|---|
| 81 | 74 | for (it=lstVideos.begin();it!=lstVideos.end();it++) |
|---|
| … | … | |
| 86 | 79 | |
|---|
| 87 | 80 | //Colocamos el frame |
|---|
| 88 | | video->input->SetFrame(mosaic,mosaicTotalWidth,mosaicTotalHeight); |
|---|
| | 81 | video->input->SetFrame(mosaic->GetFrame(),mosaic->GetWidth(),mosaic->GetHeight()); |
|---|
| 89 | 82 | } |
|---|
| 90 | 83 | } |
|---|
| 91 | 84 | |
|---|
| 92 | 85 | //Reset |
|---|
| 93 | | mosaicChanged = false; |
|---|
| | 86 | mosaic->Reset(); |
|---|
| 94 | 87 | |
|---|
| 95 | 88 | //Desprotege la lista |
|---|
| … | … | |
| 109 | 102 | video = (*it).second; |
|---|
| 110 | 103 | |
|---|
| 111 | | //Si ha cambiado |
|---|
| | 104 | //If we've got a new frame on source |
|---|
| 112 | 105 | if (video->output->IsChanged()) |
|---|
| 113 | | { |
|---|
| 114 | | //Actualizamos el mosaico |
|---|
| 115 | | UpdatePosition(id-1,video->output->GetFrame(),video->output->GetWidth(),video->output->GetHeight()); |
|---|
| 116 | | |
|---|
| 117 | | //Y hemos cambiado el frame |
|---|
| 118 | | mosaicChanged = true; |
|---|
| 119 | | } |
|---|
| | 106 | //Change mosaic |
|---|
| | 107 | mosaic->Update(id-1,video->output->GetFrame(),video->output->GetWidth(),video->output->GetHeight()); |
|---|
| 120 | 108 | } |
|---|
| 121 | 109 | |
|---|
| … | … | |
| 136 | 124 | int VideoMixer::Init() |
|---|
| 137 | 125 | { |
|---|
| 138 | | //Alocamos el mosaico |
|---|
| 139 | | mosaic = (BYTE *) malloc(mosaicSize); |
|---|
| 140 | | |
|---|
| 141 | | //Lo ponemos a cero |
|---|
| 142 | | memset(mosaic,0,mosaicSize); |
|---|
| | 126 | //If we don't have mosaic |
|---|
| | 127 | if (!mosaic) |
|---|
| | 128 | //Error |
|---|
| | 129 | return 0; |
|---|
| 143 | 130 | |
|---|
| 144 | 131 | //Allocamos para el logo |
|---|
| 145 | | logo = (BYTE *) malloc(logoSize); |
|---|
| | 132 | //logo = (BYTE *) malloc(logoSize); |
|---|
| 146 | 133 | |
|---|
| 147 | 134 | //Lo obtenemos |
|---|
| … | … | |
| 149 | 136 | |
|---|
| 150 | 137 | //Ponemos el logito |
|---|
| 151 | | for (int i=0;i<mosaicNum;i++) |
|---|
| 152 | | UpdatePosition(i,logo,mosaicWidth,mosaicHeight); |
|---|
| | 138 | //for (int i=0;i<mosaicNum;i++) |
|---|
| | 139 | //UpdatePosition(i,logo,mosaicWidth,mosaicHeight); |
|---|
| 153 | 140 | |
|---|
| 154 | 141 | // Estamos mzclando |
|---|
| … | … | |
| 192 | 179 | DeleteMixer((*it).first); |
|---|
| 193 | 180 | |
|---|
| 194 | | //Liberamos el mosaico |
|---|
| 195 | | free(mosaic); |
|---|
| | 181 | //If we've got mosaic |
|---|
| | 182 | if (mosaic) |
|---|
| | 183 | //Delete it |
|---|
| | 184 | delete mosaic; |
|---|
| 196 | 185 | |
|---|
| 197 | 186 | //Y el logo |
|---|
| 198 | | free(logo); |
|---|
| | 187 | //free(logo); |
|---|
| 199 | 188 | |
|---|
| 200 | 189 | Log("<End videomixer\n"); |
|---|
| … | … | |
| 209 | 198 | int VideoMixer::CreateMixer(int id) |
|---|
| 210 | 199 | { |
|---|
| 211 | | Log(">CreateMixer video [%d,%d,%d]\n",id,mosaicTotalWidth,mosaicTotalHeight); |
|---|
| | 200 | Log(">CreateMixer video [%d]\n",id); |
|---|
| 212 | 201 | |
|---|
| 213 | 202 | //Protegemos la lista |
|---|
| … | … | |
| 241 | 230 | } |
|---|
| 242 | 231 | |
|---|
| 243 | | #if 0 |
|---|
| 244 | 232 | /*********************** |
|---|
| 245 | 233 | * InitMixer |
|---|
| … | … | |
| 316 | 304 | return true; |
|---|
| 317 | 305 | } |
|---|
| 318 | | #endif |
|---|
| 319 | 306 | |
|---|
| 320 | 307 | /*********************** |
|---|
| … | … | |
| 408 | 395 | //Si esta devolvemos el input |
|---|
| 409 | 396 | return (VideoOutput*)(*it).second->output; |
|---|
| | 397 | } |
|---|
| | 398 | |
|---|
| | 399 | /************************** |
|---|
| | 400 | * GetCompositionType |
|---|
| | 401 | * Obtiene el modo de mosaico |
|---|
| | 402 | ***************************/ |
|---|
| | 403 | int VideoMixer::GetCompositionType() |
|---|
| | 404 | { |
|---|
| | 405 | return compositionType; |
|---|
| 410 | 406 | } |
|---|
| 411 | 407 | |
|---|
| … | … | |
| 416 | 412 | int VideoMixer::SetCompositionType(CompositionType comp, int type) |
|---|
| 417 | 413 | { |
|---|
| 418 | | //Dependiendo del tipo |
|---|
| 419 | | switch(type) |
|---|
| 420 | | { |
|---|
| 421 | | case CIF: |
|---|
| 422 | | mosaicTotalWidth = 352; |
|---|
| 423 | | mosaicTotalHeight= 288; |
|---|
| | 414 | |
|---|
| | 415 | Log(">SetCompositionType [%d,%d]\n",comp,type); |
|---|
| | 416 | |
|---|
| | 417 | //Protegemos la lista |
|---|
| | 418 | lstVideosUse.WaitUnusedAndLock(); |
|---|
| | 419 | |
|---|
| | 420 | //If we've got mosaic |
|---|
| | 421 | if (mosaic) |
|---|
| | 422 | //Delete it |
|---|
| | 423 | delete mosaic; |
|---|
| | 424 | |
|---|
| | 425 | //Create mosaic depending on composition |
|---|
| | 426 | switch(comp) |
|---|
| | 427 | { |
|---|
| | 428 | case mosaic1x1: |
|---|
| | 429 | //Set mosaic |
|---|
| | 430 | mosaic = new PartedMosaic(1,type); |
|---|
| 424 | 431 | break; |
|---|
| 425 | | case QCIF: |
|---|
| 426 | | mosaicTotalWidth = 176; |
|---|
| 427 | | mosaicTotalHeight= 144; |
|---|
| | 432 | case mosaic2x2: |
|---|
| | 433 | //Set mosaic |
|---|
| | 434 | mosaic = new PartedMosaic(2,type); |
|---|
| | 435 | break; |
|---|
| | 436 | case mosaic3x3: |
|---|
| | 437 | //Set mosaic |
|---|
| | 438 | mosaic = new PartedMosaic(3,type); |
|---|
| 428 | 439 | break; |
|---|
| 429 | 440 | default: |
|---|
| 430 | | return 0; |
|---|
| 431 | | } |
|---|
| 432 | | |
|---|
| 433 | | //El tamaño |
|---|
| 434 | | mosaicSize = (mosaicTotalWidth * mosaicTotalHeight * 3)/2; |
|---|
| 435 | | |
|---|
| 436 | | |
|---|
| 437 | | //Dependiendo del tipo de composicion |
|---|
| 438 | | switch(comp) |
|---|
| 439 | | { |
|---|
| 440 | | case mosaic1x1: |
|---|
| 441 | | mosaicNum = 1; |
|---|
| 442 | | mosaicCols = 1; |
|---|
| 443 | | mosaicRows = 1; |
|---|
| 444 | | mosaicWidth = mosaicTotalWidth; |
|---|
| 445 | | mosaicHeight = mosaicTotalHeight; |
|---|
| 446 | | break; |
|---|
| 447 | | case mosaic2x1: |
|---|
| 448 | | mosaicNum = 2; |
|---|
| 449 | | mosaicCols = 1; |
|---|
| 450 | | mosaicRows = 1; |
|---|
| 451 | | mosaicWidth = mosaicTotalWidth/2; |
|---|
| 452 | | mosaicHeight = mosaicTotalHeight/2; |
|---|
| 453 | | break; |
|---|
| 454 | | case mosaic2x2: |
|---|
| 455 | | mosaicNum = 4; |
|---|
| 456 | | mosaicCols = 2; |
|---|
| 457 | | mosaicRows = 2; |
|---|
| 458 | | mosaicWidth = mosaicTotalWidth/2; |
|---|
| 459 | | mosaicHeight = mosaicTotalHeight/2; |
|---|
| 460 | | break; |
|---|
| 461 | | default: |
|---|
| 462 | | return 0; |
|---|
| 463 | | } |
|---|
| 464 | | |
|---|
| 465 | | //Y el del logo |
|---|
| 466 | | logoSize = (mosaicWidth*mosaicHeight*3)/2; |
|---|
| 467 | | |
|---|
| 468 | | //Nos quedamos con el tipo |
|---|
| | 441 | //No mosaic |
|---|
| | 442 | mosaic = NULL; |
|---|
| | 443 | } |
|---|
| | 444 | |
|---|
| | 445 | //Save type |
|---|
| 469 | 446 | compositionType = comp; |
|---|
| 470 | 447 | |
|---|
| | 448 | //Desprotegemos la lista |
|---|
| | 449 | lstVideosUse.Unlock(); |
|---|
| | 450 | |
|---|
| | 451 | Log("<SetCompositionType\n"); |
|---|
| | 452 | |
|---|
| 471 | 453 | return 1; |
|---|
| 472 | 454 | } |
|---|
| 473 | 455 | |
|---|
| 474 | | /************************** |
|---|
| 475 | | * GetCompositionType |
|---|
| 476 | | * Obtiene el modo de mosaico |
|---|
| 477 | | ***************************/ |
|---|
| 478 | | /*CompositionType VideoMixer::GetCompositionType(CompositionType comp) |
|---|
| 479 | | { |
|---|
| 480 | | return compositionType; |
|---|
| 481 | | }*/ |
|---|
| 482 | | |
|---|
| 483 | | /***************************** |
|---|
| 484 | | * UpdatePosition |
|---|
| 485 | | * Actualiza el cuadrante del mosaico con una imagen |
|---|
| 486 | | *****************************/ |
|---|
| 487 | | int VideoMixer::UpdatePosition(int pos, BYTE *image, int imgWidth, int imgHeight) |
|---|
| 488 | | { |
|---|
| 489 | | //Los punteros |
|---|
| 490 | | DWORD mosaicNumPixels = mosaicTotalWidth*mosaicTotalHeight; |
|---|
| 491 | | DWORD offset,offset2; |
|---|
| 492 | | BYTE *lineaY; |
|---|
| 493 | | BYTE *lineaU; |
|---|
| 494 | | BYTE *lineaV; |
|---|
| 495 | | |
|---|
| 496 | | DWORD imgNumPixels = imgHeight*imgWidth; |
|---|
| 497 | | BYTE *imageY = image; |
|---|
| 498 | | BYTE *imageU = image + imgNumPixels; |
|---|
| 499 | | BYTE *imageV = imageU + imgNumPixels/4; |
|---|
| 500 | | |
|---|
| 501 | | //Comprobamos que esta dentro |
|---|
| 502 | | if (pos >= mosaicNum) |
|---|
| 503 | | return 0; |
|---|
| 504 | | |
|---|
| 505 | | //Obtenemos la posicion en el mosaico |
|---|
| 506 | | int i = pos / mosaicCols; |
|---|
| 507 | | int j = pos - i*mosaicCols; |
|---|
| 508 | | |
|---|
| 509 | | //Obtenemos el offset |
|---|
| 510 | | offset = (mosaicTotalWidth*mosaicHeight*i) + mosaicWidth*j; |
|---|
| 511 | | offset2 = (mosaicTotalWidth*mosaicHeight*i)/4+(mosaicWidth*j)/2; |
|---|
| 512 | | |
|---|
| 513 | | //Y los punteros |
|---|
| 514 | | lineaY = mosaic + offset; |
|---|
| 515 | | lineaU = mosaic + mosaicNumPixels + offset2; |
|---|
| 516 | | lineaV = lineaU + mosaicNumPixels/4; |
|---|
| 517 | | |
|---|
| 518 | | //Si los tamaños son iguales |
|---|
| 519 | | if (imgWidth == mosaicWidth) |
|---|
| 520 | | { |
|---|
| 521 | | //copiamos la Y |
|---|
| 522 | | for (int i = 0; i<mosaicHeight; i++) |
|---|
| 523 | | { |
|---|
| 524 | | //Copiamos dos lineas de Y |
|---|
| 525 | | memcpy(lineaY, imageY, imgWidth); |
|---|
| 526 | | |
|---|
| 527 | | //Saltamos a las siguientes |
|---|
| 528 | | lineaY += mosaicTotalWidth; |
|---|
| 529 | | imageY += imgWidth; |
|---|
| 530 | | } |
|---|
| 531 | | |
|---|
| 532 | | //Y una de U y V |
|---|
| 533 | | for (int i = 0; i<mosaicHeight/2; i++) |
|---|
| 534 | | { |
|---|
| 535 | | //Copiamos |
|---|
| 536 | | memcpy(lineaU, imageU, imgWidth/2); |
|---|
| 537 | | memcpy(lineaV, imageV, imgWidth/2); |
|---|
| 538 | | |
|---|
| 539 | | lineaU += mosaicTotalWidth/2; |
|---|
| 540 | | lineaV += mosaicTotalWidth/2; |
|---|
| 541 | | |
|---|
| 542 | | imageU += imgWidth/2; |
|---|
| 543 | | imageV += imgWidth/2; |
|---|
| 544 | | } |
|---|
| 545 | | } |
|---|
| 546 | | |
|---|
| 547 | | return 1; |
|---|
| 548 | | } |
|---|
| r4 |
r6 |
|
| 412 | 412 | //Nos quedamos con el puntero antes de que lo cambien |
|---|
| 413 | 413 | pic=videoInput->GrabFrame(); |
|---|
| 414 | | Log("-PIC\n"); |
|---|
| 415 | 414 | |
|---|
| 416 | 415 | //Si es nulo |
|---|
| 417 | 416 | if (!pic) |
|---|
| 418 | | continue; |
|---|
| | 417 | //Exit |
|---|
| | 418 | break;; |
|---|
| 419 | 419 | |
|---|
| 420 | 420 | //Mandamos un FPU cada 220 muestras |
|---|
| … | … | |
| 440 | 440 | bitRateControl=0; |
|---|
| 441 | 441 | } |
|---|
| 442 | | Log("-NEC\n"); |
|---|
| 443 | 442 | |
|---|
| 444 | 443 | //Procesamos el frame |
|---|
| 445 | 444 | videoEncoder->EncodeFrame(pic,videoInput->GetBufferSize()); |
|---|
| 446 | | Log("-ENC\n"); |
|---|
| 447 | 445 | |
|---|
| 448 | 446 | //Actualizamos el timepod e captura y codificacion del frame |
|---|
| |