summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-02-20 13:15:50 +0100
committerwm4 <wm4@nowhere>2017-02-20 13:15:50 +0100
commitfefc5a8f735a62f3dd317fd18e51e33959c07690 (patch)
treea799fa43126866c596739cca4ad9f3e262aa8a41
parent79272e1469a591e753240b5e8e7a3069194759da (diff)
downloadmpv-fefc5a8f735a62f3dd317fd18e51e33959c07690.tar.bz2
mpv-fefc5a8f735a62f3dd317fd18e51e33959c07690.tar.xz
lavfi: use mp_image to store the filter pad format
Preparation for enabling hw filters. mp_image_params can't have an AVHWFramesContext reference (because it can't hold any allocations, and isn't meant to hold "active" data in the first place. So just use a mp_image. It has all real data removed, because that would essentially leak 1 frame once the decoder or renderer don't need it anymore.
-rw-r--r--player/lavfi.c35
-rw-r--r--video/mp_image.c11
-rw-r--r--video/mp_image.h1
3 files changed, 31 insertions, 16 deletions
diff --git a/player/lavfi.c b/player/lavfi.c
index c31def9d0d..be0b119c42 100644
--- a/player/lavfi.c
+++ b/player/lavfi.c
@@ -102,7 +102,7 @@ struct lavfi_pad {
bool input_eof; // caller notified us that no input will come anymore
// used to check for format changes manually
- struct mp_image_params in_fmt_v;
+ struct mp_image *in_fmt_v;
struct mp_audio in_fmt_a;
// -- dir==LAVFI_OUT
@@ -194,7 +194,7 @@ static void free_graph(struct lavfi *c)
pad->filter = NULL;
pad->filter_pad = -1;
pad->buffer = NULL;
- pad->in_fmt_v = (struct mp_image_params){0};
+ TA_FREEP(&pad->in_fmt_v);
pad->in_fmt_a = (struct mp_audio){0};
pad->buffer_is_eof = false;
pad->input_needed = false;
@@ -305,11 +305,11 @@ static bool is_aformat_ok(struct mp_audio *a, struct mp_audio *b)
{
return mp_audio_config_equals(a, b);
}
-static bool is_vformat_ok(struct mp_image_params *a, struct mp_image_params *b)
+static bool is_vformat_ok(struct mp_image *a, struct mp_image *b)
{
return a->imgfmt == b->imgfmt &&
a->w == b->w && a->h && b->h &&
- a->p_w == b->p_w && a->p_h == b->p_h;
+ a->params.p_w == b->params.p_w && a->params.p_h == b->params.p_h;
}
static void check_format_changes(struct lavfi *c)
@@ -324,9 +324,9 @@ static void check_format_changes(struct lavfi *c)
c->draining_new_format |= !is_aformat_ok(pad->pending_a,
&pad->in_fmt_a);
}
- if (pad->type == STREAM_VIDEO && pad->pending_v && pad->in_fmt_v.imgfmt) {
- c->draining_new_format |= !is_vformat_ok(&pad->pending_v->params,
- &pad->in_fmt_v);
+ if (pad->type == STREAM_VIDEO && pad->pending_v && pad->in_fmt_v) {
+ c->draining_new_format |= !is_vformat_ok(pad->pending_v,
+ pad->in_fmt_v);
}
}
@@ -375,6 +375,8 @@ static bool init_pads(struct lavfi *c)
char src_args[256];
AVFilter *src_filter = NULL;
+ TA_FREEP(&pad->in_fmt_v); // potentially cleanup previous error state
+
pad->input_eof |= !pad->connected;
if (pad->pending_a) {
@@ -382,7 +384,10 @@ static bool init_pads(struct lavfi *c)
mp_audio_copy_config(&pad->in_fmt_a, pad->pending_a);
} else if (pad->pending_v) {
assert(pad->type == STREAM_VIDEO);
- pad->in_fmt_v = pad->pending_v->params;
+ pad->in_fmt_v = mp_image_new_ref(pad->pending_v);
+ if (!pad->in_fmt_v)
+ goto error;
+ mp_image_unref_data(pad->in_fmt_v);
} else if (pad->input_eof) {
// libavfilter makes this painful. Init it with a dummy config,
// just so we can tell it the stream is EOF.
@@ -391,11 +396,9 @@ static bool init_pads(struct lavfi *c)
mp_audio_set_num_channels(&pad->in_fmt_a, 2);
pad->in_fmt_a.rate = 48000;
} else if (pad->type == STREAM_VIDEO) {
- pad->in_fmt_v = (struct mp_image_params){
- .imgfmt = IMGFMT_420P,
- .w = 64, .h = 64,
- .p_w = 1, .p_h = 1,
- };
+ pad->in_fmt_v = talloc_zero(NULL, struct mp_image);
+ mp_image_setfmt(pad->in_fmt_v, IMGFMT_420P);
+ mp_image_set_size(pad->in_fmt_v, 64, 64);
}
} else {
// no input data, format unknown, can't init, wait longer.
@@ -415,10 +418,10 @@ static bool init_pads(struct lavfi *c)
} else if (pad->type == STREAM_VIDEO) {
pad->timebase = AV_TIME_BASE_Q;
snprintf(src_args, sizeof(src_args), "%d:%d:%d:%d:%d:%d:%d",
- pad->in_fmt_v.w, pad->in_fmt_v.h,
- imgfmt2pixfmt(pad->in_fmt_v.imgfmt),
+ pad->in_fmt_v->w, pad->in_fmt_v->h,
+ imgfmt2pixfmt(pad->in_fmt_v->imgfmt),
pad->timebase.num, pad->timebase.den,
- pad->in_fmt_v.p_w, pad->in_fmt_v.p_h);
+ pad->in_fmt_v->params.p_w, pad->in_fmt_v->params.p_h);
src_filter = avfilter_get_by_name("buffer");
} else {
assert(0);
diff --git a/video/mp_image.c b/video/mp_image.c
index e4e6ffa266..7e0dd173b7 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -177,6 +177,17 @@ void mp_image_steal_data(struct mp_image *dst, struct mp_image *src)
talloc_free(src);
}
+// Unref most data buffer (and clear the data array), but leave other fields
+// allocated. In particular, mp_image.hwctx is preserved.
+void mp_image_unref_data(struct mp_image *img)
+{
+ for (int n = 0; n < MP_MAX_PLANES; n++) {
+ img->planes[n] = NULL;
+ img->stride[n] = 0;
+ av_buffer_unref(&img->bufs[n]);
+ }
+}
+
// Return a new reference to img. The returned reference is owned by the caller,
// while img is left untouched.
struct mp_image *mp_image_new_ref(struct mp_image *img)
diff --git a/video/mp_image.h b/video/mp_image.h
index 6606f19c90..e3ffd55adc 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -124,6 +124,7 @@ int mp_image_plane_h(struct mp_image *mpi, int plane);
void mp_image_setfmt(mp_image_t* mpi, int out_fmt);
void mp_image_steal_data(struct mp_image *dst, struct mp_image *src);
+void mp_image_unref_data(struct mp_image *img);
struct mp_image *mp_image_new_dummy_ref(struct mp_image *img);
struct mp_image *mp_image_new_custom_ref(struct mp_image *img, void *arg,