Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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