aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>2016-02-24 16:03:57 +0000
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2016-02-24 16:03:57 +0000
commit10424024a16a7646169b9c9008c5f7b77cbc2211 (patch)
treeea852976be3a8b8d0cd3d57bc1beb918b89991d0
parent6992276acaaee32b33bd5f6e2f0d89588c4ae59a (diff)
parentb3dd30db0b2d857147fc0e1461a00bd6172a26a3 (diff)
downloadffmpeg-10424024a16a7646169b9c9008c5f7b77cbc2211.tar.gz
Merge commit 'b3dd30db0b2d857147fc0e1461a00bd6172a26a3'
* commit 'b3dd30db0b2d857147fc0e1461a00bd6172a26a3': lavfi: pass the hw frames context through the filter chain Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
-rw-r--r--doc/APIchanges4
-rw-r--r--doc/filters.texi4
-rw-r--r--libavfilter/avfilter.c15
-rw-r--r--libavfilter/avfilter.h7
-rw-r--r--libavfilter/buffersrc.c71
-rw-r--r--libavfilter/buffersrc.h74
-rw-r--r--libavfilter/version.h2
7 files changed, 174 insertions, 3 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index 5af5ab10a1..3c18454647 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,10 @@ libavutil: 2015-08-28
API changes, most recent first:
+2016-xx-xx - lavfi 6.36.0 - avfilter.h
+ xxxxxxx avfilter.h - Add AVFilterLink.hw_frames_ctx.
+ xxxxxxx buffersrc.h - Add AVBufferSrcParameters and functions for handling it.
+
2016-02-xx - xxxxxxx - lavc 57.25.100
Add AV_PKT_DATA_MPEGTS_STREAM_ID for exporting the MPEGTS stream ID.
diff --git a/doc/filters.texi b/doc/filters.texi
index aca76630c0..32042d013e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -13457,6 +13457,10 @@ The sample (pixel) aspect ratio of the input video.
Specify the optional parameters to be used for the scale filter which
is automatically inserted when an input change is detected in the
input size or format.
+
+@item hw_frames_ctx
+When using a hardware pixel format, this should be a reference to an
+AVHWFramesContext describing input frames.
@end table
For example:
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 2f4d59f316..3a2a6c2a60 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -22,9 +22,11 @@
#include "libavutil/atomic.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
+#include "libavutil/buffer.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/eval.h"
+#include "libavutil/hwcontext.h"
#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
@@ -322,6 +324,17 @@ int avfilter_config_links(AVFilterContext *filter)
return ret;
}
+ if (link->src->nb_inputs && link->src->inputs[0]->hw_frames_ctx &&
+ !link->hw_frames_ctx) {
+ AVHWFramesContext *input_ctx = (AVHWFramesContext*)link->src->inputs[0]->hw_frames_ctx->data;
+
+ if (input_ctx->format == link->format) {
+ link->hw_frames_ctx = av_buffer_ref(link->src->inputs[0]->hw_frames_ctx);
+ if (!link->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+ }
+ }
+
link->init_state = AVLINK_INIT;
}
}
@@ -715,6 +728,8 @@ static void free_link(AVFilterLink *link)
if (link->dst)
link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
+ av_buffer_unref(&link->hw_frames_ctx);
+
ff_formats_unref(&link->in_formats);
ff_formats_unref(&link->out_formats);
ff_formats_unref(&link->in_samplerates);
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 04bf5855e2..835a519173 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -37,6 +37,7 @@
#include "libavutil/attributes.h"
#include "libavutil/avutil.h"
+#include "libavutil/buffer.h"
#include "libavutil/dict.h"
#include "libavutil/frame.h"
#include "libavutil/log.h"
@@ -464,6 +465,12 @@ struct AVFilterLink {
AVRational frame_rate;
/**
+ * For hwaccel pixel formats, this should be a reference to the
+ * AVHWFramesContext describing the frames.
+ */
+ AVBufferRef *hw_frames_ctx;
+
+ /**
* Buffer partially filled with samples to achieve a fixed/minimum size.
*/
AVFrame *partial_buf;
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 27ad8e49ec..9294811d36 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -54,6 +54,8 @@ typedef struct BufferSourceContext {
AVRational pixel_aspect;
char *sws_param;
+ AVBufferRef *hw_frames_ctx;
+
/* audio only */
int sample_rate;
enum AVSampleFormat sample_fmt;
@@ -61,6 +63,7 @@ typedef struct BufferSourceContext {
uint64_t channel_layout;
char *channel_layout_str;
+ int got_format_from_params;
int eof;
} BufferSourceContext;
@@ -76,6 +79,62 @@ typedef struct BufferSourceContext {
return AVERROR(EINVAL);\
}
+AVBufferSrcParameters *av_buffersrc_parameters_alloc(void)
+{
+ AVBufferSrcParameters *par = av_mallocz(sizeof(*par));
+ if (!par)
+ return NULL;
+
+ par->format = -1;
+
+ return par;
+}
+
+int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *param)
+{
+ BufferSourceContext *s = ctx->priv;
+
+ if (param->time_base.num > 0 && param->time_base.den > 0)
+ s->time_base = param->time_base;
+
+ switch (ctx->filter->outputs[0].type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (param->format != AV_PIX_FMT_NONE) {
+ s->got_format_from_params = 1;
+ s->pix_fmt = param->format;
+ }
+ if (param->width > 0)
+ s->w = param->width;
+ if (param->height > 0)
+ s->h = param->height;
+ if (param->sample_aspect_ratio.num > 0 && param->sample_aspect_ratio.den > 0)
+ s->pixel_aspect = param->sample_aspect_ratio;
+ if (param->frame_rate.num > 0 && param->frame_rate.den > 0)
+ s->frame_rate = param->frame_rate;
+ if (param->hw_frames_ctx) {
+ av_buffer_unref(&s->hw_frames_ctx);
+ s->hw_frames_ctx = av_buffer_ref(param->hw_frames_ctx);
+ if (!s->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (param->format != AV_SAMPLE_FMT_NONE) {
+ s->got_format_from_params = 1;
+ s->sample_fmt = param->format;
+ }
+ if (param->sample_rate > 0)
+ s->sample_rate = param->sample_rate;
+ if (param->channel_layout)
+ s->channel_layout = param->channel_layout;
+ break;
+ default:
+ return AVERROR_BUG;
+ }
+
+ return 0;
+}
+
int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
{
return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame,
@@ -187,7 +246,8 @@ static av_cold int init_video(AVFilterContext *ctx)
{
BufferSourceContext *c = ctx->priv;
- if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h || av_q2d(c->time_base) <= 0) {
+ if (!(c->pix_fmt != AV_PIX_FMT_NONE || c->got_format_from_params) || !c->w || !c->h ||
+ av_q2d(c->time_base) <= 0) {
av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n");
return AVERROR(EINVAL);
}
@@ -251,7 +311,7 @@ static av_cold int init_audio(AVFilterContext *ctx)
BufferSourceContext *s = ctx->priv;
int ret = 0;
- if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
+ if (!(s->sample_fmt != AV_SAMPLE_FMT_NONE || s->got_format_from_params)) {
av_log(ctx, AV_LOG_ERROR, "Sample format was not set or was invalid\n");
return AVERROR(EINVAL);
}
@@ -305,6 +365,7 @@ static av_cold void uninit(AVFilterContext *ctx)
av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL);
av_frame_free(&frame);
}
+ av_buffer_unref(&s->hw_frames_ctx);
av_fifo_freep(&s->fifo);
}
@@ -352,6 +413,12 @@ static int config_props(AVFilterLink *link)
link->w = c->w;
link->h = c->h;
link->sample_aspect_ratio = c->pixel_aspect;
+
+ if (c->hw_frames_ctx) {
+ link->hw_frames_ctx = av_buffer_ref(c->hw_frames_ctx);
+ if (!link->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+ }
break;
case AVMEDIA_TYPE_AUDIO:
if (!c->channel_layout)
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index 847c093c5e..e4db1f74b2 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -66,6 +66,80 @@ enum {
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src);
/**
+ * This structure contains the parameters describing the frames that will be
+ * passed to this filter.
+ *
+ * It should be allocated with av_buffersrc_parameters_alloc() and freed with
+ * av_free(). All the allocated fields in it remain owned by the caller.
+ */
+typedef struct AVBufferSrcParameters {
+ /**
+ * video: the pixel format, value corresponds to enum AVPixelFormat
+ * audio: the sample format, value corresponds to enum AVSampleFormat
+ */
+ int format;
+ /**
+ * The timebase to be used for the timestamps on the input frames.
+ */
+ AVRational time_base;
+
+ /**
+ * Video only, the display dimensions of the input frames.
+ */
+ int width, height;
+
+ /**
+ * Video only, the sample (pixel) aspect ratio.
+ */
+ AVRational sample_aspect_ratio;
+
+ /**
+ * Video only, the frame rate of the input video. This field must only be
+ * set to a non-zero value if input stream has a known constant framerate
+ * and should be left at its initial value if the framerate is variable or
+ * unknown.
+ */
+ AVRational frame_rate;
+
+ /**
+ * Video with a hwaccel pixel format only. This should be a reference to an
+ * AVHWFramesContext instance describing the input frames.
+ */
+ AVBufferRef *hw_frames_ctx;
+
+ /**
+ * Audio only, the audio sampling rate in samples per secon.
+ */
+ int sample_rate;
+
+ /**
+ * Audio only, the audio channel layout
+ */
+ uint64_t channel_layout;
+} AVBufferSrcParameters;
+
+/**
+ * Allocate a new AVBufferSrcParameters instance. It should be freed by the
+ * caller with av_free().
+ */
+AVBufferSrcParameters *av_buffersrc_parameters_alloc(void);
+
+/**
+ * Initialize the buffersrc or abuffersrc filter with the provided parameters.
+ * This function may be called multiple times, the later calls override the
+ * previous ones. Some of the parameters may also be set through AVOptions, then
+ * whatever method is used last takes precedence.
+ *
+ * @param ctx an instance of the buffersrc or abuffersrc filter
+ * @param param the stream parameters. The frames later passed to this filter
+ * must conform to those parameters. All the allocated fields in
+ * param remain owned by the caller, libavfilter will make internal
+ * copies or references when necessary.
+ * @return 0 on success, a negative AVERROR code on failure.
+ */
+int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *param);
+
+/**
* Add a frame to the buffer source.
*
* @param ctx an instance of the buffersrc filter
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 480c464cff..d8b8ff7bc8 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 6
-#define LIBAVFILTER_VERSION_MINOR 35
+#define LIBAVFILTER_VERSION_MINOR 36
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \