Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
ffmpeg2theora
Commits
b4fe69c9
Commit
b4fe69c9
authored
Jul 28, 2009
by
Jan Gerber
Browse files
use new libtheoraenc api
add --soft-target, --buf-delay
parent
a55d565b
Changes
7
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
b4fe69c9
...
...
@@ -5,6 +5,8 @@ svn
- frontend mode outputs one json dict per line now
- select video stream if input has more than one video(--videostream N)
- update to ffmpeg trunk and new ffmepg api
- use new libtheora encoding api
add new encoding options --soft-target, --buf-delay
0.24 2009-03-12
- fix to make --max_size --no_upscaling work
...
...
SConstruct
View file @
b4fe69c9
...
...
@@ -107,7 +107,7 @@ if not conf.CheckPKGConfig(pkgconfig_version):
print
'pkg-config >= %s not found.'
%
pkgconfig_version
Exit
(
1
)
XIPH_LIBS
=
"ogg >= 1.1 vorbis vorbisenc theora
>= 1.0beta1
"
XIPH_LIBS
=
"ogg >= 1.1 vorbis vorbisenc theora
dec theoraenc
"
if
not
conf
.
CheckPKG
(
XIPH_LIBS
):
print
'some xiph libs are missing, ffmpeg2theora depends on %s'
%
XIPH_LIBS
...
...
ffmpeg2theora.1
View file @
b4fe69c9
...
...
@@ -57,6 +57,14 @@ Encode file with v2v preset. Right now, there is preview, pro and videobin. Ru
.B \-V, \-\-videobitrate
[1 to 16778] Set encoding bitrate for video (in kb/s).
.TP
.B\-\-soft\-target
Use a large reservoir and treat the rate
as a soft target; rate control is less
strict but resulting quality is usually
higher/smoother overall. Soft target also
allows an optional \-v setting to specify
a minimum allowed quality.
.TP
.B \-\-optimize
Optimize output Theora video, using a full search for motion vectors
instead of a hierarchical one. This can reduce video bitrate about 5%,
...
...
@@ -85,7 +93,21 @@ Crop input by given pixels before resizing.
sharper.
.TP
.B \-K, \-\-keyint
[8 to 65536] Set keyframe interval (default: 64).
[8 to 2147483647] Set keyframe interval (default: 64).
.TP
.B \-d, \-\-buf-delay
Buffer delay (in frames). Longer delays
allow smoother rate adaptation and provide
better overall quality, but require more
client side buffering and add latency. The
default value is the keyframe interval for
one-pass encoding (or somewhat larger if
\-\-soft\-target is used) and infinite for
two\-pass encoding. (only works in bitrate mode)
.TP
.B \-\-no-upscaling
only scale video or resample audio if input is
bigger than provided parameter
.SS Video transfer options:
.TP
.B \-\-pp
...
...
src/ffmpeg2theora.c
View file @
b4fe69c9
...
...
@@ -35,7 +35,7 @@
#include
"libswscale/swscale.h"
#include
"libpostproc/postprocess.h"
#include
"theora/theora.h"
#include
"theora/theora
enc
.h"
#include
"vorbis/codec.h"
#include
"vorbis/vorbisenc.h"
...
...
@@ -52,6 +52,7 @@
enum
{
NULL_FLAG
,
DEINTERLACE_FLAG
,
SOFTTARGET_FLAG
,
OPTIMIZE_FLAG
,
SYNC_FLAG
,
NOAUDIO_FLAG
,
...
...
@@ -111,6 +112,12 @@ static int using_stdin = 0;
static
int
padcolor
[
3
]
=
{
16
,
128
,
128
};
static
int
ilog
(
unsigned
_v
){
int
ret
;
for
(
ret
=
0
;
_v
;
ret
++
)
_v
>>=
1
;
return
ret
;
}
/**
* Allocate and initialise an AVFrame.
*/
...
...
@@ -169,9 +176,8 @@ static ff2theora ff2theora_init() {
this
->
videostream
=
-
1
;
this
->
picture_width
=
0
;
// set to 0 to not resize the output
this
->
picture_height
=
0
;
// set to 0 to not resize the output
this
->
video_quality
=
rint
(
5
*
6
.
3
);
// video quality 5
this
->
video_quality
=
-
1
;
// defaults set later
this
->
video_bitrate
=
0
;
this
->
sharpness
=
0
;
this
->
keyint
=
64
;
this
->
force_input_fps
.
num
=
-
1
;
this
->
force_input_fps
.
den
=
1
;
...
...
@@ -181,6 +187,8 @@ static ff2theora ff2theora_init() {
this
->
frame_aspect
=
0
;
this
->
max_size
=-
1
;
this
->
deinterlace
=
0
;
// auto by default, if input is flaged as interlaced it will deinterlace.
this
->
soft_target
=
0
;
this
->
buf_delay
=-
1
;
this
->
vhook
=
0
;
this
->
framerate_new
.
num
=
-
1
;
this
->
framerate_new
.
den
=
1
;
...
...
@@ -283,27 +291,30 @@ static void lut_apply(unsigned char *lut, unsigned char *src, unsigned char *dst
}
}
static
void
prepare_y
uv
_buffer
(
ff2theora
this
,
yuv
_buffer
*
yuv
,
AVFrame
*
frame
)
{
static
void
prepare_y
cbcr
_buffer
(
ff2theora
this
,
th_ycbcr
_buffer
ycbcr
,
AVFrame
*
frame
)
{
int
i
;
/* pysical pages */
yuv
->
y_width
=
this
->
frame_width
;
yuv
->
y_height
=
this
->
frame_height
;
yuv
->
y_stride
=
frame
->
linesize
[
0
];
ycbcr
[
0
].
width
=
this
->
frame_width
;
ycbcr
[
0
].
height
=
this
->
frame_height
;
ycbcr
[
0
].
stride
=
frame
->
linesize
[
0
];
ycbcr
[
0
].
data
=
frame
->
data
[
0
];
yuv
->
uv_width
=
this
->
frame_width
/
2
;
yuv
->
uv_height
=
this
->
frame_height
/
2
;
yuv
->
uv_stride
=
frame
->
linesize
[
1
];
ycbcr
[
1
].
width
=
this
->
frame_width
/
2
;
ycbcr
[
1
].
height
=
this
->
frame_height
/
2
;
ycbcr
[
1
].
stride
=
frame
->
linesize
[
1
];
ycbcr
[
1
].
data
=
frame
->
data
[
1
];
yuv
->
y
=
frame
->
data
[
0
];
yuv
->
u
=
frame
->
data
[
1
];
yuv
->
v
=
frame
->
data
[
2
];
ycbcr
[
2
].
width
=
this
->
frame_width
/
2
;
ycbcr
[
2
].
height
=
this
->
frame_height
/
2
;
ycbcr
[
2
].
stride
=
frame
->
linesize
[
1
];
ycbcr
[
2
].
data
=
frame
->
data
[
2
];
if
(
this
->
y_lut_used
)
{
lut_apply
(
this
->
y_lut
,
y
uv
->
y
,
yuv
->
y
,
yuv
->
y_width
,
yuv
->
y_
height
,
y
uv
->
y_
stride
);
lut_apply
(
this
->
y_lut
,
y
cbcr
[
0
].
data
,
ycbcr
[
0
].
data
,
ycbcr
[
0
].
width
,
ycbcr
[
0
].
height
,
y
cbcr
[
0
].
stride
);
}
if
(
this
->
uv_lut_used
)
{
lut_apply
(
this
->
uv_lut
,
y
uv
->
u
,
yuv
->
u
,
yuv
->
uv_width
,
yuv
->
uv_
height
,
y
uv
->
uv_
stride
);
lut_apply
(
this
->
uv_lut
,
y
uv
->
v
,
yuv
->
v
,
yuv
->
uv_width
,
yuv
->
uv_
height
,
y
uv
->
uv_
stride
);
lut_apply
(
this
->
uv_lut
,
y
cbcr
[
1
].
data
,
ycbcr
[
1
].
data
,
ycbcr
[
1
].
width
,
ycbcr
[
1
].
height
,
y
cbcr
[
1
].
stride
);
lut_apply
(
this
->
uv_lut
,
y
cbcr
[
2
].
data
,
ycbcr
[
2
].
data
,
ycbcr
[
2
].
width
,
ycbcr
[
2
].
height
,
y
cbcr
[
2
].
stride
);
}
}
...
...
@@ -735,9 +746,10 @@ void ff2theora_output(ff2theora this) {
this
->
frame_width
=
((
this
->
picture_width
+
15
)
>>
4
)
<<
4
;
this
->
frame_height
=
((
this
->
picture_height
+
15
)
>>
4
)
<<
4
;
this
->
frame_x_offset
=
0
;
this
->
frame_y_offset
=
0
;
/*Force the offsets to be even so that chroma samples line up like we
expect.*/
this
->
frame_x_offset
=
this
->
frame_width
-
this
->
picture_width
>>
1
&~
1
;
this
->
frame_y_offset
=
this
->
frame_height
-
this
->
picture_height
>>
1
&~
1
;
if
(
this
->
frame_width
>
0
||
this
->
frame_height
>
0
)
{
this
->
sws_colorspace_ctx
=
sws_getContext
(
...
...
@@ -944,14 +956,16 @@ void ff2theora_output(ff2theora this) {
/* video settings here */
/* config file? commandline options? v2v presets? */
th
eora
_info_init
(
&
info
.
ti
);
th_info_init
(
&
info
.
ti
);
info
.
ti
.
width
=
this
->
frame_width
;
info
.
ti
.
height
=
this
->
frame_height
;
info
.
ti
.
frame_width
=
this
->
picture_width
;
info
.
ti
.
frame_height
=
this
->
picture_height
;
info
.
ti
.
offset_x
=
this
->
frame_x_offset
;
info
.
ti
.
offset_y
=
this
->
frame_y_offset
;
//encoded size
info
.
ti
.
frame_width
=
this
->
frame_width
;
info
.
ti
.
frame_height
=
this
->
frame_height
;
//displayed size
info
.
ti
.
pic_width
=
this
->
picture_width
;
info
.
ti
.
pic_height
=
this
->
picture_height
;
info
.
ti
.
pic_x
=
this
->
frame_x_offset
;
info
.
ti
.
pic_y
=
this
->
frame_y_offset
;
if
(
this
->
framerate_new
.
num
>
0
)
{
// new framerate is interger only right now,
// so denominator is always 1
...
...
@@ -965,17 +979,28 @@ void ff2theora_output(ff2theora this) {
/* this is pixel aspect ratio */
info
.
ti
.
aspect_numerator
=
this
->
aspect_numerator
;
info
.
ti
.
aspect_denominator
=
this
->
aspect_denominator
;
/*
// FIXME: is all input material with fps==25 OC_CS_ITU_REC_470BG?
// guess not, commandline option to select colorspace would be the best.
if ((this->fps-25)<1)
info
.
ti
.
colorspace
=
OC
_CS_ITU_REC_470BG
;
info.ti.colorspace =
TH
_CS_ITU_REC_470BG;
else if (abs(this->fps-30)<1)
info
.
ti
.
colorspace
=
OC
_CS_ITU_REC_470M
;
info.ti.colorspace =
TH
_CS_ITU_REC_470M;
else
info
.
ti
.
colorspace
=
OC_CS_UNSPECIFIED
;
*/
info
.
ti
.
colorspace
=
TH_CS_UNSPECIFIED
;
/*Account for the Ogg page overhead.
This is 1 byte per 255 for lacing values, plus 26 bytes per 4096 bytes for
the page header, plus approximately 1/2 byte per packet (not accounted for
here).*/
info
.
ti
.
target_bitrate
=
(
int
)(
64870
*
(
ogg_int64_t
)
this
->
video_bitrate
>>
16
);
info
.
ti
.
target_bitrate
=
this
->
video_bitrate
;
info
.
ti
.
quality
=
this
->
video_quality
;
info
.
ti
.
keyframe_granule_shift
=
ilog
(
this
->
keyint
-
1
);
info
.
ti
.
pixel_fmt
=
TH_PF_420
;
/* no longer in new encoder api
info.ti.dropframes_p = 0;
info.ti.keyframe_auto_p = 1;
info.ti.keyframe_frequency = this->keyint;
...
...
@@ -986,7 +1011,47 @@ void ff2theora_output(ff2theora this) {
info.ti.noise_sensitivity = 1;
// range 0-2, 0 sharp, 2 less sharp,less bandwidth
info.ti.sharpness = this->sharpness;
*/
info
.
td
=
th_encode_alloc
(
&
info
.
ti
);
if
(
info
.
speed_level
>=
0
)
{
int
max_speed_level
;
th_encode_ctl
(
info
.
td
,
TH_ENCCTL_GET_SPLEVEL_MAX
,
&
max_speed_level
,
sizeof
(
int
));
if
(
info
.
speed_level
>
max_speed_level
)
info
.
speed_level
=
max_speed_level
;
th_encode_ctl
(
info
.
td
,
TH_ENCCTL_SET_SPLEVEL
,
&
info
.
speed_level
,
sizeof
(
int
));
}
if
(
this
->
buf_delay
>=
0
){
ret
=
th_encode_ctl
(
info
.
td
,
TH_ENCCTL_SET_RATE_BUFFER
,
&
this
->
buf_delay
,
sizeof
(
this
->
buf_delay
));
if
(
ret
<
0
){
fprintf
(
stderr
,
"Warning: could not set desired buffer delay. %d
\n
"
,
ret
);
}
}
/* setting just the granule shift only allows power-of-two keyframe
spacing. Set the actual requested spacing. */
ret
=
th_encode_ctl
(
info
.
td
,
TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE
,
&
this
->
keyint
,
sizeof
(
this
->
keyint
-
1
));
if
(
ret
<
0
){
fprintf
(
stderr
,
"Could not set keyframe interval to %d.
\n
"
,(
int
)
this
->
keyint
);
}
if
(
this
->
soft_target
){
/* reverse the rate control flags to favor a 'long time' strategy */
int
arg
=
TH_RATECTL_CAP_UNDERFLOW
;
ret
=
th_encode_ctl
(
info
.
td
,
TH_ENCCTL_SET_RATE_FLAGS
,
&
arg
,
sizeof
(
arg
));
if
(
ret
<
0
)
fprintf
(
stderr
,
"Could not set encoder flags for --soft-target
\n
"
);
/* Default buffer control is overridden on two-pass */
if
(
this
->
buf_delay
<
0
){
if
((
this
->
keyint
*
7
>>
1
)
>
5
*
this
->
framerate_new
.
num
/
this
->
framerate_new
.
den
)
arg
=
this
->
keyint
*
7
>>
1
;
else
arg
=
30
*
this
->
framerate_new
.
num
/
this
->
framerate_new
.
den
;
ret
=
th_encode_ctl
(
info
.
td
,
TH_ENCCTL_SET_RATE_BUFFER
,
&
arg
,
sizeof
(
arg
));
if
(
ret
<
0
)
fprintf
(
stderr
,
"Could not set rate control buffer for --soft-target
\n
"
);
}
}
}
/* audio settings here */
info
.
channels
=
this
->
channels
;
...
...
@@ -1101,7 +1166,7 @@ void ff2theora_output(ff2theora this) {
}
while
(
video_eos
||
avpkt
.
size
>
0
)
{
int
dups
=
0
;
yuv
_buffer
y
uv
;
static
th_ycbcr
_buffer
y
cbcr
;
len1
=
avcodec_decode_video2
(
vstream
->
codec
,
frame
,
&
got_picture
,
&
avpkt
);
if
(
len1
>=
0
)
{
if
(
got_picture
)
{
...
...
@@ -1218,9 +1283,9 @@ void ff2theora_output(ff2theora this) {
if
(
!
first
)
{
if
(
got_picture
||
video_eos
)
{
prepare_y
uv
_buffer
(
this
,
&
yuv
,
output_buffered
);
prepare_y
cbcr
_buffer
(
this
,
ycbcr
,
output_buffered
);
do
{
oggmux_add_video
(
&
info
,
&
yuv
,
video_eos
);
oggmux_add_video
(
&
info
,
ycbcr
,
video_eos
);
if
(
video_eos
)
{
video_done
=
1
;
}
...
...
@@ -1540,11 +1605,11 @@ void print_presets_info() {
// "v2v presets - more info at http://wiki.v2v.cc/presets"
"v2v presets:
\n
"
" preview Video: 320x240 if fps ~ 30, 384x288 otherwise
\n
"
" Quality 5
- Sharpness 2
\n
"
" Quality 5
\n
"
" Audio: Max 2 channels - Quality 1
\n
"
"
\n
"
" pro Video: 720x480 if fps ~ 30, 720x576 otherwise
\n
"
" Quality 7
- Sharpness 0
\n
"
" Quality 7
\n
"
" Audio: Max 2 channels - Quality 3
\n
"
"
\n
"
" videobin Video: 512x288 for 16:9 material, 448x336 for 4:3 material
\n
"
...
...
@@ -1552,7 +1617,7 @@ void print_presets_info() {
" Audio: Max 2 channels - Quality 3
\n
"
"
\n
"
" padma Video: 640x360 for 16:9 material, 640x480 for 4:3 material
\n
"
" Quality 5
- Sharpness 0
\n
"
" Quality 5
\n
"
" Audio: Max 2 channels - Quality 3
\n
"
"
\n
"
" padma-stream Video: 128x72 for 16:9 material, 128x96 for 4:3 material
\n
"
...
...
@@ -1580,8 +1645,15 @@ void print_usage() {
" -v, --videoquality [0 to 10] encoding quality for video (default: 5)
\n
"
" use higher values for better quality
\n
"
" -V, --videobitrate [1 to 16778] encoding bitrate for video (kb/s)
\n
"
" --soft-target Use a large reservoir and treat the rate
\n
"
" as a soft target; rate control is less
\n
"
" strict but resulting quality is usually
\n
"
" higher/smoother overall. Soft target also
\n
"
" allows an optional -v setting to specify
\n
"
" a minimum allowed quality.
\n\n
"
" --optimize optimize video output filesize (slower) (same as speedlevel 0)
\n
"
" --speedlevel [0 2] encoding is faster with higher values the cost is quality and bandwidth
\n
"
" -x, --width scale to given width (in pixels)
\n
"
" -y, --height scale to given height (in pixels)
\n
"
" --max_size scale output frame to be withing box of
\n
"
...
...
@@ -1590,9 +1662,15 @@ void print_usage() {
" -F, --framerate output framerate e.g 25:2 or 16
\n
"
" --croptop, --cropbottom, --cropleft, --cropright
\n
"
" crop input by given pixels before resizing
\n
"
" -S, --sharpness [0 to 2] sharpness of images (default: 0).
\n
"
" Note: lower values make the video sharper.
\n
"
" -K, --keyint [1 to 65536] keyframe interval (default: 64)
\n
"
" -K, --keyint [1 to 2147483647] keyframe interval (default: 64)
\n
"
" -d --buf-delay <n> Buffer delay (in frames). Longer delays
\n
"
" allow smoother rate adaptation and provide
\n
"
" better overall quality, but require more
\n
"
" client side buffering and add latency. The
\n
"
" default value is the keyframe interval for
\n
"
" one-pass encoding (or somewhat larger if
\n
"
" --soft-target is used) and infinite for
\n
"
" two-pass encoding. (only works in bitrate mode)
\n
"
" --no-upscaling only scale video or resample audio if input is
\n
"
" bigger than provided parameters
\n
"
"
\n
"
...
...
@@ -1708,7 +1786,7 @@ int main(int argc, char **argv) {
AVFormatParameters
params
,
*
formatParams
=
NULL
;
int
c
,
long_option_index
;
const
char
*
optstring
=
"P:o:k:f:F:x:y:v:V:a:A:
S:
K:d:H:c:G:Z:C:B:p:N:s:e:D:h::"
;
const
char
*
optstring
=
"P:o:k:f:F:x:y:v:V:a:A:K:d:H:c:G:Z:C:B:p:N:s:e:D:h::"
;
struct
option
options
[]
=
{
{
"pid"
,
required_argument
,
NULL
,
'P'
},
{
"output"
,
required_argument
,
NULL
,
'o'
},
...
...
@@ -1722,8 +1800,9 @@ int main(int argc, char **argv) {
{
"videobitrate"
,
required_argument
,
NULL
,
'V'
},
{
"audioquality"
,
required_argument
,
NULL
,
'a'
},
{
"audiobitrate"
,
required_argument
,
NULL
,
'A'
},
{
"s
harpness"
,
required_argument
,
NULL
,
'S'
},
{
"s
oft-target"
,
0
,
&
flag
,
SOFTTARGET_FLAG
},
{
"keyint"
,
required_argument
,
NULL
,
'K'
},
{
"buf-delay"
,
required_argument
,
NULL
,
'd'
},
{
"deinterlace"
,
0
,
&
flag
,
DEINTERLACE_FLAG
},
{
"pp"
,
required_argument
,
&
flag
,
PP_FLAG
},
{
"samplerate"
,
required_argument
,
NULL
,
'H'
},
...
...
@@ -1804,6 +1883,10 @@ int main(int argc, char **argv) {
convert
->
deinterlace
=
1
;
flag
=
-
1
;
break
;
case
SOFTTARGET_FLAG
:
convert
->
soft_target
=
1
;
flag
=
-
1
;
break
;
case
PP_FLAG
:
if
(
!
strcmp
(
optarg
,
"help"
))
{
fprintf
(
stdout
,
"%s"
,
pp_help
);
...
...
@@ -2009,7 +2092,6 @@ int main(int argc, char **argv) {
fprintf
(
stderr
,
"Only values from 0 to 10 are valid for video quality.
\n
"
);
exit
(
1
);
}
convert
->
video_bitrate
=
0
;
break
;
case
'V'
:
convert
->
video_bitrate
=
rint
(
atof
(
optarg
)
*
1000
);
...
...
@@ -2017,7 +2099,6 @@ int main(int argc, char **argv) {
fprintf
(
stderr
,
"Only values from 1 to 16000 are valid for video bitrate (in kb/s).
\n
"
);
exit
(
1
);
}
convert
->
video_quality
=
0
;
break
;
case
'a'
:
convert
->
audio_quality
=
atof
(
optarg
);
...
...
@@ -2047,20 +2128,16 @@ int main(int argc, char **argv) {
case
'B'
:
convert
->
video_bright
=
atof
(
optarg
);
break
;
case
'S'
:
convert
->
sharpness
=
atoi
(
optarg
);
if
(
convert
->
sharpness
<
0
||
convert
->
sharpness
>
2
)
{
fprintf
(
stderr
,
"Only values from 0 to 2 are valid for sharpness.
\n
"
);
exit
(
1
);
}
break
;
case
'K'
:
convert
->
keyint
=
atoi
(
optarg
);
if
(
convert
->
keyint
<
1
||
convert
->
keyint
>
65536
)
{
fprintf
(
stderr
,
"Only values from 1 to
65536
are valid for keyframe interval.
\n
"
);
if
(
convert
->
keyint
<
1
||
convert
->
keyint
>
2147483647
)
{
fprintf
(
stderr
,
"Only values from 1 to
2147483647
are valid for keyframe interval.
\n
"
);
exit
(
1
);
}
break
;
case
'd'
:
convert
->
buf_delay
=
atoi
(
optarg
);
break
;
case
'H'
:
convert
->
sample_rate
=
atoi
(
optarg
);
break
;
...
...
@@ -2085,7 +2162,6 @@ int main(int argc, char **argv) {
convert
->
preset
=
V2V_PRESET_PRO
;
convert
->
video_quality
=
rint
(
7
*
6
.
3
);
convert
->
audio_quality
=
3
.
00
;
convert
->
sharpness
=
0
;
info
.
speed_level
=
0
;
}
else
if
(
!
strcmp
(
optarg
,
"preview"
))
{
...
...
@@ -2093,7 +2169,6 @@ int main(int argc, char **argv) {
convert
->
preset
=
V2V_PRESET_PREVIEW
;
convert
->
video_quality
=
rint
(
5
*
6
.
3
);
convert
->
audio_quality
=
1
.
00
;
convert
->
sharpness
=
2
;
info
.
speed_level
=
0
;
}
else
if
(
!
strcmp
(
optarg
,
"videobin"
))
{
...
...
@@ -2101,14 +2176,12 @@ int main(int argc, char **argv) {
convert
->
video_bitrate
=
rint
(
600
*
1000
);
convert
->
video_quality
=
0
;
convert
->
audio_quality
=
3
.
00
;
convert
->
sharpness
=
2
;
info
.
speed_level
=
0
;
}
else
if
(
!
strcmp
(
optarg
,
"padma"
))
{
convert
->
preset
=
V2V_PRESET_PADMA
;
convert
->
video_quality
=
rint
(
5
*
6
.
3
);
convert
->
audio_quality
=
3
.
00
;
convert
->
sharpness
=
0
;
info
.
speed_level
=
0
;
}
else
if
(
!
strcmp
(
optarg
,
"padma-stream"
))
{
...
...
@@ -2117,7 +2190,6 @@ int main(int argc, char **argv) {
convert
->
video_quality
=
0
;
convert
->
audio_quality
=
-
1
.
00
;
convert
->
sample_rate
=
44100
;
convert
->
sharpness
=
2
;
convert
->
keyint
=
16
;
info
.
speed_level
=
0
;
}
...
...
@@ -2184,6 +2256,24 @@ int main(int argc, char **argv) {
exit
(
1
);
}
if
(
convert
->
soft_target
)
{
if
(
convert
->
video_bitrate
<=
0
)
{
fprintf
(
stderr
,
"Soft rate target (--soft-tagret) requested without a bitrate (-V).
\n
"
);
exit
(
1
);
}
if
(
convert
->
video_quality
==
-
1
)
convert
->
video_quality
=
0
;
}
else
{
if
(
convert
->
video_bitrate
>
0
)
convert
->
video_quality
=
0
;
if
(
convert
->
video_quality
==
-
1
)
convert
->
video_quality
=
rint
(
5
*
6
.
3
);
// default quality 5
}
if
(
convert
->
buf_delay
>
0
&&
convert
->
video_bitrate
==
0
)
{
fprintf
(
stderr
,
"Buffer delay can only be used with target bitrate (-V).
\n
"
);
exit
(
1
);
}
if
(
*
pidfile_name
)
{
fpid
=
fopen
(
pidfile_name
,
"w"
);
if
(
fpid
!=
NULL
)
{
...
...
src/ffmpeg2theora.h
View file @
b4fe69c9
...
...
@@ -32,6 +32,8 @@ typedef struct ff2theora{
int
audio_index
;
int
deinterlace
;
int
soft_target
;
int
buf_delay
;
int
vhook
;
int
disable_video
;
int
no_upscaling
;
...
...
@@ -61,8 +63,7 @@ typedef struct ff2theora{
int
pix_fmt
;
int
video_quality
;
int
video_bitrate
;
int
sharpness
;
int
keyint
;
ogg_uint32_t
keyint
;
char
pp_mode
[
255
];
AVRational
force_input_fps
;
...
...
src/theorautils.c
View file @
b4fe69c9
...
...
@@ -25,7 +25,7 @@
#include
<string.h>
#include
<time.h>
#include
"theora/theora.h"
#include
"theora/theora
enc
.h"
#include
"vorbis/codec.h"
#include
"vorbis/vorbisenc.h"
#ifdef HAVE_OGGKATE
...
...
@@ -169,7 +169,7 @@ void add_fisbone_packet (oggmux_info *info) {
write64le
(
op
.
packet
+
28
,
info
->
ti
.
fps_denominator
);
/* granulrate denominator */
write64le
(
op
.
packet
+
36
,
0
);
/* start granule */
write32le
(
op
.
packet
+
44
,
0
);
/* preroll, for theora its 0 */
*
(
op
.
packet
+
48
)
=
theora
_granule_shift
(
&
info
->
ti
)
;
/* granule shift */
*
(
op
.
packet
+
48
)
=
info
->
ti
.
keyframe
_granule_shift
;
/* granule shift */
memcpy
(
op
.
packet
+
FISBONE_SIZE
,
"Content-Type: video/theora
\r\n
"
,
28
);
/* message header field, Content-Type */
op
.
b_o_s
=
0
;
...
...
@@ -244,6 +244,7 @@ void add_fisbone_packet (oggmux_info *info) {
void
oggmux_init
(
oggmux_info
*
info
)
{
ogg_page
og
;
ogg_packet
op
;
int
ret
;
/* yayness. Set up Ogg output stream */
srand
(
time
(
NULL
));
...
...
@@ -251,15 +252,6 @@ void oggmux_init (oggmux_info *info) {
if
(
!
info
->
audio_only
)
{
ogg_stream_init
(
&
info
->
to
,
rand
());
/* oops, add one ot the above */
theora_encode_init
(
&
info
->
td
,
&
info
->
ti
);
if
(
info
->
speed_level
>=
0
)
{
int
max_speed_level
;
theora_control
(
&
info
->
td
,
TH_ENCCTL_GET_SPLEVEL_MAX
,
&
max_speed_level
,
sizeof
(
int
));
if
(
info
->
speed_level
>
max_speed_level
)
info
->
speed_level
=
max_speed_level
;
theora_control
(
&
info
->
td
,
TH_ENCCTL_SET_SPLEVEL
,
&
info
->
speed_level
,
sizeof
(
int
));
}
}
/* init theora done */
...
...
@@ -332,28 +324,37 @@ void oggmux_init (oggmux_info *info) {
/* first packet will get its own page automatically */
if
(
!
info
->
audio_only
)
{
/* write the bitstream header packets with proper page interleave */
th_comment_init
(
&
info
->
tc
);
th_comment_add_tag
(
&
info
->
tc
,
"ENCODER"
,
PACKAGE_STRING
);
if
(
strcmp
(
info
->
oshash
,
"0"
)
>
0
)
{
th_comment_add_tag
(
&
info
->
tc
,
"SOURCE_OSHASH"
,
info
->
oshash
);
}
theora_encode_header
(
&
info
->
td
,
&
op
);
ogg_stream_packetin
(
&
info
->
to
,
&
op
);
if
(
ogg_stream_pageout
(
&
info
->
t
o
,
&
o
g
)
!
=
1
)
{
fprintf
(
stderr
,
"Internal
Ogg
library error.
\n
"
);
exit
(
1
);
/* write the bitstream header packets with proper page interleave */
/* first packet will get its own page automatically */
if
(
th_encode_flushheader
(
info
->
td
,
&
info
->
t
c
,
&
o
p
)
<
=
0
)
{
fprintf
(
stderr
,
"Internal
Theora
library error.
\n
"
);
exit
(
1
);
}
fwrite
(
og
.
header
,
1
,
og
.
header_len
,
info
->
outfile
);
fwrite
(
og
.
body
,
1
,
og
.
body_len
,
info
->
outfile
);
ogg_stream_packetin
(
&
info
->
to
,
&
op
);
if
(
ogg_stream_pageout
(
&
info
->
to
,
&
og
)
!=
1
)
{
fprintf
(
stderr
,
"Internal Ogg library error.
\n
"
);
exit
(
1
);
}
fwrite
(
og
.
header
,
1
,
og
.
header_len
,
info
->
outfile
);
fwrite
(
og
.
body
,
1
,
og
.
body_len
,
info
->
outfile
);
/* create the remaining theora headers */
/* theora_comment_init (&info->tc); is called in main() prior to parsing options */
theora_comment_add_tag
(
&
info
->
tc
,
"ENCODER"
,
PACKAGE_STRING
);
if
(
strcmp
(
info
->
oshash
,
"0"
)
>
0
)
{
theora_comment_add_tag
(
&
info
->
tc
,
"SOURCE_OSHASH"
,
info
->
oshash
);
for
(;;){
ret
=
th_encode_flushheader
(
info
->
td
,
&
info
->
tc
,
&
op
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"Internal Theora library error.
\n
"
);
exit
(
1
);
}
else
if
(
!
ret
)
break
;
ogg_stream_packetin
(
&
info
->
to
,
&
op
);
}
theora_encode_comment
(
&
info
->
tc
,
&
op
);
ogg_stream_packetin
(
&
info
->
to
,
&
op
);
_ogg_free
(
op
.
packet
);
theora_encode_tables
(
&
info
->
td
,
&
op
);
ogg_stream_packetin
(
&
info
->
to
,
&
op
);
}
if
(
!
info
->
video_only
)
{
ogg_packet
header
;
...
...
@@ -421,10 +422,6 @@ void oggmux_init (oggmux_info *info) {
}
}
if
(
!
info
->
audio_only
)
{
theora_info_clear
(
&
info
->
ti
);
}
/* Flush the rest of our headers. This ensures
* the actual data in each stream will start
* on a new page, as per spec. */
...
...
@@ -493,6 +490,9 @@ void oggmux_init (oggmux_info *info) {
fwrite
(
og
.
header
,
1
,
og
.
header_len
,
info
->
outfile
);
fwrite
(
og
.
body
,
1
,
og
.
body_len
,
info
->
outfile
);
}
if
(
!
info
->
audio_only
)
{
th_info_clear
(
&
info
->
ti
);
}
}
/**
...
...
@@ -503,10 +503,11 @@ void oggmux_init (oggmux_info *info) {