Я хотел бы записать видео MPEG от движения камеры в SoQtExaminerViewer
, Первоначальная проблема заключается в том, что, когда я позвонил SoMpegNavRenderer::stop()
, зритель должен ждать завершения кода. Таким образом, я попытался использовать std::thread()
а также std::async()
создать новый поток, который будет обрабатывать запись видео в формате MPEG. Я считал, что запись уже происходит в фоновом режиме и способна создавать видео.
Тем не менее, (это тот, который мне нужна помощь и понимание), когда код достиг SoMpegNavRenderer::stop()
область просмотра / рендеринга в SoQtExaminerViewer
Воспроизвести / перерисовать обратно видео в формате MPEG от начала до того, как пользователь сможет получить контроль над зрителем. Я хочу, чтобы пользователь нажал р чтобы сделать запись, сделайте некоторое движение камеры и нажмите с чтобы остановить запись, сохранить видео и продолжить их работу.
Ниже приведен полный код:
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#include <Inventor/events/SoKeyboardEvent.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/MPEG/SoMPEGNavRenderer.h>
// Use Open Inventor's portable thread classes
#include <Inventor/threads/SbThread.h>
SoQtExaminerViewer *myViewer;
SoMPEGNavRenderer *MPEGRenderer;
// Forward decls
SoGroup *getConeGroup(SbVec3f color) ;
void myKeyPressCB (void *, SoEventCallback *eventCB);
void startRecord();
void* stopRecord(void *userData);
int main(int, char **argv)
{
// Initialize Open Inventor. --------------------------------------
QWidget *myWindow = SoQt::threadInit(argv[0]); // pass the app name
myWindow->resize(500,500);
if (myWindow == NULL)
return 1;
// Create scene graph ----------------------------------------------
SoSeparator *root = new SoSeparator();
root->ref();
SoLightModel *lModel = new SoLightModel ;
lModel->model = SoLightModel::BASE_COLOR ;
root->addChild(lModel) ;
SoOrthographicCamera *camera = new SoOrthographicCamera();
camera->ref();
root->addChild(camera);
root->addChild(getConeGroup(SbVec3f(1.0,0.0,0.0)));
SoEventCallback *myEventCB = new SoEventCallback;
myEventCB->addEventCallback(SoKeyboardEvent::getClassTypeId(),
myKeyPressCB, myViewer);
root->addChild(myEventCB);
// Create viewer ---------------------------------------------------
myViewer = new SoQtExaminerViewer(myWindow);
myViewer->setSceneGraph(root);
myViewer->setTitle("Movie with thread");
myViewer->show();
// Create mpegrenderer ---------------------------------------------
MPEGRenderer = new SoMPEGNavRenderer (myViewer->getSceneManager()->getSceneGraph());
MPEGRenderer->setSize (SbVec2s (300, 300));
MPEGRenderer->adjustNumFramesPerSecond(TRUE);
MPEGRenderer->setBitPerSec(-1);
MPEGRenderer->setCompressionRate(0.);
MPEGRenderer->setShareContext( (myViewer->getShareContext()));
int i = 0;
char mpegFileName[20] = "MPEGOutput.mpg";
while (!MPEGRenderer->openFile(mpegFileName))
{
sprintf(mpegFileName, "MPEGOutput%d.mpg", i);
i++;
}
SoQt::show(myWindow);
SoQt::mainLoop();
delete myViewer;
root->unref();
SoQt::finish();
return 0;
}
void* stopRecord(void *userData)
{
SoDB::threadInit();
// Get pointer to mpegrenderer
SoMPEGNavRenderer *pMpegRenderer = (SoMPEGNavRenderer *)userData;
pMpegRenderer->stop();
pMpegRenderer->closeFile();
return NULL;
}
void startRecord()
{
MPEGRenderer->record();
}
void myKeyPressCB (void *, SoEventCallback *eventCB)
{
const SoEvent *event = eventCB->getEvent();
// check for the keys being pressed
if (SO_KEY_PRESS_EVENT(event, R))
{
startRecord();
}
else if (SO_KEY_PRESS_EVENT(event, C))
{
SbThread *pModifyThread = SbThread::create(stopRecord, (void*)MPEGRenderer);
}
else if (SO_KEY_PRESS_EVENT(event, Z))
{
exit(0);
}
}
SoGroup *getConeGroup(SbVec3f color)
{
SoGroup *grp = new SoSeparator();
SoMaterial *mat = new SoMaterial();
SoCone *cone = new SoCone();
SoTransform *trans = new SoTransform();
trans->rotation.setValue(1.0,0.0,0.0,-3.14);
mat->diffuseColor.setValue(color);
grp->addChild(mat);
grp->addChild(trans);
grp->addChild(cone);
return grp;
}
Задача ещё не решена.
Других решений пока нет …