Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
0a024268
Commit
0a024268
authored
Aug 20, 2014
by
Gabriel Dume
Committed by
Diego Biurrun
Aug 26, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libxvid: K&R formatting cosmetics
Signed-off-by:
Diego Biurrun
<
diego@biurrun.de
>
parent
56a721f0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
329 additions
and
309 deletions
+329
-309
libxvid.c
libavcodec/libxvid.c
+253
-244
libxvid.h
libavcodec/libxvid.h
+0
-1
libxvid_rc.c
libavcodec/libxvid_rc.c
+76
-64
No files found.
libavcodec/libxvid.c
View file @
0a024268
...
...
@@ -25,21 +25,23 @@
* @author Adam Thayer (krevnik@comcast.net)
*/
#include <xvid.h>
#include <unistd.h>
#include "avcodec.h"
#include <xvid.h>
#include "libavutil/cpu.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "avcodec.h"
#include "libxvid.h"
#include "mpegvideo.h"
/**
* Buffer management macros.
*/
#define BUFFER_SIZE
1024
#define BUFFER_REMAINING(x)
(BUFFER_SIZE - strlen(x))
#define BUFFER_CAT(x)
(&((x)[strlen(x)]))
#define BUFFER_SIZE 1024
#define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
#define BUFFER_CAT(x) (&((x)[strlen(x)]))
/**
* Structure for the private Xvid context.
...
...
@@ -71,7 +73,7 @@ struct xvid_context {
* Structure for the private first-pass plugin.
*/
struct
xvid_ff_pass1
{
int
version
;
/**< Xvid version */
int
version
;
/**< Xvid version */
struct
xvid_context
*
context
;
/**< Pointer to private context */
};
...
...
@@ -92,9 +94,9 @@ struct xvid_ff_pass1 {
* @param handle Private context handle
* @return Returns XVID_ERR_xxxx on failure, or 0 on success.
*/
static
int
xvid_ff_2pass_create
(
xvid_plg_create_t
*
param
,
void
**
handle
)
{
struct
xvid_ff_pass1
*
x
=
(
struct
xvid_ff_pass1
*
)
param
->
param
;
static
int
xvid_ff_2pass_create
(
xvid_plg_create_t
*
param
,
void
**
handle
)
{
struct
xvid_ff_pass1
*
x
=
(
struct
xvid_ff_pass1
*
)
param
->
param
;
char
*
log
=
x
->
context
->
twopassbuffer
;
/* Do a quick bounds check */
...
...
@@ -105,12 +107,12 @@ static int xvid_ff_2pass_create(xvid_plg_create_t * param,
/* This is because we can safely prevent a buffer overflow */
log
[
0
]
=
0
;
snprintf
(
log
,
BUFFER_REMAINING
(
log
),
"# avconv 2-pass log file, using xvid codec
\n
"
);
"# avconv 2-pass log file, using xvid codec
\n
"
);
snprintf
(
BUFFER_CAT
(
log
),
BUFFER_REMAINING
(
log
),
"# Do not modify. libxvidcore version: %d.%d.%d
\n\n
"
,
XVID_VERSION_MAJOR
(
XVID_VERSION
),
XVID_VERSION_MINOR
(
XVID_VERSION
),
XVID_VERSION_PATCH
(
XVID_VERSION
));
"# Do not modify. libxvidcore version: %d.%d.%d
\n\n
"
,
XVID_VERSION_MAJOR
(
XVID_VERSION
),
XVID_VERSION_MINOR
(
XVID_VERSION
),
XVID_VERSION_PATCH
(
XVID_VERSION
));
*
handle
=
x
->
context
;
return
0
;
...
...
@@ -124,7 +126,8 @@ static int xvid_ff_2pass_create(xvid_plg_create_t * param,
* @return Returns 0, success guaranteed
*/
static
int
xvid_ff_2pass_destroy
(
struct
xvid_context
*
ref
,
xvid_plg_destroy_t
*
param
)
{
xvid_plg_destroy_t
*
param
)
{
/* Currently cannot think of anything to do on destruction */
/* Still, the framework should be here for reference/use */
if
(
ref
->
twopassbuffer
)
...
...
@@ -140,35 +143,36 @@ static int xvid_ff_2pass_destroy(struct xvid_context *ref,
* @return Returns 0, success guaranteed
*/
static
int
xvid_ff_2pass_before
(
struct
xvid_context
*
ref
,
xvid_plg_data_t
*
param
)
{
xvid_plg_data_t
*
param
)
{
int
motion_remove
;
int
motion_replacements
;
int
vop_remove
;
/* Nothing to do here, result is changed too much */
if
(
param
->
zone
&&
param
->
zone
->
mode
==
XVID_ZONE_QUANT
)
if
(
param
->
zone
&&
param
->
zone
->
mode
==
XVID_ZONE_QUANT
)
return
0
;
/* We can implement a 'turbo' first pass mode here */
param
->
quant
=
2
;
/* Init values */
motion_remove
=
~
XVID_ME_CHROMA_PVOP
&
~
XVID_ME_CHROMA_BVOP
&
~
XVID_ME_EXTSEARCH16
&
~
XVID_ME_ADVANCEDDIAMOND16
;
motion_remove
=
~
XVID_ME_CHROMA_PVOP
&
~
XVID_ME_CHROMA_BVOP
&
~
XVID_ME_EXTSEARCH16
&
~
XVID_ME_ADVANCEDDIAMOND16
;
motion_replacements
=
XVID_ME_FAST_MODEINTERPOLATE
|
XVID_ME_SKIP_DELTASEARCH
|
XVID_ME_FASTREFINE16
|
XVID_ME_SKIP_DELTASEARCH
|
XVID_ME_FASTREFINE16
|
XVID_ME_BFRAME_EARLYSTOP
;
vop_remove
=
~
XVID_VOP_MODEDECISION_RD
&
~
XVID_VOP_FAST_MODEDECISION_RD
&
~
XVID_VOP_TRELLISQUANT
&
~
XVID_VOP_INTER4V
&
~
XVID_VOP_HQACPRED
;
param
->
vol_flags
&=
~
XVID_VOL_GMC
;
param
->
vop_flags
&=
vop_remove
;
vop_remove
=
~
XVID_VOP_MODEDECISION_RD
&
~
XVID_VOP_FAST_MODEDECISION_RD
&
~
XVID_VOP_TRELLISQUANT
&
~
XVID_VOP_INTER4V
&
~
XVID_VOP_HQACPRED
;
param
->
vol_flags
&=
~
XVID_VOL_GMC
;
param
->
vop_flags
&=
vop_remove
;
param
->
motion_flags
&=
motion_remove
;
param
->
motion_flags
|=
motion_replacements
;
...
...
@@ -183,7 +187,8 @@ static int xvid_ff_2pass_before(struct xvid_context *ref,
* @return Returns XVID_ERR_xxxx on failure, or 0 on success
*/
static
int
xvid_ff_2pass_after
(
struct
xvid_context
*
ref
,
xvid_plg_data_t
*
param
)
{
xvid_plg_data_t
*
param
)
{
char
*
log
=
ref
->
twopassbuffer
;
const
char
*
frame_types
=
" ipbs"
;
char
frame_type
;
...
...
@@ -193,16 +198,16 @@ static int xvid_ff_2pass_after(struct xvid_context *ref,
return
XVID_ERR_FAIL
;
/* Convert the type given to us into a character */
if
(
param
->
type
<
5
&&
param
->
type
>
0
)
{
if
(
param
->
type
<
5
&&
param
->
type
>
0
)
frame_type
=
frame_types
[
param
->
type
];
}
else
{
else
return
XVID_ERR_FAIL
;
}
snprintf
(
BUFFER_CAT
(
log
),
BUFFER_REMAINING
(
log
),
"%c %d %d %d %d %d %d
\n
"
,
frame_type
,
param
->
stats
.
quant
,
param
->
stats
.
kblks
,
param
->
stats
.
mblks
,
param
->
stats
.
ublks
,
param
->
stats
.
length
,
param
->
stats
.
hlength
);
"%c %d %d %d %d %d %d
\n
"
,
frame_type
,
param
->
stats
.
quant
,
param
->
stats
.
kblks
,
param
->
stats
.
mblks
,
param
->
stats
.
ublks
,
param
->
stats
.
length
,
param
->
stats
.
hlength
);
return
0
;
}
...
...
@@ -220,25 +225,20 @@ static int xvid_ff_2pass_after(struct xvid_context *ref,
*/
static
int
xvid_ff_2pass
(
void
*
ref
,
int
cmd
,
void
*
p1
,
void
*
p2
)
{
switch
(
cmd
)
{
case
XVID_PLG_INFO
:
case
XVID_PLG_FRAME
:
return
0
;
case
XVID_PLG_BEFORE
:
return
xvid_ff_2pass_before
(
ref
,
p1
);
case
XVID_PLG_CREATE
:
return
xvid_ff_2pass_create
(
p1
,
p2
);
case
XVID_PLG_AFTER
:
return
xvid_ff_2pass_after
(
ref
,
p1
);
case
XVID_PLG_DESTROY
:
return
xvid_ff_2pass_destroy
(
ref
,
p1
);
default:
return
XVID_ERR_FAIL
;
switch
(
cmd
)
{
case
XVID_PLG_INFO
:
case
XVID_PLG_FRAME
:
return
0
;
case
XVID_PLG_BEFORE
:
return
xvid_ff_2pass_before
(
ref
,
p1
);
case
XVID_PLG_CREATE
:
return
xvid_ff_2pass_create
(
p1
,
p2
);
case
XVID_PLG_AFTER
:
return
xvid_ff_2pass_after
(
ref
,
p1
);
case
XVID_PLG_DESTROY
:
return
xvid_ff_2pass_destroy
(
ref
,
p1
);
default:
return
XVID_ERR_FAIL
;
}
}
...
...
@@ -255,23 +255,23 @@ static int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2)
* @param frame_len Length of encoded frame data
* @return Returns new length of frame data
*/
static
int
xvid_strip_vol_header
(
AVCodecContext
*
avctx
,
AVPacket
*
pkt
,
unsigned
int
header_len
,
unsigned
int
frame_len
)
{
static
int
xvid_strip_vol_header
(
AVCodecContext
*
avctx
,
AVPacket
*
pkt
,
unsigned
int
header_len
,
unsigned
int
frame_len
)
{
int
vo_len
=
0
,
i
;
for
(
i
=
0
;
i
<
header_len
-
3
;
i
++
)
{
if
(
pkt
->
data
[
i
]
==
0x00
&&
pkt
->
data
[
i
+
1
]
==
0x00
&&
pkt
->
data
[
i
+
2
]
==
0x01
&&
pkt
->
data
[
i
+
3
]
==
0xB6
)
{
for
(
i
=
0
;
i
<
header_len
-
3
;
i
++
)
{
if
(
pkt
->
data
[
i
]
==
0x00
&&
pkt
->
data
[
i
+
1
]
==
0x00
&&
pkt
->
data
[
i
+
2
]
==
0x01
&&
pkt
->
data
[
i
+
3
]
==
0xB6
)
{
vo_len
=
i
;
break
;
}
}
if
(
vo_len
>
0
)
{
if
(
vo_len
>
0
)
{
/* We need to store the header, so extract it */
if
(
!
avctx
->
extradata
)
{
avctx
->
extradata
=
av_malloc
(
vo_len
);
...
...
@@ -279,7 +279,7 @@ static int xvid_strip_vol_header(AVCodecContext *avctx,
avctx
->
extradata_size
=
vo_len
;
}
/* Less dangerous now, memmove properly copies the two
chunks of overlapping data */
*
chunks of overlapping data */
memmove
(
pkt
->
data
,
&
pkt
->
data
[
vo_len
],
frame_len
-
vo_len
);
pkt
->
size
=
frame_len
-
vo_len
;
}
...
...
@@ -306,114 +306,113 @@ static void xvid_correct_framerate(AVCodecContext *avctx)
fbase
=
avctx
->
time_base
.
num
;
gcd
=
av_gcd
(
frate
,
fbase
);
if
(
gcd
>
1
)
{
if
(
gcd
>
1
)
{
frate
/=
gcd
;
fbase
/=
gcd
;
}
if
(
frate
<=
65000
&&
fbase
<=
65000
)
{
if
(
frate
<=
65000
&&
fbase
<=
65000
)
{
avctx
->
time_base
.
den
=
frate
;
avctx
->
time_base
.
num
=
fbase
;
return
;
}
fps
=
(
float
)
frate
/
(
float
)
fbase
;
fps
=
(
float
)
frate
/
(
float
)
fbase
;
est_fps
=
roundf
(
fps
*
1000
.
0
)
/
1000
.
0
;
est_frate
=
(
int
)
est_fps
;
if
(
est_fps
>
(
int
)
est_fps
)
{
est_frate
=
(
int
)
est_fps
;
if
(
est_fps
>
(
int
)
est_fps
)
{
est_frate
=
(
est_frate
+
1
)
*
1000
;
est_fbase
=
(
int
)
roundf
((
float
)
est_frate
/
est_fps
);
est_fbase
=
(
int
)
roundf
((
float
)
est_frate
/
est_fps
);
}
else
est_fbase
=
1
;
gcd
=
av_gcd
(
est_frate
,
est_fbase
);
if
(
gcd
>
1
)
{
if
(
gcd
>
1
)
{
est_frate
/=
gcd
;
est_fbase
/=
gcd
;
}
if
(
fbase
>
est_fbase
)
{
if
(
fbase
>
est_fbase
)
{
avctx
->
time_base
.
den
=
est_frate
;
avctx
->
time_base
.
num
=
est_fbase
;
av_log
(
avctx
,
AV_LOG_DEBUG
,
"Xvid: framerate re-estimated: %.2f, %.3f%% correction
\n
"
,
est_fps
,
(((
est_fps
-
fps
)
/
fps
)
*
100
.
0
));
"Xvid: framerate re-estimated: %.2f, %.3f%% correction
\n
"
,
est_fps
,
(((
est_fps
-
fps
)
/
fps
)
*
100
.
0
));
}
else
{
avctx
->
time_base
.
den
=
frate
;
avctx
->
time_base
.
num
=
fbase
;
}
}
static
av_cold
int
xvid_encode_init
(
AVCodecContext
*
avctx
)
{
static
av_cold
int
xvid_encode_init
(
AVCodecContext
*
avctx
)
{
int
xerr
,
i
;
int
xvid_flags
=
avctx
->
flags
;
struct
xvid_context
*
x
=
avctx
->
priv_data
;
uint16_t
*
intra
,
*
inter
;
int
fd
;
xvid_plugin_single_t
single
=
{
0
};
struct
xvid_ff_pass1
rc2pass1
=
{
0
};
xvid_plugin_2pass2_t
rc2pass2
=
{
0
};
xvid_plugin_single_t
single
=
{
0
};
struct
xvid_ff_pass1
rc2pass1
=
{
0
};
xvid_plugin_2pass2_t
rc2pass2
=
{
0
};
xvid_plugin_lumimasking_t
masking_l
=
{
0
};
/* For lumi masking */
xvid_plugin_lumimasking_t
masking_v
=
{
0
};
/* For variance AQ */
xvid_plugin_ssim_t
ssim
=
{
0
};
xvid_gbl_init_t
xvid_gbl_init
=
{
0
};
xvid_enc_create_t
xvid_enc_create
=
{
0
};
xvid_plugin_ssim_t
ssim
=
{
0
};
xvid_gbl_init_t
xvid_gbl_init
=
{
0
};
xvid_enc_create_t
xvid_enc_create
=
{
0
};
xvid_enc_plugin_t
plugins
[
7
];
/* Bring in VOP flags from avconv command-line */
x
->
vop_flags
=
XVID_VOP_HALFPEL
;
/* Bare minimum quality */
if
(
xvid_flags
&
CODEC_FLAG_4MV
)
if
(
xvid_flags
&
CODEC_FLAG_4MV
)
x
->
vop_flags
|=
XVID_VOP_INTER4V
;
/* Level 3 */
if
(
avctx
->
trellis
)
if
(
avctx
->
trellis
)
x
->
vop_flags
|=
XVID_VOP_TRELLISQUANT
;
/* Level 5 */
if
(
xvid_flags
&
CODEC_FLAG_AC_PRED
)
if
(
xvid_flags
&
CODEC_FLAG_AC_PRED
)
x
->
vop_flags
|=
XVID_VOP_HQACPRED
;
/* Level 6 */
if
(
xvid_flags
&
CODEC_FLAG_GRAY
)
if
(
xvid_flags
&
CODEC_FLAG_GRAY
)
x
->
vop_flags
|=
XVID_VOP_GREYSCALE
;
/* Decide which ME quality setting to use */
x
->
me_flags
=
0
;
switch
(
avctx
->
me_method
)
{
case
ME_FULL
:
/* Quality 6 */
x
->
me_flags
|=
XVID_ME_EXTSEARCH16
|
XVID_ME_EXTSEARCH8
;
case
ME_EPZS
:
/* Quality 4 */
x
->
me_flags
|=
XVID_ME_ADVANCEDDIAMOND8
|
XVID_ME_HALFPELREFINE8
|
XVID_ME_CHROMA_PVOP
|
XVID_ME_CHROMA_BVOP
;
case
ME_LOG
:
/* Quality 2 */
case
ME_PHODS
:
case
ME_X1
:
x
->
me_flags
|=
XVID_ME_ADVANCEDDIAMOND16
|
XVID_ME_HALFPELREFINE16
;
case
ME_ZERO
:
/* Quality 0 */
default:
break
;
switch
(
avctx
->
me_method
)
{
case
ME_FULL
:
/* Quality 6 */
x
->
me_flags
|=
XVID_ME_EXTSEARCH16
|
XVID_ME_EXTSEARCH8
;
case
ME_EPZS
:
/* Quality 4 */
x
->
me_flags
|=
XVID_ME_ADVANCEDDIAMOND8
|
XVID_ME_HALFPELREFINE8
|
XVID_ME_CHROMA_PVOP
|
XVID_ME_CHROMA_BVOP
;
case
ME_LOG
:
/* Quality 2 */
case
ME_PHODS
:
case
ME_X1
:
x
->
me_flags
|=
XVID_ME_ADVANCEDDIAMOND16
|
XVID_ME_HALFPELREFINE16
;
case
ME_ZERO
:
/* Quality 0 */
default:
break
;
}
/* Decide how we should decide blocks */
switch
(
avctx
->
mb_decision
)
{
case
2
:
x
->
vop_flags
|=
XVID_VOP_MODEDECISION_RD
;
x
->
me_flags
|=
XVID_ME_HALFPELREFINE8_RD
|
XVID_ME_QUARTERPELREFINE8_RD
|
XVID_ME_EXTSEARCH_RD
|
XVID_ME_CHECKPREDICTION_RD
;
case
1
:
if
(
!
(
x
->
vop_flags
&
XVID_VOP_MODEDECISION_RD
)
)
x
->
vop_flags
|=
XVID_VOP_FAST_MODEDECISION_RD
;
x
->
me_flags
|=
XVID_ME_HALFPELREFINE16_RD
|
XVID_ME_QUARTERPELREFINE16_RD
;
default:
break
;
switch
(
avctx
->
mb_decision
)
{
case
2
:
x
->
vop_flags
|=
XVID_VOP_MODEDECISION_RD
;
x
->
me_flags
|=
XVID_ME_HALFPELREFINE8_RD
|
XVID_ME_QUARTERPELREFINE8_RD
|
XVID_ME_EXTSEARCH_RD
|
XVID_ME_CHECKPREDICTION_RD
;
case
1
:
if
(
!
(
x
->
vop_flags
&
XVID_VOP_MODEDECISION_RD
))
x
->
vop_flags
|=
XVID_VOP_FAST_MODEDECISION_RD
;
x
->
me_flags
|=
XVID_ME_HALFPELREFINE16_RD
|
XVID_ME_QUARTERPELREFINE16_RD
;
default:
break
;
}
/* Bring in VOL flags from avconv command-line */
...
...
@@ -425,17 +424,17 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
x
->
vol_flags
=
0
;
if
(
x
->
gmc
)
{
x
->
vol_flags
|=
XVID_VOL_GMC
;
x
->
me_flags
|=
XVID_ME_GME_REFINE
;
x
->
me_flags
|=
XVID_ME_GME_REFINE
;
}
if
(
xvid_flags
&
CODEC_FLAG_QPEL
)
{
if
(
xvid_flags
&
CODEC_FLAG_QPEL
)
{
x
->
vol_flags
|=
XVID_VOL_QUARTERPEL
;
x
->
me_flags
|=
XVID_ME_QUARTERPELREFINE16
;
if
(
x
->
vop_flags
&
XVID_VOP_INTER4V
)
x
->
me_flags
|=
XVID_ME_QUARTERPELREFINE16
;
if
(
x
->
vop_flags
&
XVID_VOP_INTER4V
)
x
->
me_flags
|=
XVID_ME_QUARTERPELREFINE8
;
}
xvid_gbl_init
.
version
=
XVID_VERSION
;
xvid_gbl_init
.
debug
=
0
;
xvid_gbl_init
.
version
=
XVID_VERSION
;
xvid_gbl_init
.
debug
=
0
;
xvid_gbl_init
.
cpu_flags
=
0
;
/* Initialize */
...
...
@@ -445,77 +444,78 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
xvid_enc_create
.
version
=
XVID_VERSION
;
/* Store the desired frame size */
xvid_enc_create
.
width
=
x
->
xsize
=
avctx
->
width
;
xvid_enc_create
.
height
=
x
->
ysize
=
avctx
->
height
;
xvid_enc_create
.
width
=
x
->
xsize
=
avctx
->
width
;
xvid_enc_create
.
height
=
x
->
ysize
=
avctx
->
height
;
/* Xvid can determine the proper profile to use */
/* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
/* We don't use zones */
xvid_enc_create
.
zones
=
NULL
;
xvid_enc_create
.
zones
=
NULL
;
xvid_enc_create
.
num_zones
=
0
;
xvid_enc_create
.
num_threads
=
avctx
->
thread_count
;
xvid_enc_create
.
plugins
=
plugins
;
xvid_enc_create
.
plugins
=
plugins
;
xvid_enc_create
.
num_plugins
=
0
;
/* Initialize Buffers */
x
->
twopassbuffer
=
NULL
;
x
->
twopassbuffer
=
NULL
;
x
->
old_twopassbuffer
=
NULL
;
x
->
twopassfile
=
NULL
;
x
->
twopassfile
=
NULL
;
if
(
xvid_flags
&
CODEC_FLAG_PASS1
)
{
rc2pass1
.
version
=
XVID_VERSION
;
rc2pass1
.
context
=
x
;
x
->
twopassbuffer
=
av_malloc
(
BUFFER_SIZE
);
if
(
xvid_flags
&
CODEC_FLAG_PASS1
)
{
rc2pass1
.
version
=
XVID_VERSION
;
rc2pass1
.
context
=
x
;
x
->
twopassbuffer
=
av_malloc
(
BUFFER_SIZE
);
x
->
old_twopassbuffer
=
av_malloc
(
BUFFER_SIZE
);
if
(
!
x
->
twopassbuffer
||
!
x
->
old_twopassbuffer
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Cannot allocate 2-pass log buffers
\n
"
);
"Xvid: Cannot allocate 2-pass log buffers
\n
"
);
return
-
1
;
}
x
->
twopassbuffer
[
0
]
=
x
->
old_twopassbuffer
[
0
]
=
0
;
x
->
twopassbuffer
[
0
]
=
x
->
old_twopassbuffer
[
0
]
=
0
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_ff_2pass
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_ff_2pass
;
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
&
rc2pass1
;
xvid_enc_create
.
num_plugins
++
;
}
else
if
(
xvid_flags
&
CODEC_FLAG_PASS2
)
{
}
else
if
(
xvid_flags
&
CODEC_FLAG_PASS2
)
{
rc2pass2
.
version
=
XVID_VERSION
;
rc2pass2
.
bitrate
=
avctx
->
bit_rate
;
fd
=
ff_tempfile
(
"xvidff."
,
&
x
->
twopassfile
);
if
(
fd
==
-
1
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Cannot write 2-pass pipe
\n
"
);
if
(
fd
==
-
1
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Cannot write 2-pass pipe
\n
"
);
return
-
1
;
}
if
(
!
avctx
->
stats_in
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: No 2-pass information loaded for second pass
\n
"
);
"Xvid: No 2-pass information loaded for second pass
\n
"
);
return
-
1
;
}
if
(
strlen
(
avctx
->
stats_in
)
>
write
(
fd
,
avctx
->
stats_in
,
strlen
(
avctx
->
stats_in
))
)
{
if
(
strlen
(
avctx
->
stats_in
)
>
write
(
fd
,
avctx
->
stats_in
,
strlen
(
avctx
->
stats_in
))
)
{
close
(
fd
);
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Cannot write to 2-pass pipe
\n
"
);
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Cannot write to 2-pass pipe
\n
"
);
return
-
1
;
}
close
(
fd
);
rc2pass2
.
filename
=
x
->
twopassfile
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_2pass2
;
rc2pass2
.
filename
=
x
->
twopassfile
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_2pass2
;
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
&
rc2pass2
;
xvid_enc_create
.
num_plugins
++
;
}
else
if
(
!
(
xvid_flags
&
CODEC_FLAG_QSCALE
)
)
{
}
else
if
(
!
(
xvid_flags
&
CODEC_FLAG_QSCALE
)
)
{
/* Single Pass Bitrate Control! */
single
.
version
=
XVID_VERSION
;
single
.
bitrate
=
avctx
->
bit_rate
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_single
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_single
;
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
&
single
;
xvid_enc_create
.
num_plugins
++
;
}
...
...
@@ -531,19 +531,19 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
/* Luminance Masking */
if
(
x
->
lumi_aq
)
{
masking_l
.
method
=
0
;
masking_l
.
method
=
0
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_lumimasking
;
/* The old behavior is that when avctx->lumi_masking is specified,
* plugins[...].param = NULL. Trying to keep the old behavior here. */
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
avctx
->
lumi_masking
?
NULL
:
&
masking_l
;
xvid_enc_create
.
num_plugins
++
;
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
avctx
->
lumi_masking
?
NULL
:
&
masking_l
;
xvid_enc_create
.
num_plugins
++
;
}
/* Variance AQ */
if
(
x
->
variance_aq
)
{
masking_v
.
method
=
1
;
masking_v
.
method
=
1
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_lumimasking
;
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
&
masking_v
;
xvid_enc_create
.
num_plugins
++
;
...
...
@@ -551,11 +551,11 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
/* SSIM */
if
(
x
->
ssim
)
{
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_ssim
;
ssim
.
b_printstat
=
x
->
ssim
==
2
;
ssim
.
acc
=
x
->
ssim_acc
;
ssim
.
cpu_flags
=
xvid_gbl_init
.
cpu_flags
;
ssim
.
b_visualize
=
0
;
plugins
[
xvid_enc_create
.
num_plugins
].
func
=
xvid_plugin_ssim
;
ssim
.
b_printstat
=
x
->
ssim
==
2
;
ssim
.
acc
=
x
->
ssim_acc
;
ssim
.
cpu_flags
=
xvid_gbl_init
.
cpu_flags
;
ssim
.
b_visualize
=
0
;
plugins
[
xvid_enc_create
.
num_plugins
].
param
=
&
ssim
;
xvid_enc_create
.
num_plugins
++
;
}
...
...
@@ -564,14 +564,16 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
xvid_correct_framerate
(
avctx
);
xvid_enc_create
.
fincr
=
avctx
->
time_base
.
num
;
xvid_enc_create
.
fbase
=
avctx
->
time_base
.
den
;
if
(
avctx
->
gop_size
>
0
)
if
(
avctx
->
gop_size
>
0
)
xvid_enc_create
.
max_key_interval
=
avctx
->
gop_size
;
else
xvid_enc_create
.
max_key_interval
=
240
;
/* Xvid's best default */
/* Quants */
if
(
xvid_flags
&
CODEC_FLAG_QSCALE
)
x
->
qscale
=
1
;
else
x
->
qscale
=
0
;
if
(
xvid_flags
&
CODEC_FLAG_QSCALE
)
x
->
qscale
=
1
;
else
x
->
qscale
=
0
;
xvid_enc_create
.
min_quant
[
0
]
=
avctx
->
qmin
;
xvid_enc_create
.
min_quant
[
1
]
=
avctx
->
qmin
;
...
...
@@ -581,65 +583,67 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
xvid_enc_create
.
max_quant
[
2
]
=
avctx
->
qmax
;
/* Quant Matrices */
x
->
intra_matrix
=
x
->
inter_matrix
=
NULL
;
if
(
avctx
->
mpeg_quant
)
x
->
vol_flags
|=
XVID_VOL_MPEGQUANT
;
if
(
(
avctx
->
intra_matrix
||
avctx
->
inter_matrix
)
)
{
x
->
vol_flags
|=
XVID_VOL_MPEGQUANT
;
if
(
avctx
->
intra_matrix
)
{
intra
=
avctx
->
intra_matrix
;
x
->
intra_matrix
=
av_malloc
(
sizeof
(
unsigned
char
)
*
64
);
}
else
intra
=
NULL
;
if
(
avctx
->
inter_matrix
)
{
inter
=
avctx
->
inter_matrix
;
x
->
inter_matrix
=
av_malloc
(
sizeof
(
unsigned
char
)
*
64
);
}
else
inter
=
NULL
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
if
(
intra
)
x
->
intra_matrix
[
i
]
=
(
unsigned
char
)
intra
[
i
];
if
(
inter
)
x
->
inter_matrix
[
i
]
=
(
unsigned
char
)
inter
[
i
];
}
x
->
intra_matrix
=
x
->
inter_matrix
=
NULL
;
if
(
avctx
->
mpeg_quant
)
x
->
vol_flags
|=
XVID_VOL_MPEGQUANT
;
if
((
avctx
->
intra_matrix
||
avctx
->
inter_matrix
))
{
x
->
vol_flags
|=
XVID_VOL_MPEGQUANT
;
if
(
avctx
->
intra_matrix
)
{
intra
=
avctx
->
intra_matrix
;
x
->
intra_matrix
=
av_malloc
(
sizeof
(
unsigned
char
)
*
64
);
}
else
intra
=
NULL
;
if
(
avctx
->
inter_matrix
)
{
inter
=
avctx
->
inter_matrix
;
x
->
inter_matrix
=
av_malloc
(
sizeof
(
unsigned
char
)
*
64
);
}
else
inter
=
NULL
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
if
(
intra
)
x
->
intra_matrix
[
i
]
=
(
unsigned
char
)
intra
[
i
];
if
(
inter
)
x
->
inter_matrix
[
i
]
=
(
unsigned
char
)
inter
[
i
];
}
}
/* Misc Settings */
xvid_enc_create
.
frame_drop_ratio
=
0
;
xvid_enc_create
.
global
=
0
;
if
(
xvid_flags
&
CODEC_FLAG_CLOSED_GOP
)
xvid_enc_create
.
global
=
0
;
if
(
xvid_flags
&
CODEC_FLAG_CLOSED_GOP
)
xvid_enc_create
.
global
|=
XVID_GLOBAL_CLOSED_GOP
;
/* Determines which codec mode we are operating in */
avctx
->
extradata
=
NULL
;
avctx
->
extradata
=
NULL
;
avctx
->
extradata_size
=
0
;
if
(
xvid_flags
&
CODEC_FLAG_GLOBAL_HEADER
)
{
if
(
xvid_flags
&
CODEC_FLAG_GLOBAL_HEADER
)
{
/* In this case, we are claiming to be MPEG4 */
x
->
quicktime_format
=
1
;
avctx
->
codec_id
=
AV_CODEC_ID_MPEG4
;
avctx
->
codec_id
=
AV_CODEC_ID_MPEG4
;
}
else
{
/* We are claiming to be Xvid */
x
->
quicktime_format
=
0
;
if
(
!
avctx
->
codec_tag
)
if
(
!
avctx
->
codec_tag
)
avctx
->
codec_tag
=
AV_RL32
(
"xvid"
);
}
/* Bframes */
xvid_enc_create
.
max_bframes
=
avctx
->
max_b_frames
;
xvid_enc_create
.
max_bframes
=
avctx
->
max_b_frames
;
xvid_enc_create
.
bquant_offset
=
100
*
avctx
->
b_quant_offset
;
xvid_enc_create
.
bquant_ratio
=
100
*
avctx
->
b_quant_factor
;
if
(
avctx
->
max_b_frames
>
0
&&
!
x
->
quicktime_format
)
xvid_enc_create
.
global
|=
XVID_GLOBAL_PACKED
;
xvid_enc_create
.
bquant_ratio
=
100
*
avctx
->
b_quant_factor
;
if
(
avctx
->
max_b_frames
>
0
&&
!
x
->
quicktime_format
)
xvid_enc_create
.
global
|=
XVID_GLOBAL_PACKED
;
/* Create encoder context */
xerr
=
xvid_encore
(
NULL
,
XVID_ENC_CREATE
,
&
xvid_enc_create
,
NULL
);
if
(
xerr
)
{
if
(
xerr
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Could not create encoder reference
\n
"
);
return
-
1
;
}
x
->
encoder_handle
=
xvid_enc_create
.
handle
;
x
->
encoder_handle
=
xvid_enc_create
.
handle
;
avctx
->
coded_frame
=
av_frame_alloc
();
if
(
!
avctx
->
coded_frame
)
return
AVERROR
(
ENOMEM
);
...
...
@@ -651,17 +655,17 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const
AVFrame
*
picture
,
int
*
got_packet
)
{
int
xerr
,
i
,
ret
,
user_packet
=
!!
pkt
->
data
;
char
*
tmp
;
struct
xvid_context
*
x
=
avctx
->
priv_data
;
AVFrame
*
p
=
avctx
->
coded_frame
;
int
mb_width
=
(
avctx
->
width
+
15
)
/
16
;
int
mb_height
=
(
avctx
->
height
+
15
)
/
16
;
AVFrame
*
p
=
avctx
->
coded_frame
;
int
mb_width
=
(
avctx
->
width
+
15
)
/
16
;
int
mb_height
=
(
avctx
->
height
+
15
)
/
16
;
char
*
tmp
;
xvid_enc_frame_t
xvid_enc_frame
=
{
0
};
xvid_enc_stats_t
xvid_enc_stats
=
{
0
};
if
(
!
user_packet
&&
(
ret
=
av_new_packet
(
pkt
,
mb_width
*
mb_height
*
MAX_MB_BYTES
+
FF_MIN_BUFFER_SIZE
))
<
0
)
{
(
ret
=
av_new_packet
(
pkt
,
mb_width
*
mb_height
*
MAX_MB_BYTES
+
FF_MIN_BUFFER_SIZE
))
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error getting output packet.
\n
"
);
return
ret
;
}
...
...
@@ -675,27 +679,28 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
xvid_enc_frame
.
length
=
pkt
->
size
;
/* Initialize input image fields */
if
(
avctx
->
pix_fmt
!=
AV_PIX_FMT_YUV420P
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Color spaces other than 420p not supported
\n
"
);
if
(
avctx
->
pix_fmt
!=
AV_PIX_FMT_YUV420P
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Color spaces other than 420P not supported
\n
"
);
return
-
1
;
}
xvid_enc_frame
.
input
.
csp
=
XVID_CSP_PLANAR
;
/* YUV420P */
for
(
i
=
0
;
i
<
4
;
i
++
)
{
xvid_enc_frame
.
input
.
plane
[
i
]
=
picture
->
data
[
i
];
for
(
i
=
0
;
i
<
4
;
i
++
)
{
xvid_enc_frame
.
input
.
plane
[
i
]
=
picture
->
data
[
i
];
xvid_enc_frame
.
input
.
stride
[
i
]
=
picture
->
linesize
[
i
];
}
/* Encoder Flags */
xvid_enc_frame
.
vop_flags
=
x
->
vop_flags
;
xvid_enc_frame
.
vol_flags
=
x
->
vol_flags
;
xvid_enc_frame
.
motion
=
x
->
me_flags
;
xvid_enc_frame
.
type
=
xvid_enc_frame
.
motion
=
x
->
me_flags
;
xvid_enc_frame
.
type
=
picture
->
pict_type
==
AV_PICTURE_TYPE_I
?
XVID_TYPE_IVOP
:
picture
->
pict_type
==
AV_PICTURE_TYPE_P
?
XVID_TYPE_PVOP
:
picture
->
pict_type
==
AV_PICTURE_TYPE_B
?
XVID_TYPE_BVOP
:
XVID_TYPE_AUTO
;
XVID_TYPE_AUTO
;
/* Pixel aspect ratio setting */
if
(
avctx
->
sample_aspect_ratio
.
num
<
1
||
avctx
->
sample_aspect_ratio
.
num
>
255
||
...
...
@@ -704,13 +709,15 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
avctx
->
sample_aspect_ratio
.
num
,
avctx
->
sample_aspect_ratio
.
den
);
return
-
1
;
}
xvid_enc_frame
.
par
=
XVID_PAR_EXT
;
xvid_enc_frame
.
par
=
XVID_PAR_EXT
;
xvid_enc_frame
.
par_width
=
avctx
->
sample_aspect_ratio
.
num
;
xvid_enc_frame
.
par_height
=
avctx
->
sample_aspect_ratio
.
den
;
/* Quant Setting */
if
(
x
->
qscale
)
xvid_enc_frame
.
quant
=
picture
->
quality
/
FF_QP2LAMBDA
;
else
xvid_enc_frame
.
quant
=
0
;
if
(
x
->
qscale
)
xvid_enc_frame
.
quant
=
picture
->
quality
/
FF_QP2LAMBDA
;
else
xvid_enc_frame
.
quant
=
0
;
/* Matrices */
xvid_enc_frame
.
quant_intra_matrix
=
x
->
intra_matrix
;
...
...
@@ -718,16 +725,16 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
/* Encode */
xerr
=
xvid_encore
(
x
->
encoder_handle
,
XVID_ENC_ENCODE
,
&
xvid_enc_frame
,
&
xvid_enc_stats
);
&
xvid_enc_frame
,
&
xvid_enc_stats
);
/* Two-pass log buffer swapping */
avctx
->
stats_out
=
NULL
;
if
(
x
->
twopassbuffer
)
{
tmp
=
x
->
old_twopassbuffer
;
if
(
x
->
twopassbuffer
)
{
tmp
=
x
->
old_twopassbuffer
;
x
->
old_twopassbuffer
=
x
->
twopassbuffer
;
x
->
twopassbuffer
=
tmp
;
x
->
twopassbuffer
[
0
]
=
0
;
if
(
x
->
old_twopassbuffer
[
0
]
!=
0
)
{
x
->
twopassbuffer
=
tmp
;
x
->
twopassbuffer
[
0
]
=
0
;
if
(
x
->
old_twopassbuffer
[
0
]
!=
0
)
{
avctx
->
stats_out
=
x
->
old_twopassbuffer
;
}
}
...
...
@@ -736,21 +743,21 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
*
got_packet
=
1
;
p
->
quality
=
xvid_enc_stats
.
quant
*
FF_QP2LAMBDA
;
if
(
xvid_enc_stats
.
type
==
XVID_TYPE_PVOP
)
if
(
xvid_enc_stats
.
type
==
XVID_TYPE_PVOP
)
p
->
pict_type
=
AV_PICTURE_TYPE_P
;
else
if
(
xvid_enc_stats
.
type
==
XVID_TYPE_BVOP
)
else
if
(
xvid_enc_stats
.
type
==
XVID_TYPE_BVOP
)
p
->
pict_type
=
AV_PICTURE_TYPE_B
;
else
if
(
xvid_enc_stats
.
type
==
XVID_TYPE_SVOP
)
else
if
(
xvid_enc_stats
.
type
==
XVID_TYPE_SVOP
)
p
->
pict_type
=
AV_PICTURE_TYPE_S
;
else
p
->
pict_type
=
AV_PICTURE_TYPE_I
;
if
(
xvid_enc_frame
.
out_flags
&
XVID_KEYFRAME
)
{
if
(
xvid_enc_frame
.
out_flags
&
XVID_KEYFRAME
)
{
p
->
key_frame
=
1
;
pkt
->
flags
|=
AV_PKT_FLAG_KEY
;
if
(
x
->
quicktime_format
)
pkt
->
flags
|=
AV_PKT_FLAG_KEY
;
if
(
x
->
quicktime_format
)
return
xvid_strip_vol_header
(
avctx
,
pkt
,
xvid_enc_stats
.
hlength
,
xerr
);
}
else
xvid_enc_stats
.
hlength
,
xerr
);
}
else
p
->
key_frame
=
0
;
pkt
->
size
=
xerr
;
...
...
@@ -761,12 +768,14 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
av_free_packet
(
pkt
);
if
(
!
xerr
)
return
0
;
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Encoding Error Occurred: %i
\n
"
,
xerr
);
av_log
(
avctx
,
AV_LOG_ERROR
,
"Xvid: Encoding Error Occurred: %i
\n
"
,
xerr
);
return
-
1
;
}
}
static
av_cold
int
xvid_encode_close
(
AVCodecContext
*
avctx
)
{
static
av_cold
int
xvid_encode_close
(
AVCodecContext
*
avctx
)
{
struct
xvid_context
*
x
=
avctx
->
priv_data
;
xvid_encore
(
x
->
encoder_handle
,
XVID_ENC_DESTROY
,
NULL
,
NULL
);
...
...
@@ -786,14 +795,14 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) {
#define OFFSET(x) offsetof(struct xvid_context, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static
const
AVOption
options
[]
=
{
{
"lumi_aq"
,
"Luminance masking AQ"
,
OFFSET
(
lumi_aq
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
"variance_aq"
,
"Variance AQ"
,
OFFSET
(
variance_aq
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
"ssim"
,
"Show SSIM information to stdout"
,
OFFSET
(
ssim
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
2
,
VE
,
"ssim"
},
{
"off"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
0
},
INT_MIN
,
INT_MAX
,
VE
,
"ssim"
},
{
"avg"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
1
},
INT_MIN
,
INT_MAX
,
VE
,
"ssim"
},
{
"frame"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
2
},
INT_MIN
,
INT_MAX
,
VE
,
"ssim"
},
{
"ssim_acc"
,
"SSIM accuracy"
,
OFFSET
(
ssim_acc
),
AV_OPT_TYPE_INT
,
{
.
i64
=
2
},
0
,
4
,
VE
},
{
"gmc"
,
"use GMC"
,
OFFSET
(
gmc
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
"lumi_aq"
,
"Luminance masking AQ"
,
OFFSET
(
lumi_aq
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
"variance_aq"
,
"Variance AQ"
,
OFFSET
(
variance_aq
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
"ssim"
,
"Show SSIM information to stdout"
,
OFFSET
(
ssim
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
2
,
VE
,
"ssim"
},
{
"off"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
0
},
INT_MIN
,
INT_MAX
,
VE
,
"ssim"
},
{
"avg"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
1
},
INT_MIN
,
INT_MAX
,
VE
,
"ssim"
},
{
"frame"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
2
},
INT_MIN
,
INT_MAX
,
VE
,
"ssim"
},
{
"ssim_acc"
,
"SSIM accuracy"
,
OFFSET
(
ssim_acc
),
AV_OPT_TYPE_INT
,
{
.
i64
=
2
},
0
,
4
,
VE
},
{
"gmc"
,
"use GMC"
,
OFFSET
(
gmc
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
NULL
},
};
...
...
@@ -813,6 +822,6 @@ AVCodec ff_libxvid_encoder = {
.
init
=
xvid_encode_init
,
.
encode2
=
xvid_encode_frame
,
.
close
=
xvid_encode_close
,
.
pix_fmts
=
(
const
enum
AVPixelFormat
[]){
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_NONE
},
.
pix_fmts
=
(
const
enum
AVPixelFormat
[])
{
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_NONE
},
.
priv_class
=
&
xvid_class
,
};
libavcodec/libxvid.h
View file @
0a024268
...
...
@@ -26,7 +26,6 @@
* common functions for use with the Xvid wrappers
*/
int
ff_tempfile
(
const
char
*
prefix
,
char
**
filename
);
#endif
/* AVCODEC_LIBXVID_H */
libavcodec/libxvid_rc.c
View file @
0a024268
...
...
@@ -21,33 +21,33 @@
*/
#include "config.h"
#include <xvid.h>
#include <unistd.h>
#if !HAVE_MKSTEMP
#include <fcntl.h>
#endif
#include <unistd.h>
#include <xvid.h>
#include "libavutil/attributes.h"
#include "libavutil/internal.h"
#include "avcodec.h"
#include "libxvid.h"
#include "mpegvideo.h"
#undef NDEBUG
#include <assert.h>
/* Wrapper to work around the lack of mkstemp() on mingw.
* Also, tries to create file in /tmp first, if possible.
* *prefix can be a character constant; *filename will be allocated internally.
* @return file descriptor of opened file (or -1 on error)
* and opened file name in **filename. */
int
ff_tempfile
(
const
char
*
prefix
,
char
**
filename
)
{
int
fd
=-
1
;
int
ff_tempfile
(
const
char
*
prefix
,
char
**
filename
)
{
int
fd
=
-
1
;
#if !HAVE_MKSTEMP
*
filename
=
tempnam
(
"."
,
prefix
);
#else
size_t
len
=
strlen
(
prefix
)
+
12
;
/* room for "/tmp/" and "XXXXXX\0" */
*
filename
=
av_malloc
(
len
);
*
filename
=
av_malloc
(
len
);
#endif
/* -----common section-----*/
if
(
!
(
*
filename
))
{
...
...
@@ -79,94 +79,105 @@ av_cold int ff_xvid_rate_control_init(MpegEncContext *s)
xvid_plg_create_t
xvid_plg_create
=
{
0
};
xvid_plugin_2pass2_t
xvid_2pass2
=
{
0
};
fd
=
ff_tempfile
(
"xvidrc."
,
&
tmp_name
);
fd
=
ff_tempfile
(
"xvidrc."
,
&
tmp_name
);
if
(
fd
==
-
1
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"Can't create temporary pass2 file.
\n
"
);
return
-
1
;
}
for
(
i
=
0
;
i
<
s
->
rc_context
.
num_entries
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
rc_context
.
num_entries
;
i
++
)
{
static
const
char
frame_types
[]
=
" ipbs"
;
char
tmp
[
256
];
RateControlEntry
*
rce
;
rce
=
&
s
->
rc_context
.
entry
[
i
];
rce
=
&
s
->
rc_context
.
entry
[
i
];
snprintf
(
tmp
,
sizeof
(
tmp
),
"%c %d %d %d %d %d %d
\n
"
,
frame_types
[
rce
->
pict_type
],
(
int
)
lrintf
(
rce
->
qscale
/
FF_QP2LAMBDA
),
rce
->
i_count
,
s
->
mb_num
-
rce
->
i_count
-
rce
->
skip_count
,
rce
->
skip_count
,
(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
rce
->
misc_bits
+
7
)
/
8
,
(
rce
->
header_bits
+
rce
->
mv_bits
+
7
)
/
8
);
frame_types
[
rce
->
pict_type
],
(
int
)
lrintf
(
rce
->
qscale
/
FF_QP2LAMBDA
),
rce
->
i_count
,
s
->
mb_num
-
rce
->
i_count
-
rce
->
skip_count
,
rce
->
skip_count
,
(
rce
->
i_tex_bits
+
rce
->
p_tex_bits
+
rce
->
misc_bits
+
7
)
/
8
,
(
rce
->
header_bits
+
rce
->
mv_bits
+
7
)
/
8
);
write
(
fd
,
tmp
,
strlen
(
tmp
));
}
close
(
fd
);
xvid_2pass2
.
version
=
XVID_MAKE_VERSION
(
1
,
1
,
0
);
xvid_2pass2
.
filename
=
tmp_name
;
xvid_2pass2
.
bitrate
=
s
->
avctx
->
bit_rate
;
xvid_2pass2
.
vbv_size
=
s
->
avctx
->
rc_buffer_size
;
xvid_2pass2
.
vbv_maxrate
=
s
->
avctx
->
rc_max_rate
;
xvid_2pass2
.
vbv_initial
=
s
->
avctx
->
rc_initial_buffer_occupancy
;
xvid_2pass2
.
version
=
XVID_MAKE_VERSION
(
1
,
1
,
0
);
xvid_2pass2
.
filename
=
tmp_name
;
xvid_2pass2
.
bitrate
=
s
->
avctx
->
bit_rate
;
xvid_2pass2
.
vbv_size
=
s
->
avctx
->
rc_buffer_size
;
xvid_2pass2
.
vbv_maxrate
=
s
->
avctx
->
rc_max_rate
;
xvid_2pass2
.
vbv_initial
=
s
->
avctx
->
rc_initial_buffer_occupancy
;
xvid_plg_create
.
version
=
XVID_MAKE_VERSION
(
1
,
1
,
0
);
xvid_plg_create
.
fbase
=
s
->
avctx
->
time_base
.
den
;
xvid_plg_create
.
fincr
=
s
->
avctx
->
time_base
.
num
;
xvid_plg_create
.
param
=
&
xvid_2pass2
;
xvid_plg_create
.
version
=
XVID_MAKE_VERSION
(
1
,
1
,
0
);
xvid_plg_create
.
fbase
=
s
->
avctx
->
time_base
.
den
;
xvid_plg_create
.
fincr
=
s
->
avctx
->
time_base
.
num
;
xvid_plg_create
.
param
=
&
xvid_2pass2
;
if
(
xvid_plugin_2pass2
(
NULL
,
XVID_PLG_CREATE
,
&
xvid_plg_create
,
&
s
->
rc_context
.
non_lavc_opaque
)
<
0
){
if
(
xvid_plugin_2pass2
(
NULL
,
XVID_PLG_CREATE
,
&
xvid_plg_create
,
&
s
->
rc_context
.
non_lavc_opaque
)
<
0
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"xvid_plugin_2pass2 failed
\n
"
);
return
-
1
;
}
return
0
;
}
float
ff_xvid_rate_estimate_qscale
(
MpegEncContext
*
s
,
int
dry_run
){
float
ff_xvid_rate_estimate_qscale
(
MpegEncContext
*
s
,
int
dry_run
)
{
xvid_plg_data_t
xvid_plg_data
=
{
0
};
xvid_plg_data
.
version
=
XVID_MAKE_VERSION
(
1
,
1
,
0
);
xvid_plg_data
.
width
=
s
->
width
;
xvid_plg_data
.
height
=
s
->
height
;
xvid_plg_data
.
mb_width
=
s
->
mb_width
;
xvid_plg_data
.
mb_height
=
s
->
mb_height
;
xvid_plg_data
.
fbase
=
s
->
avctx
->
time_base
.
den
;
xvid_plg_data
.
fincr
=
s
->
avctx
->
time_base
.
num
;
xvid_plg_data
.
min_quant
[
0
]
=
s
->
avctx
->
qmin
;
xvid_plg_data
.
min_quant
[
1
]
=
s
->
avctx
->
qmin
;
xvid_plg_data
.
min_quant
[
2
]
=
s
->
avctx
->
qmin
;
//FIXME i/b factor & offset
xvid_plg_data
.
max_quant
[
0
]
=
s
->
avctx
->
qmax
;
xvid_plg_data
.
max_quant
[
1
]
=
s
->
avctx
->
qmax
;
xvid_plg_data
.
max_quant
[
2
]
=
s
->
avctx
->
qmax
;
//FIXME i/b factor & offset
xvid_plg_data
.
bquant_offset
=
0
;
// 100 * s->avctx->b_quant_offset;
xvid_plg_data
.
bquant_ratio
=
100
;
// * s->avctx->b_quant_factor;
if
(
!
s
->
rc_context
.
dry_run_qscale
){
if
(
s
->
picture_number
){
xvid_plg_data
.
length
=
xvid_plg_data
.
stats
.
length
=
(
s
->
frame_bits
+
7
)
/
8
;
xvid_plg_data
.
frame_num
=
s
->
rc_context
.
last_picture_number
;
xvid_plg_data
.
quant
=
s
->
qscale
;
xvid_plg_data
.
type
=
s
->
last_pict_type
;
if
(
xvid_plugin_2pass2
(
s
->
rc_context
.
non_lavc_opaque
,
XVID_PLG_AFTER
,
&
xvid_plg_data
,
NULL
)){
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"xvid_plugin_2pass2(handle, XVID_PLG_AFTER, ...) FAILED
\n
"
);
xvid_plg_data
.
version
=
XVID_MAKE_VERSION
(
1
,
1
,
0
);
xvid_plg_data
.
width
=
s
->
width
;
xvid_plg_data
.
height
=
s
->
height
;
xvid_plg_data
.
mb_width
=
s
->
mb_width
;
xvid_plg_data
.
mb_height
=
s
->
mb_height
;
xvid_plg_data
.
fbase
=
s
->
avctx
->
time_base
.
den
;
xvid_plg_data
.
fincr
=
s
->
avctx
->
time_base
.
num
;
xvid_plg_data
.
min_quant
[
0
]
=
s
->
avctx
->
qmin
;
xvid_plg_data
.
min_quant
[
1
]
=
s
->
avctx
->
qmin
;
xvid_plg_data
.
min_quant
[
2
]
=
s
->
avctx
->
qmin
;
// FIXME i/b factor & offset
xvid_plg_data
.
max_quant
[
0
]
=
s
->
avctx
->
qmax
;
xvid_plg_data
.
max_quant
[
1
]
=
s
->
avctx
->
qmax
;
xvid_plg_data
.
max_quant
[
2
]
=
s
->
avctx
->
qmax
;
// FIXME i/b factor & offset
xvid_plg_data
.
bquant_offset
=
0
;
// 100 * s->avctx->b_quant_offset;
xvid_plg_data
.
bquant_ratio
=
100
;
// * s->avctx->b_quant_factor;
if
(
!
s
->
rc_context
.
dry_run_qscale
)
{
if
(
s
->
picture_number
)
{
xvid_plg_data
.
length
=
xvid_plg_data
.
stats
.
length
=
(
s
->
frame_bits
+
7
)
/
8
;
xvid_plg_data
.
frame_num
=
s
->
rc_context
.
last_picture_number
;
xvid_plg_data
.
quant
=
s
->
qscale
;
xvid_plg_data
.
type
=
s
->
last_pict_type
;
if
(
xvid_plugin_2pass2
(
s
->
rc_context
.
non_lavc_opaque
,
XVID_PLG_AFTER
,
&
xvid_plg_data
,
NULL
))
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"xvid_plugin_2pass2(handle, XVID_PLG_AFTER, ...) FAILED
\n
"
);
return
-
1
;
}
}
s
->
rc_context
.
last_picture_number
=
xvid_plg_data
.
frame_num
=
s
->
picture_number
;
xvid_plg_data
.
quant
=
0
;
if
(
xvid_plugin_2pass2
(
s
->
rc_context
.
non_lavc_opaque
,
XVID_PLG_BEFORE
,
&
xvid_plg_data
,
NULL
)){
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"xvid_plugin_2pass2(handle, XVID_PLG_BEFORE, ...) FAILED
\n
"
);
s
->
rc_context
.
last_picture_number
=
xvid_plg_data
.
frame_num
=
s
->
picture_number
;
xvid_plg_data
.
quant
=
0
;
if
(
xvid_plugin_2pass2
(
s
->
rc_context
.
non_lavc_opaque
,
XVID_PLG_BEFORE
,
&
xvid_plg_data
,
NULL
))
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"xvid_plugin_2pass2(handle, XVID_PLG_BEFORE, ...) FAILED
\n
"
);
return
-
1
;
}
s
->
rc_context
.
dry_run_qscale
=
xvid_plg_data
.
quant
;
s
->
rc_context
.
dry_run_qscale
=
xvid_plg_data
.
quant
;
}
xvid_plg_data
.
quant
=
s
->
rc_context
.
dry_run_qscale
;
if
(
!
dry_run
)
s
->
rc_context
.
dry_run_qscale
=
0
;
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
)
//FIXME this is not exactly identical to xvid
return
xvid_plg_data
.
quant
*
FF_QP2LAMBDA
*
s
->
avctx
->
b_quant_factor
+
s
->
avctx
->
b_quant_offset
;
xvid_plg_data
.
quant
=
s
->
rc_context
.
dry_run_qscale
;
if
(
!
dry_run
)
s
->
rc_context
.
dry_run_qscale
=
0
;
// FIXME this is not exactly identical to Xvid
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
)
return
xvid_plg_data
.
quant
*
FF_QP2LAMBDA
*
s
->
avctx
->
b_quant_factor
+
s
->
avctx
->
b_quant_offset
;
else
return
xvid_plg_data
.
quant
*
FF_QP2LAMBDA
;
}
...
...
@@ -175,5 +186,6 @@ av_cold void ff_xvid_rate_control_uninit(MpegEncContext *s)
{
xvid_plg_destroy_t
xvid_plg_destroy
;
xvid_plugin_2pass2
(
s
->
rc_context
.
non_lavc_opaque
,
XVID_PLG_DESTROY
,
&
xvid_plg_destroy
,
NULL
);
xvid_plugin_2pass2
(
s
->
rc_context
.
non_lavc_opaque
,
XVID_PLG_DESTROY
,
&
xvid_plg_destroy
,
NULL
);
}
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