1 #define _XOPEN_SOURCE 600 /* for usleep */
6 #include <libavformat/avformat.h>
7 #include <libavcodec/avcodec.h>
8 #include <libavfilter/avfiltergraph.h>
9 #include <libavfilter/vsrc_buffer.h>
11 const char *filter_descr = "scale=78:24,format=gray";
13 static AVFormatContext *avf;
14 static AVCodecContext *video_dec;
15 AVFilterContext *video_in_filter;
16 AVFilterContext *video_out_filter;
17 AVFilterGraph *filter_graph;
18 static int video_stream = -1;
19 static int64_t last_pts = AV_NOPTS_VALUE;
21 static void fatal_libav_error(const char *tag, int r)
25 av_strerror(r, buf, sizeof(buf));
26 fprintf(stderr, "%s: %s\n", tag, buf);
30 static void open_input_file(const char *filename)
36 avcodec_register_all();
38 r = av_open_input_file(&avf, filename, NULL, 0, NULL);
40 fatal_libav_error("av_open_input_file", r);
41 r = av_find_stream_info(avf);
43 fatal_libav_error("av_find_stream_info", r);
45 /* Find a video stream */
46 for (i = 0; i < (int)avf->nb_streams; i) {
47 avc = avf->streams[i]->codec;
48 if (!video_dec && avc->codec_type == CODEC_TYPE_VIDEO) {
53 /* Init the video decoder */
55 codec = avcodec_find_decoder(video_dec->codec_id);
57 fprintf(stderr, "Unable to find video decoder\n");
60 r = avcodec_open(video_dec, codec);
62 fatal_libav_error("avcodec_open", r);
66 static void init_filters(const char *filters)
70 AVFilter *vf_buffer = avfilter_get_by_name("buffer");
71 AVFilter *vf_nullsink = avfilter_get_by_name("nullsink");
72 AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
73 AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
76 filter_graph = avfilter_graph_alloc();
78 /* Buffer video source: the decoded frames from the codec will be
80 snprintf(args, sizeof(args), "%d:%d:%d:%d:%d", video_dec->width,
81 video_dec->height, video_dec->pix_fmt,
82 video_dec->time_base.num, video_dec->time_base.den);
83 r = avfilter_graph_create_filter(&video_in_filter, vf_buffer, "src", args,
86 fatal_libav_error("avfilter_graph_create_filter: buffer", r);
88 /* Null video sink: to terminate the filter chain. */
89 r = avfilter_graph_create_filter(&video_out_filter, vf_nullsink, "out",
90 NULL, NULL, filter_graph);
92 fatal_libav_error("avfilter_graph_create_filter: nullsink", r);
94 /* Endpoints for the filter graph. */
95 outputs->name = av_strdup("in");
96 outputs->filter_ctx = video_in_filter;
99 inputs->name = av_strdup("out");
100 inputs->filter_ctx = video_out_filter;
103 r = avfilter_graph_parse(filter_graph, filters, inputs, outputs, NULL);
105 fatal_libav_error("avfilter_graph_parse", r);
107 r = avfilter_graph_config(filter_graph, NULL);
109 fatal_libav_error("avfilter_graph_config", r);
112 static void display_frame(AVFilterLink *link)
114 AVFilterBufferRef *ob;
120 if (ob->pts != AV_NOPTS_VALUE) {
121 if (last_pts != AV_NOPTS_VALUE) {
122 /* sleep roughly the right amount of time;
123 * usleep is in microseconds, just like AV_TIME_BASE. */
124 delay = av_rescale_q(ob->pts - last_pts,
127 if (delay > 0 && delay < 1000000)
132 /* ob->data, ob->linesize and ob->pts could be copied to an AVFrame
134 /* Trivial ASCII grayscale display. */
137 for (y = 0; y < link->h; y) {
139 for (x = 0; x < link->w; x)
140 putchar(" .-#"[*(p) / 52]);
142 p0 = ob->linesize[0];
147 static void got_video_frame(AVFrame *frame)
150 AVFilterLink *out = video_out_filter->inputs[0];
152 av_vsrc_buffer_add_frame(video_in_filter, frame, frame->pts,
153 video_dec->sample_aspect_ratio);
154 while (avfilter_poll_frame(out)) {
155 r = avfilter_request_frame(out);
157 fatal_libav_error("avfilter_request_frame", r);
159 fatal_libav_error("avfilter_request_frame", AVERROR(ENOENT));
164 int main(int argc, char **argv)
172 fprintf(stderr, "Usage: api_example file\n");
175 avcodec_register_all();
176 avfilter_register_all();
178 open_input_file(argv[1]);
179 init_filters(filter_descr);
180 /* Read all packets. */
182 r = av_read_frame(avf, &packet);
185 if (packet.stream_index == video_stream) {
186 avcodec_get_frame_defaults(&frame);
188 if (packet.pts != AV_NOPTS_VALUE)
189 video_dec->reordered_opaque =
190 av_rescale_q(packet.pts,
191 avf->streams[video_stream]->time_base,
192 video_dec->time_base);
193 r = avcodec_decode_video2(video_dec, &frame, &got_frame, &packet);
195 fatal_libav_error("avcodec_decode_video2", r);
197 if (frame.pts == AV_NOPTS_VALUE)
198 frame.pts = frame.reordered_opaque;
199 got_video_frame(&frame);
202 av_free_packet(&packet);