void x264_sei_pic_timing_write( x264_t *h, bs_t *s ) { x264_sps_t *sps = h->sps; bs_t q; uint8_t tmp_buf[100]; bs_init( &q, tmp_buf, 100 ); bs_realign( &q ); if( sps->vui.b_nal_hrd_parameters_present || sps->vui.b_vcl_hrd_parameters_present ) { bs_write( &q, sps->vui.hrd.i_cpb_removal_delay_length, h->fenc->i_cpb_delay - h->i_cpb_delay_pir_offset ); bs_write( &q, sps->vui.hrd.i_dpb_output_delay_length, h->fenc->i_dpb_output_delay ); } if( sps->vui.b_pic_struct_present ) { bs_write( &q, 4, h->fenc->i_pic_struct-1 ); // We use index 0 for "Auto" // These clock timestamps are not standardised so we don't set them // They could be time of origin, capture or alternative ideal display for( int i = 0; i < num_clock_ts[h->fenc->i_pic_struct]; i++ ) bs_write1( &q, 0 ); // clock_timestamp_flag } bs_align_10( &q ); bs_flush( &q ); x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_PIC_TIMING ); }
static int write_rtcp_pkt( hnd_t handle ) { obe_rtp_ctx *p_rtp = handle; uint64_t ntp_time = obe_ntp_time(); uint8_t pkt[100]; bs_t s; bs_init( &s, pkt, RTCP_PACKET_SIZE ); bs_write( &s, 2, RTP_VERSION ); // version bs_write1( &s, 0 ); // padding bs_write( &s, 5, 0 ); // reception report count bs_write( &s, 8, RTCP_SR_PACKET_TYPE ); // packet type bs_write( &s, 8, 6 ); // length (length in words - 1) bs_write32( &s, p_rtp->ssrc ); // ssrc bs_write32( &s, ntp_time / 1000000 ); // NTP timestamp, most significant word bs_write32( &s, ((ntp_time % 1000000) << 32) / 1000000 ); // NTP timestamp, least significant word bs_write32( &s, 0 ); // RTP timestamp FIXME bs_write32( &s, p_rtp->pkt_cnt ); // sender's packet count bs_write32( &s, p_rtp->octet_cnt ); // sender's octet count bs_flush( &s ); if( udp_write( p_rtp->udp_handle, pkt, RTCP_PACKET_SIZE ) < 0 ) return -1; return 0; }
void x264_pps_write( bs_t *s, x264_pps_t *pps ) { bs_realign( s ); bs_write_ue( s, pps->i_id ); bs_write_ue( s, pps->i_sps_id ); bs_write1( s, pps->b_cabac ); bs_write1( s, pps->b_pic_order ); bs_write_ue( s, pps->i_num_slice_groups - 1 ); bs_write_ue( s, pps->i_num_ref_idx_l0_default_active - 1 ); bs_write_ue( s, pps->i_num_ref_idx_l1_default_active - 1 ); bs_write1( s, pps->b_weighted_pred ); bs_write( s, 2, pps->b_weighted_bipred ); bs_write_se( s, pps->i_pic_init_qp - 26 - QP_BD_OFFSET ); bs_write_se( s, pps->i_pic_init_qs - 26 - QP_BD_OFFSET ); bs_write_se( s, pps->i_chroma_qp_index_offset ); bs_write1( s, pps->b_deblocking_filter_control ); bs_write1( s, pps->b_constrained_intra_pred ); bs_write1( s, pps->b_redundant_pic_cnt ); if( pps->b_transform_8x8_mode || pps->i_cqm_preset != X264_CQM_FLAT ) { bs_write1( s, pps->b_transform_8x8_mode ); bs_write1( s, (pps->i_cqm_preset != X264_CQM_FLAT) ); if( pps->i_cqm_preset != X264_CQM_FLAT ) { scaling_list_write( s, pps, CQM_4IY ); scaling_list_write( s, pps, CQM_4IC ); bs_write1( s, 0 ); // Cr = Cb scaling_list_write( s, pps, CQM_4PY ); scaling_list_write( s, pps, CQM_4PC ); bs_write1( s, 0 ); // Cr = Cb if( pps->b_transform_8x8_mode ) { scaling_list_write( s, pps, CQM_8IY+4 ); scaling_list_write( s, pps, CQM_8PY+4 ); } } bs_write_se( s, pps->i_chroma_qp_index_offset ); } bs_rbsp_trailing( s ); bs_flush( s ); }
void x264_sei_recovery_point_write( x264_t *h, bs_t *s, int recovery_frame_cnt ) { bs_t q; uint8_t tmp_buf[100]; bs_init( &q, tmp_buf, 100 ); bs_realign( &q ); bs_write_ue( &q, recovery_frame_cnt ); // recovery_frame_cnt bs_write1( &q, 1 ); //exact_match_flag 1 bs_write1( &q, 0 ); //broken_link_flag 0 bs_write( &q, 2, 0 ); //changing_slice_group 0 bs_align_10( &q ); bs_flush( &q ); x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_RECOVERY_POINT ); }
void xavs_sequence_write (bs_t * s, xavs_seq_header_t * sqh) { bs_write (s, 8, sqh->i_video_sequence_start_code); bs_write (s, 8, sqh->i_profile_idc); bs_write (s, 8, sqh->i_level_idc); bs_write1 (s, sqh->b_progressive_sequence); bs_write (s, 14, sqh->i_horizontal_size); bs_write (s, 14, sqh->i_vertical_size); bs_write (s, 2, sqh->i_chroma_format); bs_write (s, 3, sqh->i_sample_precision); bs_write (s, 4, sqh->i_aspect_ratio); bs_write (s, 4, sqh->i_frame_rate_code); bs_write (s, 18, 500); //sqh->i_bit_rate_lower); bs_write1 (s, 1); //marker bit bs_write (s, 12, 0); //sqh->i_bit_rate_upper); bs_write1 (s, sqh->b_low_delay); bs_write1 (s, 1); bs_write (s, 18, 122800); //sqh->i_bbv_buffer_size); bs_write (s, 3, 0); //reserved bits //bs_rbsp_trailing( s ); }
static void scaling_list_write( bs_t *s, x264_pps_t *pps, int idx ) { const int len = idx<4 ? 16 : 64; const uint8_t *zigzag = idx<4 ? x264_zigzag_scan4[0] : x264_zigzag_scan8[0]; const uint8_t *list = pps->scaling_list[idx]; const uint8_t *def_list = (idx==CQM_4IC) ? pps->scaling_list[CQM_4IY] : (idx==CQM_4PC) ? pps->scaling_list[CQM_4PY] : (idx==CQM_8IC+4) ? pps->scaling_list[CQM_8IY+4] : (idx==CQM_8PC+4) ? pps->scaling_list[CQM_8PY+4] : x264_cqm_jvt[idx]; if( !memcmp( list, def_list, len ) ) bs_write1( s, 0 ); // scaling_list_present_flag else if( !memcmp( list, x264_cqm_jvt[idx], len ) ) { bs_write1( s, 1 ); // scaling_list_present_flag bs_write_se( s, -8 ); // use jvt list } else { int run; bs_write1( s, 1 ); // scaling_list_present_flag // try run-length compression of trailing values for( run = len; run > 1; run-- ) if( list[zigzag[run-1]] != list[zigzag[run-2]] ) break; if( run < len && len - run < bs_size_se( (int8_t)-list[zigzag[run]] ) ) run = len; for( int j = 0; j < run; j++ ) bs_write_se( s, (int8_t)(list[zigzag[j]] - (j>0 ? list[zigzag[j-1]] : 8)) ); // delta if( run < len ) bs_write_se( s, (int8_t)-list[zigzag[run]] ); } }
void x264_sei_frame_packing_write( x264_t *h, bs_t *s ) { bs_t q; uint8_t tmp_buf[100]; bs_init( &q, tmp_buf, 100 ); bs_realign( &q ); bs_write_ue( &q, 0 ); // frame_packing_arrangement_id bs_write1( &q, 0 ); // frame_packing_arrangement_cancel_flag bs_write ( &q, 7, h->param.i_frame_packing ); // frame_packing_arrangement_type bs_write1( &q, 0 ); // quincunx_sampling_flag // 0: views are unrelated, 1: left view is on the left, 2: left view is on the right bs_write ( &q, 6, 1 ); // content_interpretation_type bs_write1( &q, 0 ); // spatial_flipping_flag bs_write1( &q, 0 ); // frame0_flipped_flag bs_write1( &q, 0 ); // field_views_flag bs_write1( &q, h->param.i_frame_packing == 5 && !(h->fenc->i_frame&1) ); // current_frame_is_frame0_flag bs_write1( &q, 0 ); // frame0_self_contained_flag bs_write1( &q, 0 ); // frame1_self_contained_flag if ( /* quincunx_sampling_flag == 0 && */ h->param.i_frame_packing != 5 ) { bs_write( &q, 4, 0 ); // frame0_grid_position_x bs_write( &q, 4, 0 ); // frame0_grid_position_y bs_write( &q, 4, 0 ); // frame1_grid_position_x bs_write( &q, 4, 0 ); // frame1_grid_position_y } bs_write( &q, 8, 0 ); // frame_packing_arrangement_reserved_byte bs_write_ue( &q, 1 ); // frame_packing_arrangement_repetition_period bs_write1( &q, 0 ); // frame_packing_arrangement_extension_flag bs_align_10( &q ); bs_flush( &q ); x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_FRAME_PACKING ); }
void x264_sps_write( bs_t *s, x264_sps_t *sps ) { bs_realign( s ); bs_write( s, 8, sps->i_profile_idc ); bs_write1( s, sps->b_constraint_set0 ); bs_write1( s, sps->b_constraint_set1 ); bs_write1( s, sps->b_constraint_set2 ); bs_write1( s, sps->b_constraint_set3 ); bs_write( s, 4, 0 ); /* reserved */ bs_write( s, 8, sps->i_level_idc ); bs_write_ue( s, sps->i_id ); if( sps->i_profile_idc >= PROFILE_HIGH ) { bs_write_ue( s, sps->i_chroma_format_idc ); if( sps->i_chroma_format_idc == CHROMA_444 ) bs_write1( s, 0 ); // separate_colour_plane_flag bs_write_ue( s, BIT_DEPTH-8 ); // bit_depth_luma_minus8 bs_write_ue( s, BIT_DEPTH-8 ); // bit_depth_chroma_minus8 bs_write1( s, sps->b_qpprime_y_zero_transform_bypass ); bs_write1( s, 0 ); // seq_scaling_matrix_present_flag } bs_write_ue( s, sps->i_log2_max_frame_num - 4 ); bs_write_ue( s, sps->i_poc_type ); if( sps->i_poc_type == 0 ) bs_write_ue( s, sps->i_log2_max_poc_lsb - 4 ); bs_write_ue( s, sps->i_num_ref_frames ); bs_write1( s, sps->b_gaps_in_frame_num_value_allowed ); bs_write_ue( s, sps->i_mb_width - 1 ); bs_write_ue( s, (sps->i_mb_height >> !sps->b_frame_mbs_only) - 1); bs_write1( s, sps->b_frame_mbs_only ); if( !sps->b_frame_mbs_only ) bs_write1( s, sps->b_mb_adaptive_frame_field ); bs_write1( s, sps->b_direct8x8_inference ); bs_write1( s, sps->b_crop ); if( sps->b_crop ) { int h_shift = sps->i_chroma_format_idc == CHROMA_420 || sps->i_chroma_format_idc == CHROMA_422; int v_shift = sps->i_chroma_format_idc == CHROMA_420; bs_write_ue( s, sps->crop.i_left >> h_shift ); bs_write_ue( s, sps->crop.i_right >> h_shift ); bs_write_ue( s, sps->crop.i_top >> v_shift ); bs_write_ue( s, sps->crop.i_bottom >> v_shift ); }
/* TODO: factor shared code out from 608 and 708 */ int write_608_cc( obe_user_data_t *user_data, obe_raw_frame_t *raw_frame ) { bs_t q, r; uint8_t temp[1000]; uint8_t temp2[500]; const char *user_identifier = "GA94"; const int data_type_code = 0x03; int cc_count = 0; const int echostar_captions = 0; /* TODO: when MPEG-2 is added make this do the right thing */ /* FIXME: enable echostar captions and add more types */ for( int i = 0; cc_timecode[i].timebase_num != 0; i++ ) { if( raw_frame->timebase_num == cc_timecode[i].timebase_num && raw_frame->timebase_den == cc_timecode[i].timebase_den ) cc_count = cc_timecode[i].cc_count; } if( !cc_count ) { syslog( LOG_ERR, "[cc]: Unsupported framerate for captions\n" ); return -1; } bs_init( &r, temp, 1000 ); /* N.B MPEG-4 only */ write_itu_t_codes( &r ); if( !echostar_captions ) { for( int i = 0; i < 4; i++ ) bs_write( &r, 8, user_identifier[i] ); // user_identifier } bs_write( &r, 8, data_type_code ); // user_data_type_code bs_init( &q, temp2, 500 ); // user_data_type_structure (echostar) // cc_data bs_write1( &q, 1 ); // reserved bs_write1( &q, 1 ); // process_cc_data_flag bs_write1( &q, 0 ); // zero_bit / additional_data_flag bs_write( &q, 5, cc_count ); // cc_count bs_write( &q, 8, 0xff ); // reserved for( int i = 0; i < cc_count; i++ ) { bs_write1( &q, 1 ); // one_bit bs_write( &q, 4, 0xf ); // reserved if( i <= 1 && user_data->len >= (i+1)*2 ) { bs_write1( &q, 1 ); // cc_valid bs_write( &q, 2, i ); // cc_type bs_write( &q, 8, user_data->data[2*i] ); // c_data_1 bs_write( &q, 8, user_data->data[2*i+1] ); // c_data_2 } else /* nothing to write so maintain a constant bitrate */ write_invalid( &q ); } bs_write( &q, 8, 0xff ); // marker_bits bs_flush( &q ); if( echostar_captions ) { // ATSC1_data bs_write( &r, 8, bs_pos( &q ) >> 3 ); // user_data_code_length } write_bytes( &r, temp2, bs_pos( &q ) >> 3 ); bs_flush( &r ); user_data->type = USER_DATA_AVC_REGISTERED_ITU_T35; user_data->len = bs_pos( &r ) >> 3; free( user_data->data ); user_data->data = malloc( user_data->len ); if( !user_data->data ) { syslog( LOG_ERR, "Malloc failed\n" ); return -1; } memcpy( user_data->data, temp, user_data->len ); return 0; }
void x264_sps_write( bs_t *s, x264_sps_t *sps ) { bs_write( s, 8, sps->i_profile_idc ); bs_write( s, 1, sps->b_constraint_set0 ); bs_write( s, 1, sps->b_constraint_set1 ); bs_write( s, 1, sps->b_constraint_set2 ); bs_write( s, 5, 0 ); /* reserved */ bs_write( s, 8, sps->i_level_idc ); bs_write_ue( s, sps->i_id ); if( sps->i_profile_idc >= PROFILE_HIGH ) { bs_write_ue( s, 1 ); // chroma_format_idc = 4:2:0 bs_write_ue( s, 0 ); // bit_depth_luma_minus8 bs_write_ue( s, 0 ); // bit_depth_chroma_minus8 bs_write( s, 1, sps->b_qpprime_y_zero_transform_bypass ); bs_write( s, 1, 0 ); // seq_scaling_matrix_present_flag } bs_write_ue( s, sps->i_log2_max_frame_num - 4 ); bs_write_ue( s, sps->i_poc_type ); if( sps->i_poc_type == 0 ) { bs_write_ue( s, sps->i_log2_max_poc_lsb - 4 ); } else if( sps->i_poc_type == 1 ) { int i; bs_write( s, 1, sps->b_delta_pic_order_always_zero ); bs_write_se( s, sps->i_offset_for_non_ref_pic ); bs_write_se( s, sps->i_offset_for_top_to_bottom_field ); bs_write_ue( s, sps->i_num_ref_frames_in_poc_cycle ); for( i = 0; i < sps->i_num_ref_frames_in_poc_cycle; i++ ) { bs_write_se( s, sps->i_offset_for_ref_frame[i] ); } } bs_write_ue( s, sps->i_num_ref_frames ); bs_write( s, 1, sps->b_gaps_in_frame_num_value_allowed ); bs_write_ue( s, sps->i_mb_width - 1 ); if (sps->b_frame_mbs_only) { bs_write_ue( s, sps->i_mb_height - 1); } else // interlaced { bs_write_ue( s, sps->i_mb_height/2 - 1); } bs_write( s, 1, sps->b_frame_mbs_only ); if( !sps->b_frame_mbs_only ) { bs_write( s, 1, sps->b_mb_adaptive_frame_field ); } bs_write( s, 1, sps->b_direct8x8_inference ); bs_write( s, 1, sps->b_crop ); if( sps->b_crop ) { bs_write_ue( s, sps->crop.i_left / 2 ); bs_write_ue( s, sps->crop.i_right / 2 ); bs_write_ue( s, sps->crop.i_top / 2 ); bs_write_ue( s, sps->crop.i_bottom / 2 ); } bs_write( s, 1, sps->b_vui ); if( sps->b_vui ) { bs_write1( s, sps->vui.b_aspect_ratio_info_present ); if( sps->vui.b_aspect_ratio_info_present ) { int i; static const struct { int w, h; int sar; } sar[] = { { 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}, { 0, 0, -1 } }; for( i = 0; sar[i].sar != -1; i++ ) { if( sar[i].w == sps->vui.i_sar_width && sar[i].h == sps->vui.i_sar_height ) break; } if( sar[i].sar != -1 ) { bs_write( s, 8, sar[i].sar ); } else { bs_write( s, 8, 255); /* aspect_ratio_idc (extended) */ bs_write( s, 16, sps->vui.i_sar_width ); bs_write( s, 16, sps->vui.i_sar_height ); } } bs_write1( s, sps->vui.b_overscan_info_present ); if( sps->vui.b_overscan_info_present ) bs_write1( s, sps->vui.b_overscan_info ); bs_write1( s, sps->vui.b_signal_type_present ); if( sps->vui.b_signal_type_present ) { bs_write( s, 3, sps->vui.i_vidformat ); bs_write1( s, sps->vui.b_fullrange ); bs_write1( s, sps->vui.b_color_description_present ); if( sps->vui.b_color_description_present ) { bs_write( s, 8, sps->vui.i_colorprim ); bs_write( s, 8, sps->vui.i_transfer ); bs_write( s, 8, sps->vui.i_colmatrix ); } } bs_write1( s, sps->vui.b_chroma_loc_info_present ); if( sps->vui.b_chroma_loc_info_present ) { bs_write_ue( s, sps->vui.i_chroma_loc_top ); bs_write_ue( s, sps->vui.i_chroma_loc_bottom ); } bs_write1( s, sps->vui.b_timing_info_present ); if( sps->vui.b_timing_info_present ) { bs_write32( s, sps->vui.i_num_units_in_tick ); bs_write32( s, sps->vui.i_time_scale ); bs_write1( s, sps->vui.b_fixed_frame_rate ); } bs_write1( s, 0 ); /* nal_hrd_parameters_present_flag */ bs_write1( s, 0 ); /* vcl_hrd_parameters_present_flag */ bs_write1( s, 0 ); /* pic_struct_present_flag */ bs_write1( s, sps->vui.b_bitstream_restriction ); if( sps->vui.b_bitstream_restriction ) { bs_write1( s, sps->vui.b_motion_vectors_over_pic_boundaries ); bs_write_ue( s, sps->vui.i_max_bytes_per_pic_denom ); bs_write_ue( s, sps->vui.i_max_bits_per_mb_denom ); bs_write_ue( s, sps->vui.i_log2_max_mv_length_horizontal ); bs_write_ue( s, sps->vui.i_log2_max_mv_length_vertical ); bs_write_ue( s, sps->vui.i_num_reorder_frames ); bs_write_ue( s, sps->vui.i_max_dec_frame_buffering ); } } bs_rbsp_trailing( s ); }