Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Xiph.Org
aom-rav1e
Commits
49b4b72b
Commit
49b4b72b
authored
Feb 13, 2014
by
Dmitry Kovalev
Committed by
Gerrit Code Review
Feb 13, 2014
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Adapting vp8_set_maps.c example to use new APIs."
parents
afad1a84
8837b022
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
172 additions
and
224 deletions
+172
-224
examples.mk
examples.mk
+4
-0
examples/vp8_set_maps.c
examples/vp8_set_maps.c
+168
-224
No files found.
examples.mk
View file @
49b4b72b
...
...
@@ -137,6 +137,10 @@ error_resilient.GUID = DF5837B9-4145-4F92-A031-44E4F832E00C
error_resilient.DESCRIPTION
=
Error Resiliency Feature
EXAMPLES-$(CONFIG_VP8_ENCODER)
+=
vp8_set_maps.c
vp8_set_maps.SRCS
+=
ivfenc.h ivfenc.c
vp8_set_maps.SRCS
+=
tools_common.h tools_common.c
vp8_set_maps.SRCS
+=
video_common.h
vp8_set_maps.SRCS
+=
video_writer.h video_writer.c
vp8_set_maps.GUID
=
ECB2D24D-98B8-4015-A465-A4AF3DCC145F
vp8_set_maps.DESCRIPTION
=
VP8
set
active and ROI maps
EXAMPLES-$(CONFIG_VP8_ENCODER)
+=
vp8cx_set_ref.c
...
...
examples/vp8_set_maps.c
View file @
49b4b72b
...
...
@@ -44,253 +44,197 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#define VPX_CODEC_DISABLE_COMPAT 1
#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"
#define interface (vpx_codec_vp8_cx())
#define fourcc 0x30385056
#include "vpx/vpx_encoder.h"
#
define IVF_FILE_HDR_SZ (32)
#
define IVF_FRAME_HDR_SZ (12)
#
include "./tools_common.h"
#
include "./video_writer.h"
static
void
mem_put_le16
(
char
*
mem
,
unsigned
int
val
)
{
mem
[
0
]
=
val
;
mem
[
1
]
=
val
>>
8
;
}
static
const
char
*
exec_name
;
static
void
mem_put_le32
(
char
*
mem
,
unsigned
int
val
)
{
mem
[
0
]
=
val
;
mem
[
1
]
=
val
>>
8
;
mem
[
2
]
=
val
>>
16
;
mem
[
3
]
=
val
>>
24
;
void
usage_exit
()
{
fprintf
(
stderr
,
"Usage: %s <width> <height> <infile> <outfile>
\n
"
,
exec_name
);
exit
(
EXIT_FAILURE
);
}
static
void
die
(
const
char
*
fmt
,
...)
{
va_list
ap
;
static
void
set_roi_map
(
const
vpx_codec_enc_cfg_t
*
cfg
,
vpx_codec_ctx_t
*
codec
)
{
int
i
;
vpx_roi_map_t
roi
=
{
0
};
va_start
(
ap
,
fmt
);
vprintf
(
fmt
,
ap
);
if
(
fmt
[
strlen
(
fmt
)
-
1
]
!=
'\n'
)
printf
(
"
\n
"
);
exit
(
EXIT_FAILURE
);
}
roi
.
rows
=
cfg
->
g_h
/
16
;
roi
.
cols
=
cfg
->
g_w
/
16
;
static
void
die_codec
(
vpx_codec_ctx_t
*
ctx
,
const
char
*
s
)
{
const
char
*
detail
=
vpx_codec_error_detail
(
ctx
);
roi
.
delta_q
[
0
]
=
0
;
roi
.
delta_q
[
1
]
=
-
2
;
roi
.
delta_q
[
2
]
=
-
4
;
roi
.
delta_q
[
3
]
=
-
6
;
printf
(
"%s: %s
\n
"
,
s
,
vpx_codec_error
(
ctx
));
if
(
detail
)
printf
(
" %s
\n
"
,
detail
);
exit
(
EXIT_FAILURE
);
}
roi
.
delta_lf
[
0
]
=
0
;
roi
.
delta_lf
[
1
]
=
1
;
roi
.
delta_lf
[
2
]
=
2
;
roi
.
delta_lf
[
3
]
=
3
;
static
int
read_frame
(
FILE
*
f
,
vpx_image_t
*
img
)
{
size_t
nbytes
,
to_read
;
int
res
=
1
;
roi
.
static_threshold
[
0
]
=
1500
;
roi
.
static_threshold
[
1
]
=
1000
;
roi
.
static_threshold
[
2
]
=
500
;
roi
.
static_threshold
[
3
]
=
0
;
to_read
=
img
->
w
*
img
->
h
*
3
/
2
;
nbytes
=
fread
(
img
->
planes
[
0
],
1
,
to_read
,
f
);
if
(
nbytes
!=
to_read
)
{
res
=
0
;
if
(
nbytes
>
0
)
printf
(
"Warning: Read partial frame. Check your width & height!
\n
"
);
}
return
res
;
}
roi
.
roi_map
=
(
uint8_t
*
)
malloc
(
roi
.
rows
*
roi
.
cols
);
for
(
i
=
0
;
i
<
roi
.
rows
*
roi
.
cols
;
++
i
)
roi
.
roi_map
[
i
]
=
i
%
4
;
static
void
write_ivf_file_header
(
FILE
*
outfile
,
const
vpx_codec_enc_cfg_t
*
cfg
,
int
frame_cnt
)
{
char
header
[
32
];
if
(
cfg
->
g_pass
!=
VPX_RC_ONE_PASS
&&
cfg
->
g_pass
!=
VPX_RC_LAST_PASS
)
return
;
header
[
0
]
=
'D'
;
header
[
1
]
=
'K'
;
header
[
2
]
=
'I'
;
header
[
3
]
=
'F'
;
mem_put_le16
(
header
+
4
,
0
);
/* version */
mem_put_le16
(
header
+
6
,
32
);
/* headersize */
mem_put_le32
(
header
+
8
,
fourcc
);
/* headersize */
mem_put_le16
(
header
+
12
,
cfg
->
g_w
);
/* width */
mem_put_le16
(
header
+
14
,
cfg
->
g_h
);
/* height */
mem_put_le32
(
header
+
16
,
cfg
->
g_timebase
.
den
);
/* rate */
mem_put_le32
(
header
+
20
,
cfg
->
g_timebase
.
num
);
/* scale */
mem_put_le32
(
header
+
24
,
frame_cnt
);
/* length */
mem_put_le32
(
header
+
28
,
0
);
/* unused */
(
void
)
fwrite
(
header
,
1
,
32
,
outfile
);
if
(
vpx_codec_control
(
codec
,
VP8E_SET_ROI_MAP
,
&
roi
))
die_codec
(
codec
,
"Failed to set ROI map"
);
free
(
roi
.
roi_map
);
}
static
void
set_active_map
(
const
vpx_codec_enc_cfg_t
*
cfg
,
vpx_codec_ctx_t
*
codec
)
{
int
i
;
vpx_active_map_t
map
=
{
0
};
static
void
write_ivf_frame_header
(
FILE
*
outfile
,
const
vpx_codec_cx_pkt_t
*
pkt
)
{
char
header
[
12
];
vpx_codec_pts_t
pts
;
map
.
rows
=
cfg
->
g_h
/
16
;
map
.
cols
=
cfg
->
g_w
/
16
;
if
(
pkt
->
kind
!=
VPX_CODEC_CX_FRAME_PKT
)
return
;
map
.
active_map
=
(
uint8_t
*
)
malloc
(
map
.
rows
*
map
.
cols
);
for
(
i
=
0
;
i
<
map
.
rows
*
map
.
cols
;
++
i
)
map
.
active_map
[
i
]
=
i
%
2
;
pts
=
pkt
->
data
.
frame
.
pts
;
mem_put_le32
(
header
,
pkt
->
data
.
frame
.
sz
);
mem_put_le32
(
header
+
4
,
pts
&
0xFFFFFFFF
);
mem_put_le32
(
header
+
8
,
pts
>>
32
);
if
(
vpx_codec_control
(
codec
,
VP8E_SET_ACTIVEMAP
,
&
map
))
die_codec
(
codec
,
"Failed to set active map"
);
(
void
)
fwrite
(
header
,
1
,
12
,
outfile
);
free
(
map
.
active_map
);
}
static
void
unset_active_map
(
const
vpx_codec_enc_cfg_t
*
cfg
,
vpx_codec_ctx_t
*
codec
)
{
vpx_active_map_t
map
=
{
0
};
map
.
rows
=
cfg
->
g_h
/
16
;
map
.
cols
=
cfg
->
g_w
/
16
;
map
.
active_map
=
NULL
;
if
(
vpx_codec_control
(
codec
,
VP8E_SET_ACTIVEMAP
,
&
map
))
die_codec
(
codec
,
"Failed to set active map"
);
}
static
void
encode_frame
(
vpx_codec_ctx_t
*
codec
,
vpx_image_t
*
img
,
int
frame_index
,
VpxVideoWriter
*
writer
)
{
vpx_codec_iter_t
iter
=
NULL
;
const
vpx_codec_cx_pkt_t
*
pkt
=
NULL
;
const
vpx_codec_err_t
res
=
vpx_codec_encode
(
codec
,
img
,
frame_index
,
1
,
0
,
VPX_DL_GOOD_QUALITY
);
if
(
res
!=
VPX_CODEC_OK
)
die_codec
(
codec
,
"Failed to encode frame"
);
while
((
pkt
=
vpx_codec_get_cx_data
(
codec
,
&
iter
))
!=
NULL
)
{
if
(
pkt
->
kind
==
VPX_CODEC_CX_FRAME_PKT
)
{
const
int
keyframe
=
(
pkt
->
data
.
frame
.
flags
&
VPX_FRAME_IS_KEY
)
!=
0
;
if
(
!
vpx_video_writer_write_frame
(
writer
,
pkt
->
data
.
frame
.
buf
,
pkt
->
data
.
frame
.
sz
,
pkt
->
data
.
frame
.
pts
))
{
die_codec
(
codec
,
"Failed to write compressed frame"
);
}
printf
(
keyframe
?
"K"
:
"."
);
fflush
(
stdout
);
}
}
}
int
main
(
int
argc
,
char
**
argv
)
{
FILE
*
infile
,
*
outfile
;
vpx_codec_ctx_t
codec
;
vpx_codec_enc_cfg_t
cfg
;
int
frame_cnt
=
0
;
vpx_image_t
raw
;
vpx_codec_err_t
res
;
long
width
;
long
height
;
int
frame_avail
;
int
got_data
;
int
flags
=
0
;
/* Open files */
if
(
argc
!=
5
)
die
(
"Usage: %s <width> <height> <infile> <outfile>
\n
"
,
argv
[
0
]);
width
=
strtol
(
argv
[
1
],
NULL
,
0
);
height
=
strtol
(
argv
[
2
],
NULL
,
0
);
if
(
width
<
16
||
width
%
2
||
height
<
16
||
height
%
2
)
die
(
"Invalid resolution: %ldx%ld"
,
width
,
height
);
if
(
!
vpx_img_alloc
(
&
raw
,
VPX_IMG_FMT_I420
,
width
,
height
,
1
))
die
(
"Faile to allocate image"
,
width
,
height
);
if
(
!
(
outfile
=
fopen
(
argv
[
4
],
"wb"
)))
die
(
"Failed to open %s for writing"
,
argv
[
4
]);
printf
(
"Using %s
\n
"
,
vpx_codec_iface_name
(
interface
));
/* Populate encoder configuration */
res
=
vpx_codec_enc_config_default
(
interface
,
&
cfg
,
0
);
if
(
res
)
{
printf
(
"Failed to get config: %s
\n
"
,
vpx_codec_err_to_string
(
res
));
return
EXIT_FAILURE
;
FILE
*
infile
=
NULL
;
vpx_codec_ctx_t
codec
=
{
0
};
vpx_codec_enc_cfg_t
cfg
=
{
0
};
int
frame_count
=
0
;
vpx_image_t
raw
=
{
0
};
vpx_codec_err_t
res
;
VpxVideoInfo
info
=
{
0
};
VpxVideoWriter
*
writer
=
NULL
;
const
VpxInterface
*
encoder
=
NULL
;
const
int
fps
=
2
;
// TODO(dkovalev) add command line argument
const
int
bitrate
=
200
;
// kbit/s TODO(dkovalev) add command line argument
exec_name
=
argv
[
0
];
if
(
argc
!=
5
)
die
(
"Invalid number of arguments"
);
encoder
=
get_vpx_encoder_by_name
(
"vp8"
);
// only vp8 for now
if
(
!
encoder
)
die
(
"Unsupported codec."
);
info
.
codec_fourcc
=
encoder
->
fourcc
;
info
.
frame_width
=
strtol
(
argv
[
1
],
NULL
,
0
);
info
.
frame_height
=
strtol
(
argv
[
2
],
NULL
,
0
);
info
.
time_base
.
numerator
=
1
;
info
.
time_base
.
denominator
=
fps
;
if
(
info
.
frame_width
<=
0
||
info
.
frame_height
<=
0
||
(
info
.
frame_width
%
2
)
!=
0
||
(
info
.
frame_height
%
2
)
!=
0
)
{
die
(
"Invalid frame size: %dx%d"
,
info
.
frame_width
,
info
.
frame_height
);
}
if
(
!
vpx_img_alloc
(
&
raw
,
VPX_IMG_FMT_I420
,
info
.
frame_width
,
info
.
frame_height
,
1
))
{
die
(
"Failed to allocate image."
);
}
printf
(
"Using %s
\n
"
,
vpx_codec_iface_name
(
encoder
->
interface
()));
res
=
vpx_codec_enc_config_default
(
encoder
->
interface
(),
&
cfg
,
0
);
if
(
res
)
die_codec
(
&
codec
,
"Failed to get default codec config."
);
cfg
.
g_w
=
info
.
frame_width
;
cfg
.
g_h
=
info
.
frame_height
;
cfg
.
g_timebase
.
num
=
info
.
time_base
.
numerator
;
cfg
.
g_timebase
.
den
=
info
.
time_base
.
denominator
;
cfg
.
rc_target_bitrate
=
bitrate
;
writer
=
vpx_video_writer_open
(
argv
[
4
],
kContainerIVF
,
&
info
);
if
(
!
writer
)
die
(
"Failed to open %s for writing."
,
argv
[
4
]);
if
(
!
(
infile
=
fopen
(
argv
[
3
],
"rb"
)))
die
(
"Failed to open %s for reading."
,
argv
[
3
]);
if
(
vpx_codec_enc_init
(
&
codec
,
encoder
->
interface
(),
&
cfg
,
0
))
die_codec
(
&
codec
,
"Failed to initialize encoder"
);
while
(
vpx_img_read
(
&
raw
,
infile
))
{
++
frame_count
;
if
(
frame_count
==
22
)
{
set_roi_map
(
&
cfg
,
&
codec
);
}
else
if
(
frame_count
==
33
)
{
set_active_map
(
&
cfg
,
&
codec
);
}
else
if
(
frame_count
==
44
)
{
unset_active_map
(
&
cfg
,
&
codec
);
}
/* Update the default configuration with our settings */
cfg
.
rc_target_bitrate
=
width
*
height
*
cfg
.
rc_target_bitrate
/
cfg
.
g_w
/
cfg
.
g_h
;
cfg
.
g_w
=
width
;
cfg
.
g_h
=
height
;
write_ivf_file_header
(
outfile
,
&
cfg
,
0
);
/* Open input file for this encoding pass */
if
(
!
(
infile
=
fopen
(
argv
[
3
],
"rb"
)))
die
(
"Failed to open %s for reading"
,
argv
[
3
]);
/* Initialize codec */
if
(
vpx_codec_enc_init
(
&
codec
,
interface
,
&
cfg
,
0
))
die_codec
(
&
codec
,
"Failed to initialize encoder"
);
frame_avail
=
1
;
got_data
=
0
;
while
(
frame_avail
||
got_data
)
{
vpx_codec_iter_t
iter
=
NULL
;
const
vpx_codec_cx_pkt_t
*
pkt
;
if
(
frame_cnt
+
1
==
22
)
{
vpx_roi_map_t
roi
;
unsigned
int
i
;
roi
.
rows
=
cfg
.
g_h
/
16
;
roi
.
cols
=
cfg
.
g_w
/
16
;
roi
.
delta_q
[
0
]
=
0
;
roi
.
delta_q
[
1
]
=
-
2
;
roi
.
delta_q
[
2
]
=
-
4
;
roi
.
delta_q
[
3
]
=
-
6
;
roi
.
delta_lf
[
0
]
=
0
;
roi
.
delta_lf
[
1
]
=
1
;
roi
.
delta_lf
[
2
]
=
2
;
roi
.
delta_lf
[
3
]
=
3
;
roi
.
static_threshold
[
0
]
=
1500
;
roi
.
static_threshold
[
1
]
=
1000
;
roi
.
static_threshold
[
2
]
=
500
;
roi
.
static_threshold
[
3
]
=
0
;
/* generate an ROI map for example */
roi
.
roi_map
=
malloc
(
roi
.
rows
*
roi
.
cols
);
for
(
i
=
0
;
i
<
roi
.
rows
*
roi
.
cols
;
i
++
)
roi
.
roi_map
[
i
]
=
i
&
3
;
if
(
vpx_codec_control
(
&
codec
,
VP8E_SET_ROI_MAP
,
&
roi
))
die_codec
(
&
codec
,
"Failed to set ROI map"
);
free
(
roi
.
roi_map
);
}
else
if
(
frame_cnt
+
1
==
33
)
{
vpx_active_map_t
active
;
unsigned
int
i
;
active
.
rows
=
cfg
.
g_h
/
16
;
active
.
cols
=
cfg
.
g_w
/
16
;
/* generate active map for example */
active
.
active_map
=
malloc
(
active
.
rows
*
active
.
cols
);
for
(
i
=
0
;
i
<
active
.
rows
*
active
.
cols
;
i
++
)
active
.
active_map
[
i
]
=
i
&
1
;
if
(
vpx_codec_control
(
&
codec
,
VP8E_SET_ACTIVEMAP
,
&
active
))
die_codec
(
&
codec
,
"Failed to set active map"
);
free
(
active
.
active_map
);
}
else
if
(
frame_cnt
+
1
==
44
)
{
vpx_active_map_t
active
;
active
.
rows
=
cfg
.
g_h
/
16
;
active
.
cols
=
cfg
.
g_w
/
16
;
/* pass in null map to disable active_map*/
active
.
active_map
=
NULL
;
if
(
vpx_codec_control
(
&
codec
,
VP8E_SET_ACTIVEMAP
,
&
active
))
die_codec
(
&
codec
,
"Failed to set active map"
);
}
frame_avail
=
read_frame
(
infile
,
&
raw
);
if
(
vpx_codec_encode
(
&
codec
,
frame_avail
?
&
raw
:
NULL
,
frame_cnt
,
1
,
flags
,
VPX_DL_REALTIME
))
die_codec
(
&
codec
,
"Failed to encode frame"
);
got_data
=
0
;
while
(
(
pkt
=
vpx_codec_get_cx_data
(
&
codec
,
&
iter
))
)
{
got_data
=
1
;
switch
(
pkt
->
kind
)
{
case
VPX_CODEC_CX_FRAME_PKT
:
write_ivf_frame_header
(
outfile
,
pkt
);
(
void
)
fwrite
(
pkt
->
data
.
frame
.
buf
,
1
,
pkt
->
data
.
frame
.
sz
,
outfile
);
break
;
default:
break
;
}
printf
(
pkt
->
kind
==
VPX_CODEC_CX_FRAME_PKT
&&
(
pkt
->
data
.
frame
.
flags
&
VPX_FRAME_IS_KEY
)
?
"K"
:
"."
);
fflush
(
stdout
);
}
frame_cnt
++
;
}
printf
(
"
\n
"
);
fclose
(
infile
);
printf
(
"Processed %d frames.
\n
"
,
frame_cnt
-
1
);
vpx_img_free
(
&
raw
);
if
(
vpx_codec_destroy
(
&
codec
))
die_codec
(
&
codec
,
"Failed to destroy codec"
);
/* Try to rewrite the file header with the actual frame count */
if
(
!
fseek
(
outfile
,
0
,
SEEK_SET
))
write_ivf_file_header
(
outfile
,
&
cfg
,
frame_cnt
-
1
);
fclose
(
outfile
);
return
EXIT_SUCCESS
;
encode_frame
(
&
codec
,
&
raw
,
frame_count
,
writer
);
}
encode_frame
(
&
codec
,
NULL
,
-
1
,
writer
);
printf
(
"
\n
"
);
fclose
(
infile
);
printf
(
"Processed %d frames.
\n
"
,
frame_count
);
vpx_img_free
(
&
raw
);
if
(
vpx_codec_destroy
(
&
codec
))
die_codec
(
&
codec
,
"Failed to destroy codec."
);
vpx_video_writer_close
(
writer
);
return
EXIT_SUCCESS
;
}
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