fixed blurs causing black frames and added backend for stabilizer

This commit is contained in:
itsmattkc
2018-12-08 16:37:34 +11:00
parent 0e2632e578
commit f21742c2f3
6 changed files with 26 additions and 45 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ uniform bool horiz_blur;
uniform bool vert_blur;
void main(void) {
float rad = floor(radius);
float rad = ceil(radius);
float x_rad = (horiz_blur) ? rad : 0.5;
float y_rad = (vert_blur) ? rad : 0.5;
vec2 texCoord = gl_FragCoord.xy/resolution;
+3 -2
View File
@@ -11,12 +11,13 @@ uniform vec2 resolution;
void main(void) {
if (length > 0.0) {
float ceillen = ceil(length);
float radians = (angle*M_PI)/180.0;
float divider = 1.0 / length;
float divider = 1.0 / ceillen;
float sin_angle = sin(radians);
float cos_angle = cos(radians);
for (float i=-length+0.5;i<=length;i+=2.0) {
for (float i=-ceillen+0.5;i<=ceillen;i+=2.0) {
float y = sin_angle * i;
float x = cos_angle * i;
gl_FragColor += texture2D(image, vec2(gl_FragCoord.x+x, gl_FragCoord.y+y)/resolution)*(divider);
+1 -1
View File
@@ -24,7 +24,7 @@ void main(void) {
if (radius == 0.0 || sigma == 0.0 || (!horiz_blur && !vert_blur)) {
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution);
} else {
float rad = floor(radius);
float rad = ceil(radius);
float x_rad = horiz_blur ? rad : 0.5;
float y_rad = vert_blur ? rad : 0.5;
+19 -38
View File
@@ -456,9 +456,7 @@ void cache_video_worker(Clip* c, long playhead) {
MediaStream* ms = media->get_stream_from_file_index(true, c->media_stream);
while ((retr_ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) {
if (c->multithreaded && c->cacher->interrupt) { // abort
return;
}
if (c->multithreaded && c->cacher->interrupt) return; // abort
AVFrame* send_frame = c->frame;
read_ret = (c->use_existing_frame) ? 0 : retrieve_next_frame(c, send_frame);
@@ -476,11 +474,11 @@ void cache_video_worker(Clip* c, long playhead) {
dout << "skipped adding a frame to the queue - fpts:" << send_frame->pts << "target:" << target_pts;
}*/
if (send_it) {
if (send_it) {
if ((send_ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, send_frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) {
dout << "[ERROR] Failed to add frame to buffer source." << send_ret;
break;
}
}
}
av_frame_unref(c->frame);
@@ -693,27 +691,7 @@ void open_clip_worker(Clip* clip) {
}
char filter_args[512];
if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
/* SKIP_TYPE_SEEK is used if a video is playing at a speed so fast
* that it is quicker to seek to the next frame than to just play
* up to it (e.g. 2000% speed would require playing and skipping
* 20 frames per frame and it many cases it would be quicker to
* seek to it and cache in memory instead.
*
* TODO there could probably be a better heuristic than
* (speed >= 5) for using seek mode. Experiment with the value
* but also in the future perhaps we could implement a system
* of testing how long it takes to seek vs how long it takes to
* decode a frame and compare them to choose with method.
*/
clip->skip_type = (clip->speed < 5) ? SKIP_TYPE_DISCARD : SKIP_TYPE_SEEK;
// create memory cache for video (deprecated)
// clip->cache_size = (ms->infinite_length) ? 1 : ceil(av_q2d(clip->stream->avg_frame_rate)/4); // cache is half a second in total
// if (clip->skip_type == SKIP_TYPE_SEEK) clip->cache_size *= 2;
// if (ms->video_interlacing != VIDEO_PROGRESSIVE) clip->cache_size *= 2;
if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
snprintf(filter_args, sizeof(filter_args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
clip->stream->codecpar->width,
clip->stream->codecpar->height,
@@ -727,39 +705,42 @@ void open_clip_worker(Clip* clip) {
avfilter_graph_create_filter(&clip->buffersrc_ctx, avfilter_get_by_name("buffer"), "in", filter_args, NULL, clip->filter_graph);
avfilter_graph_create_filter(&clip->buffersink_ctx, avfilter_get_by_name("buffersink"), "out", NULL, NULL, clip->filter_graph);
enum AVPixelFormat pix_fmts[] = { static_cast<AVPixelFormat>(dest_format), AV_PIX_FMT_NONE };
if (av_opt_set_int_list(clip->buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN) < 0) {
dout << "[ERROR] Could not set output pixel format";
}
/*enum AVPixelFormat sinkpix_fmts[] = { static_cast<AVPixelFormat>(dest_format), AV_PIX_FMT_NONE };
if (av_opt_set_int_list(clip->buffersink_ctx, "pix_fmts", sinkpix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN) < 0) {
dout << "[ERROR] Could not set output pixel format";
}*/
AVFilterContext* last_filter = clip->buffersrc_ctx;
if (ms->video_interlacing != VIDEO_PROGRESSIVE) {
AVFilterContext* yadif_filter;
char yadif_args[100];
snprintf(yadif_args, sizeof(yadif_args), "mode=3:parity=%d", ((ms->video_interlacing == VIDEO_TOP_FIELD_FIRST) ? 0 : 1)); // try mode 1
snprintf(yadif_args, sizeof(yadif_args), "mode=3:parity=%d", ((ms->video_interlacing == VIDEO_TOP_FIELD_FIRST) ? 0 : 1)); // there's a CUDA version if we start using nvdec/nvenc
avfilter_graph_create_filter(&yadif_filter, avfilter_get_by_name("yadif"), "yadif", yadif_args, NULL, clip->filter_graph);
avfilter_link(last_filter, 0, yadif_filter, 0);
last_filter = yadif_filter;
}
/* stabilization code one day
if (false) {
/* stabilization code one day */
bool stabilize = false;
if (stabilize) {
AVFilterContext* stab_filter;
int stab_ret = avfilter_graph_create_filter(&stab_filter, avfilter_get_by_name("vidstabtransform"), "vidstab", "input=C\\:/Users/Matt/Desktop/samples/transforms.trf", NULL, clip->filter_graph);
int stab_ret = avfilter_graph_create_filter(&stab_filter, avfilter_get_by_name("vidstabtransform"), "vidstab", "input=/media/matt/Home/samples/transforms.trf", NULL, clip->filter_graph);
if (stab_ret < 0) {
char err[100];
av_strerror(stab_ret, err, sizeof(err));
dout << "stab ret:" << stab_ret << err;
} else {
dout << "link 1:" << avfilter_link(last_filter, 0, stab_filter, 0);
avfilter_link(last_filter, 0, stab_filter, 0);
last_filter = stab_filter;
}
}
*/
avfilter_link(last_filter, 0, clip->buffersink_ctx, 0);
AVFilterContext* format_conv;
avfilter_graph_create_filter(&format_conv, avfilter_get_by_name("format"), "fmt", "pix_fmts=rgba", NULL, clip->filter_graph);
avfilter_link(last_filter, 0, format_conv, 0);
avfilter_link(format_conv, 0, clip->buffersink_ctx, 0);
avfilter_graph_config(clip->filter_graph, NULL);
} else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+1 -2
View File
@@ -96,8 +96,7 @@ struct Clip
bool pkt_written;
bool open;
bool finished_opening;
bool replaced;
int skip_type;
bool replaced;
bool ignore_reverse;
// caching functions
+1 -1
View File
@@ -52,7 +52,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
format.setDepthBufferSize(24);
setFormat(format);
// error handler - retries after 500ms if we couldn't get the entire image
// error handler - retries after 50ms if we couldn't get the entire image
retry_timer.setInterval(50);
connect(&retry_timer, SIGNAL(timeout()), this, SLOT(retry()));