Write flags and SEI messages for interlacing.

This commit is contained in:
Ari Lemmetti 2015-04-08 17:17:45 +03:00
parent fc038cb8bf
commit 581ff95412
3 changed files with 95 additions and 3 deletions

View file

@ -155,6 +155,8 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failed to seek %d frames.\n", opts->seek); fprintf(stderr, "Failed to seek %d frames.\n", opts->seek);
goto exit_failure; goto exit_failure;
} }
encoder->vui.field_seq_flag = encoder->cfg->source_scan_type != 0;
encoder->vui.frame_field_info_present_flag = encoder->cfg->source_scan_type != 0;
//Now, do the real stuff //Now, do the real stuff
{ {

View file

@ -92,6 +92,9 @@ typedef struct encoder_control_t
int8_t transfer; int8_t transfer;
int8_t colormatrix; int8_t colormatrix;
int8_t chroma_loc; int8_t chroma_loc;
int8_t field_seq_flag;
int8_t frame_field_info_present_flag;
} vui; } vui;
int8_t aud_enable; int8_t aud_enable;

View file

@ -63,7 +63,7 @@ static void encoder_state_write_bitstream_PTL(encoder_state_t * const state)
WRITE_U(stream, 3<<29, 32, "general_profile_compatibility_flag[]"); WRITE_U(stream, 3<<29, 32, "general_profile_compatibility_flag[]");
WRITE_U(stream, 1, 1, "general_progressive_source_flag"); WRITE_U(stream, 1, 1, "general_progressive_source_flag");
WRITE_U(stream, 0, 1, "general_interlaced_source_flag"); WRITE_U(stream, state->encoder_control->in.source_scan_type!= 0, 1, "general_interlaced_source_flag");
WRITE_U(stream, 0, 1, "general_non_packed_constraint_flag"); WRITE_U(stream, 0, 1, "general_non_packed_constraint_flag");
WRITE_U(stream, 0, 1, "general_frame_only_constraint_flag"); WRITE_U(stream, 0, 1, "general_frame_only_constraint_flag");
@ -262,8 +262,8 @@ static void encoder_state_write_bitstream_VUI(encoder_state_t * const state)
//ENDIF //ENDIF
WRITE_U(stream, 0, 1, "neutral_chroma_indication_flag"); WRITE_U(stream, 0, 1, "neutral_chroma_indication_flag");
WRITE_U(stream, 0, 1, "field_seq_flag"); WRITE_U(stream, state->encoder_control->vui.field_seq_flag, 1, "field_seq_flag"); // 0: frames, 1: fields
WRITE_U(stream, 0, 1, "frame_field_info_present_flag"); WRITE_U(stream, state->encoder_control->vui.frame_field_info_present_flag, 1, "frame_field_info_present_flag");
WRITE_U(stream, 0, 1, "default_display_window_flag"); WRITE_U(stream, 0, 1, "default_display_window_flag");
//IF default display window //IF default display window
@ -512,6 +512,80 @@ static void encoder_state_write_bitstream_prefix_sei_version(encoder_state_t * c
#undef STR_BUF_LEN #undef STR_BUF_LEN
} }
/*
static void encoder_state_write_active_parameter_sets_sei_message(encoder_state_t * const state) {
const encoder_control_t * const encoder = state->encoder_control;
bitstream_t * const stream = &state->stream;
int i = 0;
int active_vps_id = 0;
int self_contained_cvs_flag = 0;
int no_parameter_set_update_flag = 0;
int num_sps_ids_minus1 = 0;
int layer_sps_idx = 0;
int active_seq_parameter_set_id = 0;
int vps_base_layer_internal_flag = 0;
int max_layers_minus1 = 0;
WRITE_U(stream, 129, 8, "last_payload_type_byte"); //active_parameter_sets
WRITE_U(stream, 2, 8, "last_payload_size_byte");
WRITE_U(stream, active_vps_id, 4, "active_video_parameter_set_id");
WRITE_U(stream, self_contained_cvs_flag, 1, "self_contained_cvs_flag");
WRITE_U(stream, no_parameter_set_update_flag, 1, "no_parameter_set_update_flag");
WRITE_UE(stream, num_sps_ids_minus1, "num_sps_ids_minus1");
//for (i = 0; i <= num_sps_ids_minus1; ++i) {
WRITE_UE(stream, active_seq_parameter_set_id, "active_seq_parameter_set_id");
//}
// for (i = vps_base_layer_internal_flag; i <= max_layers_minus1; ++i){
WRITE_UE(stream, layer_sps_idx, "layer_sps_idx");
//}
bitstream_align(stream); //rbsp_trailing_bits
}
*/
static void encoder_state_write_picture_timing_sei_message(encoder_state_t * const state) {
bitstream_t * const stream = &state->stream;
if (state->encoder_control->vui.frame_field_info_present_flag){
int8_t odd_picture = state->global->frame % 2;
int8_t pic_struct = 0; //0: progressive picture, 1: top field, 2: bottom field, 3...
int8_t source_scan_type = 1; //0: interlaced, 1: progressive
switch (state->encoder_control->in.source_scan_type){
case 0: //Progressive frame
pic_struct = 0;
source_scan_type = 1;
break;
case 1: //Top field first
pic_struct = odd_picture ? 2 : 1;
source_scan_type = 0;
break;
case 2: //Bottom field first
pic_struct = odd_picture ? 1 : 2;
source_scan_type = 0;
break;
default:
assert(0); //Should never execute
break;
}
WRITE_U(stream, 1, 8, "last_payload_type_byte"); //pic_timing
WRITE_U(stream, 1, 8, "last_payload_size_byte");
WRITE_U(stream, pic_struct, 4, "pic_struct");
WRITE_U(stream, source_scan_type, 2, "source_scan_type");
WRITE_U(stream, 0, 1, "duplicate_flag");
bitstream_align(stream); //rbsp_trailing_bits
}
}
static void encoder_state_entry_points_explore(const encoder_state_t * const state, int * const r_count, int * const r_max_length) { static void encoder_state_entry_points_explore(const encoder_state_t * const state, int * const r_count, int * const r_max_length) {
int i; int i;
for (i = 0; state->children[i].encoder_control; ++i) { for (i = 0; state->children[i].encoder_control; ++i) {
@ -785,6 +859,19 @@ static void encoder_state_write_bitstream_main(encoder_state_t * const state)
bitstream_align(stream); bitstream_align(stream);
} }
//SEI messages for interlacing
if (state->encoder_control->vui.frame_field_info_present_flag){
// These should be optional, needed for earlier versions
// of HM decoder to accept bitstream
//nal_write(stream, PREFIX_SEI_NUT, 0, 0);
//encoder_state_write_active_parameter_sets_sei_message(state);
//bitstream_align(stream);
nal_write(stream, PREFIX_SEI_NUT, 0, 0);
encoder_state_write_picture_timing_sei_message(state);
bitstream_align(stream);
}
{ {
uint8_t nal_type = (state->global->is_idr_frame ? NAL_IDR_W_RADL : NAL_TRAIL_R); uint8_t nal_type = (state->global->is_idr_frame ? NAL_IDR_W_RADL : NAL_TRAIL_R);
nal_write(stream, nal_type, 0, first_nal_in_au); nal_write(stream, nal_type, 0, first_nal_in_au);