Commit 3d8176d2 authored by Michael Niedermayer's avatar Michael Niedermayer

avfilter: Add avfilter_graph_que_command()

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent f782ce3b
...@@ -45,6 +45,15 @@ const char *avfilter_license(void) ...@@ -45,6 +45,15 @@ const char *avfilter_license(void)
return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
} }
static void command_queue_pop(AVFilterContext *filter)
{
AVFilterCommand *c= filter->command_queue;
av_freep(&c->arg);
av_freep(&c->command);
filter->command_queue= c->next;
av_free(c);
}
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask) AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
{ {
AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef)); AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
...@@ -534,6 +543,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) ...@@ -534,6 +543,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
void (*start_frame)(AVFilterLink *, AVFilterBufferRef *); void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
AVFilterPad *dst = link->dstpad; AVFilterPad *dst = link->dstpad;
int perms = picref->perms; int perms = picref->perms;
AVFilterCommand *cmd= link->dst->command_queue;
FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1); FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
...@@ -556,6 +566,11 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) ...@@ -556,6 +566,11 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
else else
link->cur_buf = picref; link->cur_buf = picref;
if(cmd && cmd->time <= picref->pts * av_q2d(link->time_base)){
avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
command_queue_pop(link->dst);
}
start_frame(link, link->cur_buf); start_frame(link, link->cur_buf);
} }
...@@ -815,6 +830,9 @@ void avfilter_free(AVFilterContext *filter) ...@@ -815,6 +830,9 @@ void avfilter_free(AVFilterContext *filter)
av_freep(&filter->inputs); av_freep(&filter->inputs);
av_freep(&filter->outputs); av_freep(&filter->outputs);
av_freep(&filter->priv); av_freep(&filter->priv);
while(filter->command_queue){
command_queue_pop(filter);
}
av_free(filter); av_free(filter);
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "libavutil/rational.h" #include "libavutil/rational.h"
#define LIBAVFILTER_VERSION_MAJOR 2 #define LIBAVFILTER_VERSION_MAJOR 2
#define LIBAVFILTER_VERSION_MINOR 36 #define LIBAVFILTER_VERSION_MINOR 37
#define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_MICRO 0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
...@@ -585,6 +585,8 @@ struct AVFilterContext { ...@@ -585,6 +585,8 @@ struct AVFilterContext {
AVFilterLink **outputs; ///< array of pointers to output links AVFilterLink **outputs; ///< array of pointers to output links
void *priv; ///< private data for use by the filter void *priv; ///< private data for use by the filter
struct AVFilterCommand *command_queue;
}; };
enum AVFilterPacking { enum AVFilterPacking {
......
...@@ -283,3 +283,28 @@ int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const ...@@ -283,3 +283,28 @@ int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const
return r; return r;
} }
int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
{
int i;
if(!graph)
return 0;
for (i = 0; i < graph->filter_count; i++) {
AVFilterContext *filter = graph->filters[i];
if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
AVFilterCommand **que = &filter->command_queue;
while(*que) que = &(*que)->next;
*que= av_mallocz(sizeof(AVFilterCommand));
(*que)->command = av_strdup(command);
(*que)->arg = av_strdup(arg);
(*que)->time = ts;
(*que)->flags = flags;
if(flags & AVFILTER_CMD_FLAG_ONE)
return 0;
}
}
return 0;
}
...@@ -153,4 +153,22 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, ...@@ -153,4 +153,22 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
*/ */
int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags); int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags);
/**
* Queue a command for one or more filter instances.
*
* @param graph the filter graph
* @param target the filter(s) to which the command should be sent
* "all" sends to all filters
* otherwise it can be a filter or filter instance name
* which will send the command to all matching filters.
* @param cmd the command to sent, for handling simplicity all commands must be alphanummeric only
* @param arg the argument for the command
* @param ts time at which the command should be sent to the filter
*
* @note As this executes commands after this function returns, no return code
* from the filter is provided, also AVFILTER_CMD_FLAG_ONE is not supported.
*/
int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts);
#endif /* AVFILTER_AVFILTERGRAPH_H */ #endif /* AVFILTER_AVFILTERGRAPH_H */
...@@ -33,6 +33,13 @@ typedef struct AVFilterPool { ...@@ -33,6 +33,13 @@ typedef struct AVFilterPool {
int count; int count;
} AVFilterPool; } AVFilterPool;
typedef struct AVFilterCommand {
double time;
char *command, *arg;
int flags;
struct AVFilterCommand *next;
} AVFilterCommand;
/** /**
* Check for the validity of graph. * Check for the validity of graph.
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment