1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index 243bef5..d20b000 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -504,6 +504,10 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000;
}
}
+ if(v->broadcast) { // Pulldown may be present
+ v->s.avctx->time_base.den *= 2;
+ v->s.avctx->ticks_per_frame = 2;
+ }
}
if(get_bits1(gb)){
@@ -821,7 +825,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
case 4:
v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic
v->p_frame_skipped = 1;
- return 0;
+ break;
}
if(v->tfcntrflag)
skip_bits(gb, 8);
@@ -830,13 +834,16 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
v->rptfrm = get_bits(gb, 2);
} else {
v->tff = get_bits1(gb);
- v->rptfrm = get_bits1(gb);
+ v->rff = get_bits1(gb);
}
}
if(v->panscanflag) {
av_log_missing_feature(v->s.avctx, "Pan-scan", 0);
//...
}
+ if(v->p_frame_skipped) {
+ return 0;
+ }
v->rnd = get_bits1(gb);
if(v->interlace)
v->uvsamp = get_bits1(gb);
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 27ff1bd..4151119 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -45,6 +45,7 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
vpc->v.s.avctx = avctx;
vpc->v.parse_only = 1;
next = buf;
+ s->repeat_pict = 0;
for(start = buf, end = buf + buf_size; next < end; start = next){
int buf2_size, size;
@@ -73,6 +74,18 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
else
s->pict_type = vpc->v.s.pict_type;
+ // process pulldown flags
+ s->repeat_pict = 1;
+ // Pulldown flags are only valid when 'broadcast' has been set.
+ // So ticks_per_frame will be 2
+ if (vpc->v.rff){
+ // repeat field
+ s->repeat_pict = 2;
+ }else if (vpc->v.rptfrm){
+ // repeat frames
+ s->repeat_pict = vpc->v.rptfrm * 2 + 1;
+ }
+
break;
}
}
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index ae7906d..58cb8c0 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -3698,6 +3698,18 @@ static int vc1_decode_frame(AVCodecContext *avctx,
av_log(v->s.avctx, AV_LOG_WARNING, "Sprite decoder: expected I-frame\n");
}
+ // process pulldown flags
+ s->current_picture_ptr->repeat_pict = 0;
+ // Pulldown flags are only valid when 'broadcast' has been set.
+ // So ticks_per_frame will be 2
+ if (v->rff){
+ // repeat field
+ s->current_picture_ptr->repeat_pict = 1;
+ }else if (v->rptfrm){
+ // repeat frames
+ s->current_picture_ptr->repeat_pict = v->rptfrm * 2;
+ }
+
// for skipping the frame
s->current_picture.f.pict_type = s->pict_type;
s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
|