2 * Memory buffer source filter
3 * Copyright (c) 2008 Vitor Sessak
5 * This file is part of FFmpeg.
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.
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.
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
23 #include "vsrc_buffer.h"
30 AVRational pixel_aspect
;
31 } BufferSourceContext
;
34 int av_vsrc_buffer_add_frame(AVFilterContext
*buffer_filter
, AVFrame
*frame
,
35 int64_t pts
, AVRational pixel_aspect
)
37 BufferSourceContext
*c
= buffer_filter
->priv
;
40 av_log(buffer_filter
, AV_LOG_ERROR
,
41 "Buffering several frames is not supported. "
42 "Please consume all available frames before adding a new one.\n"
47 memcpy(c
->frame
.data
, frame
->data
, sizeof(frame
->data
));
48 memcpy(c
->frame
.linesize
, frame
->linesize
, sizeof(frame
->linesize
));
49 c
->frame
.interlaced_frame
= frame
->interlaced_frame
;
50 c
->frame
.top_field_first
= frame
->top_field_first
;
52 c
->pixel_aspect
= pixel_aspect
;
58 static av_cold
int init(AVFilterContext
*ctx
, const char *args
, void *opaque
)
60 BufferSourceContext
*c
= ctx
->priv
;
62 if(args
&& sscanf(args
, "%d:%d:%d", &c
->w
, &c
->h
, &c
->pix_fmt
) == 3)
65 av_log(ctx
, AV_LOG_ERROR
, "init() expected 3 arguments:'%s'\n", args
);
69 static int query_formats(AVFilterContext
*ctx
)
71 BufferSourceContext
*c
= ctx
->priv
;
72 enum PixelFormat pix_fmts
[] = { c
->pix_fmt
, PIX_FMT_NONE
};
74 avfilter_set_common_formats(ctx
, avfilter_make_format_list(pix_fmts
));
78 static int config_props(AVFilterLink
*link
)
80 BufferSourceContext
*c
= link
->src
->priv
;
89 static int request_frame(AVFilterLink
*link
)
91 BufferSourceContext
*c
= link
->src
->priv
;
92 AVFilterPicRef
*picref
;
95 av_log(link
->src
, AV_LOG_ERROR
,
96 "request_frame() called with no available frame!\n");
100 /* This picture will be needed unmodified later for decoding the next
102 picref
= avfilter_get_video_buffer(link
, AV_PERM_WRITE
| AV_PERM_PRESERVE
|
106 av_picture_copy((AVPicture
*)&picref
->data
, (AVPicture
*)&c
->frame
,
107 picref
->pic
->format
, link
->w
, link
->h
);
109 picref
->pts
= c
->pts
;
110 picref
->pixel_aspect
= c
->pixel_aspect
;
111 picref
->interlaced
= c
->frame
.interlaced_frame
;
112 picref
->top_field_first
= c
->frame
.top_field_first
;
113 avfilter_start_frame(link
, avfilter_ref_pic(picref
, ~0));
114 avfilter_draw_slice(link
, 0, link
->h
, 1);
115 avfilter_end_frame(link
);
116 avfilter_unref_pic(picref
);
123 static int poll_frame(AVFilterLink
*link
)
125 BufferSourceContext
*c
= link
->src
->priv
;
126 return !!(c
->has_frame
);
129 AVFilter avfilter_vsrc_buffer
=
132 .priv_size
= sizeof(BufferSourceContext
),
133 .query_formats
= query_formats
,
137 .inputs
= (AVFilterPad
[]) {{ .name
= NULL
}},
138 .outputs
= (AVFilterPad
[]) {{ .name
= "default",
139 .type
= AVMEDIA_TYPE_VIDEO
,
140 .request_frame
= request_frame
,
141 .poll_frame
= poll_frame
,
142 .config_props
= config_props
, },