Ticket #25: yadif-libavfilter.c

File yadif-libavfilter.c, 6.1 KB (added by fpretto, 6 years ago)
Line 
1/*
2* API example for libavfilter
3* Copyright (c) 2010 Nicolas George
4*
5* This file is part of FFmpeg.
6*
7* FFmpeg is free software; you can redistribute it and/or
8* modify it under the terms of the GNU Lesser General Public
9* License as published by the Free Software Foundation; either
10* version 2.1 of the License, or (at your option) any later version.
11*
12* FFmpeg is distributed in the hope that it will be useful,
13* but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15* Lesser General Public License for more details.
16*
17* You should have received a copy of the GNU Lesser General Public
18* License along with FFmpeg; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#include "stdafx.h"
23
24#include <stdio.h>
25#include <stdlib.h>
26
27extern "C" {
28#include <libavformat/avformat.h>
29#include <libavcodec/avcodec.h>
30#include <libavfilter/avfiltergraph.h>
31#include <libavfilter/vsrc_buffer.h>
32}
33
34const char *filter_descr = "yadif=1:-1";
35
36static AVFormatContext *avf;
37static AVCodecContext *video_dec;
38AVFilterContext *video_in_filter;
39AVFilterContext *video_out_filter;
40AVFilterGraph *filter_graph;
41static int video_stream = -1;
42static int64_t last_pts = AV_NOPTS_VALUE;
43
44static void fatal_libav_error(const char *tag, int r)
45{
46    char buf[1024];
47
48    av_strerror(r, buf, sizeof(buf));
49    fprintf(stderr, "%s: %s\n", tag, buf);
50    exit(1);
51}
52
53static void open_input_file(const char *filename)
54{
55    int r, i;
56    AVCodec *codec;
57    AVCodecContext *avc;
58
59    avcodec_register_all();
60    av_register_all();
61    r = av_open_input_file(&avf, filename, NULL, 0, NULL);
62    if (r < 0)
63        fatal_libav_error("av_open_input_file", r);
64    r = av_find_stream_info(avf);
65    if (r < 0)
66        fatal_libav_error("av_find_stream_info", r);
67
68    /* Find a video stream */
69    for (i = 0; i < (int)avf->nb_streams; i++) {
70        avc = avf->streams[i]->codec;
71        if (!video_dec && avc->codec_type == CODEC_TYPE_VIDEO) {
72            video_dec = avc;
73            video_stream = i;
74        }
75    }
76    /* Init the video decoder */
77    if (video_dec) {
78        codec = avcodec_find_decoder(video_dec->codec_id);
79        if (!codec) {
80            fprintf(stderr, "Unable to find video decoder\n");
81            exit(1);
82        }
83        r = avcodec_open(video_dec, codec);
84        if (r < 0)
85            fatal_libav_error("avcodec_open", r);
86    }
87}
88
89static void init_filters(const char *filters)
90{
91    char args[256];
92    int r;
93    AVFilter *vf_buffer = avfilter_get_by_name("buffer");
94    AVFilter *vf_nullsink = avfilter_get_by_name("nullsink");
95    AVFilterInOut *outputs = (AVFilterInOut *)av_malloc(sizeof(AVFilterInOut));
96    AVFilterInOut *inputs  = (AVFilterInOut *)av_malloc(sizeof(AVFilterInOut));
97
98
99    filter_graph = avfilter_graph_alloc();
100
101    /* Buffer video source: the decoded frames from the codec will be
102     * inserted here. */
103    sprintf_s(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", video_dec->width,
104             video_dec->height, video_dec->pix_fmt,
105             video_dec->time_base.num, video_dec->time_base.den,
106          video_dec->sample_aspect_ratio.num, video_dec->sample_aspect_ratio.den);
107    r = avfilter_graph_create_filter(&video_in_filter, vf_buffer, "src", args,
108                                     NULL, filter_graph);
109    if (r < 0)
110        fatal_libav_error("avfilter_graph_create_filter: buffer", r);
111
112    /* Null video sink: to terminate the filter chain. */
113    r = avfilter_graph_create_filter(&video_out_filter, vf_nullsink, "out",
114                                     NULL, NULL, filter_graph);
115    if (r < 0)
116        fatal_libav_error("avfilter_graph_create_filter: nullsink", r);
117
118    /* Endpoints for the filter graph. */
119    outputs->name       = av_strdup("in");
120    outputs->filter_ctx = video_in_filter;
121    outputs->pad_idx    = 0;
122    outputs->next       = NULL;
123    inputs->name       = av_strdup("out");
124    inputs->filter_ctx = video_out_filter;
125    inputs->pad_idx    = 0;
126    inputs->next       = NULL;
127    r = avfilter_graph_parse(filter_graph, filters, inputs, outputs, NULL);
128    if (r < 0)
129        fatal_libav_error("avfilter_graph_parse", r);
130
131    r = avfilter_graph_config(filter_graph, NULL);
132    if (r < 0)
133        fatal_libav_error("avfilter_graph_config", r);
134}
135
136static void got_video_frame(AVFrame *frame)
137{
138    int r;
139    AVFilterLink *out = video_out_filter->inputs[0];
140
141    av_vsrc_buffer_add_frame(video_in_filter, frame, frame->pts,
142                             video_dec->sample_aspect_ratio);
143    while (avfilter_poll_frame(out)) {
144        r = avfilter_request_frame(out);
145        if (r < 0)
146            fatal_libav_error("avfilter_request_frame", r);
147        if (!out->cur_buf)
148            fatal_libav_error("avfilter_request_frame", AVERROR(ENOENT));
149        //display_frame(out);
150    }
151}
152
153#define FILENAME "video.avi"
154
155int main(int argc, char **argv)
156{
157    int r;
158    AVPacket packet;
159    AVFrame frame;
160    int got_frame;
161
162    avcodec_register_all();
163    avfilter_register_all();
164    av_register_all();
165    open_input_file(FILENAME);
166    init_filters(filter_descr);
167    /* Read all packets. */
168    while (1) {
169        r = av_read_frame(avf, &packet);
170        if (r < 0)
171            break;
172        if (packet.stream_index == video_stream) {
173            avcodec_get_frame_defaults(&frame);
174            got_frame = 0;
175            if (packet.pts != AV_NOPTS_VALUE)
176                video_dec->reordered_opaque =
177                    av_rescale_q(packet.pts,
178                                 avf->streams[video_stream]->time_base,
179                                 video_dec->time_base);
180            r = avcodec_decode_video2(video_dec, &frame, &got_frame, &packet);
181            if (r < 0)
182                fatal_libav_error("avcodec_decode_video2", r);
183            if (got_frame) {
184                if (frame.pts == AV_NOPTS_VALUE)
185                    frame.pts = frame.reordered_opaque;
186                got_video_frame(&frame);
187            }
188        }
189        av_free_packet(&packet);
190    }
191    avfilter_graph_free(&filter_graph);
192    av_free(filter_graph);
193    if (video_dec)
194        avcodec_close(video_dec);
195    av_close_input_file(avf);
196}