Kieran Kunhya
2014-12-24 12:41:58 UTC
I think this is right but would be useful to get it checked. Visually the output looks ok
---
libavfilter/vf_scale.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 64b88c2..83a0666 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -373,6 +373,13 @@ static int config_props(AVFilterLink *outlink)
av_opt_set_int(*s, "dst_format", outfmt, 0);
av_opt_set_int(*s, "sws_flags", scale->flags, 0);
+ /* Override interlaced YUV420P settings to have the correct (MPEG-2) chroma positions
+ * MPEG-2 chroma positions are used by convention
+ * Set the context up for tff */
+ if (i && scale->interlaced && inlink->format == AV_PIX_FMT_YUV420P){
+ scale->in_v_chr_pos = (i == 1) ? 64 : -64;
+ }
+
av_opt_set_int(*s, "src_h_chr_pos", scale->in_h_chr_pos, 0);
av_opt_set_int(*s, "src_v_chr_pos", scale->in_v_chr_pos, 0);
av_opt_set_int(*s, "dst_h_chr_pos", scale->out_h_chr_pos, 0);
@@ -418,7 +425,12 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s
int vsub= ((i+1)&2) ? scale->vsub : 0;
in_stride[i] = cur_pic->linesize[i] * mul;
out_stride[i] = out_buf->linesize[i] * mul;
- in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i];
+
+ /* Chroma planes are shared in interlaced 4:2:0 */
+ if (i && cur_pic->format == AV_PIX_FMT_YUV420P && scale->interlaced)
+ in[i] = cur_pic->data[i];
+ else
+ in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i];
out[i] = out_buf->data[i] + field * out_buf->linesize[i];
}
if(scale->input_is_pal)
@@ -520,8 +532,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
INT_MAX);
if(scale->interlaced>0 || (scale->interlaced<0 && in->interlaced_frame)){
- scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0);
- scale_slice(link, out, in, scale->isws[1], 0, link->h /2, 2, 1);
+ scale_slice(link, out, in, scale->isws[!in->top_field_first], 0, (link->h+1)/2, 2, 0);
+ scale_slice(link, out, in, scale->isws[in->top_field_first], 0, link->h /2, 2, 1);
}else{
scale_slice(link, out, in, scale->sws, 0, link->h, 1, 0);
}
---
libavfilter/vf_scale.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 64b88c2..83a0666 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -373,6 +373,13 @@ static int config_props(AVFilterLink *outlink)
av_opt_set_int(*s, "dst_format", outfmt, 0);
av_opt_set_int(*s, "sws_flags", scale->flags, 0);
+ /* Override interlaced YUV420P settings to have the correct (MPEG-2) chroma positions
+ * MPEG-2 chroma positions are used by convention
+ * Set the context up for tff */
+ if (i && scale->interlaced && inlink->format == AV_PIX_FMT_YUV420P){
+ scale->in_v_chr_pos = (i == 1) ? 64 : -64;
+ }
+
av_opt_set_int(*s, "src_h_chr_pos", scale->in_h_chr_pos, 0);
av_opt_set_int(*s, "src_v_chr_pos", scale->in_v_chr_pos, 0);
av_opt_set_int(*s, "dst_h_chr_pos", scale->out_h_chr_pos, 0);
@@ -418,7 +425,12 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s
int vsub= ((i+1)&2) ? scale->vsub : 0;
in_stride[i] = cur_pic->linesize[i] * mul;
out_stride[i] = out_buf->linesize[i] * mul;
- in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i];
+
+ /* Chroma planes are shared in interlaced 4:2:0 */
+ if (i && cur_pic->format == AV_PIX_FMT_YUV420P && scale->interlaced)
+ in[i] = cur_pic->data[i];
+ else
+ in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i];
out[i] = out_buf->data[i] + field * out_buf->linesize[i];
}
if(scale->input_is_pal)
@@ -520,8 +532,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
INT_MAX);
if(scale->interlaced>0 || (scale->interlaced<0 && in->interlaced_frame)){
- scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0);
- scale_slice(link, out, in, scale->isws[1], 0, link->h /2, 2, 1);
+ scale_slice(link, out, in, scale->isws[!in->top_field_first], 0, (link->h+1)/2, 2, 0);
+ scale_slice(link, out, in, scale->isws[in->top_field_first], 0, link->h /2, 2, 1);
}else{
scale_slice(link, out, in, scale->sws, 0, link->h, 1, 0);
}
--
1.9.1
1.9.1