From b05783609b08bbe4ee8c3e3b962a85749be19f11 Mon Sep 17 00:00:00 2001 From: ronag Date: Sat, 14 May 2011 14:27:53 +0000 Subject: [PATCH] Added libavfilter sample. --- ffmpeg 0.6/samples/libavfilter_sample.txt | 206 ++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 ffmpeg 0.6/samples/libavfilter_sample.txt diff --git a/ffmpeg 0.6/samples/libavfilter_sample.txt b/ffmpeg 0.6/samples/libavfilter_sample.txt new file mode 100644 index 000000000..05d091efd --- /dev/null +++ b/ffmpeg 0.6/samples/libavfilter_sample.txt @@ -0,0 +1,206 @@ +#define _XOPEN_SOURCE 600 /* for usleep */ +#include +#include +#include +#include +#include +#include +#include +#include + +const char *filter_descr = "scale=78:24,format=gray"; + +static AVFormatContext *avf; +static AVCodecContext *video_dec; +AVFilterContext *video_in_filter; +AVFilterContext *video_out_filter; +AVFilterGraph *filter_graph; +static int video_stream = -1; +static int64_t last_pts = AV_NOPTS_VALUE; + +static void fatal_libav_error(const char *tag, int r) +{ + char buf[1024]; + + av_strerror(r, buf, sizeof(buf)); + fprintf(stderr, "%s: %s\n", tag, buf); + exit(1); +} + +static void open_input_file(const char *filename) +{ + int r, i; + AVCodec *codec; + AVCodecContext *avc; + + avcodec_register_all(); + av_register_all(); + r = av_open_input_file(&avf, filename, NULL, 0, NULL); + if (r < 0) + fatal_libav_error("av_open_input_file", r); + r = av_find_stream_info(avf); + if (r < 0) + fatal_libav_error("av_find_stream_info", r); + + /* Find a video stream */ + for (i = 0; i < (int)avf->nb_streams; i) { + avc = avf->streams[i]->codec; + if (!video_dec && avc->codec_type == CODEC_TYPE_VIDEO) { + video_dec = avc; + video_stream = i; + } + } + /* Init the video decoder */ + if (video_dec) { + codec = avcodec_find_decoder(video_dec->codec_id); + if (!codec) { + fprintf(stderr, "Unable to find video decoder\n"); + exit(1); + } + r = avcodec_open(video_dec, codec); + if (r < 0) + fatal_libav_error("avcodec_open", r); + } +} + +static void init_filters(const char *filters) +{ + char args[256]; + int r; + AVFilter *vf_buffer = avfilter_get_by_name("buffer"); + AVFilter *vf_nullsink = avfilter_get_by_name("nullsink"); + AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut)); + AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut)); + + + filter_graph = avfilter_graph_alloc(); + + /* Buffer video source: the decoded frames from the codec will be + * inserted here. */ + snprintf(args, sizeof(args), "%d:%d:%d:%d:%d", video_dec->width, + video_dec->height, video_dec->pix_fmt, + video_dec->time_base.num, video_dec->time_base.den); + r = avfilter_graph_create_filter(&video_in_filter, vf_buffer, "src", args, + NULL, filter_graph); + if (r < 0) + fatal_libav_error("avfilter_graph_create_filter: buffer", r); + + /* Null video sink: to terminate the filter chain. */ + r = avfilter_graph_create_filter(&video_out_filter, vf_nullsink, "out", + NULL, NULL, filter_graph); + if (r < 0) + fatal_libav_error("avfilter_graph_create_filter: nullsink", r); + + /* Endpoints for the filter graph. */ + outputs->name = av_strdup("in"); + outputs->filter_ctx = video_in_filter; + outputs->pad_idx = 0; + outputs->next = NULL; + inputs->name = av_strdup("out"); + inputs->filter_ctx = video_out_filter; + inputs->pad_idx = 0; + inputs->next = NULL; + r = avfilter_graph_parse(filter_graph, filters, inputs, outputs, NULL); + if (r < 0) + fatal_libav_error("avfilter_graph_parse", r); + + r = avfilter_graph_config(filter_graph, NULL); + if (r < 0) + fatal_libav_error("avfilter_graph_config", r); +} + +static void display_frame(AVFilterLink *link) +{ + AVFilterBufferRef *ob; + int x, y; + uint8_t *p0, *p; + int64_t delay; + + ob = link->cur_buf; + if (ob->pts != AV_NOPTS_VALUE) { + if (last_pts != AV_NOPTS_VALUE) { + /* sleep roughly the right amount of time; + * usleep is in microseconds, just like AV_TIME_BASE. */ + delay = av_rescale_q(ob->pts - last_pts, + link->time_base, + AV_TIME_BASE_Q); + if (delay > 0 && delay < 1000000) + usleep(delay); + } + last_pts = ob->pts; + } + /* ob->data, ob->linesize and ob->pts could be copied to an AVFrame + * structure. */ + /* Trivial ASCII grayscale display. */ + p0 = ob->data[0]; + puts("\033c"); + for (y = 0; y < link->h; y) { + p = p0; + for (x = 0; x < link->w; x) + putchar(" .-#"[*(p) / 52]); + putchar('\n'); + p0 = ob->linesize[0]; + } + fflush(stdout); +} + +static void got_video_frame(AVFrame *frame) +{ + int r; + AVFilterLink *out = video_out_filter->inputs[0]; + + av_vsrc_buffer_add_frame(video_in_filter, frame, frame->pts, + video_dec->sample_aspect_ratio); + while (avfilter_poll_frame(out)) { + r = avfilter_request_frame(out); + if (r < 0) + fatal_libav_error("avfilter_request_frame", r); + if (!out->cur_buf) + fatal_libav_error("avfilter_request_frame", AVERROR(ENOENT)); + display_frame(out); + } +} + +int main(int argc, char **argv) +{ + int r; + AVPacket packet; + AVFrame frame; + int got_frame; + + if (argc != 2) { + fprintf(stderr, "Usage: api_example file\n"); + exit(1); + } + avcodec_register_all(); + avfilter_register_all(); + av_register_all(); + open_input_file(argv[1]); + init_filters(filter_descr); + /* Read all packets. */ + while (1) { + r = av_read_frame(avf, &packet); + if (r < 0) + break; + if (packet.stream_index == video_stream) { + avcodec_get_frame_defaults(&frame); + got_frame = 0; + if (packet.pts != AV_NOPTS_VALUE) + video_dec->reordered_opaque = + av_rescale_q(packet.pts, + avf->streams[video_stream]->time_base, + video_dec->time_base); + r = avcodec_decode_video2(video_dec, &frame, &got_frame, &packet); + if (r < 0) + fatal_libav_error("avcodec_decode_video2", r); + if (got_frame) { + if (frame.pts == AV_NOPTS_VALUE) + frame.pts = frame.reordered_opaque; + got_video_frame(&frame); + } + } + av_free_packet(&packet); + } + + return 0; +} -- 2.39.2