mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
Merge branch 'options'
This commit is contained in:
commit
903484387f
42
README.md
42
README.md
|
@ -14,16 +14,38 @@ meant to be user configurable later.
|
||||||
Usage:
|
Usage:
|
||||||
hevc_encoder -i <input> -w <width> -h <height> -o <output>
|
hevc_encoder -i <input> -w <width> -h <height> -o <output>
|
||||||
Optional parameters:
|
Optional parameters:
|
||||||
-n, --frames <integer> : number of frames to code [all]
|
-n, --frames <integer> : number of frames to code [all]
|
||||||
-q, --qp <integer> : Quantization Parameter [32]
|
-q, --qp <integer> : Quantization Parameter [32]
|
||||||
-p, --period <integer> : Period of intra pictures [0]
|
-p, --period <integer> : Period of intra pictures [0]
|
||||||
0: only first picture is intra
|
0: only first picture is intra
|
||||||
1: all pictures are intra
|
1: all pictures are intra
|
||||||
2-N: every Nth picture is intra
|
2-N: every Nth picture is intra
|
||||||
--no-deblock : Disable deblocking filter
|
--no-deblock : Disable deblocking filter
|
||||||
--deblock <beta:tc> : Deblocking filter parameters
|
--deblock <beta:tc> : Deblocking filter parameters
|
||||||
beta and tc range is -6..6 [0:0]
|
beta and tc range is -6..6 [0:0]
|
||||||
--no-sao : Disable sample adaptive offset
|
--no-sao : Disable sample adaptive offset
|
||||||
|
--aud : Use access unit delimiters
|
||||||
|
|
||||||
|
Video Usability Information:
|
||||||
|
--sar <width:height> : Specify Sample Aspect Ratio
|
||||||
|
--overscan <string> : Specify crop overscan setting ["undef"]
|
||||||
|
- undef, show, crop
|
||||||
|
--videoformat <string> : Specify video format ["undef"]
|
||||||
|
- component, pal, ntsc, secam, mac, undef
|
||||||
|
--range <string> : Specify color range ["off"]
|
||||||
|
- off, on
|
||||||
|
--colorprim <string> : Specify color primaries ["undef"]
|
||||||
|
- undef, bt709, bt470m, bt470bg,
|
||||||
|
smpte170m, smpte240m, film, bt2020
|
||||||
|
--transfer <string> : Specify transfer characteristics ["undef"]
|
||||||
|
- undef, bt709, bt470m, bt470bg,
|
||||||
|
smpte170m, smpte240m, linear, log100,
|
||||||
|
log316, iec61966-2-4, bt1361e,
|
||||||
|
iec61966-2-1, bt2020-10, bt2020-12
|
||||||
|
--colormatrix <string> : Specify color matrix setting ["undef"]
|
||||||
|
- undef, bt709, fcc, bt470bg, smpte170m,
|
||||||
|
smpte240m, GBR, YCgCo, bt2020nc, bt2020c
|
||||||
|
--chromaloc <integer> : Specify chroma sample location (0 to 5) [0]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
100
src/config.c
100
src/config.c
|
@ -52,18 +52,28 @@ config *config_alloc()
|
||||||
*/
|
*/
|
||||||
int config_init(config *cfg)
|
int config_init(config *cfg)
|
||||||
{
|
{
|
||||||
cfg->input = NULL;
|
cfg->input = NULL;
|
||||||
cfg->output = NULL;
|
cfg->output = NULL;
|
||||||
cfg->debug = NULL;
|
cfg->debug = NULL;
|
||||||
cfg->frames = 0;
|
cfg->frames = 0;
|
||||||
cfg->width = 320;
|
cfg->width = 320;
|
||||||
cfg->height = 240;
|
cfg->height = 240;
|
||||||
cfg->qp = 32;
|
cfg->qp = 32;
|
||||||
cfg->intra_period = 0;
|
cfg->intra_period = 0;
|
||||||
cfg->deblock_enable = 1;
|
cfg->deblock_enable = 1;
|
||||||
cfg->deblock_beta = 0;
|
cfg->deblock_beta = 0;
|
||||||
cfg->deblock_tc = 0;
|
cfg->deblock_tc = 0;
|
||||||
cfg->sao_enable = 1;
|
cfg->sao_enable = 1;
|
||||||
|
cfg->vui.sar_width = 0;
|
||||||
|
cfg->vui.sar_height = 0;
|
||||||
|
cfg->vui.overscan = 0; /* undef */
|
||||||
|
cfg->vui.videoformat = 5; /* undef */
|
||||||
|
cfg->vui.fullrange = 0; /* limited range */
|
||||||
|
cfg->vui.colorprim = 2; /* undef */
|
||||||
|
cfg->vui.transfer = 2; /* undef */
|
||||||
|
cfg->vui.colormatrix = 2; /* undef */
|
||||||
|
cfg->vui.chroma_loc = 0; /* left center */
|
||||||
|
cfg->aud_enable = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -115,9 +125,33 @@ static int atobool(const char *str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int config_parse(config *cfg, const char *name, const char *value)
|
static int parse_enum(const char *arg, const char * const *names, int8_t *dst)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
for (i = 0; names[i]; i++)
|
||||||
|
if (!strcmp(arg, names[i])) {
|
||||||
|
*dst = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_parse(config *cfg, const char *name, const char *value)
|
||||||
|
{
|
||||||
|
static const char * const overscan_names[] = { "undef", "show", "crop", NULL };
|
||||||
|
static const char * const videoformat_names[] = { "component", "pal", "ntsc", "secam", "mac", "undef", NULL };
|
||||||
|
static const char * const fullrange_names[] = { "off", "on", NULL };
|
||||||
|
static const char * const colorprim_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m",
|
||||||
|
"smpte240m", "film", "bt2020", NULL };
|
||||||
|
static const char * const transfer_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m",
|
||||||
|
"smpte240m", "linear", "log100", "log316", "iec61966-2-4",
|
||||||
|
"bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", NULL };
|
||||||
|
static const char * const colormatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m",
|
||||||
|
"smpte240m", "YCgCo", "bt2020nc", "bt2020c", NULL };
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -171,11 +205,40 @@ static int config_parse(config *cfg, const char *name, const char *value)
|
||||||
}
|
}
|
||||||
OPT("sao")
|
OPT("sao")
|
||||||
cfg->sao_enable = atobool(value);
|
cfg->sao_enable = atobool(value);
|
||||||
|
OPT("sar") {
|
||||||
|
int sar_width, sar_height;
|
||||||
|
if (2 == sscanf(value, "%d:%d", &sar_width, &sar_height)) {
|
||||||
|
cfg->vui.sar_width = sar_width;
|
||||||
|
cfg->vui.sar_height = sar_height;
|
||||||
|
} else
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
OPT("overscan")
|
||||||
|
error = !parse_enum(value, overscan_names, &cfg->vui.overscan);
|
||||||
|
OPT("videoformat")
|
||||||
|
error = !parse_enum(value, videoformat_names, &cfg->vui.videoformat);
|
||||||
|
OPT("fullrange")
|
||||||
|
error = !parse_enum(value, fullrange_names, &cfg->vui.fullrange);
|
||||||
|
OPT("colorprim")
|
||||||
|
error = !parse_enum(value, colorprim_names, &cfg->vui.colorprim);
|
||||||
|
OPT("transfer")
|
||||||
|
error = !parse_enum(value, transfer_names, &cfg->vui.transfer);
|
||||||
|
OPT("colormatrix")
|
||||||
|
error = !parse_enum(value, colormatrix_names, &cfg->vui.colormatrix);
|
||||||
|
OPT("chromaloc") {
|
||||||
|
cfg->vui.chroma_loc = atoi(value);
|
||||||
|
if (cfg->vui.chroma_loc < 0 || cfg->vui.chroma_loc > 5) {
|
||||||
|
fprintf(stderr, "--chromaloc parameter out of range [0..5], set to 0\n");
|
||||||
|
cfg->vui.chroma_loc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OPT("aud")
|
||||||
|
cfg->aud_enable = atobool(value);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
#undef OPT
|
#undef OPT
|
||||||
|
|
||||||
return 1;
|
return error ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -205,6 +268,15 @@ int config_read(config *cfg,int argc, char *argv[])
|
||||||
{ "no-deblock", no_argument, NULL, 0 },
|
{ "no-deblock", no_argument, NULL, 0 },
|
||||||
{ "deblock", required_argument, NULL, 0 },
|
{ "deblock", required_argument, NULL, 0 },
|
||||||
{ "no-sao", no_argument, NULL, 0 },
|
{ "no-sao", no_argument, NULL, 0 },
|
||||||
|
{ "sar", required_argument, NULL, 0 },
|
||||||
|
{ "overscan", required_argument, NULL, 0 },
|
||||||
|
{ "videoformat", required_argument, NULL, 0 },
|
||||||
|
{ "range", required_argument, NULL, 0 },
|
||||||
|
{ "colorprim", required_argument, NULL, 0 },
|
||||||
|
{ "transfer", required_argument, NULL, 0 },
|
||||||
|
{ "colormatrix", required_argument, NULL, 0 },
|
||||||
|
{ "chromaloc", required_argument, NULL, 0 },
|
||||||
|
{ "aud", no_argument, NULL, 0 },
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
src/config.h
13
src/config.h
|
@ -45,6 +45,19 @@ typedef struct
|
||||||
int8_t sao_enable; /*!< \brief Flag to enable sample adaptive offset filter */
|
int8_t sao_enable; /*!< \brief Flag to enable sample adaptive offset filter */
|
||||||
int8_t deblock_beta; /*!< \brief (deblocking) beta offset (div 2), range -6...6 */
|
int8_t deblock_beta; /*!< \brief (deblocking) beta offset (div 2), range -6...6 */
|
||||||
int8_t deblock_tc; /*!< \brief (deblocking) tc offset (div 2), range -6...6 */
|
int8_t deblock_tc; /*!< \brief (deblocking) tc offset (div 2), range -6...6 */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int16_t sar_width; /*!< \brief the horizontal size of the sample aspect ratio (in arbitrary units) */
|
||||||
|
int16_t sar_height; /*!< \brief the vertical size of the sample aspect ratio (in the same arbitrary units as sar_width). */
|
||||||
|
int8_t overscan; /*!< \brief Crop overscan setting */
|
||||||
|
int8_t videoformat; /*!< \brief Video format */
|
||||||
|
int8_t fullrange; /*!< \brief Flag to indicate full-range */
|
||||||
|
int8_t colorprim; /*!< \brief Color primaries */
|
||||||
|
int8_t transfer; /*!< \brief Transfer characteristics */
|
||||||
|
int8_t colormatrix; /*!< \brief Color matrix coefficients */
|
||||||
|
int8_t chroma_loc; /*!< \brief Chroma sample location */
|
||||||
|
} vui;
|
||||||
|
int8_t aud_enable; /*!< \brief Flag to use access unit delimiters */
|
||||||
} config;
|
} config;
|
||||||
|
|
||||||
/* Function definitions */
|
/* Function definitions */
|
||||||
|
|
|
@ -82,24 +82,47 @@ int main(int argc, char *argv[])
|
||||||
if (!cfg || !config_init(cfg) || !config_read(cfg,argc,argv)) {
|
if (!cfg || !config_init(cfg) || !config_read(cfg,argc,argv)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"/***********************************************/\n"
|
"/***********************************************/\n"
|
||||||
" * Kvazaar HEVC Encoder v. " VERSION_STRING "*\n"
|
" * Kvazaar HEVC Encoder v. " VERSION_STRING " *\n"
|
||||||
" * Tampere University of Technology 2014 *\n"
|
" * Tampere University of Technology 2014 *\n"
|
||||||
"/***********************************************/\n\n");
|
"/***********************************************/\n\n");
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
"hevc_encoder -i <input> -w <width> -h <height> -o <output>\n"
|
"hevc_encoder -i <input> -w <width> -h <height> -o <output>\n"
|
||||||
|
"\n"
|
||||||
"Optional parameters:\n"
|
"Optional parameters:\n"
|
||||||
" -n, --frames <integer> : number of frames to code [all]\n"
|
" -n, --frames <integer> : number of frames to code [all]\n"
|
||||||
" -q, --qp <integer> : Quantization Parameter [32]\n"
|
" -q, --qp <integer> : Quantization Parameter [32]\n"
|
||||||
" -p, --period <integer> : Period of intra pictures [0]\n"
|
" -p, --period <integer> : Period of intra pictures [0]\n"
|
||||||
" 0: only first picture is intra\n"
|
" 0: only first picture is intra\n"
|
||||||
" 1: all pictures are intra\n"
|
" 1: all pictures are intra\n"
|
||||||
" 2-N: every Nth picture is intra\n"
|
" 2-N: every Nth picture is intra\n"
|
||||||
" --no-deblock : Disable deblocking filter\n"
|
" --no-deblock : Disable deblocking filter\n"
|
||||||
" --deblock <beta:tc> : Deblocking filter parameters\n"
|
" --deblock <beta:tc> : Deblocking filter parameters\n"
|
||||||
" beta and tc range is -6..6 [0:0]\n"
|
" beta and tc range is -6..6 [0:0]\n"
|
||||||
" --no-sao : Disable sample adaptive offset\n");
|
" --no-sao : Disable sample adaptive offset\n"
|
||||||
|
" --aud : Use access unit delimiters\n"
|
||||||
|
"\n"
|
||||||
|
" Video Usability Information:\n"
|
||||||
|
" --sar <width:height> : Specify Sample Aspect Ratio\n"
|
||||||
|
" --overscan <string> : Specify crop overscan setting [\"undef\"]\n"
|
||||||
|
" - undef, show, crop\n"
|
||||||
|
" --videoformat <string> : Specify video format [\"undef\"]\n"
|
||||||
|
" - component, pal, ntsc, secam, mac, undef\n"
|
||||||
|
" --range <string> : Specify color range [\"off\"]\n"
|
||||||
|
" - off, on\n"
|
||||||
|
" --colorprim <string> : Specify color primaries [\"undef\"]\n"
|
||||||
|
" - undef, bt709, bt470m, bt470bg,\n"
|
||||||
|
" smpte170m, smpte240m, film, bt2020\n"
|
||||||
|
" --transfer <string> : Specify transfer characteristics [\"undef\"]\n"
|
||||||
|
" - undef, bt709, bt470m, bt470bg,\n"
|
||||||
|
" smpte170m, smpte240m, linear, log100,\n"
|
||||||
|
" log316, iec61966-2-4, bt1361e,\n"
|
||||||
|
" iec61966-2-1, bt2020-10, bt2020-12\n"
|
||||||
|
" --colormatrix <string> : Specify color matrix setting [\"undef\"]\n"
|
||||||
|
" - undef, bt709, fcc, bt470bg, smpte170m,\n"
|
||||||
|
" smpte240m, GBR, YCgCo, bt2020nc, bt2020c\n"
|
||||||
|
" --chromaloc <integer> : Specify chroma sample location (0 to 5) [0]\n");
|
||||||
|
|
||||||
if (cfg)
|
if (cfg)
|
||||||
config_destroy(cfg);
|
config_destroy(cfg);
|
||||||
|
@ -167,6 +190,18 @@ int main(int argc, char *argv[])
|
||||||
encoder->tc_offset_div2 = encoder->cfg->deblock_tc;
|
encoder->tc_offset_div2 = encoder->cfg->deblock_tc;
|
||||||
// SAO
|
// SAO
|
||||||
encoder->sao_enable = encoder->cfg->sao_enable;
|
encoder->sao_enable = encoder->cfg->sao_enable;
|
||||||
|
// VUI
|
||||||
|
encoder->vui.sar_width = encoder->cfg->vui.sar_width;
|
||||||
|
encoder->vui.sar_height = encoder->cfg->vui.sar_height;
|
||||||
|
encoder->vui.overscan = encoder->cfg->vui.overscan;
|
||||||
|
encoder->vui.videoformat = encoder->cfg->vui.videoformat;
|
||||||
|
encoder->vui.fullrange = encoder->cfg->vui.fullrange;
|
||||||
|
encoder->vui.colorprim = encoder->cfg->vui.colorprim;
|
||||||
|
encoder->vui.transfer = encoder->cfg->vui.transfer;
|
||||||
|
encoder->vui.colormatrix = encoder->cfg->vui.colormatrix;
|
||||||
|
encoder->vui.chroma_loc = encoder->cfg->vui.chroma_loc;
|
||||||
|
// AUD
|
||||||
|
encoder->aud_enable = encoder->cfg->aud_enable;
|
||||||
|
|
||||||
init_encoder_input(&encoder->in, input, cfg->width, cfg->height);
|
init_encoder_input(&encoder->in, input, cfg->width, cfg->height);
|
||||||
|
|
||||||
|
|
164
src/encoder.c
164
src/encoder.c
|
@ -47,6 +47,7 @@ uint32_t* g_sig_last_scan[3][7];
|
||||||
|
|
||||||
/* Local functions. */
|
/* Local functions. */
|
||||||
static void add_checksum(encoder_control* encoder);
|
static void add_checksum(encoder_control* encoder);
|
||||||
|
static void encode_VUI(encoder_control* encoder);
|
||||||
|
|
||||||
void init_sig_last_scan(uint32_t *buff_d, uint32_t *buff_h, uint32_t *buff_v,
|
void init_sig_last_scan(uint32_t *buff_d, uint32_t *buff_h, uint32_t *buff_v,
|
||||||
int32_t width, int32_t height)
|
int32_t width, int32_t height)
|
||||||
|
@ -366,7 +367,17 @@ void init_encoder_input(encoder_input *input, FILE *inputfile,
|
||||||
input->height);
|
input->height);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_aud(encoder_control* encoder)
|
||||||
|
{
|
||||||
|
encode_access_unit_delimiter(encoder);
|
||||||
|
bitstream_align(encoder->stream);
|
||||||
|
bitstream_flush(encoder->stream);
|
||||||
|
nal_write(encoder->output, encoder->stream->buffer,
|
||||||
|
encoder->stream->buffer_pos, 0, AUD_NUT, 0, 1);
|
||||||
|
bitstream_clear_buffer(encoder->stream);
|
||||||
|
}
|
||||||
|
|
||||||
void encode_one_frame(encoder_control* encoder)
|
void encode_one_frame(encoder_control* encoder)
|
||||||
{
|
{
|
||||||
|
@ -383,6 +394,13 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
(encoder->cfg->intra_period != 1 || encoder->frame % 2 == 0 ) ) ) {
|
(encoder->cfg->intra_period != 1 || encoder->frame % 2 == 0 ) ) ) {
|
||||||
encoder->poc = 0;
|
encoder->poc = 0;
|
||||||
|
|
||||||
|
encoder->in.cur_pic->slicetype = SLICE_I;
|
||||||
|
encoder->in.cur_pic->type = NAL_IDR_W_RADL;
|
||||||
|
|
||||||
|
// Access Unit Delimiter (AUD)
|
||||||
|
if (encoder->aud_enable)
|
||||||
|
write_aud(encoder);
|
||||||
|
|
||||||
// Video Parameter Set (VPS)
|
// Video Parameter Set (VPS)
|
||||||
encode_vid_parameter_set(encoder);
|
encode_vid_parameter_set(encoder);
|
||||||
bitstream_align(encoder->stream);
|
bitstream_align(encoder->stream);
|
||||||
|
@ -407,10 +425,17 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
encoder->stream->buffer_pos, 0, NAL_PPS_NUT, 0, 1);
|
encoder->stream->buffer_pos, 0, NAL_PPS_NUT, 0, 1);
|
||||||
bitstream_clear_buffer(encoder->stream);
|
bitstream_clear_buffer(encoder->stream);
|
||||||
|
|
||||||
|
if (encoder->frame == 0) {
|
||||||
|
encode_prefix_sei_version(encoder);
|
||||||
|
bitstream_align(encoder->stream);
|
||||||
|
bitstream_flush(encoder->stream);
|
||||||
|
nal_write(encoder->output, encoder->stream->buffer,
|
||||||
|
encoder->stream->buffer_pos, 0, PREFIX_SEI_NUT, 0, 0);
|
||||||
|
bitstream_clear_buffer(encoder->stream);
|
||||||
|
}
|
||||||
|
|
||||||
// First slice is IDR
|
// First slice is IDR
|
||||||
cabac_start(&cabac);
|
cabac_start(&cabac);
|
||||||
encoder->in.cur_pic->slicetype = SLICE_I;
|
|
||||||
encoder->in.cur_pic->type = NAL_IDR_W_RADL;
|
|
||||||
scalinglist_process();
|
scalinglist_process();
|
||||||
search_slice_data(encoder);
|
search_slice_data(encoder);
|
||||||
|
|
||||||
|
@ -424,10 +449,15 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
encoder->stream->buffer_pos, 0, NAL_IDR_W_RADL, 0, 0);
|
encoder->stream->buffer_pos, 0, NAL_IDR_W_RADL, 0, 0);
|
||||||
bitstream_clear_buffer(encoder->stream);
|
bitstream_clear_buffer(encoder->stream);
|
||||||
} else {
|
} else {
|
||||||
cabac_start(&cabac);
|
|
||||||
// When intra period == 1, all pictures are intra
|
// When intra period == 1, all pictures are intra
|
||||||
encoder->in.cur_pic->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P;
|
encoder->in.cur_pic->slicetype = encoder->cfg->intra_period==1 ? SLICE_I : SLICE_P;
|
||||||
encoder->in.cur_pic->type = NAL_TRAIL_R;
|
encoder->in.cur_pic->type = NAL_TRAIL_R;
|
||||||
|
|
||||||
|
// Access Unit Delimiter (AUD)
|
||||||
|
if (encoder->aud_enable)
|
||||||
|
write_aud(encoder);
|
||||||
|
|
||||||
|
cabac_start(&cabac);
|
||||||
scalinglist_process();
|
scalinglist_process();
|
||||||
search_slice_data(encoder);
|
search_slice_data(encoder);
|
||||||
|
|
||||||
|
@ -438,7 +468,7 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
bitstream_align(encoder->stream);
|
bitstream_align(encoder->stream);
|
||||||
bitstream_flush(encoder->stream);
|
bitstream_flush(encoder->stream);
|
||||||
nal_write(encoder->output, encoder->stream->buffer,
|
nal_write(encoder->output, encoder->stream->buffer,
|
||||||
encoder->stream->buffer_pos, 0, NAL_TRAIL_R, 0, 1);
|
encoder->stream->buffer_pos, 0, NAL_TRAIL_R, 0, encoder->aud_enable ? 0 : 1);
|
||||||
bitstream_clear_buffer(encoder->stream);
|
bitstream_clear_buffer(encoder->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +587,60 @@ static void add_checksum(encoder_control* encoder)
|
||||||
bitstream_clear_buffer(encoder->stream);
|
bitstream_clear_buffer(encoder->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void encode_access_unit_delimiter(encoder_control* encoder)
|
||||||
|
{
|
||||||
|
uint8_t pic_type = encoder->in.cur_pic->slicetype == SLICE_I ? 0
|
||||||
|
: encoder->in.cur_pic->slicetype == SLICE_P ? 1
|
||||||
|
: 2;
|
||||||
|
WRITE_U(encoder->stream, pic_type, 3, "pic_type");
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode_prefix_sei_version(encoder_control* encoder)
|
||||||
|
{
|
||||||
|
#define STR_BUF_LEN 1000
|
||||||
|
|
||||||
|
int i, length;
|
||||||
|
char buf[STR_BUF_LEN] = { 0 };
|
||||||
|
char *s = buf + 16;
|
||||||
|
config *cfg = encoder->cfg;
|
||||||
|
|
||||||
|
// random uuid_iso_iec_11578 generated with www.famkruithof.net/uuid/uuidgen
|
||||||
|
static const uint8_t uuid[16] = {
|
||||||
|
0x32, 0xfe, 0x46, 0x6c, 0x98, 0x41, 0x42, 0x69,
|
||||||
|
0xae, 0x35, 0x6a, 0x91, 0x54, 0x9e, 0xf3, 0xf1
|
||||||
|
};
|
||||||
|
memcpy(buf, uuid, 16);
|
||||||
|
|
||||||
|
// user_data_payload_byte
|
||||||
|
s += sprintf(s, "Kvazaar HEVC Encoder v. " VERSION_STRING " - "
|
||||||
|
"Copyleft 2012-2014 - http://ultravideo.cs.tut.fi/ - options:");
|
||||||
|
s += sprintf(s, " %dx%d", cfg->width, cfg->height);
|
||||||
|
s += sprintf(s, " deblock=%d:%d:%d", cfg->deblock_enable,
|
||||||
|
cfg->deblock_beta, cfg->deblock_tc);
|
||||||
|
s += sprintf(s, " sao=%d", cfg->sao_enable);
|
||||||
|
s += sprintf(s, " intra_period=%d", cfg->intra_period);
|
||||||
|
s += sprintf(s, " qp=%d", cfg->qp);
|
||||||
|
|
||||||
|
length = (int)(s - buf + 1); // length, +1 for \0
|
||||||
|
|
||||||
|
// Assert this so that in the future if the message gets longer, we remember
|
||||||
|
// to increase the buf len. Divide by 2 for margin.
|
||||||
|
assert(length < STR_BUF_LEN / 2);
|
||||||
|
|
||||||
|
// payloadType = 5 -> user_data_unregistered
|
||||||
|
WRITE_U(encoder->stream, 5, 8, "last_payload_type_byte");
|
||||||
|
|
||||||
|
// payloadSize
|
||||||
|
for (i = 0; i <= length - 255; i += 255)
|
||||||
|
WRITE_U(encoder->stream, 255, 8, "ff_byte");
|
||||||
|
WRITE_U(encoder->stream, length - i, 8, "last_payload_size_byte");
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
WRITE_U(encoder->stream, ((uint8_t *)buf)[i], 8, "sei_payload");
|
||||||
|
|
||||||
|
#undef STR_BUF_LEN
|
||||||
|
}
|
||||||
|
|
||||||
void encode_pic_parameter_set(encoder_control* encoder)
|
void encode_pic_parameter_set(encoder_control* encoder)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -751,10 +835,9 @@ void encode_seq_parameter_set(encoder_control* encoder)
|
||||||
WRITE_U(encoder->stream, ENABLE_TEMPORAL_MVP, 1,
|
WRITE_U(encoder->stream, ENABLE_TEMPORAL_MVP, 1,
|
||||||
"sps_temporal_mvp_enable_flag");
|
"sps_temporal_mvp_enable_flag");
|
||||||
WRITE_U(encoder->stream, 0, 1, "sps_strong_intra_smoothing_enable_flag");
|
WRITE_U(encoder->stream, 0, 1, "sps_strong_intra_smoothing_enable_flag");
|
||||||
WRITE_U(encoder->stream, 0, 1, "vui_parameters_present_flag");
|
WRITE_U(encoder->stream, 1, 1, "vui_parameters_present_flag");
|
||||||
|
|
||||||
//TODO: VUI?
|
encode_VUI(encoder);
|
||||||
//encode_VUI(encoder);
|
|
||||||
|
|
||||||
WRITE_U(encoder->stream, 0, 1, "sps_extension_flag");
|
WRITE_U(encoder->stream, 0, 1, "sps_extension_flag");
|
||||||
}
|
}
|
||||||
|
@ -794,27 +877,82 @@ void encode_vid_parameter_set(encoder_control* encoder)
|
||||||
WRITE_U(encoder->stream, 0, 1, "vps_extension_flag");
|
WRITE_U(encoder->stream, 0, 1, "vps_extension_flag");
|
||||||
}
|
}
|
||||||
|
|
||||||
void encode_VUI(encoder_control* encoder)
|
static void encode_VUI(encoder_control* encoder)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
printf("=========== VUI Set ID: 0 ===========\n");
|
printf("=========== VUI Set ID: 0 ===========\n");
|
||||||
#endif
|
#endif
|
||||||
WRITE_U(encoder->stream, 0, 1, "aspect_ratio_info_present_flag");
|
if (encoder->vui.sar_width > 0 && encoder->vui.sar_height > 0) {
|
||||||
|
int i;
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
uint8_t width;
|
||||||
|
uint8_t height;
|
||||||
|
uint8_t idc;
|
||||||
|
} sar[] = {
|
||||||
|
// aspect_ratio_idc = 0 -> unspecified
|
||||||
|
{ 1, 1, 1 }, { 12, 11, 2 }, { 10, 11, 3 }, { 16, 11, 4 },
|
||||||
|
{ 40, 33, 5 }, { 24, 11, 6 }, { 20, 11, 7 }, { 32, 11, 8 },
|
||||||
|
{ 80, 33, 9 }, { 18, 11, 10}, { 15, 11, 11}, { 64, 33, 12},
|
||||||
|
{160, 99, 13}, { 4, 3, 14}, { 3, 2, 15}, { 2, 1, 16},
|
||||||
|
// aspect_ratio_idc = [17..254] -> reserved
|
||||||
|
{ 0, 0, 255 }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; sar[i].idc != 255; i++)
|
||||||
|
if (sar[i].width == encoder->vui.sar_width &&
|
||||||
|
sar[i].height == encoder->vui.sar_height)
|
||||||
|
break;
|
||||||
|
|
||||||
|
WRITE_U(encoder->stream, 1, 1, "aspect_ratio_info_present_flag");
|
||||||
|
WRITE_U(encoder->stream, sar[i].idc, 8, "aspect_ratio_idc");
|
||||||
|
if (sar[i].idc == 255) {
|
||||||
|
// EXTENDED_SAR
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.sar_width, 16, "sar_width");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.sar_height, 16, "sar_height");
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
WRITE_U(encoder->stream, 0, 1, "aspect_ratio_info_present_flag");
|
||||||
|
|
||||||
//IF aspect ratio info
|
//IF aspect ratio info
|
||||||
//ENDIF
|
//ENDIF
|
||||||
|
|
||||||
WRITE_U(encoder->stream, 0, 1, "overscan_info_present_flag");
|
if (encoder->vui.overscan > 0) {
|
||||||
|
WRITE_U(encoder->stream, 1, 1, "overscan_info_present_flag");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.overscan - 1, 1, "overscan_appropriate_flag");
|
||||||
|
} else
|
||||||
|
WRITE_U(encoder->stream, 0, 1, "overscan_info_present_flag");
|
||||||
|
|
||||||
//IF overscan info
|
//IF overscan info
|
||||||
//ENDIF
|
//ENDIF
|
||||||
|
|
||||||
WRITE_U(encoder->stream, 0, 1, "video_signal_type_present_flag");
|
if (encoder->vui.videoformat != 5 || encoder->vui.fullrange ||
|
||||||
|
encoder->vui.colorprim != 2 || encoder->vui.transfer != 2 ||
|
||||||
|
encoder->vui.colormatrix != 2) {
|
||||||
|
WRITE_U(encoder->stream, 1, 1, "video_signal_type_present_flag");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.videoformat, 3, "video_format");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.fullrange, 1, "video_full_range_flag");
|
||||||
|
|
||||||
|
if (encoder->vui.colorprim != 2 || encoder->vui.transfer != 2 ||
|
||||||
|
encoder->vui.colormatrix != 2) {
|
||||||
|
WRITE_U(encoder->stream, 1, 1, "colour_description_present_flag");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.colorprim, 8, "colour_primaries");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.transfer, 8, "transfer_characteristics");
|
||||||
|
WRITE_U(encoder->stream, encoder->vui.colormatrix, 8, "matrix_coeffs");
|
||||||
|
} else
|
||||||
|
WRITE_U(encoder->stream, 0, 1, "colour_description_present_flag");
|
||||||
|
} else
|
||||||
|
WRITE_U(encoder->stream, 0, 1, "video_signal_type_present_flag");
|
||||||
|
|
||||||
//IF video type
|
//IF video type
|
||||||
//ENDIF
|
//ENDIF
|
||||||
|
|
||||||
WRITE_U(encoder->stream, 0, 1, "chroma_loc_info_present_flag");
|
if (encoder->vui.chroma_loc > 0) {
|
||||||
|
WRITE_U(encoder->stream, 1, 1, "chroma_loc_info_present_flag");
|
||||||
|
WRITE_UE(encoder->stream, encoder->vui.chroma_loc, "chroma_sample_loc_type_top_field");
|
||||||
|
WRITE_UE(encoder->stream, encoder->vui.chroma_loc, "chroma_sample_loc_type_bottom_field");
|
||||||
|
} else
|
||||||
|
WRITE_U(encoder->stream, 0, 1, "chroma_loc_info_present_flag");
|
||||||
|
|
||||||
//IF chroma loc info
|
//IF chroma loc info
|
||||||
//ENDIF
|
//ENDIF
|
||||||
|
|
|
@ -78,6 +78,22 @@ typedef struct
|
||||||
int8_t sao_enable; // \brief Flag to enable sample adaptive offset filter
|
int8_t sao_enable; // \brief Flag to enable sample adaptive offset filter
|
||||||
int8_t beta_offset_div2; // \brief (deblocking) beta offset (div 2), range -6...6
|
int8_t beta_offset_div2; // \brief (deblocking) beta offset (div 2), range -6...6
|
||||||
int8_t tc_offset_div2; // \brief (deblocking)tc offset (div 2), range -6...6
|
int8_t tc_offset_div2; // \brief (deblocking)tc offset (div 2), range -6...6
|
||||||
|
|
||||||
|
/* VUI */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int16_t sar_width;
|
||||||
|
int16_t sar_height;
|
||||||
|
int8_t overscan;
|
||||||
|
int8_t videoformat;
|
||||||
|
int8_t fullrange;
|
||||||
|
int8_t colorprim;
|
||||||
|
int8_t transfer;
|
||||||
|
int8_t colormatrix;
|
||||||
|
int8_t chroma_loc;
|
||||||
|
} vui;
|
||||||
|
|
||||||
|
int8_t aud_enable;
|
||||||
} encoder_control;
|
} encoder_control;
|
||||||
|
|
||||||
void init_tables(void);
|
void init_tables(void);
|
||||||
|
@ -94,6 +110,8 @@ void encode_pic_parameter_set(encoder_control *encoder);
|
||||||
void encode_vid_parameter_set(encoder_control *encoder);
|
void encode_vid_parameter_set(encoder_control *encoder);
|
||||||
void encode_slice_data(encoder_control *encoder);
|
void encode_slice_data(encoder_control *encoder);
|
||||||
void encode_slice_header(encoder_control *encoder);
|
void encode_slice_header(encoder_control *encoder);
|
||||||
|
void encode_access_unit_delimiter(encoder_control* encoder);
|
||||||
|
void encode_prefix_sei_version(encoder_control* encoder);
|
||||||
void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb,
|
void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb,
|
||||||
uint16_t y_ctb, uint8_t depth);
|
uint16_t y_ctb, uint8_t depth);
|
||||||
void encode_last_significant_xy(encoder_control *encoder, uint8_t lastpos_x,
|
void encode_last_significant_xy(encoder_control *encoder, uint8_t lastpos_x,
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
/*
|
/*
|
||||||
* \file
|
* \file
|
||||||
* \brief Header that is included in every other header.
|
* \brief Header that is included in every other header.
|
||||||
´*
|
*
|
||||||
* This file contains global constants that can be referred to from any header
|
* This file contains global constants that can be referred to from any header
|
||||||
* or source file. It also contains some helper macros and includes stdint.h
|
* or source file. It also contains some helper macros and includes stdint.h
|
||||||
* so that any file can refer to integer types with exact widths.
|
* so that any file can refer to integer types with exact widths.
|
||||||
|
@ -109,7 +109,7 @@ typedef int16_t coefficient;
|
||||||
//#define SIGN3(x) ((x) > 0) ? +1 : ((x) == 0 ? 0 : -1)
|
//#define SIGN3(x) ((x) > 0) ? +1 : ((x) == 0 ? 0 : -1)
|
||||||
#define SIGN3(x) (((x) > 0) - ((x) < 0))
|
#define SIGN3(x) (((x) > 0) - ((x) < 0))
|
||||||
|
|
||||||
#define VERSION_STRING "0.2.3 "
|
#define VERSION_STRING "0.2.3"
|
||||||
#define VERSION 0.2
|
#define VERSION 0.2
|
||||||
|
|
||||||
//#define VERBOSE 1
|
//#define VERBOSE 1
|
||||||
|
|
Loading…
Reference in a new issue