Ticket #25: yadif-libavfilter.c

File yadif-libavfilter.c, 6.1 KB (added by Francesco Pretto, 15 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}