Add MP4 output using xvidcore (raw MP4 without container).
This commit is contained in:
parent
c98358da83
commit
d5c449fb5f
4 changed files with 134 additions and 6 deletions
|
|
@ -122,6 +122,7 @@
|
|||
|
||||
#include "video_png.h"
|
||||
#include "video_vpx.h"
|
||||
#include "video_xvid.h"
|
||||
#include "boosty.h"
|
||||
#include "FontCache.h"
|
||||
|
||||
|
|
@ -524,6 +525,7 @@ MainWindow::MainWindow(const QString &filename)
|
|||
|
||||
animationFormatComboBox->addItem("PNG Images", 0);
|
||||
animationFormatComboBox->addItem("WebM Video (VP8)", 1);
|
||||
animationFormatComboBox->addItem("MP4", 2);
|
||||
connect(this->actionAnimationPlay, SIGNAL(triggered()), this, SLOT(animationStart()));
|
||||
connect(this->actionAnimationStop, SIGNAL(triggered()), this, SLOT(animationStop()));
|
||||
connect(this->animationFormatComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(videoExportChanged(int)));
|
||||
|
|
@ -1840,12 +1842,18 @@ void MainWindow::csgRender()
|
|||
double s = this->e_fsteps->text().toDouble();
|
||||
double t = this->e_tval->text().toDouble();
|
||||
if (video == NULL) {
|
||||
if (this->animationFormatComboBox->currentIndex() == 0) {
|
||||
video = new PngVideo(img.width(), img.height());
|
||||
} else {
|
||||
switch (this->animationFormatComboBox->currentIndex()) {
|
||||
case 1:
|
||||
video = new VpxVideo(img.width(), img.height());
|
||||
break;
|
||||
case 2:
|
||||
video = new XvidVideo(img.width(), img.height());
|
||||
break;
|
||||
default:
|
||||
video = new PngVideo(img.width(), img.height());
|
||||
break;
|
||||
}
|
||||
video->open("");
|
||||
video->open("test");
|
||||
}
|
||||
video->exportFrame(img, s, t);
|
||||
}
|
||||
|
|
|
|||
93
src/video_xvid.cc
Normal file
93
src/video_xvid.cc
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "video_xvid.h"
|
||||
|
||||
XvidVideo::XvidVideo(const int width, const int height)
|
||||
{
|
||||
this->width = width & ~1;
|
||||
this->height = height & ~1;
|
||||
printf("width = %d, height = %d\n", width, height);
|
||||
|
||||
memset(&_gbl_init, 0, sizeof (xvid_gbl_init_t));
|
||||
_gbl_init.version = XVID_VERSION;
|
||||
xvid_global(NULL, XVID_GBL_INIT, &_gbl_init, NULL);
|
||||
}
|
||||
|
||||
XvidVideo::~XvidVideo()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
XvidVideo::open(const QString fileName)
|
||||
{
|
||||
printf("XvidVideo::open()\n");
|
||||
|
||||
init_ok = false;
|
||||
|
||||
double fps_den = 1;
|
||||
memset(&_enc_create, 0, sizeof (xvid_enc_create_t));
|
||||
_enc_create.version = XVID_VERSION;
|
||||
_enc_create.width = width;
|
||||
_enc_create.height = height;
|
||||
_enc_create.zones = NULL;
|
||||
_enc_create.fincr = fps_den;
|
||||
_enc_create.fbase = 50;
|
||||
_enc_create.max_key_interval = 500 / fps_den;
|
||||
_enc_create.bquant_ratio = 150;
|
||||
_enc_create.bquant_offset = 100;
|
||||
|
||||
memset(&_plugin_single, 0, sizeof(xvid_plugin_single_t));
|
||||
_plugin_single.version = XVID_VERSION;
|
||||
|
||||
_plugins[0].func = xvid_plugin_single;
|
||||
_plugins[0].param = &_plugin_single;
|
||||
|
||||
_enc_create.plugins = _plugins;
|
||||
_enc_create.num_plugins = 1;
|
||||
|
||||
xvid_encore(NULL, XVID_ENC_CREATE, &_enc_create, NULL);
|
||||
|
||||
f = fopen(fileName.toStdString().c_str(), "wb+");
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
buf = new unsigned char[width * height * 4];
|
||||
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
void
|
||||
XvidVideo::close()
|
||||
{
|
||||
printf("XvidVideo::close()\n");
|
||||
|
||||
xvid_encore(_enc_create.handle, XVID_ENC_DESTROY, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
XvidVideo::exportFrame(const QImage frame, const double, const double)
|
||||
{
|
||||
const QImage scaled = frame.scaled(width, height).convertToFormat(QImage::Format_RGB32);
|
||||
|
||||
xvid_enc_frame_t enc_frame;
|
||||
memset(&enc_frame, 0, sizeof(xvid_enc_frame_t));
|
||||
|
||||
const uchar *bits = scaled.bits();
|
||||
unsigned char *bitstream = new unsigned char[width * height * 4];
|
||||
enc_frame.version = XVID_VERSION;
|
||||
enc_frame.bitstream = bitstream;
|
||||
enc_frame.length = -1;
|
||||
enc_frame.input.plane[0] = (void *)bits;
|
||||
enc_frame.input.csp = XVID_CSP_BGRA;
|
||||
enc_frame.input.stride[0] = scaled.bytesPerLine();
|
||||
enc_frame.vol_flags = 0;
|
||||
enc_frame.vop_flags = XVID_VOP_HALFPEL | XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED;
|
||||
enc_frame.type = XVID_TYPE_AUTO;
|
||||
enc_frame.quant = 0.8;
|
||||
enc_frame.motion = XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8;
|
||||
|
||||
int size = xvid_encore(_enc_create.handle, XVID_ENC_ENCODE, &enc_frame, NULL);
|
||||
bool write_ok = fwrite(bitstream, 1, size, f) == (size_t)size;
|
||||
delete bitstream;
|
||||
}
|
||||
27
src/video_xvid.h
Normal file
27
src/video_xvid.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <xvid.h>
|
||||
|
||||
#include "video.h"
|
||||
|
||||
class XvidVideo : public AbstractVideo
|
||||
{
|
||||
private:
|
||||
bool init_ok;
|
||||
int width, height;
|
||||
|
||||
FILE *f;
|
||||
unsigned char *buf;
|
||||
xvid_gbl_init_t _gbl_init;
|
||||
xvid_enc_create_t _enc_create;
|
||||
xvid_plugin_single_t _plugin_single;
|
||||
xvid_enc_plugin_t _plugins[1];
|
||||
|
||||
public:
|
||||
XvidVideo(const int width, const int height);
|
||||
virtual ~XvidVideo();
|
||||
|
||||
virtual void open(const QString fileName);
|
||||
virtual void close();
|
||||
virtual void exportFrame(const QImage frame, const double s, const double t);
|
||||
};
|
||||
|
|
@ -43,8 +43,8 @@ XVIDCORE_DIR = $$(XVIDCOREDIR)
|
|||
LIBS += -L$$XVIDCORE_LIBPATH -lxvidcore
|
||||
DEFINES += ENABLE_VIDEO_XVID
|
||||
|
||||
# HEADERS += src/video_xvid.h
|
||||
# SOURCES += src/video_xvid.cc
|
||||
HEADERS += src/video_xvid.h
|
||||
SOURCES += src/video_xvid.cc
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue