FFmpeg
Loading...
Searching...
No Matches
vf_stack_vaapi.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file
21 * Hardware accelerated hstack, vstack and xstack filters based on VA-API
22 */
23
24#include "config_components.h"
25
26#include "libavutil/opt.h"
27#include "libavutil/common.h"
28#include "libavutil/pixdesc.h"
29#include "libavutil/eval.h"
30#include "libavutil/hwcontext.h"
31#include "libavutil/avstring.h"
32#include "libavutil/avassert.h"
33#include "libavutil/imgutils.h"
36#include "libavutil/mem.h"
37
38#include "filters.h"
39#include "formats.h"
40#include "video.h"
41#include "framesync.h"
42#include "vaapi_vpp.h"
43
44#define HSTACK_NAME "hstack_vaapi"
45#define VSTACK_NAME "vstack_vaapi"
46#define XSTACK_NAME "xstack_vaapi"
47#define HWContext VAAPIVPPContext
48#define StackHWContext StackVAAPIContext
49#include "stack_internal.h"
50
51typedef struct StackVAAPIContext {
52 StackBaseContext base;
53
54 VARectangle *rects;
56
58{
59 AVFilterContext *avctx = fs->parent;
60 AVFilterLink *outlink = avctx->outputs[0];
61 StackVAAPIContext *sctx = fs->opaque;
62 VAAPIVPPContext *vppctx = fs->opaque;
63 AVFrame *oframe, *iframe;
64 VAProcPipelineParameterBuffer *params = NULL;
65 VARectangle *irect = NULL;
66 int ret = 0;
67
68 if (vppctx->va_context == VA_INVALID_ID)
69 return AVERROR(EINVAL);
70
71 oframe = ff_get_video_buffer(outlink, outlink->w, outlink->h);
72 if (!oframe)
73 return AVERROR(ENOMEM);
74
75 irect = av_calloc(avctx->nb_inputs, sizeof(*irect));
76 params = av_calloc(avctx->nb_inputs, sizeof(*params));
77 if (!irect || !params) {
78 ret = AVERROR(ENOMEM);
79 goto fail;
80 }
81
82 for (int i = 0; i < avctx->nb_inputs; i++) {
83 ret = ff_framesync_get_frame(fs, i, &iframe, 0);
84 if (ret)
85 goto fail;
86
87 if (i == 0) {
88 ret = av_frame_copy_props(oframe, iframe);
89 if (ret < 0)
90 goto fail;
91 }
92
93 ret = ff_vaapi_vpp_init_params(avctx, &params[i], iframe, oframe);
94 if (ret)
95 goto fail;
96
97 av_log(avctx, AV_LOG_DEBUG, "stack input %d: %s, %ux%u (%"PRId64").\n",
99 iframe->width, iframe->height, iframe->pts);
100 irect[i].x = 0;
101 irect[i].y = 0;
102 irect[i].width = iframe->width;
103 irect[i].height = iframe->height;
104 params[i].surface_region = &irect[i];
105 params[i].surface = (VASurfaceID)(uintptr_t)iframe->data[3];
106 params[i].output_region = &sctx->rects[i];
107
108 if (sctx->base.fillcolor_enable)
109 params[i].output_background_color = (sctx->base.fillcolor[3] << 24 |
110 sctx->base.fillcolor[0] << 16 |
111 sctx->base.fillcolor[1] << 8 |
112 sctx->base.fillcolor[2]);
113 }
114
115 oframe->pts = av_rescale_q(sctx->base.fs.pts, sctx->base.fs.time_base, outlink->time_base);
116 oframe->sample_aspect_ratio = outlink->sample_aspect_ratio;
117
118 ret = ff_vaapi_vpp_render_pictures(avctx, params, avctx->nb_inputs, oframe);
119 if (ret)
120 goto fail;
121
122 av_freep(&irect);
124 return ff_filter_frame(outlink, oframe);
125
126fail:
127 av_freep(&irect);
129 av_frame_free(&oframe);
130 return ret;
131}
132
133static int config_output(AVFilterLink *outlink)
134{
135 AVFilterContext *avctx = outlink->src;
136 StackVAAPIContext *sctx = avctx->priv;
137 VAAPIVPPContext *vppctx = avctx->priv;
138 AVFilterLink *inlink0 = avctx->inputs[0];
139 FilterLink *inl0 = ff_filter_link(inlink0);
140 AVHWFramesContext *hwfc0 = NULL;
141 int ret;
142
143 if (inlink0->format != AV_PIX_FMT_VAAPI || !inl0->hw_frames_ctx || !inl0->hw_frames_ctx->data) {
144 av_log(avctx, AV_LOG_ERROR, "Software pixel format is not supported.\n");
145 return AVERROR(EINVAL);
146 }
147
148 hwfc0 = (AVHWFramesContext *)inl0->hw_frames_ctx->data;
149
150 for (int i = 1; i < sctx->base.nb_inputs; i++) {
151 AVFilterLink *inlink = avctx->inputs[i];
152 FilterLink *inl = ff_filter_link(inlink);
153 AVHWFramesContext *hwfc = NULL;
154
155 if (inlink->format != AV_PIX_FMT_VAAPI || !inl->hw_frames_ctx || !inl->hw_frames_ctx->data) {
156 av_log(avctx, AV_LOG_ERROR, "Software pixel format is not supported.\n");
157 return AVERROR(EINVAL);
158 }
159
160 hwfc = (AVHWFramesContext *)inl->hw_frames_ctx->data;
161
162 if (hwfc0->sw_format != hwfc->sw_format) {
163 av_log(avctx, AV_LOG_ERROR, "All inputs should have the same underlying software pixel format.\n");
164 return AVERROR(EINVAL);
165 }
166
167 if (hwfc0->device_ctx != hwfc->device_ctx) {
168 av_log(avctx, AV_LOG_ERROR, "All inputs should have the same underlying vaapi devices.\n");
169 return AVERROR(EINVAL);
170 }
171 }
172
174 vppctx->output_format = hwfc0->sw_format;
175
176 ret = config_comm_output(outlink);
177 if (ret < 0)
178 return ret;
179
180 for (int i = 0; i < sctx->base.nb_inputs; i++) {
181 sctx->rects[i].x = sctx->base.regions[i].x;
182 sctx->rects[i].y = sctx->base.regions[i].y;
183 sctx->rects[i].width = sctx->base.regions[i].width;
184 sctx->rects[i].height = sctx->base.regions[i].height;
185 }
186
187 vppctx->output_width = outlink->w;
188 vppctx->output_height = outlink->h;
189
190 return ff_vaapi_vpp_config_output(outlink);
191}
192
194{
195 StackVAAPIContext *sctx = avctx->priv;
196 VAAPIVPPContext *vppctx = avctx->priv;
197 int ret;
198
199 ret = stack_init(avctx);
200 if (ret)
201 return ret;
202
203 /* stack region */
204 sctx->rects = av_calloc(sctx->base.nb_inputs, sizeof(*sctx->rects));
205 if (!sctx->rects)
206 return AVERROR(ENOMEM);
207
210
211 return 0;
212}
213
215{
216 StackVAAPIContext *sctx = avctx->priv;
217
218 stack_uninit(avctx);
219
220 av_freep(&sctx->rects);
221}
222
227
228#include "stack_internal.c"
229
230#if CONFIG_HSTACK_VAAPI_FILTER
231
233DEFINE_STACK_FILTER(hstack, vaapi, "VA-API", 0);
234
235#endif
236
237#if CONFIG_VSTACK_VAAPI_FILTER
238
240DEFINE_STACK_FILTER(vstack, vaapi, "VA-API", 0);
241
242#endif
243
244#if CONFIG_XSTACK_VAAPI_FILTER
245
247DEFINE_STACK_FILTER(xstack, vaapi, "VA-API", 0);
248
249#endif
SwsAArch64OpImplParams params
Definition ops.c:51
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define fs(width, name, subs,...)
Definition cbs_vp9.c:200
common internal and external API header
#define NULL
Definition coverity.c:32
simple arithmetic expression evaluator
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition framesync.c:269
#define fail
Definition test.h:479
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
misc image utilities
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define av_cold
Definition attributes.h:117
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
AVOptions.
misc parsing utilities
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition pixfmt.h:126
static int stack_init(AVFilterContext *avctx)
static int config_comm_output(AVFilterLink *outlink)
#define DEFINE_XSTACK_OPTIONS(api)
#define DEFINE_VSTACK_OPTIONS(api)
#define DEFINE_STACK_FILTER(category, api, capi, filter_flags)
#define DEFINE_HSTACK_OPTIONS(api)
static av_cold void stack_uninit(AVFilterContext *avctx)
uint8_t * data
The data buffer.
Definition buffer.h:90
An instance of a filter.
Definition avfilter.h:273
unsigned nb_inputs
number of input pads
Definition avfilter.h:282
AVFilterLink ** inputs
array of pointers to input links
Definition avfilter.h:281
void * priv
private data for use by the filter
Definition avfilter.h:288
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int width
Definition frame.h:544
int height
Definition frame.h:544
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:569
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:559
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition hwcontext.h:137
Frame sync structure.
Definition framesync.h:168
StackBaseContext base
VARectangle * rects
enum AVPixelFormat output_format
Definition vaapi_vpp.h:52
VAContextID va_context
Definition vaapi_vpp.h:46
#define av_freep(p)
#define av_log(a,...)
int ff_vaapi_vpp_render_pictures(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params_list, int cout, AVFrame *output_frame)
Definition vaapi_vpp.c:639
int ff_vaapi_vpp_config_output(AVFilterLink *outlink)
Definition vaapi_vpp.c:97
int ff_vaapi_vpp_config_input(AVFilterLink *inlink)
Definition vaapi_vpp.c:71
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
Definition vaapi_vpp.c:714
int ff_vaapi_vpp_init_params(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition vaapi_vpp.c:533
static int vaapi_stack_init(AVFilterContext *avctx)
static av_cold void vaapi_stack_uninit(AVFilterContext *avctx)
static enum AVPixelFormat vaapi_stack_pix_fmts[]
static int config_output(AVFilterLink *outlink)
static int process_frame(FFFrameSync *fs)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:89