code cleanups and fixed gif export #360
This commit is contained in:
+24
-15
@@ -38,7 +38,6 @@ ExportThread::ExportThread(QObject *parent) :
|
||||
vcodec = nullptr;
|
||||
vcodec_ctx = nullptr;
|
||||
video_frame = nullptr;
|
||||
sws_frame = nullptr;
|
||||
sws_ctx = nullptr;
|
||||
audio_stream = nullptr;
|
||||
acodec = nullptr;
|
||||
@@ -125,18 +124,17 @@ bool ExportThread::setupVideo() {
|
||||
vcodec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
if (vcodec_ctx->codec_id == AV_CODEC_ID_H264) {
|
||||
/*char buffer[50];
|
||||
itoa(vcodec_ctx, buffer, 10);*/
|
||||
|
||||
//av_opt_set(vcodec_ctx->priv_data, "preset", "fast", AV_OPT_SEARCH_CHILDREN);
|
||||
//av_opt_set(vcodec_ctx->priv_data, "x264opts", "opencl", AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
switch (vcodec_ctx->codec_id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
switch (video_compression_type) {
|
||||
case COMPRESSION_TYPE_CFR:
|
||||
av_opt_set(vcodec_ctx->priv_data, "crf", QString::number(static_cast<int>(video_bitrate)).toUtf8(), AV_OPT_SEARCH_CHILDREN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AV_CODEC_ID_GIF:
|
||||
av_opt_set(vcodec_ctx->priv_data, "image", "1", AV_OPT_SEARCH_CHILDREN);
|
||||
break;
|
||||
}
|
||||
|
||||
AVDictionary* opts = nullptr;
|
||||
@@ -180,12 +178,6 @@ bool ExportThread::setupVideo() {
|
||||
nullptr
|
||||
);
|
||||
|
||||
sws_frame = av_frame_alloc();
|
||||
sws_frame->format = vcodec_ctx->pix_fmt;
|
||||
sws_frame->width = video_width;
|
||||
sws_frame->height = video_height;
|
||||
av_frame_get_buffer(sws_frame, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -369,12 +361,30 @@ void ExportThread::run() {
|
||||
// encode last frame while rendering next frame
|
||||
double timecode_secs = (double) (sequence->playhead-start_frame) / sequence->frame_rate;
|
||||
if (video_enabled) {
|
||||
// create sws_frame for converting pixel format
|
||||
|
||||
//
|
||||
// - I'm not sure why, but we have to alloc/free sws_frame every frame, or it breaks GIF exporting.
|
||||
// - (i.e. GIFs get stuck on the first frame)
|
||||
// - The same problem/solution can be seen here: https://stackoverflow.com/a/38997739
|
||||
// - Perhaps this is the intended way to use swscale, but it seems inefficient.
|
||||
// - Anyway, here we are.
|
||||
//
|
||||
|
||||
sws_frame = av_frame_alloc();
|
||||
sws_frame->format = vcodec_ctx->pix_fmt;
|
||||
sws_frame->width = video_width;
|
||||
sws_frame->height = video_height;
|
||||
av_frame_get_buffer(sws_frame, 0);
|
||||
|
||||
// change pixel format
|
||||
sws_scale(sws_ctx, video_frame->data, video_frame->linesize, 0, video_frame->height, sws_frame->data, sws_frame->linesize);
|
||||
sws_frame->pts = qRound(timecode_secs/av_q2d(video_stream->time_base));
|
||||
|
||||
// send to encoder
|
||||
if (!encode(fmt_ctx, vcodec_ctx, sws_frame, &video_pkt, video_stream, false)) continueEncode = false;
|
||||
|
||||
av_frame_free(&sws_frame);
|
||||
}
|
||||
if (audio_enabled) {
|
||||
// do we need to encode more audio samples?
|
||||
@@ -481,7 +491,6 @@ void ExportThread::run() {
|
||||
|
||||
if (sws_ctx != nullptr) {
|
||||
sws_freeContext(sws_ctx);
|
||||
av_frame_free(&sws_frame);
|
||||
}
|
||||
if (swr_ctx != nullptr) {
|
||||
swr_free(&swr_ctx);
|
||||
|
||||
Reference in New Issue
Block a user