Add MP4 output using xvidcore (raw MP4 without container).

This commit is contained in:
Torsten Paul 2016-09-28 18:51:26 +02:00
parent c98358da83
commit d5c449fb5f
4 changed files with 134 additions and 6 deletions

View file

@ -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
View 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
View 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);
};

View file

@ -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
}
}