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
0c59d40a
Commit
0c59d40a
authored
Dec 11, 2015
by
Matthieu Bouron
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi: use a video frame pool for each link of the filtergraph
parent
04cc4d05
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
309 additions
and
14 deletions
+309
-14
Makefile
libavfilter/Makefile
+1
-0
avfilter.c
libavfilter/avfilter.c
+1
-0
avfilter.h
libavfilter/avfilter.h
+5
-0
framepool.c
libavfilter/framepool.c
+189
-0
framepool.h
libavfilter/framepool.h
+84
-0
internal.h
libavfilter/internal.h
+1
-0
video.c
libavfilter/video.c
+28
-14
No files found.
libavfilter/Makefile
View file @
0c59d40a
...
...
@@ -17,6 +17,7 @@ OBJS = allfilters.o \
drawutils.o
\
fifo.o
\
formats.o
\
framepool.o
\
graphdump.o
\
graphparser.o
\
opencl_allkernels.o
\
...
...
libavfilter/avfilter.c
View file @
0c59d40a
...
...
@@ -168,6 +168,7 @@ void avfilter_link_free(AVFilterLink **link)
return
;
av_frame_free
(
&
(
*
link
)
->
partial_buf
);
ff_video_frame_pool_uninit
((
FFVideoFramePool
**
)
&
(
*
link
)
->
video_frame_pool
);
av_freep
(
link
);
}
...
...
libavfilter/avfilter.h
View file @
0c59d40a
...
...
@@ -509,6 +509,11 @@ struct AVFilterLink {
* Number of past frames sent through the link.
*/
int64_t
frame_count
;
/**
* A pointer to a FFVideoFramePool struct.
*/
void
*
video_frame_pool
;
};
/**
...
...
libavfilter/framepool.c
0 → 100644
View file @
0c59d40a
/*
* This file is part of FFmpeg.
*
* Copyright (c) 2015 Matthieu Bouron <matthieu.bouron stupeflix.com>
*
* 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 "framepool.h"
#include "libavutil/avassert.h"
#include "libavutil/buffer.h"
#include "libavutil/frame.h"
#include "libavutil/imgutils.h"
#include "libavutil/mem.h"
#include "libavutil/pixfmt.h"
struct
FFVideoFramePool
{
int
width
;
int
height
;
int
format
;
int
align
;
int
linesize
[
4
];
AVBufferPool
*
pools
[
4
];
};
FFVideoFramePool
*
ff_video_frame_pool_init
(
AVBufferRef
*
(
*
alloc
)(
int
size
),
int
width
,
int
height
,
enum
AVPixelFormat
format
,
int
align
)
{
int
i
,
ret
;
FFVideoFramePool
*
pool
;
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
format
);
if
(
!
desc
)
return
NULL
;
pool
=
av_mallocz
(
sizeof
(
FFVideoFramePool
));
if
(
!
pool
)
return
NULL
;
pool
->
width
=
width
;
pool
->
height
=
height
;
pool
->
format
=
format
;
pool
->
align
=
align
;
if
((
ret
=
av_image_check_size
(
width
,
height
,
0
,
NULL
))
<
0
)
{
goto
fail
;
}
if
(
!
pool
->
linesize
[
0
])
{
for
(
i
=
1
;
i
<=
align
;
i
+=
i
)
{
ret
=
av_image_fill_linesizes
(
pool
->
linesize
,
pool
->
format
,
FFALIGN
(
pool
->
width
,
i
));
if
(
ret
<
0
)
{
goto
fail
;
}
if
(
!
(
pool
->
linesize
[
0
]
&
(
pool
->
align
-
1
)))
break
;
}
for
(
i
=
0
;
i
<
4
&&
pool
->
linesize
[
i
];
i
++
)
{
pool
->
linesize
[
i
]
=
FFALIGN
(
pool
->
linesize
[
i
],
pool
->
align
);
}
}
for
(
i
=
0
;
i
<
4
&&
pool
->
linesize
[
i
];
i
++
)
{
int
h
=
FFALIGN
(
pool
->
height
,
32
);
if
(
i
==
1
||
i
==
2
)
h
=
FF_CEIL_RSHIFT
(
h
,
desc
->
log2_chroma_h
);
pool
->
pools
[
i
]
=
av_buffer_pool_init
(
pool
->
linesize
[
i
]
*
h
+
16
+
16
-
1
,
alloc
);
if
(
!
pool
->
pools
[
i
])
goto
fail
;
}
if
(
desc
->
flags
&
AV_PIX_FMT_FLAG_PAL
||
desc
->
flags
&
AV_PIX_FMT_FLAG_PSEUDOPAL
)
{
pool
->
pools
[
1
]
=
av_buffer_pool_init
(
AVPALETTE_SIZE
,
alloc
);
if
(
!
pool
->
pools
[
1
])
goto
fail
;
}
return
pool
;
fail:
ff_video_frame_pool_uninit
(
&
pool
);
return
NULL
;
}
int
ff_video_frame_pool_get_config
(
FFVideoFramePool
*
pool
,
int
*
width
,
int
*
height
,
enum
AVPixelFormat
*
format
,
int
*
align
)
{
if
(
!
pool
)
return
AVERROR
(
EINVAL
);
*
width
=
pool
->
width
;
*
height
=
pool
->
height
;
*
format
=
pool
->
format
;
*
align
=
pool
->
align
;
return
0
;
}
AVFrame
*
ff_video_frame_pool_get
(
FFVideoFramePool
*
pool
)
{
int
i
;
AVFrame
*
frame
;
const
AVPixFmtDescriptor
*
desc
;
frame
=
av_frame_alloc
();
if
(
!
frame
)
{
return
NULL
;
}
desc
=
av_pix_fmt_desc_get
(
pool
->
format
);
if
(
!
desc
)
{
goto
fail
;
}
frame
->
width
=
pool
->
width
;
frame
->
height
=
pool
->
height
;
frame
->
format
=
pool
->
format
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
frame
->
linesize
[
i
]
=
pool
->
linesize
[
i
];
if
(
!
pool
->
pools
[
i
])
break
;
frame
->
buf
[
i
]
=
av_buffer_pool_get
(
pool
->
pools
[
i
]);
if
(
!
frame
->
buf
[
i
])
{
goto
fail
;
}
frame
->
data
[
i
]
=
frame
->
buf
[
i
]
->
data
;
}
if
(
desc
->
flags
&
AV_PIX_FMT_FLAG_PAL
||
desc
->
flags
&
AV_PIX_FMT_FLAG_PSEUDOPAL
)
{
enum
AVPixelFormat
format
=
pool
->
format
==
AV_PIX_FMT_PAL8
?
AV_PIX_FMT_BGR8
:
pool
->
format
;
av_assert0
(
frame
->
data
[
1
]
!=
NULL
);
if
(
avpriv_set_systematic_pal2
((
uint32_t
*
)
frame
->
data
[
1
],
format
)
<
0
)
{
goto
fail
;
}
}
frame
->
extended_data
=
frame
->
data
;
return
frame
;
fail:
av_frame_free
(
&
frame
);
return
NULL
;
}
void
ff_video_frame_pool_uninit
(
FFVideoFramePool
**
pool
)
{
int
i
;
if
(
!
pool
||
!*
pool
)
return
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
av_buffer_pool_uninit
(
&
(
*
pool
)
->
pools
[
i
]);
}
av_freep
(
pool
);
}
libavfilter/framepool.h
0 → 100644
View file @
0c59d40a
/*
* This file is part of FFmpeg.
*
* Copyright (c) 2015 Matthieu Bouron <matthieu.bouron stupeflix.com>
*
* 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 AVUTIL_FRAME_POOL_H
#define AVUTIL_FRAME_POOL_H
#include "libavutil/buffer.h"
#include "libavutil/frame.h"
/**
* Video frame pool. This structure is opaque and not meant to be accessed
* directly. It is allocated with ff_video_frame_pool_init() and freed with
* ff_video_frame_pool_uninit().
*/
typedef
struct
FFVideoFramePool
FFVideoFramePool
;
/**
* Allocate and initialize a video frame pool.
*
* @param alloc a function that will be used to allocate new frame buffers when
* the pool is empty. May be NULL, then the default allocator will be used
* (av_buffer_alloc()).
* @param width width of each frame in this pool
* @param height height of each frame in this pool
* @param format format of each frame in this pool
* @param align buffers alignement of each frame in this pool
* @return newly created video frame pool on success, NULL on error.
*/
FFVideoFramePool
*
ff_video_frame_pool_init
(
AVBufferRef
*
(
*
alloc
)(
int
size
),
int
width
,
int
height
,
enum
AVPixelFormat
format
,
int
align
);
/**
* Deallocate the video frame pool. It is safe to call this function while
* some of the allocated video frame are still in use.
*
* @param pool pointer to the video frame pool to be freed. It will be set to NULL.
*/
void
ff_video_frame_pool_uninit
(
FFVideoFramePool
**
pool
);
/**
* Get the video frame pool configuration.
*
* @param width width of each frame in this pool
* @param height height of each frame in this pool
* @param format format of each frame in this pool
* @param align buffers alignement of each frame in this pool
* @return 0 on success, a negative AVERROR otherwise.
*/
int
ff_video_frame_pool_get_config
(
FFVideoFramePool
*
pool
,
int
*
width
,
int
*
height
,
enum
AVPixelFormat
*
format
,
int
*
align
);
/**
* Allocate a new AVFrame, reussing old buffers from the pool when available.
* This function may be called simultaneously from multiple threads.
*
* @return a new AVFrame on success, NULL on error.
*/
AVFrame
*
ff_video_frame_pool_get
(
FFVideoFramePool
*
pool
);
#endif
/* AVUTIL_FRAME_POOL_H */
libavfilter/internal.h
View file @
0c59d40a
...
...
@@ -28,6 +28,7 @@
#include "avfilter.h"
#include "avfiltergraph.h"
#include "formats.h"
#include "framepool.h"
#include "thread.h"
#include "version.h"
#include "video.h"
...
...
libavfilter/video.c
View file @
0c59d40a
...
...
@@ -32,31 +32,45 @@
#include "internal.h"
#include "video.h"
#define BUFFER_ALIGN 32
AVFrame
*
ff_null_get_video_buffer
(
AVFilterLink
*
link
,
int
w
,
int
h
)
{
return
ff_get_video_buffer
(
link
->
dst
->
outputs
[
0
],
w
,
h
);
}
/* TODO: set the buffer's priv member to a context structure for the whole
* filter chain. This will allow for a buffer pool instead of the constant
* alloc & free cycle currently implemented. */
AVFrame
*
ff_default_get_video_buffer
(
AVFilterLink
*
link
,
int
w
,
int
h
)
{
AVFrame
*
frame
=
av_frame_alloc
();
int
ret
;
int
pool_width
=
0
;
int
pool_height
=
0
;
int
pool_align
=
0
;
enum
AVPixelFormat
pool_format
=
AV_PIX_FMT_NONE
;
if
(
!
frame
)
return
NULL
;
if
(
!
link
->
video_frame_pool
)
{
link
->
video_frame_pool
=
ff_video_frame_pool_init
(
av_buffer_allocz
,
w
,
h
,
link
->
format
,
BUFFER_ALIGN
);
if
(
!
link
->
video_frame_pool
)
return
NULL
;
}
else
{
if
(
ff_video_frame_pool_get_config
(
link
->
video_frame_pool
,
&
pool_width
,
&
pool_height
,
&
pool_format
,
&
pool_align
)
<
0
)
{
return
NULL
;
}
frame
->
width
=
w
;
frame
->
height
=
h
;
frame
->
format
=
link
->
format
;
if
(
pool_width
!=
w
||
pool_height
!=
h
||
pool_format
!=
link
->
format
||
pool_align
!=
BUFFER_ALIGN
)
{
ret
=
av_frame_get_buffer
(
frame
,
32
);
if
(
ret
<
0
)
av_frame_free
(
&
frame
);
ff_video_frame_pool_uninit
((
FFVideoFramePool
**
)
&
link
->
video_frame_pool
);
link
->
video_frame_pool
=
ff_video_frame_pool_init
(
av_buffer_allocz
,
w
,
h
,
link
->
format
,
BUFFER_ALIGN
);
if
(
!
link
->
video_frame_pool
)
return
NULL
;
}
}
return
f
rame
;
return
f
f_video_frame_pool_get
(
link
->
video_frame_pool
)
;
}
AVFrame
*
ff_get_video_buffer
(
AVFilterLink
*
link
,
int
w
,
int
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