Re: [FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.

2015-04-22 Thread Michael Niedermayer
On Tue, Apr 21, 2015 at 08:54:51PM -0400, Ronald S. Bultje wrote:
> ---
>  libavcodec/vp9.c | 316 
> ++-
>  libavcodec/vp9_mc_template.c | 171 +++
>  libavcodec/vp9_parser.c  |   5 +-
>  libavcodec/vp9dsp.c  | 205 ++--
>  libavcodec/vp9dsp.h  |   9 ++
>  5 files changed, 535 insertions(+), 171 deletions(-)
>  create mode 100644 libavcodec/vp9_mc_template.c

applied

thanks

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Republics decline into democracies and democracies degenerate into
despotisms. -- Aristotle


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.

2015-04-22 Thread Ronald S. Bultje
Hi,

On Tue, Apr 21, 2015 at 11:25 PM, James Almer  wrote:

> On 22/04/15 12:20 AM, James Almer wrote:
> > On 21/04/15 9:54 PM, Ronald S. Bultje wrote:
> >> ---
> >>  libavcodec/vp9.c | 316
> ++-
> >>  libavcodec/vp9_mc_template.c | 171 +++
> >>  libavcodec/vp9_parser.c  |   5 +-
> >>  libavcodec/vp9dsp.c  | 205 ++--
> >>  libavcodec/vp9dsp.h  |   9 ++
> >>  5 files changed, 535 insertions(+), 171 deletions(-)
> >>  create mode 100644 libavcodec/vp9_mc_template.c
> >>
> >> diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
> >> index 89257fa..ee73325 100644
> >> --- a/libavcodec/vp9.c
> >> +++ b/libavcodec/vp9.c
> >> @@ -242,7 +242,7 @@ typedef struct VP9Context {
> >>  // whole-frame cache
> >>  uint8_t *intra_pred_data[3];
> >>  struct VP9Filter *lflvl;
> >> -DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
> >> +DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135*144];
> >>
> >>  // block reconstruction intermediates
> >>  int block_alloc_using_2pass;
> >> @@ -251,6 +251,8 @@ typedef struct VP9Context {
> >>  struct { int x, y; } min_mv, max_mv;
> >>  DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
> >>  DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
> >> +uint16_t mvscale[3][2];
> >> +uint8_t mvstep[3][2];
> >>  } VP9Context;
> >>
> >>  static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
> >> @@ -577,6 +579,26 @@ static int decode_frame_header(AVCodecContext *ctx,
> >>  s->varcompref[1] = 2;
> >>  }
> >>  }
> >> +
> >> +for (i = 0; i < 3; i++) {
> >> +AVFrame *ref = s->refs[s->refidx[i]].f;
> >> +int refw = ref->width, refh = ref->height;
> >> +
> >> +if (refw == w && refh == h) {
> >> +s->mvscale[i][0] = s->mvscale[i][1] = 0;
> >> +} else {
> >> +if (w * 2 < refw || h * 2 < refh || w > 16 * refw
> || h > 16 * refh) {
> >> +av_log(ctx, AV_LOG_ERROR,
> >> +   "Invalid ref frame dimensions %dx%d for
> frame size %dx%d\n",
> >> +   refw, refh, w, h);
> >> +return AVERROR_INVALIDDATA;
> >> +}
> >> +s->mvscale[i][0] = (refw << 14) / w;
> >> +s->mvscale[i][1] = (refh << 14) / h;
> >> +s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
> >> +s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
> >> +}
> >> +}
> >>  }
> >>  }
> >>  s->refreshctx   = s->errorres ? 0 : get_bits1(&s->gb);
> >> @@ -2524,12 +2546,118 @@ static void intra_recon(AVCodecContext *ctx,
> ptrdiff_t y_off, ptrdiff_t uv_off)
> >>  }
> >>  }
> >>
> >> -static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func
> (*mc)[2],
> >> - uint8_t *dst, ptrdiff_t
> dst_stride,
> >> - const uint8_t *ref, ptrdiff_t
> ref_stride,
> >> - ThreadFrame *ref_frame,
> >> - ptrdiff_t y, ptrdiff_t x,
> const VP56mv *mv,
> >> - int bw, int bh, int w, int h)
> >> +static av_always_inline void mc_luma_scaled(VP9Context *s,
> vp9_scaled_mc_func smc,
> >> +uint8_t *dst, ptrdiff_t
> dst_stride,
> >> +const uint8_t *ref,
> ptrdiff_t ref_stride,
> >> +ThreadFrame *ref_frame,
> >> +ptrdiff_t y, ptrdiff_t x,
> const VP56mv *mv,
> >> +int bw, int bh, int w, int
> h,
> >> +const uint16_t *scale,
> const uint8_t *step)
> >> +{
> >> +#define scale_mv(n, dim) (((int64_t)n * scale[dim]) >> 14)
> >> +// BUG libvpx seems to scale the two components separately. This
> introduces
> >> +// rounding errors but we have to reproduce them to be exactly
> compatible
> >> +// with the output from libvpx...
> >
> > Did you report it to libvpx? It's probably a better idea to fix the bug
> in the reference
> > library than purposely reproduce the buggy behavior in our
> implementation to remain
> > compatible.
>
> Just checked the link further down the patch (As i should have done before
> replying).
> Assuming it's the same bug as this one then forget what i said, they
> decided to leave
> the bitstream unchanged.


Yes, sadly, not much can be done here on our end...

Ronald
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.

2015-04-21 Thread James Almer
On 22/04/15 12:20 AM, James Almer wrote:
> On 21/04/15 9:54 PM, Ronald S. Bultje wrote:
>> ---
>>  libavcodec/vp9.c | 316 
>> ++-
>>  libavcodec/vp9_mc_template.c | 171 +++
>>  libavcodec/vp9_parser.c  |   5 +-
>>  libavcodec/vp9dsp.c  | 205 ++--
>>  libavcodec/vp9dsp.h  |   9 ++
>>  5 files changed, 535 insertions(+), 171 deletions(-)
>>  create mode 100644 libavcodec/vp9_mc_template.c
>>
>> diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
>> index 89257fa..ee73325 100644
>> --- a/libavcodec/vp9.c
>> +++ b/libavcodec/vp9.c
>> @@ -242,7 +242,7 @@ typedef struct VP9Context {
>>  // whole-frame cache
>>  uint8_t *intra_pred_data[3];
>>  struct VP9Filter *lflvl;
>> -DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
>> +DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135*144];
>>  
>>  // block reconstruction intermediates
>>  int block_alloc_using_2pass;
>> @@ -251,6 +251,8 @@ typedef struct VP9Context {
>>  struct { int x, y; } min_mv, max_mv;
>>  DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
>>  DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
>> +uint16_t mvscale[3][2];
>> +uint8_t mvstep[3][2];
>>  } VP9Context;
>>  
>>  static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
>> @@ -577,6 +579,26 @@ static int decode_frame_header(AVCodecContext *ctx,
>>  s->varcompref[1] = 2;
>>  }
>>  }
>> +
>> +for (i = 0; i < 3; i++) {
>> +AVFrame *ref = s->refs[s->refidx[i]].f;
>> +int refw = ref->width, refh = ref->height;
>> +
>> +if (refw == w && refh == h) {
>> +s->mvscale[i][0] = s->mvscale[i][1] = 0;
>> +} else {
>> +if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h 
>> > 16 * refh) {
>> +av_log(ctx, AV_LOG_ERROR,
>> +   "Invalid ref frame dimensions %dx%d for 
>> frame size %dx%d\n",
>> +   refw, refh, w, h);
>> +return AVERROR_INVALIDDATA;
>> +}
>> +s->mvscale[i][0] = (refw << 14) / w;
>> +s->mvscale[i][1] = (refh << 14) / h;
>> +s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
>> +s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
>> +}
>> +}
>>  }
>>  }
>>  s->refreshctx   = s->errorres ? 0 : get_bits1(&s->gb);
>> @@ -2524,12 +2546,118 @@ static void intra_recon(AVCodecContext *ctx, 
>> ptrdiff_t y_off, ptrdiff_t uv_off)
>>  }
>>  }
>>  
>> -static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func 
>> (*mc)[2],
>> - uint8_t *dst, ptrdiff_t dst_stride,
>> - const uint8_t *ref, ptrdiff_t 
>> ref_stride,
>> - ThreadFrame *ref_frame,
>> - ptrdiff_t y, ptrdiff_t x, const 
>> VP56mv *mv,
>> - int bw, int bh, int w, int h)
>> +static av_always_inline void mc_luma_scaled(VP9Context *s, 
>> vp9_scaled_mc_func smc,
>> +uint8_t *dst, ptrdiff_t 
>> dst_stride,
>> +const uint8_t *ref, ptrdiff_t 
>> ref_stride,
>> +ThreadFrame *ref_frame,
>> +ptrdiff_t y, ptrdiff_t x, const 
>> VP56mv *mv,
>> +int bw, int bh, int w, int h,
>> +const uint16_t *scale, const 
>> uint8_t *step)
>> +{
>> +#define scale_mv(n, dim) (((int64_t)n * scale[dim]) >> 14)
>> +// BUG libvpx seems to scale the two components separately. This 
>> introduces
>> +// rounding errors but we have to reproduce them to be exactly 
>> compatible
>> +// with the output from libvpx...
> 
> Did you report it to libvpx? It's probably a better idea to fix the bug in 
> the reference
> library than purposely reproduce the buggy behavior in our implementation to 
> remain
> compatible.

Just checked the link further down the patch (As i should have done before 
replying).
Assuming it's the same bug as this one then forget what i said, they decided to 
leave
the bitstream unchanged.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.

2015-04-21 Thread James Almer
On 21/04/15 9:54 PM, Ronald S. Bultje wrote:
> ---
>  libavcodec/vp9.c | 316 
> ++-
>  libavcodec/vp9_mc_template.c | 171 +++
>  libavcodec/vp9_parser.c  |   5 +-
>  libavcodec/vp9dsp.c  | 205 ++--
>  libavcodec/vp9dsp.h  |   9 ++
>  5 files changed, 535 insertions(+), 171 deletions(-)
>  create mode 100644 libavcodec/vp9_mc_template.c
> 
> diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
> index 89257fa..ee73325 100644
> --- a/libavcodec/vp9.c
> +++ b/libavcodec/vp9.c
> @@ -242,7 +242,7 @@ typedef struct VP9Context {
>  // whole-frame cache
>  uint8_t *intra_pred_data[3];
>  struct VP9Filter *lflvl;
> -DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
> +DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135*144];
>  
>  // block reconstruction intermediates
>  int block_alloc_using_2pass;
> @@ -251,6 +251,8 @@ typedef struct VP9Context {
>  struct { int x, y; } min_mv, max_mv;
>  DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
>  DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
> +uint16_t mvscale[3][2];
> +uint8_t mvstep[3][2];
>  } VP9Context;
>  
>  static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
> @@ -577,6 +579,26 @@ static int decode_frame_header(AVCodecContext *ctx,
>  s->varcompref[1] = 2;
>  }
>  }
> +
> +for (i = 0; i < 3; i++) {
> +AVFrame *ref = s->refs[s->refidx[i]].f;
> +int refw = ref->width, refh = ref->height;
> +
> +if (refw == w && refh == h) {
> +s->mvscale[i][0] = s->mvscale[i][1] = 0;
> +} else {
> +if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 
> 16 * refh) {
> +av_log(ctx, AV_LOG_ERROR,
> +   "Invalid ref frame dimensions %dx%d for frame 
> size %dx%d\n",
> +   refw, refh, w, h);
> +return AVERROR_INVALIDDATA;
> +}
> +s->mvscale[i][0] = (refw << 14) / w;
> +s->mvscale[i][1] = (refh << 14) / h;
> +s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
> +s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
> +}
> +}
>  }
>  }
>  s->refreshctx   = s->errorres ? 0 : get_bits1(&s->gb);
> @@ -2524,12 +2546,118 @@ static void intra_recon(AVCodecContext *ctx, 
> ptrdiff_t y_off, ptrdiff_t uv_off)
>  }
>  }
>  
> -static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
> - uint8_t *dst, ptrdiff_t dst_stride,
> - const uint8_t *ref, ptrdiff_t 
> ref_stride,
> - ThreadFrame *ref_frame,
> - ptrdiff_t y, ptrdiff_t x, const 
> VP56mv *mv,
> - int bw, int bh, int w, int h)
> +static av_always_inline void mc_luma_scaled(VP9Context *s, 
> vp9_scaled_mc_func smc,
> +uint8_t *dst, ptrdiff_t 
> dst_stride,
> +const uint8_t *ref, ptrdiff_t 
> ref_stride,
> +ThreadFrame *ref_frame,
> +ptrdiff_t y, ptrdiff_t x, const 
> VP56mv *mv,
> +int bw, int bh, int w, int h,
> +const uint16_t *scale, const 
> uint8_t *step)
> +{
> +#define scale_mv(n, dim) (((int64_t)n * scale[dim]) >> 14)
> +// BUG libvpx seems to scale the two components separately. This 
> introduces
> +// rounding errors but we have to reproduce them to be exactly compatible
> +// with the output from libvpx...

Did you report it to libvpx? It's probably a better idea to fix the bug in the 
reference
library than purposely reproduce the buggy behavior in our implementation to 
remain
compatible.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 1/2] vp9: add support for resolution changes in inter frames.

2015-04-21 Thread Ronald S. Bultje
---
 libavcodec/vp9.c | 316 ++-
 libavcodec/vp9_mc_template.c | 171 +++
 libavcodec/vp9_parser.c  |   5 +-
 libavcodec/vp9dsp.c  | 205 ++--
 libavcodec/vp9dsp.h  |   9 ++
 5 files changed, 535 insertions(+), 171 deletions(-)
 create mode 100644 libavcodec/vp9_mc_template.c

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 89257fa..ee73325 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -242,7 +242,7 @@ typedef struct VP9Context {
 // whole-frame cache
 uint8_t *intra_pred_data[3];
 struct VP9Filter *lflvl;
-DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
+DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135*144];
 
 // block reconstruction intermediates
 int block_alloc_using_2pass;
@@ -251,6 +251,8 @@ typedef struct VP9Context {
 struct { int x, y; } min_mv, max_mv;
 DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
 DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
+uint16_t mvscale[3][2];
+uint8_t mvstep[3][2];
 } VP9Context;
 
 static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
@@ -577,6 +579,26 @@ static int decode_frame_header(AVCodecContext *ctx,
 s->varcompref[1] = 2;
 }
 }
+
+for (i = 0; i < 3; i++) {
+AVFrame *ref = s->refs[s->refidx[i]].f;
+int refw = ref->width, refh = ref->height;
+
+if (refw == w && refh == h) {
+s->mvscale[i][0] = s->mvscale[i][1] = 0;
+} else {
+if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 
16 * refh) {
+av_log(ctx, AV_LOG_ERROR,
+   "Invalid ref frame dimensions %dx%d for frame 
size %dx%d\n",
+   refw, refh, w, h);
+return AVERROR_INVALIDDATA;
+}
+s->mvscale[i][0] = (refw << 14) / w;
+s->mvscale[i][1] = (refh << 14) / h;
+s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
+s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
+}
+}
 }
 }
 s->refreshctx   = s->errorres ? 0 : get_bits1(&s->gb);
@@ -2524,12 +2546,118 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t 
y_off, ptrdiff_t uv_off)
 }
 }
 
-static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
- uint8_t *dst, ptrdiff_t dst_stride,
- const uint8_t *ref, ptrdiff_t 
ref_stride,
- ThreadFrame *ref_frame,
- ptrdiff_t y, ptrdiff_t x, const 
VP56mv *mv,
- int bw, int bh, int w, int h)
+static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func 
smc,
+uint8_t *dst, ptrdiff_t dst_stride,
+const uint8_t *ref, ptrdiff_t 
ref_stride,
+ThreadFrame *ref_frame,
+ptrdiff_t y, ptrdiff_t x, const 
VP56mv *mv,
+int bw, int bh, int w, int h,
+const uint16_t *scale, const 
uint8_t *step)
+{
+#define scale_mv(n, dim) (((int64_t)n * scale[dim]) >> 14)
+// BUG libvpx seems to scale the two components separately. This introduces
+// rounding errors but we have to reproduce them to be exactly compatible
+// with the output from libvpx...
+int mx = scale_mv(mv->x * 2, 0) + scale_mv(x * 16, 0);
+int my = scale_mv(mv->y * 2, 1) + scale_mv(y * 16, 1);
+int refbw_m1, refbh_m1;
+int th;
+
+y = my >> 4;
+x = mx >> 4;
+ref += y * ref_stride + x;
+mx &= 15;
+my &= 15;
+refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;
+refbh_m1 = ((bh - 1) * step[1] + my) >> 4;
+// FIXME bilinear filter only needs 0/1 pixels, not 3/4
+// we use +7 because the last 7 pixels of each sbrow can be changed in
+// the longest loopfilter of the next sbrow
+th = (y + refbh_m1 + 4 + 7) >> 6;
+ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
+if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {
+s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref - 3 * ref_stride - 3,
+ 144, ref_stride,
+ refbw_m1 + 8, refbh_m1 + 8,
+ x - 3, y - 3, w, h);
+ref = s->edge_emu_buffer + 3 * 144 + 3;
+ref_stride = 144;
+}
+smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]);
+}
+
+static av_always_inline void mc_chroma_scaled(VP9Context *s, 
vp9_s