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
2ce79727
Commit
2ce79727
authored
Apr 18, 2012
by
Nicolas George
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfiltergraph: add avfilter_graph_request_oldest().
Keep a heap of all sink links ordered by timestamps.
parent
e0761fee
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
158 additions
and
8 deletions
+158
-8
avfilter.c
libavfilter/avfilter.c
+13
-0
avfilter.h
libavfilter/avfilter.h
+17
-0
avfiltergraph.c
libavfilter/avfiltergraph.c
+99
-8
avfiltergraph.h
libavfilter/avfiltergraph.h
+24
-0
internal.h
libavfilter/internal.h
+5
-0
No files found.
libavfilter/avfilter.c
View file @
2ce79727
...
...
@@ -278,6 +278,8 @@ int avfilter_config_links(AVFilterContext *filter)
if
(
!
link
)
continue
;
link
->
current_pts
=
AV_NOPTS_VALUE
;
switch
(
link
->
init_state
)
{
case
AVLINK_INIT
:
continue
;
...
...
@@ -568,6 +570,15 @@ int avfilter_poll_frame(AVFilterLink *link)
return
min
;
}
static
void
update_link_current_pts
(
AVFilterLink
*
link
)
{
if
(
link
->
cur_buf
->
pts
==
AV_NOPTS_VALUE
)
return
;
link
->
current_pts
=
link
->
cur_buf
->
pts
;
/* TODO use duration */
if
(
link
->
graph
&&
link
->
age_index
>=
0
)
ff_avfilter_graph_update_heap
(
link
->
graph
,
link
);
}
/* XXX: should we do the duplicating of the picture ref here, instead of
* forcing the source filter to do it? */
void
avfilter_start_frame
(
AVFilterLink
*
link
,
AVFilterBufferRef
*
picref
)
...
...
@@ -608,6 +619,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
}
start_frame
(
link
,
link
->
cur_buf
);
update_link_current_pts
(
link
);
}
void
avfilter_end_frame
(
AVFilterLink
*
link
)
...
...
@@ -712,6 +724,7 @@ void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
link
->
cur_buf
=
samplesref
;
filter_samples
(
link
,
link
->
cur_buf
);
update_link_current_pts
(
link
);
}
#define MAX_REGISTERED_AVFILTERS_NB 128
...
...
libavfilter/avfilter.h
View file @
2ce79727
...
...
@@ -696,6 +696,23 @@ struct AVFilterLink {
*/
struct
AVFilterGraph
*
graph
;
/**
* Current timestamp of the link, as defined by the most recent
* frame(s), in AV_TIME_BASE units.
*/
int64_t
current_pts
;
/**
* Private fields
*
* The following fields are for internal use only.
* Their type, offset, number and semantic can change without notice.
*/
/**
* Index in the age array.
*/
int
age_index
;
};
/**
...
...
libavfilter/avfiltergraph.c
View file @
2ce79727
...
...
@@ -24,6 +24,7 @@
#include <string.h>
#include "libavutil/audioconvert.h"
#include "libavutil/avassert.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "avfiltergraph.h"
...
...
@@ -374,19 +375,46 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
return
0
;
}
static
void
ff_avfilter_graph_config_pointers
(
AVFilterGraph
*
graph
,
AVClass
*
log_ctx
)
static
int
ff_avfilter_graph_config_pointers
(
AVFilterGraph
*
graph
,
AVClass
*
log_ctx
)
{
unsigned
i
,
j
;;
unsigned
i
,
j
;
int
sink_links_count
=
0
,
n
=
0
;
AVFilterContext
*
f
;
AVFilterLink
**
sinks
;
for
(
i
=
0
;
i
<
graph
->
filter_count
;
i
++
)
{
f
=
graph
->
filters
[
i
];
for
(
j
=
0
;
j
<
f
->
input_count
;
j
++
)
f
->
inputs
[
j
]
->
graph
=
graph
;
for
(
j
=
0
;
j
<
f
->
output_count
;
j
++
)
f
->
outputs
[
j
]
->
graph
=
graph
;
for
(
j
=
0
;
j
<
f
->
input_count
;
j
++
)
{
f
->
inputs
[
j
]
->
graph
=
graph
;
f
->
inputs
[
j
]
->
age_index
=
-
1
;
}
for
(
j
=
0
;
j
<
f
->
output_count
;
j
++
)
{
f
->
outputs
[
j
]
->
graph
=
graph
;
f
->
outputs
[
j
]
->
age_index
=
-
1
;
}
if
(
!
f
->
output_count
)
{
if
(
f
->
input_count
>
INT_MAX
-
sink_links_count
)
return
AVERROR
(
EINVAL
);
sink_links_count
+=
f
->
input_count
;
}
}
sinks
=
av_calloc
(
sink_links_count
,
sizeof
(
*
sinks
));
if
(
!
sinks
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
graph
->
filter_count
;
i
++
)
{
f
=
graph
->
filters
[
i
];
if
(
!
f
->
output_count
)
{
for
(
j
=
0
;
j
<
f
->
input_count
;
j
++
)
{
sinks
[
n
]
=
f
->
inputs
[
j
];
f
->
inputs
[
j
]
->
age_index
=
n
++
;
}
}
}
av_assert0
(
n
==
sink_links_count
);
graph
->
sink_links
=
sinks
;
graph
->
sink_links_count
=
sink_links_count
;
return
0
;
}
int
avfilter_graph_config
(
AVFilterGraph
*
graphctx
,
void
*
log_ctx
)
...
...
@@ -399,7 +427,8 @@ int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
return
ret
;
if
((
ret
=
ff_avfilter_graph_config_links
(
graphctx
,
log_ctx
)))
return
ret
;
ff_avfilter_graph_config_pointers
(
graphctx
,
log_ctx
);
if
((
ret
=
ff_avfilter_graph_config_pointers
(
graphctx
,
log_ctx
)))
return
ret
;
return
0
;
}
...
...
@@ -461,3 +490,65 @@ int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const
return
0
;
}
static
void
heap_bubble_up
(
AVFilterGraph
*
graph
,
AVFilterLink
*
link
,
int
index
)
{
AVFilterLink
**
links
=
graph
->
sink_links
;
while
(
index
)
{
int
parent
=
(
index
-
1
)
>>
1
;
if
(
links
[
parent
]
->
current_pts
>=
link
->
current_pts
)
break
;
links
[
index
]
=
links
[
parent
];
links
[
index
]
->
age_index
=
index
;
index
=
parent
;
}
links
[
index
]
=
link
;
link
->
age_index
=
index
;
}
static
void
heap_bubble_down
(
AVFilterGraph
*
graph
,
AVFilterLink
*
link
,
int
index
)
{
AVFilterLink
**
links
=
graph
->
sink_links
;
while
(
1
)
{
int
child
=
2
*
index
+
1
;
if
(
child
>=
graph
->
sink_links_count
)
break
;
if
(
child
+
1
<
graph
->
sink_links_count
&&
links
[
child
+
1
]
->
current_pts
<
links
[
child
]
->
current_pts
)
child
++
;
if
(
link
->
current_pts
<
links
[
child
]
->
current_pts
)
break
;
links
[
index
]
=
links
[
child
];
links
[
index
]
->
age_index
=
index
;
index
=
child
;
}
links
[
index
]
=
link
;
link
->
age_index
=
index
;
}
void
ff_avfilter_graph_update_heap
(
AVFilterGraph
*
graph
,
AVFilterLink
*
link
)
{
heap_bubble_up
(
graph
,
link
,
link
->
age_index
);
heap_bubble_down
(
graph
,
link
,
link
->
age_index
);
}
int
avfilter_graph_request_oldest
(
AVFilterGraph
*
graph
)
{
while
(
graph
->
sink_links_count
)
{
AVFilterLink
*
oldest
=
graph
->
sink_links
[
0
];
int
r
=
avfilter_request_frame
(
oldest
);
if
(
r
!=
AVERROR_EOF
)
return
r
;
/* EOF: remove the link from the heap */
if
(
oldest
->
age_index
<
--
graph
->
sink_links_count
)
heap_bubble_down
(
graph
,
graph
->
sink_links
[
graph
->
sink_links_count
],
oldest
->
age_index
);
oldest
->
age_index
=
-
1
;
}
return
AVERROR_EOF
;
}
libavfilter/avfiltergraph.h
View file @
2ce79727
...
...
@@ -33,6 +33,16 @@ typedef struct AVFilterGraph {
AVFilterContext
**
filters
;
char
*
scale_sws_opts
;
///< sws options to use for the auto-inserted scale filters
/**
* Private fields
*
* The following fields are for internal use only.
* Their type, offset, number and semantic can change without notice.
*/
AVFilterLink
**
sink_links
;
int
sink_links_count
;
}
AVFilterGraph
;
/**
...
...
@@ -221,4 +231,18 @@ int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const
*/
char
*
avfilter_graph_dump
(
AVFilterGraph
*
graph
,
const
char
*
options
);
/**
* Request a frame on the oldest sink link.
*
* If the request returns AVERROR_EOF, try the next.
*
* Note that this function is not meant to be the sole scheduling mechanism
* of a filtergraph, only a convenience function to help drain a filtergraph
* in a balanced way under normal circumstances.
*
* @return the return value of avfilter_request_frame,
* or AVERROR_EOF of all links returned AVERROR_EOF.
*/
int
avfilter_graph_request_oldest
(
AVFilterGraph
*
graph
);
#endif
/* AVFILTER_AVFILTERGRAPH_H */
libavfilter/internal.h
View file @
2ce79727
...
...
@@ -65,6 +65,11 @@ int ff_avfilter_graph_config_links(AVFilterGraph *graphctx, AVClass *log_ctx);
*/
int
ff_avfilter_graph_config_formats
(
AVFilterGraph
*
graphctx
,
AVClass
*
log_ctx
);
/**
* Update the position of a link in the age heap.
*/
void
ff_avfilter_graph_update_heap
(
AVFilterGraph
*
graph
,
AVFilterLink
*
link
);
/** default handler for freeing audio/video buffer when there are no references left */
void
ff_avfilter_default_free_buffer
(
AVFilterBuffer
*
buf
);
...
...
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