]> git.sesse.net Git - casparcg/blob - ffmpeg 0.6/samples/libavfilter_sample.txt
2.0.2: INFO TEMPLATE works on both compressed and uncompressed templates.
[casparcg] / ffmpeg 0.6 / samples / libavfilter_sample.txt
1 #define _XOPEN_SOURCE 600 /* for usleep */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <libavformat/avformat.h>
7 #include <libavcodec/avcodec.h>
8 #include <libavfilter/avfiltergraph.h>
9 #include <libavfilter/vsrc_buffer.h>
10
11 const char *filter_descr = "scale=78:24,format=gray";
12
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;
20
21 static void fatal_libav_error(const char *tag, int r)
22 {
23     char buf[1024];
24
25     av_strerror(r, buf, sizeof(buf));
26     fprintf(stderr, "%s: %s\n", tag, buf);
27     exit(1);
28 }
29
30 static void open_input_file(const char *filename)
31 {
32     int r, i;
33     AVCodec *codec;
34     AVCodecContext *avc;
35
36     avcodec_register_all();
37     av_register_all();
38     r = av_open_input_file(&avf, filename, NULL, 0, NULL);
39     if (r < 0)
40         fatal_libav_error("av_open_input_file", r);
41     r = av_find_stream_info(avf);
42     if (r < 0)
43         fatal_libav_error("av_find_stream_info", r);
44
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) {
49             video_dec = avc;
50             video_stream = i;
51         }
52     }
53     /* Init the video decoder */
54     if (video_dec) {
55         codec = avcodec_find_decoder(video_dec->codec_id);
56         if (!codec) {
57             fprintf(stderr, "Unable to find video decoder\n");
58             exit(1);
59         }
60         r = avcodec_open(video_dec, codec);
61         if (r < 0)
62             fatal_libav_error("avcodec_open", r);
63     }
64 }
65
66 static void init_filters(const char *filters)
67 {
68     char args[256];
69     int r;
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));
74
75
76     filter_graph = avfilter_graph_alloc();
77
78     /* Buffer video source: the decoded frames from the codec will be
79      * inserted here. */
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,
84                                      NULL, filter_graph);
85     if (r < 0)
86         fatal_libav_error("avfilter_graph_create_filter: buffer", r);
87
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);
91     if (r < 0)
92         fatal_libav_error("avfilter_graph_create_filter: nullsink", r);
93
94     /* Endpoints for the filter graph. */
95     outputs->name       = av_strdup("in");
96     outputs->filter_ctx = video_in_filter;
97     outputs->pad_idx    = 0;
98     outputs->next       = NULL;
99     inputs->name       = av_strdup("out");
100     inputs->filter_ctx = video_out_filter;
101     inputs->pad_idx    = 0;
102     inputs->next       = NULL;
103     r = avfilter_graph_parse(filter_graph, filters, inputs, outputs, NULL);
104     if (r < 0)
105         fatal_libav_error("avfilter_graph_parse", r);
106
107     r = avfilter_graph_config(filter_graph, NULL);
108     if (r < 0)
109         fatal_libav_error("avfilter_graph_config", r);
110 }
111
112 static void display_frame(AVFilterLink *link)
113 {
114     AVFilterBufferRef *ob;
115     int x, y;
116     uint8_t *p0, *p;
117     int64_t delay;
118
119     ob = link->cur_buf;
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,
125                                  link->time_base,
126                                  AV_TIME_BASE_Q);
127             if (delay > 0 && delay < 1000000)
128                 usleep(delay);
129         }
130         last_pts = ob->pts;
131     }
132     /* ob->data, ob->linesize and ob->pts could be copied to an AVFrame
133      * structure. */
134     /* Trivial ASCII grayscale display. */
135     p0 = ob->data[0];
136     puts("\033c");
137     for (y = 0; y < link->h; y) {
138         p = p0;
139         for (x = 0; x < link->w; x)
140             putchar(" .-#"[*(p) / 52]);
141         putchar('\n');
142         p0 = ob->linesize[0];
143     }
144     fflush(stdout);
145 }
146
147 static void got_video_frame(AVFrame *frame)
148 {
149     int r;
150     AVFilterLink *out = video_out_filter->inputs[0];
151
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);
156         if (r < 0)
157             fatal_libav_error("avfilter_request_frame", r);
158         if (!out->cur_buf)
159             fatal_libav_error("avfilter_request_frame", AVERROR(ENOENT));
160         display_frame(out);
161     }
162 }
163
164 int main(int argc, char **argv)
165 {
166     int r;
167     AVPacket packet;
168     AVFrame frame;
169     int got_frame;
170
171     if (argc != 2) {
172         fprintf(stderr, "Usage: api_example file\n");
173         exit(1);
174     }
175     avcodec_register_all();
176     avfilter_register_all();
177     av_register_all();
178     open_input_file(argv[1]);
179     init_filters(filter_descr);
180     /* Read all packets. */
181     while (1) {
182         r = av_read_frame(avf, &packet);
183         if (r < 0)
184             break;
185         if (packet.stream_index == video_stream) {
186             avcodec_get_frame_defaults(&frame);
187             got_frame = 0;
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);
194             if (r < 0)
195                 fatal_libav_error("avcodec_decode_video2", r);
196             if (got_frame) {
197                 if (frame.pts == AV_NOPTS_VALUE)
198                     frame.pts = frame.reordered_opaque;
199                 got_video_frame(&frame);
200             }
201         }
202         av_free_packet(&packet);
203     }
204
205     return 0;
206 }