Commit ff86d204 authored by Jan Gerber's avatar Jan Gerber

Re-enable deinterlace option using libavfilter

based on patch by Andreas Cadhalpun from Debian
parent f4800440
0.30 2014-12-12
- various bugfixes
- update to compile with ffmpeg 2.9
0.29 2012-06-25
- use GPL 2 or later, to make use of some decoders only available
in GPL 2 version of ffmpeg
......
......@@ -155,7 +155,7 @@ static AVFrame *frame_alloc(int pix_fmt, int width, int height) {
size = avpicture_get_size (pix_fmt, width, height);
picture_buf = av_malloc (size);
if (!picture_buf) {
av_free (picture);
av_frame_free (&picture);
return NULL;
}
avpicture_fill((AVPicture *) picture, picture_buf, pix_fmt, width, height);
......@@ -168,7 +168,7 @@ static AVFrame *frame_alloc(int pix_fmt, int width, int height) {
static void frame_dealloc(AVFrame *frame) {
if (frame) {
avpicture_free((AVPicture*)frame);
av_free(frame);
av_frame_free(&frame);
}
}
......@@ -522,6 +522,74 @@ static const char *find_language_for_subtitle_stream(const AVStream *s)
return lang;
}
static void delete_filter_graph(ff2theora this) {
if (this->filter_graph) {
av_frame_free(&this->filter_frame);
avfilter_graph_free(&this->filter_graph);
}
}
static int init_filter_graph(ff2theora this, enum AVPixelFormat pixfmt, int width, int height) {
AVFilterInOut *inputs = NULL, *outputs = NULL;
char args[512];
int res;
delete_filter_graph(this);
this->filter_graph = avfilter_graph_alloc();
snprintf(args, sizeof(args),
"buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
"[in]yadif[out];"
"[out]buffersink",
width, height, pixfmt);
res = avfilter_graph_parse2(this->filter_graph, args, &inputs, &outputs);
if (res < 0)
return res;
if(inputs || outputs)
return -1;
res = avfilter_graph_config(this->filter_graph, NULL);
if (res < 0)
return res;
this->buffersrc_ctx = avfilter_graph_get_filter(this->filter_graph, "Parsed_buffer_0");
this->buffersink_ctx = avfilter_graph_get_filter(this->filter_graph, "Parsed_buffersink_2");
if (!this->buffersrc_ctx || !this->buffersink_ctx)
return -1;
this->filter_frame = av_frame_alloc();
this->last_width = width;
this->last_height = height;
this->last_pixfmt = pixfmt;
return 0;
}
static int process_filter_graph(ff2theora this, AVPicture *dst, const AVPicture *src,
enum AVPixelFormat pixfmt, int width, int height) {
int res;
if (!this->filter_graph || width != this->last_width ||
height != this->last_height || pixfmt != this->last_pixfmt) {
res = init_filter_graph(this, pixfmt, width, height);
if (res < 0)
return res;
}
memcpy(this->filter_frame->data, src->data, sizeof(src->data));
memcpy(this->filter_frame->linesize, src->linesize, sizeof(src->linesize));
this->filter_frame->width = width;
this->filter_frame->height = height;
this->filter_frame->format = pixfmt;
res = av_buffersrc_add_frame(this->buffersrc_ctx, this->filter_frame);
if (res < 0)
return res;
res = av_buffersink_get_frame(this->buffersink_ctx, this->filter_frame);
if (res < 0)
return res;
av_picture_copy(dst, (const AVPicture *) this->filter_frame, pixfmt, width, height);
av_frame_unref(this->filter_frame);
return 0;
}
void ff2theora_output(ff2theora this) {
unsigned int i;
AVCodecContext *aenc = NULL;
......@@ -1471,17 +1539,15 @@ void ff2theora_output(ff2theora this) {
display_width, display_height);
output_tmp_p=NULL;
}
/*
if ((this->deinterlace==0 && frame->interlaced_frame) ||
this->deinterlace==1) {
if (avpicture_deinterlace((AVPicture *)output,(AVPicture *)output_tmp,this->pix_fmt,display_width,display_height)<0) {
if (process_filter_graph(this, (AVPicture *)output,(AVPicture *)output_tmp,this->pix_fmt,display_width,display_height)<0) {
fprintf(stderr, "Deinterlace failed.\n");
exit(1);
}
}
else
*/
{
av_picture_copy((AVPicture *)output, (AVPicture *)output_tmp, this->pix_fmt,
display_width, display_height);
......@@ -1821,7 +1887,7 @@ void ff2theora_output(ff2theora this) {
if (ppContext)
pp_free_context(ppContext);
if (!info.audio_only) {
av_free(frame_p);
av_frame_free(&frame_p);
frame_dealloc(output_p);
frame_dealloc(output_tmp_p);
frame_dealloc(output_resized_p);
......@@ -1842,6 +1908,7 @@ void ff2theora_output(ff2theora this) {
}
void ff2theora_close(ff2theora this) {
delete_filter_graph(this);
sws_freeContext(this->sws_colorspace_ctx);
sws_freeContext(this->sws_scale_ctx);
this->sws_colorspace_ctx = NULL;
......
......@@ -2,6 +2,9 @@
#define _F2T_FFMPEG2THEORA_H_
#include "subtitles.h"
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersrc.h>
#include <libavfilter/buffersink.h>
typedef struct ff2theora_subtitle{
char *text;
......@@ -117,6 +120,13 @@ typedef struct ff2theora{
unsigned char y_lut[256];
unsigned char uv_lut[256];
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
AVFrame *filter_frame;
int last_width;
int last_height;
enum AVPixelFormat last_pixfmt;
}
*ff2theora;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment