Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
external
ffmpeg
Commits
fcb48651
Commit
fcb48651
authored
Sep 26, 2002
by
Michael Niedermayer
Browse files
mpeg4 interlaced dct encoding
Originally committed as revision 971 to
svn://svn.ffmpeg.org/ffmpeg/trunk
parent
b560f4b6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
220 additions
and
35 deletions
+220
-35
libavcodec/avcodec.h
libavcodec/avcodec.h
+3
-2
libavcodec/h263.c
libavcodec/h263.c
+23
-2
libavcodec/mpegvideo.c
libavcodec/mpegvideo.c
+194
-31
No files found.
libavcodec/avcodec.h
View file @
fcb48651
...
...
@@ -5,8 +5,8 @@
#define LIBAVCODEC_VERSION_INT 0x000406
#define LIBAVCODEC_VERSION "0.4.6"
#define LIBAVCODEC_BUILD 462
6
#define LIBAVCODEC_BUILD_STR "462
6
"
#define LIBAVCODEC_BUILD 462
7
#define LIBAVCODEC_BUILD_STR "462
7
"
enum
CodecID
{
CODEC_ID_NONE
,
...
...
@@ -124,6 +124,7 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
#define CODEC_FLAG_NOT_TRUNCATED 0x00010000
/* input bitstream is not truncated, except before a startcode
allows the last part of a frame to be decoded earlier */
#define CODEC_FLAG_NORMALIZE_AQP 0x00020000
/* normalize adaptive quantization */
#define CODEC_FLAG_INTERLACED_DCT 0x00040000
/* use interlaced dct */
/* codec capabilities */
...
...
libavcodec/h263.c
View file @
fcb48651
...
...
@@ -458,6 +458,13 @@ void mpeg4_encode_mb(MpegEncContext * s,
put_bits
(
&
s
->
pb
,
1
,
0
);
}
else
s
->
qscale
-=
s
->
dquant
;
if
(
!
s
->
progressive_sequence
){
if
(
cbp
)
put_bits
(
&
s
->
pb
,
1
,
s
->
interlaced_dct
);
if
(
mb_type
)
// not diect mode
put_bits
(
&
s
->
pb
,
1
,
0
);
// no interlaced ME yet
}
if
(
interleaved_stats
){
bits
=
get_bit_count
(
&
s
->
pb
);
...
...
@@ -580,6 +587,12 @@ void mpeg4_encode_mb(MpegEncContext * s,
put_bits
(
pb2
,
cbpy_tab
[
cbpy
][
1
],
cbpy_tab
[
cbpy
][
0
]);
if
(
s
->
dquant
)
put_bits
(
pb2
,
2
,
dquant_code
[
s
->
dquant
+
2
]);
if
(
!
s
->
progressive_sequence
){
if
(
cbp
)
put_bits
(
pb2
,
1
,
s
->
interlaced_dct
);
put_bits
(
pb2
,
1
,
0
);
// no interlaced ME yet
}
if
(
interleaved_stats
){
bits
=
get_bit_count
(
&
s
->
pb
);
...
...
@@ -701,6 +714,10 @@ void mpeg4_encode_mb(MpegEncContext * s,
if
(
s
->
dquant
)
put_bits
(
dc_pb
,
2
,
dquant_code
[
s
->
dquant
+
2
]);
if
(
!
s
->
progressive_sequence
){
put_bits
(
dc_pb
,
1
,
s
->
interlaced_dct
);
}
if
(
interleaved_stats
){
bits
=
get_bit_count
(
&
s
->
pb
);
s
->
misc_bits
+=
bits
-
s
->
last_bits
;
...
...
@@ -1511,7 +1528,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
put_bits
(
&
s
->
pb
,
1
,
1
);
/* marker bit */
put_bits
(
&
s
->
pb
,
13
,
s
->
height
);
/* vol height */
put_bits
(
&
s
->
pb
,
1
,
1
);
/* marker bit */
put_bits
(
&
s
->
pb
,
1
,
0
);
/* interlace */
put_bits
(
&
s
->
pb
,
1
,
s
->
progressive_sequence
?
0
:
1
);
put_bits
(
&
s
->
pb
,
1
,
1
);
/* obmc disable */
if
(
vo_ver_id
==
1
)
{
put_bits
(
&
s
->
pb
,
1
,
s
->
vol_sprite_usage
=
0
);
/* sprite enable */
...
...
@@ -1586,6 +1603,10 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
put_bits
(
&
s
->
pb
,
1
,
s
->
no_rounding
);
/* rounding type */
}
put_bits
(
&
s
->
pb
,
3
,
0
);
/* intra dc VLC threshold */
if
(
!
s
->
progressive_sequence
){
put_bits
(
&
s
->
pb
,
1
,
s
->
top_field_first
);
put_bits
(
&
s
->
pb
,
1
,
s
->
alternate_scan
);
}
//FIXME sprite stuff
put_bits
(
&
s
->
pb
,
5
,
s
->
qscale
);
...
...
@@ -4215,7 +4236,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
check_marker
(
&
s
->
gb
,
"before time_increment"
);
time_increment
=
get_bits
(
&
s
->
gb
,
s
->
time_increment_bits
);
//printf(" type:%d
incr
:%d increment:%d\n", s->pict_type, time_incr, time_increment);
//printf(" type:%d
modulo_time_base
:%d increment:%d\n", s->pict_type, time_incr, time_increment);
if
(
s
->
pict_type
!=
B_TYPE
){
s
->
last_time_base
=
s
->
time_base
;
s
->
time_base
+=
time_incr
;
...
...
libavcodec/mpegvideo.c
View file @
fcb48651
...
...
@@ -450,6 +450,8 @@ int MPV_encode_init(AVCodecContext *avctx)
||
s
->
avctx
->
spatial_cplx_masking
||
s
->
avctx
->
p_masking
)
&&
!
s
->
fixed_qscale
;
s
->
progressive_sequence
=
!
(
avctx
->
flags
&
CODEC_FLAG_INTERLACED_DCT
);
switch
(
avctx
->
codec
->
id
)
{
case
CODEC_ID_MPEG1VIDEO
:
...
...
@@ -1747,29 +1749,154 @@ static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index
}
}
static
inline
void
requantize_coeffs
(
MpegEncContext
*
s
,
DCTELEM
block
[
64
],
int
oldq
,
int
newq
,
int
n
)
{
int
i
;
if
(
s
->
mb_intra
){
//FIXME requantize, note (mpeg1/h263/h263p-aic dont need it,...)
i
=
1
;
}
else
i
=
0
;
for
(;
i
<=
s
->
block_last_index
[
n
];
i
++
){
const
int
j
=
zigzag_direct
[
i
];
int
level
=
block
[
j
];
block
[
j
]
=
ROUNDED_DIV
(
level
*
oldq
,
newq
);
}
for
(
i
=
s
->
block_last_index
[
n
];
i
>=
0
;
i
--
){
const
int
j
=
zigzag_direct
[
i
];
//FIXME other scantabs
if
(
block
[
j
])
break
;
}
s
->
block_last_index
[
n
]
=
i
;
}
static
inline
void
auto_requantize_coeffs
(
MpegEncContext
*
s
,
DCTELEM
block
[
6
][
64
])
{
int
i
,
n
,
newq
;
const
int
maxlevel
=
s
->
max_qcoeff
;
const
int
minlevel
=
s
->
min_qcoeff
;
int
largest
=
0
,
smallest
=
0
;
assert
(
s
->
adaptive_quant
);
for
(
n
=
0
;
n
<
6
;
n
++
){
if
(
s
->
mb_intra
)
i
=
1
;
else
i
=
0
;
for
(;
i
<=
s
->
block_last_index
[
n
];
i
++
){
const
int
j
=
zigzag_direct
[
i
];
//FIXME other scantabs
int
level
=
block
[
n
][
j
];
if
(
largest
<
level
)
largest
=
level
;
if
(
smallest
>
level
)
smallest
=
level
;
}
}
for
(
newq
=
s
->
qscale
+
1
;
newq
<
32
;
newq
++
){
if
(
ROUNDED_DIV
(
smallest
*
s
->
qscale
,
newq
)
>=
minlevel
&&
ROUNDED_DIV
(
largest
*
s
->
qscale
,
newq
)
<=
maxlevel
)
break
;
}
if
(
s
->
out_format
==
FMT_H263
){
/* h263 like formats cannot change qscale by more than 2 easiely */
if
(
s
->
avctx
->
qmin
+
2
<
newq
)
newq
=
s
->
avctx
->
qmin
+
2
;
}
for
(
n
=
0
;
n
<
6
;
n
++
){
requantize_coeffs
(
s
,
block
[
n
],
s
->
qscale
,
newq
,
n
);
clip_coeffs
(
s
,
block
[
n
],
s
->
block_last_index
[
n
]);
}
s
->
dquant
+=
newq
-
s
->
qscale
;
s
->
qscale
=
newq
;
}
#if 0
static int pix_vcmp16x8(UINT8 *s, int stride){ //FIXME move to dsputil & optimize
int score=0;
int x,y;
for(y=0; y<7; y++){
for(x=0; x<16; x+=4){
score+= ABS(s[x ] - s[x +stride]) + ABS(s[x+1] - s[x+1+stride])
+ABS(s[x+2] - s[x+2+stride]) + ABS(s[x+3] - s[x+3+stride]);
}
s+= stride;
}
return score;
}
static int pix_diff_vcmp16x8(UINT8 *s1, UINT8*s2, int stride){ //FIXME move to dsputil & optimize
int score=0;
int x,y;
for(y=0; y<7; y++){
for(x=0; x<16; x++){
score+= ABS(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
}
s1+= stride;
s2+= stride;
}
return score;
}
#else
#define SQ(a) ((a)*(a))
static
int
pix_vcmp16x8
(
UINT8
*
s
,
int
stride
){
//FIXME move to dsputil & optimize
int
score
=
0
;
int
x
,
y
;
for
(
y
=
0
;
y
<
7
;
y
++
){
for
(
x
=
0
;
x
<
16
;
x
+=
4
){
score
+=
SQ
(
s
[
x
]
-
s
[
x
+
stride
])
+
SQ
(
s
[
x
+
1
]
-
s
[
x
+
1
+
stride
])
+
SQ
(
s
[
x
+
2
]
-
s
[
x
+
2
+
stride
])
+
SQ
(
s
[
x
+
3
]
-
s
[
x
+
3
+
stride
]);
}
s
+=
stride
;
}
return
score
;
}
static
int
pix_diff_vcmp16x8
(
UINT8
*
s1
,
UINT8
*
s2
,
int
stride
){
//FIXME move to dsputil & optimize
int
score
=
0
;
int
x
,
y
;
for
(
y
=
0
;
y
<
7
;
y
++
){
for
(
x
=
0
;
x
<
16
;
x
++
){
score
+=
SQ
(
s1
[
x
]
-
s2
[
x
]
-
s1
[
x
+
stride
]
+
s2
[
x
+
stride
]);
}
s1
+=
stride
;
s2
+=
stride
;
}
return
score
;
}
#endif
static
void
encode_mb
(
MpegEncContext
*
s
,
int
motion_x
,
int
motion_y
)
{
const
int
mb_x
=
s
->
mb_x
;
const
int
mb_y
=
s
->
mb_y
;
int
i
;
int
skip_dct
[
6
];
#if 0
if (s->interlaced_dct) {
dct_linesize = s->linesize * 2;
dct_offset = s->linesize;
} else {
dct_linesize = s->linesize;
dct_offset = s->linesize * 8;
}
#endif
int
dct_offset
=
s
->
linesize
*
8
;
//default for progressive frames
for
(
i
=
0
;
i
<
6
;
i
++
)
skip_dct
[
i
]
=
0
;
if
(
s
->
adaptive_quant
){
s
->
dquant
=
s
->
qscale_table
[
mb_x
+
mb_y
*
s
->
mb_width
]
-
s
->
qscale
;
if
(
s
->
codec_id
==
CODEC_ID_MPEG4
){
if
(
s
->
out_format
==
FMT_H263
){
if
(
s
->
dquant
>
2
)
s
->
dquant
=
2
;
else
if
(
s
->
dquant
<-
2
)
s
->
dquant
=-
2
;
}
if
(
s
->
codec_id
==
CODEC_ID_MPEG4
){
if
(
!
s
->
mb_intra
){
assert
(
s
->
dquant
==
0
||
s
->
mv_type
!=
MV_TYPE_8X8
);
...
...
@@ -1784,39 +1911,56 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
if
(
s
->
mb_intra
)
{
UINT8
*
ptr
;
int
wrap
;
int
wrap
_y
;
int
emu
=
0
;
wrap
=
s
->
linesize
;
ptr
=
s
->
new_picture
[
0
]
+
(
mb_y
*
16
*
wrap
)
+
mb_x
*
16
;
wrap_y
=
s
->
linesize
;
ptr
=
s
->
new_picture
[
0
]
+
(
mb_y
*
16
*
wrap_y
)
+
mb_x
*
16
;
if
(
mb_x
*
16
+
16
>
s
->
width
||
mb_y
*
16
+
16
>
s
->
height
){
emulated_edge_mc
(
s
,
ptr
,
wrap
,
16
,
16
,
mb_x
*
16
,
mb_y
*
16
,
s
->
width
,
s
->
height
);
emulated_edge_mc
(
s
,
ptr
,
wrap
_y
,
16
,
16
,
mb_x
*
16
,
mb_y
*
16
,
s
->
width
,
s
->
height
);
ptr
=
s
->
edge_emu_buffer
;
emu
=
1
;
}
get_pixels
(
s
->
block
[
0
],
ptr
,
wrap
);
get_pixels
(
s
->
block
[
1
],
ptr
+
8
,
wrap
);
get_pixels
(
s
->
block
[
2
],
ptr
+
8
*
wrap
,
wrap
);
get_pixels
(
s
->
block
[
3
],
ptr
+
8
*
wrap
+
8
,
wrap
);
if
(
s
->
flags
&
CODEC_FLAG_INTERLACED_DCT
){
int
progressive_score
,
interlaced_score
;
progressive_score
=
pix_vcmp16x8
(
ptr
,
wrap_y
)
+
pix_vcmp16x8
(
ptr
+
wrap_y
*
8
,
wrap_y
);
interlaced_score
=
pix_vcmp16x8
(
ptr
,
wrap_y
*
2
)
+
pix_vcmp16x8
(
ptr
+
wrap_y
,
wrap_y
*
2
);
if
(
progressive_score
>
interlaced_score
+
100
){
s
->
interlaced_dct
=
1
;
dct_offset
=
wrap_y
;
wrap_y
<<=
1
;
}
else
s
->
interlaced_dct
=
0
;
}
get_pixels
(
s
->
block
[
0
],
ptr
,
wrap_y
);
get_pixels
(
s
->
block
[
1
],
ptr
+
8
,
wrap_y
);
get_pixels
(
s
->
block
[
2
],
ptr
+
dct_offset
,
wrap_y
);
get_pixels
(
s
->
block
[
3
],
ptr
+
dct_offset
+
8
,
wrap_y
);
if
(
s
->
flags
&
CODEC_FLAG_GRAY
){
skip_dct
[
4
]
=
1
;
skip_dct
[
5
]
=
1
;
}
else
{
wrap
>>=
1
;
ptr
=
s
->
new_picture
[
1
]
+
(
mb_y
*
8
*
wrap
)
+
mb_x
*
8
;
int
wrap_c
=
s
->
uvlinesize
;
ptr
=
s
->
new_picture
[
1
]
+
(
mb_y
*
8
*
wrap
_c
)
+
mb_x
*
8
;
if
(
emu
){
emulated_edge_mc
(
s
,
ptr
,
wrap
,
8
,
8
,
mb_x
*
8
,
mb_y
*
8
,
s
->
width
>>
1
,
s
->
height
>>
1
);
emulated_edge_mc
(
s
,
ptr
,
wrap
_c
,
8
,
8
,
mb_x
*
8
,
mb_y
*
8
,
s
->
width
>>
1
,
s
->
height
>>
1
);
ptr
=
s
->
edge_emu_buffer
;
}
get_pixels
(
s
->
block
[
4
],
ptr
,
wrap
);
get_pixels
(
s
->
block
[
4
],
ptr
,
wrap
_c
);
ptr
=
s
->
new_picture
[
2
]
+
(
mb_y
*
8
*
wrap
)
+
mb_x
*
8
;
ptr
=
s
->
new_picture
[
2
]
+
(
mb_y
*
8
*
wrap
_c
)
+
mb_x
*
8
;
if
(
emu
){
emulated_edge_mc
(
s
,
ptr
,
wrap
,
8
,
8
,
mb_x
*
8
,
mb_y
*
8
,
s
->
width
>>
1
,
s
->
height
>>
1
);
emulated_edge_mc
(
s
,
ptr
,
wrap
_c
,
8
,
8
,
mb_x
*
8
,
mb_y
*
8
,
s
->
width
>>
1
,
s
->
height
>>
1
);
ptr
=
s
->
edge_emu_buffer
;
}
get_pixels
(
s
->
block
[
5
],
ptr
,
wrap
);
get_pixels
(
s
->
block
[
5
],
ptr
,
wrap
_c
);
}
}
else
{
op_pixels_func
(
*
op_pix
)[
4
];
...
...
@@ -1830,7 +1974,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
dest_cb
=
s
->
current_picture
[
1
]
+
(
mb_y
*
8
*
(
s
->
uvlinesize
))
+
mb_x
*
8
;
dest_cr
=
s
->
current_picture
[
2
]
+
(
mb_y
*
8
*
(
s
->
uvlinesize
))
+
mb_x
*
8
;
wrap_y
=
s
->
linesize
;
wrap_c
=
wrap_y
>>
1
;
wrap_c
=
s
->
uvlinesize
;
ptr_y
=
s
->
new_picture
[
0
]
+
(
mb_y
*
16
*
wrap_y
)
+
mb_x
*
16
;
ptr_cb
=
s
->
new_picture
[
1
]
+
(
mb_y
*
8
*
wrap_c
)
+
mb_x
*
8
;
ptr_cr
=
s
->
new_picture
[
2
]
+
(
mb_y
*
8
*
wrap_c
)
+
mb_x
*
8
;
...
...
@@ -1857,10 +2001,28 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
ptr_y
=
s
->
edge_emu_buffer
;
emu
=
1
;
}
if
(
s
->
flags
&
CODEC_FLAG_INTERLACED_DCT
){
int
progressive_score
,
interlaced_score
;
progressive_score
=
pix_diff_vcmp16x8
(
ptr_y
,
dest_y
,
wrap_y
)
+
pix_diff_vcmp16x8
(
ptr_y
+
wrap_y
*
8
,
dest_y
+
wrap_y
*
8
,
wrap_y
);
interlaced_score
=
pix_diff_vcmp16x8
(
ptr_y
,
dest_y
,
wrap_y
*
2
)
+
pix_diff_vcmp16x8
(
ptr_y
+
wrap_y
,
dest_y
+
wrap_y
,
wrap_y
*
2
);
if
(
progressive_score
>
interlaced_score
+
600
){
s
->
interlaced_dct
=
1
;
dct_offset
=
wrap_y
;
wrap_y
<<=
1
;
}
else
s
->
interlaced_dct
=
0
;
}
diff_pixels
(
s
->
block
[
0
],
ptr_y
,
dest_y
,
wrap_y
);
diff_pixels
(
s
->
block
[
1
],
ptr_y
+
8
,
dest_y
+
8
,
wrap_y
);
diff_pixels
(
s
->
block
[
2
],
ptr_y
+
8
*
wrap_y
,
dest_y
+
8
*
wrap_y
,
wrap_y
);
diff_pixels
(
s
->
block
[
3
],
ptr_y
+
8
*
wrap_y
+
8
,
dest_y
+
8
*
wrap_y
+
8
,
wrap_y
);
diff_pixels
(
s
->
block
[
2
],
ptr_y
+
dct_offset
,
dest_y
+
dct_offset
,
wrap_y
);
diff_pixels
(
s
->
block
[
3
],
ptr_y
+
dct_offset
+
8
,
dest_y
+
dct_offset
+
8
,
wrap_y
);
if
(
s
->
flags
&
CODEC_FLAG_GRAY
){
skip_dct
[
4
]
=
1
;
...
...
@@ -1880,10 +2042,11 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
/* pre quantization */
if
(
s
->
mc_mb_var
[
s
->
mb_width
*
mb_y
+
mb_x
]
<
2
*
s
->
qscale
*
s
->
qscale
){
//FIXME optimize
if
(
pix_abs8x8
(
ptr_y
,
dest_y
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
0
]
=
1
;
if
(
pix_abs8x8
(
ptr_y
+
8
,
dest_y
+
8
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
1
]
=
1
;
if
(
pix_abs8x8
(
ptr_y
+
8
*
wrap_y
,
dest_y
+
8
*
wrap_y
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
2
]
=
1
;
if
(
pix_abs8x8
(
ptr_y
+
8
*
wrap_y
+
8
,
dest_y
+
8
*
wrap_y
+
8
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
3
]
=
1
;
if
(
pix_abs8x8
(
ptr_y
+
dct_offset
,
dest_y
+
dct_offset
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
2
]
=
1
;
if
(
pix_abs8x8
(
ptr_y
+
dct_offset
+
8
,
dest_y
+
dct_offset
+
8
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
3
]
=
1
;
if
(
pix_abs8x8
(
ptr_cb
,
dest_cb
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
4
]
=
1
;
if
(
pix_abs8x8
(
ptr_cr
,
dest_cr
,
wrap_y
)
<
20
*
s
->
qscale
)
skip_dct
[
5
]
=
1
;
#if 0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment