Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
5c21c41b
Commit
5c21c41b
authored
Jun 27, 2017
by
Mark Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi: Add some common code for OpenCL filtering
parent
7faae6e7
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
338 additions
and
0 deletions
+338
-0
opencl.c
libavfilter/opencl.c
+251
-0
opencl.h
libavfilter/opencl.h
+87
-0
No files found.
libavfilter/opencl.c
0 → 100644
View file @
5c21c41b
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_opencl.h"
#include "libavutil/mem.h"
#include "avfilter.h"
#include "formats.h"
#include "opencl.h"
int
ff_opencl_filter_query_formats
(
AVFilterContext
*
avctx
)
{
const
static
enum
AVPixelFormat
pix_fmts
[]
=
{
AV_PIX_FMT_OPENCL
,
AV_PIX_FMT_NONE
,
};
AVFilterFormats
*
formats
;
formats
=
ff_make_format_list
(
pix_fmts
);
if
(
!
formats
)
return
AVERROR
(
ENOMEM
);
return
ff_set_common_formats
(
avctx
,
formats
);
}
int
ff_opencl_filter_config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
avctx
=
inlink
->
dst
;
OpenCLFilterContext
*
ctx
=
avctx
->
priv
;
AVHWFramesContext
*
input_frames
;
if
(
!
inlink
->
hw_frames_ctx
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"OpenCL filtering requires a "
"hardware frames context on the input.
\n
"
);
return
AVERROR
(
EINVAL
);
}
// Extract the device and default output format from the first input.
if
(
avctx
->
inputs
[
0
]
!=
inlink
)
return
0
;
input_frames
=
(
AVHWFramesContext
*
)
inlink
->
hw_frames_ctx
->
data
;
if
(
input_frames
->
format
!=
AV_PIX_FMT_OPENCL
)
return
AVERROR
(
EINVAL
);
ctx
->
device_ref
=
av_buffer_ref
(
input_frames
->
device_ref
);
if
(
!
ctx
->
device_ref
)
return
AVERROR
(
ENOMEM
);
ctx
->
device
=
input_frames
->
device_ctx
;
ctx
->
hwctx
=
ctx
->
device
->
hwctx
;
// Default output parameters match input parameters.
if
(
ctx
->
output_format
==
AV_PIX_FMT_NONE
)
ctx
->
output_format
=
input_frames
->
sw_format
;
if
(
!
ctx
->
output_width
)
ctx
->
output_width
=
inlink
->
w
;
if
(
!
ctx
->
output_height
)
ctx
->
output_height
=
inlink
->
h
;
return
0
;
}
int
ff_opencl_filter_config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
avctx
=
outlink
->
src
;
OpenCLFilterContext
*
ctx
=
avctx
->
priv
;
AVBufferRef
*
output_frames_ref
=
NULL
;
AVHWFramesContext
*
output_frames
;
int
err
;
av_buffer_unref
(
&
outlink
->
hw_frames_ctx
);
output_frames_ref
=
av_hwframe_ctx_alloc
(
ctx
->
device_ref
);
if
(
!
output_frames_ref
)
{
err
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
output_frames
=
(
AVHWFramesContext
*
)
output_frames_ref
->
data
;
output_frames
->
format
=
AV_PIX_FMT_OPENCL
;
output_frames
->
sw_format
=
ctx
->
output_format
;
output_frames
->
width
=
ctx
->
output_width
;
output_frames
->
height
=
ctx
->
output_height
;
err
=
av_hwframe_ctx_init
(
output_frames_ref
);
if
(
err
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to initialise output "
"frames: %d.
\n
"
,
err
);
goto
fail
;
}
outlink
->
hw_frames_ctx
=
output_frames_ref
;
outlink
->
w
=
ctx
->
output_width
;
outlink
->
h
=
ctx
->
output_height
;
return
0
;
fail:
av_buffer_unref
(
&
output_frames_ref
);
return
err
;
}
int
ff_opencl_filter_init
(
AVFilterContext
*
avctx
)
{
OpenCLFilterContext
*
ctx
=
avctx
->
priv
;
ctx
->
output_format
=
AV_PIX_FMT_NONE
;
return
0
;
}
void
ff_opencl_filter_uninit
(
AVFilterContext
*
avctx
)
{
OpenCLFilterContext
*
ctx
=
avctx
->
priv
;
cl_int
cle
;
if
(
ctx
->
program
)
{
cle
=
clReleaseProgram
(
ctx
->
program
);
if
(
cle
!=
CL_SUCCESS
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to release "
"program: %d.
\n
"
,
cle
);
}
av_buffer_unref
(
&
ctx
->
device_ref
);
}
int
ff_opencl_filter_load_program
(
AVFilterContext
*
avctx
,
const
char
**
program_source_array
,
int
nb_strings
)
{
OpenCLFilterContext
*
ctx
=
avctx
->
priv
;
cl_int
cle
;
ctx
->
program
=
clCreateProgramWithSource
(
ctx
->
hwctx
->
context
,
nb_strings
,
program_source_array
,
NULL
,
&
cle
);
if
(
!
ctx
->
program
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to create program: %d.
\n
"
,
cle
);
return
AVERROR
(
EIO
);
}
cle
=
clBuildProgram
(
ctx
->
program
,
1
,
&
ctx
->
hwctx
->
device_id
,
NULL
,
NULL
,
NULL
);
if
(
cle
!=
CL_SUCCESS
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to build program: %d.
\n
"
,
cle
);
if
(
cle
==
CL_BUILD_PROGRAM_FAILURE
)
{
char
*
log
;
size_t
log_length
;
clGetProgramBuildInfo
(
ctx
->
program
,
ctx
->
hwctx
->
device_id
,
CL_PROGRAM_BUILD_LOG
,
0
,
NULL
,
&
log_length
);
log
=
av_malloc
(
log_length
);
if
(
log
)
{
cle
=
clGetProgramBuildInfo
(
ctx
->
program
,
ctx
->
hwctx
->
device_id
,
CL_PROGRAM_BUILD_LOG
,
log_length
,
log
,
NULL
);
if
(
cle
==
CL_SUCCESS
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"Build log:
\n
%s
\n
"
,
log
);
}
av_free
(
log
);
}
clReleaseProgram
(
ctx
->
program
);
ctx
->
program
=
NULL
;
return
AVERROR
(
EIO
);
}
return
0
;
}
int
ff_opencl_filter_load_program_from_file
(
AVFilterContext
*
avctx
,
const
char
*
filename
)
{
FILE
*
file
;
char
*
src
=
NULL
;
size_t
pos
,
len
,
rb
;
const
char
*
src_const
;
int
err
;
file
=
fopen
(
filename
,
"r"
);
if
(
!
file
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Unable to open program "
"source file
\"
%s
\"
.
\n
"
,
filename
);
return
AVERROR
(
ENOENT
);
}
len
=
1
<<
16
;
pos
=
0
;
err
=
av_reallocp
(
&
src
,
len
);
if
(
err
<
0
)
goto
fail
;
err
=
snprintf
(
src
,
len
,
"#line 1
\"
%s
\"\n
"
,
filename
);
if
(
err
<
0
)
{
err
=
AVERROR
(
errno
);
goto
fail
;
}
if
(
err
>
len
/
2
)
{
err
=
AVERROR
(
EINVAL
);
goto
fail
;
}
pos
=
err
;
while
(
1
)
{
rb
=
fread
(
src
+
pos
,
1
,
len
-
pos
-
1
,
file
);
if
(
rb
==
0
&&
ferror
(
file
))
{
err
=
AVERROR
(
EIO
);
goto
fail
;
}
pos
+=
rb
;
if
(
pos
<
len
)
break
;
len
<<=
1
;
err
=
av_reallocp
(
&
src
,
len
);
if
(
err
<
0
)
goto
fail
;
}
src
[
pos
]
=
0
;
src_const
=
src
;
err
=
ff_opencl_filter_load_program
(
avctx
,
&
src_const
,
1
);
fail:
fclose
(
file
);
av_freep
(
&
src
);
return
err
;
}
libavfilter/opencl.h
0 → 100644
View file @
5c21c41b
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVFILTER_OPENCL_H
#define AVFILTER_OPENCL_H
#include "libavutil/buffer.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_opencl.h"
#include "libavutil/pixfmt.h"
#include "avfilter.h"
typedef
struct
OpenCLFilterContext
{
const
AVClass
*
class
;
AVBufferRef
*
device_ref
;
AVHWDeviceContext
*
device
;
AVOpenCLDeviceContext
*
hwctx
;
cl_program
program
;
enum
AVPixelFormat
output_format
;
int
output_width
;
int
output_height
;
}
OpenCLFilterContext
;
/**
* Return that all inputs and outputs support only AV_PIX_FMT_OPENCL.
*/
int
ff_opencl_filter_query_formats
(
AVFilterContext
*
avctx
);
/**
* Check that the input link contains a suitable hardware frames
* context and extract the device from it.
*/
int
ff_opencl_filter_config_input
(
AVFilterLink
*
inlink
);
/**
* Create a suitable hardware frames context for the output.
*/
int
ff_opencl_filter_config_output
(
AVFilterLink
*
outlink
);
/**
* Initialise an OpenCL filter context.
*/
int
ff_opencl_filter_init
(
AVFilterContext
*
avctx
);
/**
* Uninitialise an OpenCL filter context.
*/
void
ff_opencl_filter_uninit
(
AVFilterContext
*
avctx
);
/**
* Load a new OpenCL program from strings in memory.
*
* Creates a new program and compiles it for the current device.
* Will log any build errors if compilation fails.
*/
int
ff_opencl_filter_load_program
(
AVFilterContext
*
avctx
,
const
char
**
program_source_array
,
int
nb_strings
);
/**
* Load a new OpenCL program from a file.
*
* Same as ff_opencl_filter_load_program(), but from a file.
*/
int
ff_opencl_filter_load_program_from_file
(
AVFilterContext
*
avctx
,
const
char
*
filename
);
#endif
/* AVFILTER_OPENCL_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment