From 6cc9784d3f1ea06353cb136e5c77b855c8fa8ade Mon Sep 17 00:00:00 2001 From: Wesnydy Ribeiro Date: Fri, 23 Oct 2015 11:41:39 -0300 Subject: [PATCH] Modificações para comunicação com o novo Player --- renderer/src/include/renderer.h | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------- renderer/src/renderer.cpp | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------ servico/src/serviceWindowGenerationFromRec.cpp | 14 +++++--------- servico/src/serviceWindowGenerationFromSRT.cpp | 15 ++++++--------- servico/src/serviceWindowGenerationFromText.cpp | 5 +---- 5 files changed, 197 insertions(+), 215 deletions(-) diff --git a/renderer/src/include/renderer.h b/renderer/src/include/renderer.h index da239e1..3ea8fb1 100644 --- a/renderer/src/include/renderer.h +++ b/renderer/src/include/renderer.h @@ -8,30 +8,34 @@ #ifndef RENDERER_H #define RENDERER_H -#include "jthread.h" -#include "logging.h" -#include "string.h" -#include #include +#include #include -#include -#include #include +#include +#include "string.h" +#include "jthread.h" +#include "logging.h" #include "listenerRenderer.h" -#include #include +#include +#include #include #include -#include -#define PATH_RENDERER "vlibras_user/unityVideo/" -#define PATH_SCREENS "vlibras_user/.config/unity3d/LAViD/VLibrasPlayer/" -#define END_FLAG "FINALIZE" #define HOST "0.0.0.0" -#define PORTNO 5555 +#define PORT 5555 + +#define OK_FLAG "OK" +#define END_FLAG "FINALIZE" +#define BADSENTENCE "SENTENCACOMBAIXAQUALIDADE" +#define BADTEXT "ESCOLHER TEXTO CERTO" + +#define PATH_RENDERER "vlibras_user/unityVideo/" +#define PATH_SCREENS "vlibras_user/.config/unity3d/LAViD/VLibrasVideoMaker/" -using namespace lavidlib; using namespace jthread; +using namespace lavidlib; using namespace std; using namespace util; @@ -44,26 +48,22 @@ class Renderer : public Thread { public: /** Construtor. * - * \param videoPath Abstração do path do vídeo de saída. - * \param user_id Identificação do usuário. + * \param path_contents Abstração do path do vídeo de saída. + * \param id Identificação do usuário. */ - Renderer(char* videoPath, char* user_id); + Renderer(char* path_Contents, char* id); /** Destrutor. */ ~Renderer(); - /** Indica o status do envio da glosa para o player. + /** Inicia os processos do renderizador. * - * \return O status do envio. + * Inicia o servidor do Unity Player, + * faz a conexão do Core com o Player + * e da inicio ao envio das glosas para + * a geração do vídeo de LIBRAS. */ - bool isSending(); - - /** Recebe a glosa q será enviada para o player. - * - * \param glosa A glosa que será enviada. - * \param pts A etiqueta de tempo da glosa. - */ - void receiveGlosa(std::string glosa, int64_t pts); + void initialize(); /** Adiciona ouvintes do renderer. * @@ -71,64 +71,44 @@ public: */ void addListener(ListenerRenderer* listener); - /** Finaliza o envio das glosas. + /** Recebe a glosa q será enviada para o player. * - * Uma flag de FINALIZE é enviada para o player - * sinalizando que não há mais glosas para serem - * enviadas. + * \param glosa A glosa que será enviada. + * \param pts A etiqueta de tempo da glosa. */ - void finalize(); + void receiveGlosa(string glosa, int64_t pts); - /** Este método é chamado quando a Thread for iniciada. */ - void Run(); - private: - StreamSocket* core_socket; - list * listeners; - - bool running; - int count_task; - int glosa_processed; - - char* folder_id; - char* path_video; - string glosa_copy; - - /** - * Renderiza o vídeo de libras a partir - * das screenshots geradas pelo player. - */ - void render(); + char* userID; + char* pathOutVideo; - /** Envia a glosa para o player - * - * \exception RuntimeException Se houver falha no envio da glosa. - */ - void sendGlosa(); + StreamSocket* cSocket; + queue glosaQueue; + list* listeners; - /** Notifica os ouvintes sobre o fim da renderização. */ - void notifyListeners(); + /** Executa o script que inicia o servidor do Player. */ + void executeServerScript(); - /** Faz a conexão com o player do Unity - * - * \exception RuntimeException Se a conexão for mal sucedida. - */ - void connectToUnity(); + /** Faz a conexão do Core com o Player. */ + void connectToUnityPlayer(); - /** Inicializa o servidor do player do Unity. - * - * A inicialização é feita a partir de um script externo. - */ - void serverInitialize(); + /** Envia as glosas para o Player. */ + void exportGlosa(); - /** Aguarda o player gerar as screenshots do vídeo de LIBRAS. - * - * \exception RuntimeException Se falhar a comunicação com o player. - */ + /** Renderiza o vídeo de LIBRAS. */ + void renderVideo(); + + /** Aguarda o Player capturar as screenshots. */ void waitScreenShots(); - /** Remove os arquivos temporários, gerados pelos processos.*/ + /** Notifica o fim da renderização. */ + void notifyListeners(); + + /** Deleta os arquivos temporários */ void cleanFiles(); + + /** Chamado quando a Thread é iniciada. */ + void Run(); }; -#endif /* RENDERER_H */ +#endif /* RENDERER_H */ \ No newline at end of file diff --git a/renderer/src/renderer.cpp b/renderer/src/renderer.cpp index 8f3577d..2d03978 100644 --- a/renderer/src/renderer.cpp +++ b/renderer/src/renderer.cpp @@ -1,164 +1,176 @@ #include "renderer.h" -Renderer::Renderer(char* videoPath, char* user_id) { - this->folder_id = user_id; - this->path_video = videoPath; - running = true; - count_task = 0; - glosa_processed = 0; - core_socket = new StreamSocket(); - listeners = new list(); - serverInitialize(); - PRINTL(util::_DEBUG, "Renderer Done!\n"); +Renderer::Renderer(char* path_Contents, char* id) { + this->pathOutVideo = path_Contents; + this->userID = id; + cSocket = new StreamSocket(); + listeners = new list(); + PRINTL(util::_DEBUG, "Renderer Done!\n"); } Renderer::~Renderer() { - listeners->clear(); + listeners->clear(); delete listeners; - if(core_socket) delete core_socket; + if(cSocket) delete cSocket; PRINTL(util::_DEBUG, "Renderer finalized!\n"); } -void Renderer::serverInitialize(){ - string render = "python render.py "; - render.append(folder_id).append(" >/dev/null 2>&1 &"); - - string command = "cd "; - char* shPath; - shPath = getenv("RENDERER"); - if(shPath != NULL) - command.append(shPath); - else - command.append(PATH_RENDERER); - - command.append(" && ").append(render); - system(command.c_str()); - sleep(5); +void Renderer::addListener(ListenerRenderer* listener) { + listeners->push_back(listener); } -void Renderer::receiveGlosa(std::string glosa, int64_t pts) { - if(glosa == "SENTENCACOMBAIXAQUALIDADE") - glosa_copy = "_DEFAULT"; - else - glosa_copy = glosa; - - ostringstream oss; - oss << pts; - glosa_copy += "#"; // formato da string enviada p/ o player: Glosa#pts - glosa_copy += oss.str(); - count_task++; +void Renderer::notifyListeners() { + PRINTL(util::_DEBUG, "Renderização finalizada!\n"); + for (list::iterator i = listeners->begin(); i != listeners->end(); i++) { + (*i)->notifyEndOfRenderization(); + } } -void Renderer::sendGlosa() { - try{ - // while(!core_socket->isConnected()) - // sleep(1); +void Renderer::executeServerScript() { + PRINTL(util::_DEBUG, "Executando o Script de inicialização do servidor\n"); - int glosa_size = strlen(glosa_copy.c_str())+1; - char* glosa_buffer = new char[glosa_size]; - strcpy(glosa_buffer, glosa_copy.c_str()); - core_socket->write(glosa_buffer, glosa_size); + string command = "cd "; - char* ok_core = new char[3]; - do { - core_socket->read(ok_core, 3); //aguarda o unity confirmar o recebimento da glosa - }while(strcmp(ok_core, "OK") != 0); - glosa_processed++; + char* renderPath; + renderPath = getenv("RENDERER"); + if(renderPath != NULL) + command.append(renderPath); + else + command.append(PATH_RENDERER); - delete [] ok_core; - delete [] glosa_buffer; + command.append(" && ").append("python render.py ") + .append(userID).append(" >/dev/null 2>&1 &"); - }catch(lavidlib::RuntimeException &ex){ - throw lavidlib::RuntimeException(ex.getMessage().c_str()); - }catch(lavidlib::IOException &ex){ - throw lavidlib::RuntimeException(ex.getMessage().c_str()); - } + system(command.c_str()); + sleep(4); //tempo para inicializar o player } -void Renderer::connectToUnity() { - try{ +void Renderer::connectToUnityPlayer() { + try{ static InetAddress* addr = InetAddress::createByName(HOST); - while(!core_socket->isConnected()){ - PRINTL(util::_DEBUG, "Conectando ao Unity...\n"); - core_socket->connect(addr, PORTNO); + while(!cSocket->isConnected()){ + PRINTL(util::_DEBUG, "Conectando ao UnityPlayer...\n"); + cSocket->connect(addr, PORT); sleep(1); } }catch(lavidlib::UnknownHostException &ex){ - throw RuntimeException(ex.getMessage().c_str()); + throw lavidlib::RuntimeException(ex.getMessage().c_str()); }catch(lavidlib::SocketException &ex){ - throw RuntimeException(ex.getMessage().c_str()); + throw lavidlib::RuntimeException(ex.getMessage().c_str()); } } -void Renderer::waitScreenShots() { - PRINTL(util::_INFO, "Gerando vídeo...\n"); - char* endgeneration = new char[strlen(END_FLAG)+1]; - int connected; - try{ - do{ - connected = core_socket->read(endgeneration, sizeof(endgeneration)); - }while(strcmp(endgeneration, END_FLAG) != 0 && connected != 0); - core_socket->close(); - }catch(IOException &ex){ - throw RuntimeException(ex.getMessage().c_str()); - } +//Armazena as glosas em uma fila até q o método initialize() seja chamado p/ fazer os envios +void Renderer::receiveGlosa(string glosa, int64_t pts) { + ostringstream oss; + string formatedGlosa; //Formato da glosa que será enviada para o player: "glosa#pts" + + if(glosa == BADSENTENCE || glosa == BADTEXT) + formatedGlosa = "_DEFAULT"; //O player entende "#pts" como pose neutra + else + formatedGlosa = glosa; + + oss << pts; + formatedGlosa += "#"; + formatedGlosa += oss.str(); + glosaQueue.push(formatedGlosa); } -void Renderer::addListener(ListenerRenderer* listener) { - listeners->push_back(listener); +void Renderer::exportGlosa() { + if(glosaQueue.empty()) + throw lavidlib::RuntimeException("Fila de glosas vazia!"); + + int glosaSize; + char* glosaBff; + + string glosaCpy = glosaQueue.front(); //Pega quem estiver na frente da fila + glosaSize = strlen(glosaCpy.c_str())+1; + glosaBff = new char[glosaSize]; + strcpy(glosaBff, glosaCpy.c_str()); + + try { + cSocket->write(glosaBff, glosaSize); //Envia a glosa formatada p/ o player + }catch(lavidlib::IOException &ex){ + throw lavidlib::RuntimeException(ex.getMessage().c_str()); + } + + char* received = new char[3]; //Mensagem de confirmação de recebimento da glosa: "OK\0" + do { + try { + cSocket->read(received, 3); //Aguarda a confirmação + }catch(lavidlib::IOException &ex){ + throw lavidlib::RuntimeException(ex.getMessage().c_str()); + } + }while(strcmp(received, OK_FLAG) != 0); //Verifica se é a confirmação correta + + glosaQueue.pop(); //Se o envio foi bem sucedido, remove a glosa da fila + + delete [] glosaBff; + delete [] received; } -void Renderer::notifyListeners() { - PRINTL(util::_DEBUG, "Renderização finalizada!\n"); - for (list::iterator i = listeners->begin(); i != listeners->end(); i++) { - (*i)->notifyEndOfRenderization(); - } +void Renderer::waitScreenShots() { + int endSize; + char* finalize; + + endSize = strlen(END_FLAG)+1; + finalize = new char[endSize]; + + PRINTL(util::_DEBUG, "Aguardando a captura das ScreenShots.\n"); + do { + try { + cSocket->read(finalize, endSize); //Aguarda o player notificar o fim da captura das ScreenShots + }catch(lavidlib::IOException &ex){ + throw lavidlib::RuntimeException(ex.getMessage().c_str()); + } + }while(strcmp(finalize, END_FLAG) != 0); //Verifica se é a mensagem correta ("FINALIZE\0") + + cSocket->close(); } -void Renderer::finalize() { - while(glosa_processed < count_task) - usleep(10000); - receiveGlosa(END_FLAG, (int64_t) -1); - this->running = false; -} +void Renderer::renderVideo() { + PRINTL(util::_INFO, "Gerando vídeo...\n"); -bool Renderer::isSending() { - if(glosa_processed < count_task) - return true; - else - return false; + string command = "ffmpeg -y -loglevel quiet -framerate 30 -i "; + command.append(PATH_SCREENS).append(userID).append("/frame_%d.png ") + .append("-vcodec libx264 -pix_fmt yuv420p ").append(pathOutVideo); + system(command.c_str()); } -void Renderer::Run() { - try{ - while(running){ - while(count_task <= glosa_processed){ - usleep(10000); - } - if(!core_socket->isConnected()) - connectToUnity(); - sendGlosa(); - } - waitScreenShots(); - render(); - cleanFiles(); - }catch(lavidlib::RuntimeException &ex){ - PRINTL(util::_ERROR, "%s\n", ex.getMessage().c_str()); - Logging::instance()->writeLog("renderer.cpp : Falha na comunicação com o Unity player"); - throw RuntimeException(ex.getMessage().c_str()); - } +void Renderer::initialize() { + executeServerScript(); + try{ + connectToUnityPlayer(); + }catch(lavidlib::RuntimeException &ex){ + throw lavidlib::RuntimeException(ex.getMessage().c_str()); + } + this->Start(); } -void Renderer::render() { - string command = "ffmpeg -y -loglevel quiet -framerate 30 -i "; - command.append(PATH_SCREENS).append(folder_id).append("/frame_%d.png ") - .append("-vcodec libx264 -pix_fmt yuv420p ").append(path_video); - system(command.c_str()); - notifyListeners(); +void Renderer::Run() { + PRINTL(util::_DEBUG, "Enviando glosas para o player...\n"); + while(!glosaQueue.empty()){ //Inicia o envio das glosas que estão na fila + try{ + exportGlosa(); + }catch(lavidlib::RuntimeException &ex){ + throw lavidlib::RuntimeException(ex.getMessage().c_str()); + } + } + + receiveGlosa(END_FLAG, -1); //Quando a fila estiver vazia, a flag "FINALIZE" será enviada + try{ + exportGlosa(); + waitScreenShots(); + }catch(lavidlib::RuntimeException &ex){ + throw lavidlib::RuntimeException(ex.getMessage().c_str()); + } + renderVideo(); + notifyListeners(); + cleanFiles(); } void Renderer::cleanFiles() { string clean = "rm -rf "; - clean.append(PATH_SCREENS).append(folder_id).append("/"); + clean.append(PATH_SCREENS).append(userID).append("/"); system(clean.c_str()); } \ No newline at end of file diff --git a/servico/src/serviceWindowGenerationFromRec.cpp b/servico/src/serviceWindowGenerationFromRec.cpp index 83c1294..8e06fe0 100644 --- a/servico/src/serviceWindowGenerationFromRec.cpp +++ b/servico/src/serviceWindowGenerationFromRec.cpp @@ -50,7 +50,6 @@ ServiceWindowGenerationFromRec::~ServiceWindowGenerationFromRec(){ if (tradutor) delete tradutor; if (renderer) delete renderer; if (rec) delete rec; - if (mixer) delete mixer; PRINTL(util::_DEBUG, "Service Rec finished!\n"); } @@ -123,7 +122,7 @@ void ServiceWindowGenerationFromRec::setSizeOfSubtitles(int sub_size){ numero_legendas = sub_size; if (legendas_enviadas >= numero_legendas){ try{ - renderer->finalize(); + renderer->initialize(); }catch(lavidlib::RuntimeException &ex){ throw ServiceException(ex.getMessage().c_str()); } @@ -146,8 +145,6 @@ void ServiceWindowGenerationFromRec::notifyTextRecognized(unsigned char* text, i void ServiceWindowGenerationFromRec::notifyTranslation(char* glosa) { string sGlosa(reinterpret_cast(glosa)); - while(renderer->isSending()) - usleep(10000); try{ renderer->receiveGlosa(sGlosa, vetor_pts->front()); legendas_enviadas++; @@ -157,12 +154,12 @@ void ServiceWindowGenerationFromRec::notifyTranslation(char* glosa) { vetor_pts->erase(vetor_pts->begin()); } -void ServiceWindowGenerationFromRec::notifyEndOfRenderization() { - mixer = new Mixer(this->path_input, this->path_libras, this->size, this->position, - this->transparency, this->user_id, this->path_uploads, this->path_contents); - +void ServiceWindowGenerationFromRec::notifyEndOfRenderization() { if(this->service_type == SERVICE_TYPE_REC){ + mixer = new Mixer(this->path_input, this->path_libras, this->size, this->position, + this->transparency, this->user_id, this->path_uploads, this->path_contents); mixer->initialize(); + delete mixer; } running = false; } @@ -190,7 +187,6 @@ void ServiceWindowGenerationFromRec::initialize(){ renderer->addListener(this); try{ - renderer->Start(); rec->initialize(); } catch(RecognizeException ex){ throw ServiceException(ex.getMessage()); diff --git a/servico/src/serviceWindowGenerationFromSRT.cpp b/servico/src/serviceWindowGenerationFromSRT.cpp index 81e346c..099dc33 100644 --- a/servico/src/serviceWindowGenerationFromSRT.cpp +++ b/servico/src/serviceWindowGenerationFromSRT.cpp @@ -49,8 +49,8 @@ ServiceWindowGenerationFromSRT::ServiceWindowGenerationFromSRT(char* pathSRT, in ServiceWindowGenerationFromSRT::~ServiceWindowGenerationFromSRT() { free(vetor_pts); - if (this->mixer) delete mixer; if (tradutor) delete tradutor; + // if (mixer) delete mixer; if (renderer) delete renderer; if (extratorSRT)delete extratorSRT; if (extrator_factory) delete extrator_factory; @@ -123,7 +123,7 @@ void ServiceWindowGenerationFromSRT::setSizeOfSubtitles(int sub_size) { numero_legendas = sub_size; if (legendas_enviadas >= numero_legendas){ try{ - renderer->finalize(); + renderer->initialize(); }catch(lavidlib::RuntimeException &ex){ throw ServiceException(ex.getMessage().c_str()); } @@ -158,8 +158,6 @@ void ServiceWindowGenerationFromSRT::notifyTranslation(char* glosa) { } void ServiceWindowGenerationFromSRT::notifyRenderer(string glosa) { - while(renderer->isSending()) - usleep(10000); try{ renderer->receiveGlosa(glosa, vetor_pts->front()); legendas_enviadas++; @@ -170,11 +168,11 @@ void ServiceWindowGenerationFromSRT::notifyRenderer(string glosa) { } void ServiceWindowGenerationFromSRT::notifyEndOfRenderization() { - mixer = new Mixer(this->path_input, this->path_libras, this->size, this->position, - this->transparency, this->user_id, this->path_uploads, this->path_contents); - if(this->service_type == SERVICE_TYPE_SRT){ + mixer = new Mixer(this->path_input, this->path_libras, this->size, this->position, + this->transparency, this->user_id, this->path_uploads, this->path_contents); mixer->initialize(); + delete mixer; } this->running = false; } @@ -207,8 +205,7 @@ void ServiceWindowGenerationFromSRT::initialize() { renderer = new Renderer(this->path_libras ,this->user_id); renderer->addListener(this); - try{ - renderer->Start(); + try{ extratorSRT->initialize(); }catch(ExtratorException ex){ throw ServiceException(ex.getMessage()); diff --git a/servico/src/serviceWindowGenerationFromText.cpp b/servico/src/serviceWindowGenerationFromText.cpp index 4eca40b..0cc2f5e 100644 --- a/servico/src/serviceWindowGenerationFromText.cpp +++ b/servico/src/serviceWindowGenerationFromText.cpp @@ -83,7 +83,7 @@ void ServiceWindowGenerationFromText::setSizeOfSubtitles(int sub_size) { numero_legendas = sub_size; if (legendas_enviadas >= numero_legendas){ try{ - renderer->finalize(); + renderer->initialize(); }catch(lavidlib::RuntimeException &ex){ throw ServiceException(ex.getMessage().c_str()); } @@ -109,8 +109,6 @@ void ServiceWindowGenerationFromText::notifyTranslation(char* glosa) { } void ServiceWindowGenerationFromText::notifyRenderer(string glosa) { - while(renderer->isSending()) - usleep(10000); try{ renderer->receiveGlosa(glosa, (int64_t) -1); legendas_enviadas++; @@ -152,7 +150,6 @@ void ServiceWindowGenerationFromText::initialize() { renderer->addListener(this); try{ - renderer->Start(); extratorTXT->initialize(); }catch(ExtratorException ex){ throw ServiceException(ex.getMessage().c_str()); -- libgit2 0.21.2