int add_vui(void *srcPtr, size_t srcSize, void *dstPtr, size_t dstSize, int color) { sps_t sps; bs_t b; memset(&b, 0, sizeof(bs_t)); bs_init(&b, srcPtr, srcSize); read_seq_parameter_set_rbsp(&sps, &b); sps.vui_parameters_present_flag = 1; { sps.vui.video_signal_type_present_flag = 1; { sps.vui.video_format = 5; sps.vui.video_full_range_flag = 1; } sps.vui.colour_description_present_flag = 1; { sps.vui.colour_primaries = 1; } sps.vui.transfer_characteristics = 1; sps.vui.matrix_coefficients = 1; } switch (color) { case BT601_LIMITED: sps.vui.colour_primaries = 5; sps.vui.video_full_range_flag = 0; sps.vui.transfer_characteristics = 6; sps.vui.matrix_coefficients = 5; break; case BT601_FULL: sps.vui.colour_primaries = 5; sps.vui.transfer_characteristics = 6; sps.vui.matrix_coefficients = 5; break; case BT601_FULL_YCbCr: sps.vui.colour_primaries = 5; sps.vui.transfer_characteristics = 8; sps.vui.matrix_coefficients = 5; break; case BT709_LIMITED: sps.vui.video_full_range_flag = 0; break; case BT709_FULL: break; case BT709_ALT1_LIMITED: sps.vui.video_full_range_flag = 0; break; default: sps.vui_parameters_present_flag = 0; break; } bs_init(&b, dstPtr, dstSize); write_seq_parameter_set_rbsp(&sps, &b); return bs_pos_byte(&b); }
/* Parse WMV3 packet and extract frame type information */ static void ParseWMV3( decoder_t *p_dec, block_t *p_block ) { bs_t s; /* Parse Sequence header */ bs_init( &s, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra ); if( bs_read( &s, 2 ) == 3 ) return; bs_skip( &s, 22 ); const bool b_range_reduction = bs_read( &s, 1 ); const bool b_has_frames = bs_read( &s, 3 ) > 0; bs_skip( &s, 2 ); const bool b_frame_interpolation = bs_read( &s, 1 ); if( bs_eof( &s ) ) return; /* Parse frame type */ bs_init( &s, p_block->p_buffer, p_block->i_buffer ); bs_skip( &s, b_frame_interpolation + 2 + b_range_reduction ); p_block->i_flags &= ~BLOCK_FLAG_TYPE_MASK; if( bs_read( &s, 1 ) ) p_block->i_flags |= BLOCK_FLAG_TYPE_P; else if( !b_has_frames || bs_read( &s, 1 ) ) p_block->i_flags |= BLOCK_FLAG_TYPE_I; else p_block->i_flags |= BLOCK_FLAG_TYPE_B; }
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; }
static int write_rtp_pkt( hnd_t handle, uint8_t *data, int len, int64_t timestamp ) { obe_rtp_ctx *p_rtp = handle; uint8_t pkt[RTP_HEADER_SIZE+TS_PACKETS_SIZE]; bs_t s; bs_init( &s, pkt, RTP_HEADER_SIZE+TS_PACKETS_SIZE ); bs_write( &s, 2, RTP_VERSION ); // version bs_write1( &s, 0 ); // padding bs_write1( &s, 0 ); // extension bs_write( &s, 4, 0 ); // CSRC count bs_write1( &s, 0 ); // marker bs_write( &s, 7, MPEG_TS_PAYLOAD_TYPE ); // payload type bs_write( &s, 16, p_rtp->seq++ ); // sequence number bs_write32( &s, timestamp / 300 ); // timestamp bs_write32( &s, p_rtp->ssrc ); // ssrc bs_flush( &s ); memcpy( &pkt[RTP_HEADER_SIZE], data, len ); if( udp_write( p_rtp->udp_handle, pkt, RTP_HEADER_SIZE+TS_PACKETS_SIZE ) < 0 ) return -1; p_rtp->pkt_cnt++; p_rtp->octet_cnt += len; return 0; }
/* initialize encoder */ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf, enum mdp5_intf intf_id) { struct drm_encoder *encoder = NULL; struct mdp5_encoder *mdp5_encoder; int ret; mdp5_encoder = kzalloc(sizeof(*mdp5_encoder), GFP_KERNEL); if (!mdp5_encoder) { ret = -ENOMEM; goto fail; } mdp5_encoder->intf = intf; mdp5_encoder->intf_id = intf_id; encoder = &mdp5_encoder->base; drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, DRM_MODE_ENCODER_TMDS); drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs); bs_init(mdp5_encoder); return encoder; fail: if (encoder) mdp5_encoder_destroy(encoder); return ERR_PTR(ret); }
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 ); }
// D.1.1 SEI buffering period syntax static void read_sei_type_0(h264_stream_t* h, sei_t* s) { int sched_sel_idx; bs_t bs; sps_t *sps = h->sps; sei_type_0 *bp = malloc(sizeof(sei_type_0)); bs_init(&bs, s->payload, s->payloadSize); bp->seq_parameter_set_id = bs_read_ue(&bs); if(sps->vui.nal_hrd_parameters_present_flag) { for (sched_sel_idx = 0; sched_sel_idx < sps->hrd.cpb_cnt_minus1 + 1; sched_sel_idx++) { bp->initial_cbp_removal_delay[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); bp->initial_cbp_removal_delay_offset[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); } } if (sps->vui.vcl_hrd_parameters_present_flag) { for (sched_sel_idx = 0; sched_sel_idx < sps->hrd.cpb_cnt_minus1 + 1; sched_sel_idx++) { bp->initial_cbp_removal_delay[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); bp->initial_cbp_removal_delay_offset[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1); } } s->sei_type_struct = bp; }
// D.1.2 SEI picture timing syntax static void read_sei_type_1(h264_stream_t* h, sei_t* s) { bs_t bs; sps_t *sps = h->sps; uint32_t pict_struct, num_clock_ticks; bs_init(&bs, s->payload, s->payloadSize); sei_type_1 *pt_struct = NULL; if(sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag) { pt_struct = calloc(sizeof(sei_type_1), 1); pt_struct->cpb_removal_delay = bs_read_u(&bs, sps->hrd.cpb_removal_delay_length_minus1 + 1); pt_struct->dpb_output_delay = bs_read_u(&bs, sps->hrd.dpb_output_delay_length_minus1 + 1); } if (sps->vui.pic_struct_present_flag) { pict_struct = bs_read_u(&bs, 4); if (pict_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) { return; } num_clock_ticks = sei_num_clock_ts_table[pict_struct]; pt_struct->timings = calloc(sizeof(sei_type_1_pic_timing) * num_clock_ticks, 1); pt_struct->NumClockTS = num_clock_ticks; pt_struct->pic_struct = pict_struct; for (int i = 0; i < num_clock_ticks; i++) { sei_type_1_pic_timing *pt = &pt_struct->timings[i]; pt->clock_timestamp_flag = bs_read_u(&bs, 1); if (pt->clock_timestamp_flag) { pt->ct_type = bs_read_u(&bs, 2); pt->nuit_field_based_flag = bs_read_u(&bs, 1); pt->counting_type = bs_read_u(&bs, 5); pt->full_timestamp_flag = bs_read_u(&bs, 1); pt->discontinuity_flag = bs_read_u(&bs, 1); pt->cnt_dropped_flag = bs_read_u(&bs, 1); pt->n_frames = bs_read_u(&bs, 8); if (pt->full_timestamp_flag) { pt->seconds_value = bs_read_u(&bs, 6); pt->minutes_value = bs_read_u(&bs, 6); pt->hours_value = bs_read_u(&bs, 5); }else { pt->seconds_flag = bs_read_u(&bs, 1); if (pt->seconds_flag) { pt->seconds_value = bs_read_u(&bs, 6); pt->minutes_flag = bs_read_u(&bs, 1); if(pt->minutes_flag) { pt->minutes_value = bs_read_u(&bs, 6); pt->hours_flag = bs_read_u(&bs, 1); if (pt->hours_flag) { pt->hours_value = bs_read_u(&bs, 5); } } } } if (sps->hrd.time_offset_length > 0) { pt->time_offset = bs_read_u(&bs, sps->hrd.time_offset_length); } } } } s->sei_type_struct = pt_struct; }
void test_bs_init() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); assert_equal(bs.m_bc[0], 0xC000000000000000); assert_equal(bs.m_bc[1], 0x0); }
static INDX_ROOT *_indx_parse(BD_FILE_H *fp) { BITSTREAM bs; INDX_ROOT *index = calloc(1, sizeof(INDX_ROOT)); int indexes_start, extension_data_start; if (!index) { BD_DEBUG(DBG_CRIT, "out of memory\n"); return NULL; } bs_init(&bs, fp); if (!_parse_header(&bs, &indexes_start, &extension_data_start) || !_parse_app_info(&bs, &index->app_info)) { indx_free(&index); return NULL; } bs_seek_byte(&bs, indexes_start); if (!_parse_index(&bs, index)) { indx_free(&index); return NULL; } if (extension_data_start) { BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: unknown extension data at %d\n", extension_data_start); } return index; }
static int32_t getFPS( demux_t *p_demux, block_t * p_block ) { demux_sys_t *p_sys = p_demux->p_sys; bs_t bs; uint8_t * p_decoded_nal; int i_decoded_nal; if( p_block->i_buffer < 5 ) return -1; p_decoded_nal = CreateDecodedNAL(&i_decoded_nal, p_block->p_buffer+4, p_block->i_buffer-4); if( !p_decoded_nal ) return -1; bs_init( &bs, p_decoded_nal, i_decoded_nal ); bs_skip( &bs, 12 ); int32_t max_sub_layer_minus1 = bs_read( &bs, 3 ); bs_skip( &bs, 17 ); hevc_skip_profile_tiers_level( &bs, max_sub_layer_minus1 ); int32_t vps_sub_layer_ordering_info_present_flag = bs_read1( &bs ); int32_t i = vps_sub_layer_ordering_info_present_flag? 0 : max_sub_layer_minus1; for( ; i <= max_sub_layer_minus1; i++ ) { bs_read_ue( &bs ); bs_read_ue( &bs ); bs_read_ue( &bs ); } uint32_t vps_max_layer_id = bs_read( &bs, 6); uint32_t vps_num_layer_sets_minus1 = bs_read_ue( &bs ); bs_skip( &bs, vps_max_layer_id * vps_num_layer_sets_minus1 ); if( bs_read1( &bs )) { uint32_t num_units_in_tick = bs_read( &bs, 32 ); uint32_t time_scale = bs_read( &bs, 32 ); if( num_units_in_tick ) { p_sys->f_fps = ( (float) time_scale )/( (float) num_units_in_tick ); msg_Dbg(p_demux,"Using framerate %f fps from VPS", (double) p_sys->f_fps); } else { msg_Err( p_demux, "vps_num_units_in_tick null defaulting to 25 fps"); p_sys->f_fps = 25.0f; } } else { msg_Err( p_demux, "No timing info in VPS defaulting to 25 fps"); p_sys->f_fps = 25.0f; } free(p_decoded_nal); return 0; }
static void PutPPS( decoder_t *p_dec, block_t *p_frag ) { decoder_sys_t *p_sys = p_dec->p_sys; bs_t s; int i_pps_id; int i_sps_id; bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 ); i_pps_id = bs_read_ue( &s ); // pps id i_sps_id = bs_read_ue( &s ); // sps id if( i_pps_id >= PPS_MAX || i_sps_id >= SPS_MAX ) { msg_Warn( p_dec, "invalid PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id ); block_Release( p_frag ); return; } bs_skip( &s, 1 ); // entropy coding mode flag p_sys->i_pic_order_present_flag = bs_read( &s, 1 ); /* TODO */ /* We have a new PPS */ if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id ); p_sys->b_pps = true; if( p_sys->pp_pps[i_pps_id] ) block_Release( p_sys->pp_pps[i_pps_id] ); p_sys->pp_pps[i_pps_id] = p_frag; }
int main() { char *d; struct bs s; bs_init(&s,10); bs_add(&s,"aa"); bs_add(&s,"ab"); bs_add(&s,"ac"); bs_add(&s,"ad123456789"); bs_get(&s,&d); printf("ret \"%s\"\n",d); bs_get(&s,&d); printf("ret \"%s\"\n",d); bs_get(&s,&d); printf("ret \"%s\"\n",d); bs_get(&s,&d); printf("ret \"%s\"\n",d); bs_get(&s,&d); printf("ret \"%s\"\n",d); bs_get(&s,&d); printf("ret \"%s\"\n",d); bs_get(&s,&d); printf("ret \"%s\"\n",d); }
/* returns boolean, non zero is ok */ int ui_main(void) { uint32 flags; /* try to connect */ flags = RDP_LOGON_NORMAL; if (g_password[0] != 0) { flags |= RDP_INFO_AUTOLOGON; } if (!rdp_connect(g_servername, flags, g_domain, g_password, g_shell, g_directory, FALSE)) { return 0; } /* init backingstore */ bs_init(g_width, g_height, g_server_depth); /* create the window */ if (!mi_create_window()) { return 0; } /* if all ok, enter main loop */ return mi_main_loop(); }
void test_bs_nrun_from() { bitset bs; // 8 chks right covers 4096 bytes (our heap size). bs_init(&bs, 8, g_heap); bs_set_range(&bs, 0, 7); // we need one full byte to cover 8 chunks assert_equal(bs.m_bc[0], 0xFF00000000000000); size_t index = bs_nrun_from(&bs, 311, 8); assert_equal(8, index); for (int i = 0; i < 4; ++i) { assert_equal(bs.m_bc[i], ~0x0); } // the first 5 chunks except for one bit should be occupied. assert_equal(bs.m_bc[4], 0xFFFFFFFFFFFFFFFE); // should exhaust all remaining bits and start over index = bs_nrun_from(&bs, 193, 320); assert_equal(319, index); // build a bit board with "holes" bs_set_range(&bs, 0, 511); bs_clear_range(&bs, 10, 73); bs_clear_range(&bs, 100, 162); index = bs_nrun_from(&bs, 64, 100); assert_equal(10, index); }
void test_next_one() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); // test normal usage size_t next_pos = bs_next_one(&bs, 0); assert_equal(0, next_pos); bs_set_range(&bs, 63, 64); next_pos = bs_next_one(&bs, 62); assert_equal(63, next_pos); next_pos = bs_next_one(&bs, 63); assert_equal(63, next_pos); // test when there is no one bs_clear_range(&bs, 0, 127); assert_equal(0x0, bs.m_bc[0]); assert_equal(0x0, bs.m_bc[1]); next_pos = bs_next_one(&bs, 0); assert_equal(next_pos, BITSET_NON); // test starts from second chunk bs_set_range(&bs, 66, 69); next_pos = bs_next_one(&bs, 65); assert_equal(66, next_pos); // test start point off zero bs_clear_range(&bs, 66, 69); bs_set(&bs, 0); next_pos = bs_next_one(&bs, 0); assert_equal(0, next_pos); next_pos = bs_next_one(&bs, 1);// off by 1 assert_equal(BITSET_NON, next_pos); }
void test_bs_set1_same_chk() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); assert_equal(bs.m_bc[0], 0xC000000000000000); bs_set_range(&bs, 2, 3); assert_equal(bs.m_bc[0], 0xF000000000000000); }
void test_bs_set1_right_boundary_lo() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 63, 77); assert_equal(bs.m_bc[0], 0xC000000000000001); assert_equal(bs.m_bc[1], 0xFFFC000000000000); }
void test_bs_set1_right_boundary_hi() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 23, 63); assert_equal(bs.m_bc[0], 0xC00001FFFFFFFFFF); assert_equal(bs.m_bc[1], 0x0); }
void test_bs_set1_left_boundary() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 64, 80); assert_equal(bs.m_bc[0], 0xC000000000000000); assert_equal(bs.m_bc[1], 0xFFFF800000000000); }
static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *p_block) { decoder_t *p_dec = p_private; decoder_sys_t *p_sys = p_dec->p_sys; block_t * p_nal = NULL; while (p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 ) p_block->i_buffer--; bs_t bs; bs_init(&bs, p_block->p_buffer+3, p_block->i_buffer-3); /* Get NALU type */ uint32_t forbidden_zero_bit = bs_read1(&bs); if (forbidden_zero_bit) { msg_Err(p_dec,"Forbidden zero bit not null, corrupted NAL"); p_sys->p_frame = NULL; p_sys->b_vcl = false; return NULL; } uint32_t nalu_type = bs_read(&bs,6); bs_skip(&bs, 9); if (nalu_type < VPS) { /* NAL is a VCL NAL */ p_sys->b_vcl = true; uint32_t first_slice_in_pic = bs_read1(&bs); if (first_slice_in_pic && p_sys->p_frame) { p_nal = block_ChainGather(p_sys->p_frame); p_sys->p_frame = NULL; } block_ChainAppend(&p_sys->p_frame, p_block); } else { if (p_sys->b_vcl) { p_nal = block_ChainGather(p_sys->p_frame); p_nal->p_next = p_block; p_sys->p_frame = NULL; p_sys->b_vcl =false; } else p_nal = p_block; } *pb_ts_used = false; return p_nal; }
void test_bs_set0_right_boundary_lo() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 23, 80); bs_clear_range(&bs, 63, 77); assert_equal(bs.m_bc[0], 0xC00001FFFFFFFFFE); assert_equal(bs.m_bc[1], 0x0003800000000000); }
void test_bs_set0_same_chk() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 23, 63);// 0xC00001FFFFFFFFFF bs_clear_range(&bs, 24, 33); assert_equal(bs.m_bc[0], 0xC00001003FFFFFFF); assert_equal(bs.m_bc[1], 0x0); }
void test_bs_set0() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 23, 80); bs_clear_range(&bs, 55, 77); assert_equal(bs.m_bc[0], 0xC00001FFFFFFFE00); assert_equal(bs.m_bc[1], 0x0003800000000000); }
void test_bs_set1_same_chk_middle() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); assert_equal(bs.m_bc[0], 0xC000000000000000); bs_set_range(&bs, 23, 33); assert_equal(bs.m_bc[0], 0xC00001FFC0000000); assert_equal(bs.m_bc[1], 0x0); }
static MOBJ_OBJECTS *_mobj_parse(BD_FILE_H *fp) { BITSTREAM bs; MOBJ_OBJECTS *objects = NULL; uint16_t num_objects; uint32_t data_len; int extension_data_start, i; bs_init(&bs, fp); if (!_mobj_parse_header(&bs, &extension_data_start)) { BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: invalid header\n"); goto error; } if (extension_data_start) { BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: unknown extension data at %d\n", extension_data_start); } bs_seek_byte(&bs, 40); data_len = bs_read(&bs, 32); if ((bs_end(&bs) - bs_pos(&bs))/8 < (int64_t)data_len) { BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: invalid data_len %d !\n", data_len); goto error; } objects = calloc(1, sizeof(MOBJ_OBJECTS)); if (!objects) { BD_DEBUG(DBG_CRIT, "out of memory\n"); goto error; } bs_skip(&bs, 32); /* reserved */ num_objects = bs_read(&bs, 16); objects->num_objects = num_objects; objects->objects = calloc(num_objects, sizeof(MOBJ_OBJECT)); if (!objects->objects) { BD_DEBUG(DBG_CRIT, "out of memory\n"); goto error; } for (i = 0; i < objects->num_objects; i++) { if (!_mobj_parse_object(&bs, &objects->objects[i])) { BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: error parsing object %d\n", i); goto error; } } return objects; error: mobj_free(&objects); return NULL; }
void test_bs_set0_right_boundary_hi() { bitset bs; bs_init(&bs, 2, g_heap); bs_set_range(&bs, 0, 1); bs_set_range(&bs, 23, 80); bs_clear_range(&bs, 44, 63); assert_equal(bs.m_bc[0], 0xC00001FFFFF00000); assert_equal(bs.m_bc[1], 0xFFFF800000000000); }
/***************************************************************************** * SVCDSubRenderImage: reorders bytes of image data in subpicture region. ***************************************************************************** The image is encoded using two bits per pixel that select a palette entry except that value 0 starts a limited run-length encoding for color 0. When 0 is seen, the next two bits encode one less than the number of pixels, so we can encode run lengths from 1 to 4. These get filled with the color in palette entry 0. The encoding of each line is padded to a whole number of bytes. The first field is padded to an even byte length and the complete subtitle is padded to a 4-byte multiple that always include one zero byte at the end. However we'll transform this so that that the RLE is expanded and interlacing will also be removed. *****************************************************************************/ static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data, subpicture_region_t *p_region ) { decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p_dest = p_region->p_picture->Y_PIXELS; int i_field; /* The subtitles are interlaced */ int i_row, i_column; /* scanline row/column number */ uint8_t i_color, i_count; bs_t bs; bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset, p_data->i_buffer - p_sys->i_image_offset ); for( i_field = 0; i_field < 2; i_field++ ) { for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 ) { for( i_column = 0; i_column < p_sys->i_width; i_column++ ) { i_color = bs_read( &bs, 2 ); if( i_color == 0 && (i_count = bs_read( &bs, 2 )) ) { i_count = __MIN( i_count, p_sys->i_width - i_column ); memset( &p_dest[i_row * p_region->p_picture->Y_PITCH + i_column], 0, i_count + 1 ); i_column += i_count; continue; } p_dest[i_row * p_region->p_picture->Y_PITCH + i_column] = i_color; } bs_align( &bs ); } /* odd field */ bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset + p_sys->second_field_offset, p_data->i_buffer - p_sys->i_image_offset - p_sys->second_field_offset ); } }
int main(int argc, char* argv[]) { int rv = bs_init(argc, argv); if (rv == SC_OK) { bs_start(); bs_stop(); } bs_destroy(); return rv; }
static void write_bytes( bs_t *s, uint8_t *bytes, int length ) { bs_flush( s ); uint8_t *p_start = s->p_start; memcpy( s->p, bytes, length ); s->p += length; bs_init( s, s->p, s->p_end - s->p ); s->p_start = p_start; }