diff options
author | Mike Lampard <mlampard@users.sourceforge.net> | 2004-12-03 04:55:54 +0000 |
---|---|---|
committer | Mike Lampard <mlampard@users.sourceforge.net> | 2004-12-03 04:55:54 +0000 |
commit | 8351e13e2d26b4990f3f215664ef6ae736d4ba6f (patch) | |
tree | 7dc1538025ada1f15a770ca06e6972e38a019ca8 | |
parent | efe63928fddd53e7df5efd476cbf95fb3765452a (diff) | |
download | xine-lib-8351e13e2d26b4990f3f215664ef6ae736d4ba6f.tar.gz xine-lib-8351e13e2d26b4990f3f215664ef6ae736d4ba6f.tar.bz2 |
major code cleanup, moved more global variables from dvbsub into structs
CVS patchset: 7189
CVS date: 2004/12/03 04:55:54
-rw-r--r-- | src/libspudvb/xine_decoder.c | 975 |
1 files changed, 496 insertions, 479 deletions
diff --git a/src/libspudvb/xine_decoder.c b/src/libspudvb/xine_decoder.c index 6f16a30f6..8f54d16cd 100644 --- a/src/libspudvb/xine_decoder.c +++ b/src/libspudvb/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.4 2004/12/01 22:16:12 mlampard Exp $ + * $Id: xine_decoder.c,v 1.5 2004/12/03 04:55:54 mlampard Exp $ * * DVB Subtitle decoder (ETS 300 743) * (c) 2004 Mike Lampard <mlampard@users.sourceforge.net> @@ -32,651 +32,668 @@ #define MAX_REGIONS 5 typedef struct { - int x,y; - unsigned char is_visible; + int x, y; + unsigned char is_visible; } visible_region_t; typedef struct { - int page_time_out; - int page_version_number; - int page_state; - visible_region_t regions[MAX_REGIONS]; + int page_time_out; + int page_version_number; + int page_state; + int page_id; + visible_region_t regions[MAX_REGIONS]; } page_t; typedef struct { - int width,height; - int depth; - int win; - int CLUT_id; - int objects_start,objects_end; - unsigned int object_pos[65536]; - unsigned char img[720*576]; + int width, height; + int depth; + int win; + int CLUT_id; + int objects_start; + int objects_end; + unsigned int object_pos[65536]; + unsigned char img[720 * 576]; } region_t; typedef struct { /* dvbsub stuff */ - int x; - int y; - unsigned int curr_obj; - unsigned int curr_reg[64]; - - uint8_t *buf; - int i; - int nibble_flag; - int in_scanline; - page_t page; - region_t regions[MAX_REGIONS]; - unsigned int sub_segment_size; -} sub_image_t; - -typedef struct dvb_spu_class_s { - spu_decoder_class_t class; - xine_t *xine; + int x; + int y; + unsigned int curr_obj; + unsigned int curr_reg[64]; + uint8_t *buf; + int i; + int nibble_flag; + int in_scanline; + page_t page; + region_t regions[MAX_REGIONS]; +} dvbsub_func_t; + +typedef struct dvb_spu_class_s { + spu_decoder_class_t class; + xine_t *xine; } dvb_spu_class_t; typedef struct dvb_spu_decoder_s { - spu_decoder_t spu_decoder; - - dvb_spu_class_t *class; - xine_stream_t *stream; - - xine_event_queue_t *event_queue; - - spu_dvb_descriptor_t *spu_descriptor; - - osd_object_t *osd; + spu_decoder_t spu_decoder; + + dvb_spu_class_t *class; + xine_stream_t *stream; + + xine_event_queue_t *event_queue; + + spu_dvb_descriptor_t *spu_descriptor; + + osd_object_t *osd; char *pes_pkt; - char *pes_pkt_wrptr; - unsigned int pes_pkt_size; - unsigned int pes_pkt_complete; - unsigned int pes_pkt_rec; - - uint64_t pts; - uint64_t vpts; - - sub_image_t *dvbsub; - int timeout; - int show; + char *pes_pkt_wrptr; + unsigned int pes_pkt_size; + + uint64_t pts; + uint64_t vpts; + + dvbsub_func_t *dvbsub; + int timeout; + int show; } dvb_spu_decoder_t; -void create_region(dvb_spu_decoder_t *this, int region_id,int region_width,int region_height,int region_depth); -void do_plot(dvb_spu_decoder_t *this, int r,int x, int y, unsigned char pixel); -void plot(dvb_spu_decoder_t *this, int r,int run_length, unsigned char pixel); -unsigned char next_nibble (dvb_spu_decoder_t *this); -void set_clut(dvb_spu_decoder_t *this,int CLUT_id,int CLUT_entry_id,int Y_value, int Cr_value, int Cb_value, int T_value); -void decode_4bit_pixel_code_string(dvb_spu_decoder_t *this, int r, int object_id, int ofs, int n); -void process_pixel_data_sub_block(dvb_spu_decoder_t *this, int r, int o, int ofs, int n); -void process_page_composition_segment(dvb_spu_decoder_t *this); -void process_region_composition_segment(dvb_spu_decoder_t *this); -void process_CLUT_definition_segment(dvb_spu_decoder_t *this); -void process_object_data_segment(dvb_spu_decoder_t *this); -void draw_subtitles(dvb_spu_decoder_t *this); - -void create_region(dvb_spu_decoder_t *this, int region_id,int region_width,int region_height,int region_depth) { - - sub_image_t *dvbsub = this->dvbsub; - - dvbsub->regions[region_id].win=1; - dvbsub->regions[region_id].width=region_width; - dvbsub->regions[region_id].height=region_height; - - memset(dvbsub->regions[region_id].img,15,sizeof(dvbsub->regions[region_id].img)); +void create_region (dvb_spu_decoder_t * this, int region_id, int region_width, int region_height, int region_depth); +void do_plot (dvb_spu_decoder_t * this, int r, int x, int y, unsigned char pixel); +void plot (dvb_spu_decoder_t * this, int r, int run_length, unsigned char pixel); +unsigned char next_nibble (dvb_spu_decoder_t * this); +void set_clut (dvb_spu_decoder_t * this, int CLUT_id, int CLUT_entry_id, int Y_value, int Cr_value, int Cb_value, int T_value); +void decode_4bit_pixel_code_string (dvb_spu_decoder_t * this, int r, int object_id, int ofs, int n); +void process_pixel_data_sub_block (dvb_spu_decoder_t * this, int r, int o, int ofs, int n); +void process_page_composition_segment (dvb_spu_decoder_t * this); +void process_region_composition_segment (dvb_spu_decoder_t * this); +void process_CLUT_definition_segment (dvb_spu_decoder_t * this); +void process_object_data_segment (dvb_spu_decoder_t * this); +void draw_subtitles (dvb_spu_decoder_t * this); + +void create_region (dvb_spu_decoder_t * this, int region_id, int region_width, int region_height, int region_depth) +{ + + dvbsub_func_t *dvbsub = this->dvbsub; + + dvbsub->regions[region_id].win = 1; + dvbsub->regions[region_id].width = region_width; + dvbsub->regions[region_id].height = region_height; + + memset (dvbsub->regions[region_id].img, 15, sizeof (dvbsub->regions[region_id].img)); } - -void do_plot(dvb_spu_decoder_t *this, int r,int x, int y, unsigned char pixel) { + +void do_plot (dvb_spu_decoder_t * this, int r, int x, int y, unsigned char pixel) +{ int i; - sub_image_t *dvbsub = this->dvbsub; + dvbsub_func_t *dvbsub = this->dvbsub; - if ( ( y >= 0) && (y < dvbsub->regions[r].height)) { + if ((y >= 0) && (y < dvbsub->regions[r].height)) { i = (y * dvbsub->regions[r].width) + x; - dvbsub->regions[r].img[i]=pixel; + dvbsub->regions[r].img[i] = pixel; } } -void plot(dvb_spu_decoder_t *this, int r,int run_length, unsigned char pixel) { - - sub_image_t *dvbsub = this->dvbsub; +void plot (dvb_spu_decoder_t * this, int r, int run_length, unsigned char pixel) +{ + + dvbsub_func_t *dvbsub = this->dvbsub; int x2 = dvbsub->x + run_length; while (dvbsub->x < x2) { - do_plot(this, r,dvbsub->x,dvbsub->y,pixel); + do_plot (this, r, dvbsub->x, dvbsub->y, pixel); dvbsub->x++; } } -unsigned char next_nibble (dvb_spu_decoder_t *this) { +unsigned char next_nibble (dvb_spu_decoder_t * this) +{ unsigned char x; - sub_image_t *dvbsub = this->dvbsub; - - if (dvbsub->nibble_flag==0) { - x=(dvbsub->buf[dvbsub->i]&0xf0)>>4; - dvbsub->nibble_flag=1; - } else { - x=(dvbsub->buf[dvbsub->i++]&0x0f); - dvbsub->nibble_flag=0; + dvbsub_func_t *dvbsub = this->dvbsub; + + if (dvbsub->nibble_flag == 0) { + x = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + dvbsub->nibble_flag = 1; } - return(x); + else { + x = (dvbsub->buf[dvbsub->i++] & 0x0f); + dvbsub->nibble_flag = 0; + } + return (x); } - -void decode_4bit_pixel_code_string(dvb_spu_decoder_t *this, int r, int object_id, int ofs, int n) { - int next_bits, - switch_1, - switch_2, - switch_3, - run_length, - pixel_code; - sub_image_t *dvbsub = this->dvbsub; +void decode_4bit_pixel_code_string (dvb_spu_decoder_t * this, int r, int object_id, int ofs, int n) +{ + int next_bits, switch_1, switch_2, switch_3, run_length, pixel_code; + + dvbsub_func_t *dvbsub = this->dvbsub; int bits; unsigned int data; int j; - if (dvbsub->in_scanline==0) { - dvbsub->in_scanline=1; + if (dvbsub->in_scanline == 0) { + dvbsub->in_scanline = 1; } - dvbsub->nibble_flag=0; - j=dvbsub->i + n; - while(dvbsub->i < j) { - - bits=0; - pixel_code=0; - next_bits=next_nibble(this); - - if (next_bits!=0) { - pixel_code=next_bits; - plot(this, r,1,pixel_code); - bits+=4; - } else { - bits+=4; - data=next_nibble(this); - switch_1=(data&0x08)>>3; + dvbsub->nibble_flag = 0; + j = dvbsub->i + n; + while (dvbsub->i < j) { + + bits = 0; + pixel_code = 0; + next_bits = next_nibble (this); + + if (next_bits != 0) { + pixel_code = next_bits; + plot (this, r, 1, pixel_code); + bits += 4; + } + else { + bits += 4; + data = next_nibble (this); + switch_1 = (data & 0x08) >> 3; bits++; - if (switch_1==0) { - run_length=(data&0x07); - bits+=3; - if (run_length!=0) { - plot(this, r,run_length+2,pixel_code); - } else { - break; - } - } else { - switch_2=(data&0x04)>>2; - bits++; - if (switch_2==0) { - run_length=(data&0x03); - bits+=2; - pixel_code=next_nibble(this); - bits+=4; - plot(this, r,run_length+4,pixel_code); - } else { - switch_3=(data&0x03); - bits+=2; - switch (switch_3) { - case 0: plot(this, r,1,pixel_code); - break; - case 1: plot(this, r,2,pixel_code); - break; - case 2: run_length=next_nibble(this); - bits+=4; - pixel_code=next_nibble(this); - bits+=4; - plot(this, r,run_length+9,pixel_code); - break; - case 3: run_length=next_nibble(this); - run_length=(run_length<<4)|next_nibble(this); - bits+=8; - pixel_code=next_nibble(this); - bits+=4; - plot(this, r,run_length+25,pixel_code); - } - } + if (switch_1 == 0) { + run_length = (data & 0x07); + bits += 3; + if (run_length != 0) { + plot (this, r, run_length + 2, pixel_code); + } + else { + break; + } + } + else { + switch_2 = (data & 0x04) >> 2; + bits++; + if (switch_2 == 0) { + run_length = (data & 0x03); + bits += 2; + pixel_code = next_nibble (this); + bits += 4; + plot (this, r, run_length + 4, pixel_code); + } + else { + switch_3 = (data & 0x03); + bits += 2; + switch (switch_3) { + case 0: + plot (this, r, 1, pixel_code); + break; + case 1: + plot (this, r, 2, pixel_code); + break; + case 2: + run_length = next_nibble (this); + bits += 4; + pixel_code = next_nibble (this); + bits += 4; + plot (this, r, run_length + 9, pixel_code); + break; + case 3: + run_length = next_nibble (this); + run_length = (run_length << 4) | next_nibble (this); + bits += 8; + pixel_code = next_nibble (this); + bits += 4; + plot (this, r, run_length + 25, pixel_code); + } + } } } } - if (dvbsub->nibble_flag==1) { + if (dvbsub->nibble_flag == 1) { dvbsub->i++; - dvbsub->nibble_flag=0; + dvbsub->nibble_flag = 0; } } -void process_pixel_data_sub_block(dvb_spu_decoder_t *this, int r, int o, int ofs, int n) { +void process_pixel_data_sub_block (dvb_spu_decoder_t * this, int r, int o, int ofs, int n) +{ int data_type; int j; - sub_image_t *dvbsub = this->dvbsub; + dvbsub_func_t *dvbsub = this->dvbsub; j = dvbsub->i + n; - dvbsub->x=(dvbsub->regions[r].object_pos[o])>>16; - dvbsub->y=((dvbsub->regions[r].object_pos[o])&0xffff)+ofs; + dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16; + dvbsub->y = ((dvbsub->regions[r].object_pos[o]) & 0xffff) + ofs; while (dvbsub->i < j) { - data_type=dvbsub->buf[dvbsub->i++]; - - switch(data_type) { - case 0: dvbsub->i++; - case 0x11: decode_4bit_pixel_code_string(this, r,o,ofs,n-1); - break; - case 0xf0: dvbsub->in_scanline=0; - dvbsub->x=(dvbsub->regions[r].object_pos[o])>>16; - dvbsub->y+=2; - break; - default: fprintf(stderr,"unimplemented data_type %02x in pixel_data_sub_block\n",data_type); + data_type = dvbsub->buf[dvbsub->i++]; + + switch (data_type) { + case 0: + dvbsub->i++; + case 0x11: + decode_4bit_pixel_code_string (this, r, o, ofs, n - 1); + break; + case 0xf0: + dvbsub->in_scanline = 0; + dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16; + dvbsub->y += 2; + break; + default: + lprintf ("unimplemented data_type %02x in pixel_data_sub_block\n", data_type); } } - dvbsub->i=j; + dvbsub->i = j; } -void process_page_composition_segment(dvb_spu_decoder_t *this) { - int page_id, - segment_length, - page_time_out, - page_version_number, - page_state; - int region_id,region_x,region_y; +void process_page_composition_segment (dvb_spu_decoder_t * this) +{ + int segment_length; + int region_id, region_x, region_y; int j; int r; - sub_image_t *dvbsub = this->dvbsub; + dvbsub_func_t *dvbsub = this->dvbsub; - page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; + dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; - j=dvbsub->i+segment_length; + j = dvbsub->i + segment_length; - page_time_out = dvbsub->buf[dvbsub->i++]; - this->timeout=page_time_out; - - page_version_number = (dvbsub->buf [dvbsub->i] & 0xf0)>>4; - page_state=(dvbsub->buf[dvbsub->i]&0x0c)>>2; + dvbsub->page.page_time_out = dvbsub->buf[dvbsub->i++]; + + dvbsub->page.page_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + dvbsub->page.page_state = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; dvbsub->i++; - if ((page_state!=2) && (page_state!=1)) { + if ((dvbsub->page.page_state != 2) && (dvbsub->page.page_state != 1)) { return; - } else { - if(page_state==1 && page_id==this->spu_descriptor->comp_page_id) - draw_subtitles(this); } + else { + draw_subtitles (this); + } + + for (r = 0; r < MAX_REGIONS; r++) { + dvbsub->page.regions[r].is_visible = 0; + } + while (dvbsub->i < j) { + region_id = dvbsub->buf[dvbsub->i++]; + dvbsub->i++; /* reserved */ + region_x = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + region_y = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + dvbsub->page.regions[region_id].x = region_x; + dvbsub->page.regions[region_id].y = region_y; + dvbsub->page.regions[region_id].is_visible = 1; - for (r=0;r<MAX_REGIONS;r++) { - dvbsub->page.regions[r].is_visible=0; } - while (dvbsub->i<j) { - region_id=dvbsub->buf[dvbsub->i++]; - dvbsub->i++; /* reserved */ - region_x=(dvbsub->buf[dvbsub->i]<<8) | dvbsub->buf[dvbsub->i+1]; - dvbsub->i+=2; - region_y=(dvbsub->buf[dvbsub->i]<<8) | dvbsub->buf[dvbsub->i+1]; - dvbsub->i+=2; - - dvbsub->page.regions[region_id].x=region_x; - dvbsub->page.regions[region_id].y=region_y; - dvbsub->page.regions[region_id].is_visible=1; - - } } - - -void process_region_composition_segment(dvb_spu_decoder_t *this) { - int page_id, - segment_length, - region_id, - region_version_number, - region_fill_flag, - region_width, - region_height, - region_level_of_compatibility, - region_depth, - CLUT_id, - region_8_bit_pixel_code, - region_4_bit_pixel_code, - region_2_bit_pixel_code; - int object_id, - object_type, - object_provider_flag, - object_x, - object_y, - foreground_pixel_code, - background_pixel_code; + + +void process_region_composition_segment (dvb_spu_decoder_t * this) +{ + int segment_length, + region_id, + region_version_number, + region_fill_flag, region_width, region_height, region_level_of_compatibility, region_depth, CLUT_id, region_8_bit_pixel_code, region_4_bit_pixel_code, region_2_bit_pixel_code; + int object_id, object_type, object_provider_flag, object_x, object_y, foreground_pixel_code, background_pixel_code; int j; int o; - sub_image_t *dvbsub = this->dvbsub; + dvbsub_func_t *dvbsub = this->dvbsub; - page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - j=dvbsub->i+segment_length; + dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + j = dvbsub->i + segment_length; - region_id=dvbsub->buf[dvbsub->i++]; - region_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4; - region_fill_flag=(dvbsub->buf[dvbsub->i]&0x08)>>3; + region_id = dvbsub->buf[dvbsub->i++]; + region_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + region_fill_flag = (dvbsub->buf[dvbsub->i] & 0x08) >> 3; dvbsub->i++; - region_width=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - region_height=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - region_level_of_compatibility=(dvbsub->buf[dvbsub->i]&0xe0)>>5; - region_depth=(dvbsub->buf[dvbsub->i]&0x1c)>>2; + region_width = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + region_height = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5; + region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2; dvbsub->i++; - CLUT_id=dvbsub->buf[dvbsub->i++]; - region_8_bit_pixel_code=dvbsub->buf[dvbsub->i++]; - region_4_bit_pixel_code=(dvbsub->buf[dvbsub->i]&0xf0)>>4; - region_2_bit_pixel_code=(dvbsub->buf[dvbsub->i]&0x0c)>>2; + CLUT_id = dvbsub->buf[dvbsub->i++]; + region_8_bit_pixel_code = dvbsub->buf[dvbsub->i++]; + region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; dvbsub->i++; if (dvbsub->regions[region_id].win < 0) { /* If the region doesn't exist, then open it. */ - create_region(this, region_id,region_width,region_height,region_depth); - dvbsub->regions[region_id].CLUT_id=CLUT_id; + create_region (this, region_id, region_width, region_height, region_depth); + dvbsub->regions[region_id].CLUT_id = CLUT_id; } - dvbsub->regions[region_id].width=region_width; - dvbsub->regions[region_id].height=region_height; + dvbsub->regions[region_id].width = region_width; + dvbsub->regions[region_id].height = region_height; - if (region_fill_flag==1) { - memset(dvbsub->regions[region_id].img,region_4_bit_pixel_code,sizeof(dvbsub->regions[region_id].img)); + if (region_fill_flag == 1) { + memset (dvbsub->regions[region_id].img, region_4_bit_pixel_code, sizeof (dvbsub->regions[region_id].img)); } - dvbsub->regions[region_id].objects_start=dvbsub->i; - dvbsub->regions[region_id].objects_end=j; + dvbsub->regions[region_id].objects_start = dvbsub->i; + dvbsub->regions[region_id].objects_end = j; - for (o=0;o<65536;o++) { - dvbsub->regions[region_id].object_pos[o]=0xffffffff; + for (o = 0; o < 65536; o++) { + dvbsub->regions[region_id].object_pos[o] = 0xffffffff; } while (dvbsub->i < j) { - object_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - object_type=(dvbsub->buf[dvbsub->i]&0xc0)>>6; - object_provider_flag=(dvbsub->buf[dvbsub->i]&0x30)>>4; - object_x=((dvbsub->buf[dvbsub->i]&0x0f)<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - object_y=((dvbsub->buf[dvbsub->i]&0x0f)<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - - dvbsub->regions[region_id].object_pos[object_id]=(object_x<<16)|object_y; - - if ((object_type==0x01) || (object_type==0x02)) { - foreground_pixel_code=dvbsub->buf[dvbsub->i++]; - background_pixel_code=dvbsub->buf[dvbsub->i++]; + object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6; + object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4; + object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + dvbsub->regions[region_id].object_pos[object_id] = (object_x << 16) | object_y; + + if ((object_type == 0x01) || (object_type == 0x02)) { + foreground_pixel_code = dvbsub->buf[dvbsub->i++]; + background_pixel_code = dvbsub->buf[dvbsub->i++]; } } } -void process_object_data_segment(dvb_spu_decoder_t *this) { - int page_id, - segment_length, - object_id, - object_version_number, - object_coding_method, - non_modifying_colour_flag; - - int top_field_data_block_length, - bottom_field_data_block_length; - - sub_image_t *dvbsub = this->dvbsub; - +void process_object_data_segment (dvb_spu_decoder_t * this) +{ + int segment_length, object_id, object_version_number, object_coding_method, non_modifying_colour_flag; + + int top_field_data_block_length, bottom_field_data_block_length; + + dvbsub_func_t *dvbsub = this->dvbsub; + int j; int old_i; int r; - page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - j=dvbsub->i+segment_length; - - object_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - dvbsub->curr_obj=object_id; - object_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4; - object_coding_method=(dvbsub->buf[dvbsub->i]&0x0c)>>2; - non_modifying_colour_flag=(dvbsub->buf[dvbsub->i]&0x02)>>1; + dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + j = dvbsub->i + segment_length; + + object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + dvbsub->curr_obj = object_id; + object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4; + object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2; + non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1; dvbsub->i++; - old_i=dvbsub->i; - for (r=0;r<MAX_REGIONS;r++) { + old_i = dvbsub->i; + for (r = 0; r < MAX_REGIONS; r++) { /* If this object is in this region... */ - if (dvbsub->regions[r].win >= 0) { - if (dvbsub->regions[r].object_pos[object_id]!=0xffffffff) { - dvbsub->i=old_i; - if (object_coding_method==0) { - top_field_data_block_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - bottom_field_data_block_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2; - - process_pixel_data_sub_block(this, r,object_id,0,top_field_data_block_length); - - process_pixel_data_sub_block(this, r,object_id,1,bottom_field_data_block_length); - } - } - } + if (dvbsub->regions[r].win >= 0) { + if (dvbsub->regions[r].object_pos[object_id] != 0xffffffff) { + dvbsub->i = old_i; + if (object_coding_method == 0) { + top_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + bottom_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1]; + dvbsub->i += 2; + + process_pixel_data_sub_block (this, r, object_id, 0, top_field_data_block_length); + + process_pixel_data_sub_block (this, r, object_id, 1, bottom_field_data_block_length); + } + } + } } } -void draw_subtitles(dvb_spu_decoder_t *this) { +void draw_subtitles (dvb_spu_decoder_t * this) +{ int r; - int x,y,out_y; - int v; - int count; + int x, y, out_y; + pthread_mutex_lock (&this->osd->renderer->osd_mutex); /* update clipping area */ - this->osd->x1 = 1; + this->osd->x1 = 1; this->osd->x2 = 720; - this->osd->y1 = 1; + this->osd->y1 = 1; this->osd->y2 = 576; - /* clear it */ - memset(this->osd->area,0,720*576); - - out_y=0; - count=0; - for (r=0;r<MAX_REGIONS;r++) { + + /* render all regions onto the page */ + /* FIXME: we ought to have an osd per region, to allow for multiple CLUTs */ + out_y = 0; + for (r = 0; r < MAX_REGIONS; r++) { if (this->dvbsub->regions[r].win >= 0) { if (this->dvbsub->page.regions[r].is_visible) { - count++; - out_y=this->dvbsub->page.regions[r].y*720; - - for (y=0;y<this->dvbsub->regions[r].height;y++) { - for (x=0;x<this->dvbsub->regions[r].width;x++) { - v=this->dvbsub->regions[r].img[(y*this->dvbsub->regions[r].width)+x]; - this->osd->area[out_y+x+this->dvbsub->page.regions[r].x]=v*this->dvbsub->regions[r].CLUT_id; - } - out_y+=720; - } + + out_y = this->dvbsub->page.regions[r].y * 720; + /* clear it */ + memset (this->osd->area + (out_y), 0, (720 * 576) - out_y - (this->dvbsub->regions[r].height * 720)); + for (y = 0; y < this->dvbsub->regions[r].height; y++) { + for (x = 0; x < this->dvbsub->regions[r].width; x++) { + this->osd->area[out_y + x + this->dvbsub->page.regions[r].x] = this->dvbsub->regions[r].img[(y * this->dvbsub->regions[r].width) + x]; + } + out_y += 720; + } } } } - /* display immediately */ - this->stream->osd_renderer->show (this->osd, 0); + + pthread_mutex_unlock (&this->osd->renderer->osd_mutex); + + /* display immediately */ + /* FIXME: we should use the page timeout */ + this->stream->osd_renderer->show (this->osd, 0); } -static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { +static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf) +{ dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - if(buf->decoder_flags & BUF_FLAG_SPECIAL){ - if(buf->decoder_info[1]==BUF_SPECIAL_SPU_DVB_DESCRIPTOR) { - if(buf->decoder_info[2]==0) { - this->stream->osd_renderer->clear(this->osd); - this->stream->osd_renderer->hide(this->osd,0); - this->show=0; - } else { - if(this->spu_descriptor) - free(this->spu_descriptor); - this->show=1; - this->spu_descriptor = malloc(buf->decoder_info[2]); - memcpy(this->spu_descriptor,buf->decoder_info_ptr[2],buf->decoder_info[2]); - } + if (buf->decoder_flags & BUF_FLAG_SPECIAL) { + if (buf->decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR) { + if (buf->decoder_info[2] == 0) { + this->stream->osd_renderer->clear (this->osd); + this->stream->osd_renderer->hide (this->osd, 0); + this->show = 0; } - - } else { - if(buf->type & 0xffff){ - if(this->pes_pkt) - free(this->pes_pkt); - this->pes_pkt = malloc (buf->type & 0xffff); - memset(this->pes_pkt,0xff,buf->type & 0xffff); - - this->pes_pkt_wrptr = this->pes_pkt; - this->pes_pkt_size = (buf->type & 0xffff); - this->pts = buf->pts; - - memcpy(this->pes_pkt, buf->content, buf->size); - this->pes_pkt_wrptr+=buf->size; - this->pes_pkt_rec=1; - - }else{ - if(this->pes_pkt){ - memcpy(this->pes_pkt_wrptr, buf->content, buf->size); - this->pes_pkt_wrptr+=buf->size; - } + else { + if (this->spu_descriptor) + free (this->spu_descriptor); + this->show = 1; + this->spu_descriptor = malloc (buf->decoder_info[2]); + xine_fast_memcpy (this->spu_descriptor, buf->decoder_info_ptr[2], buf->decoder_info[2]); } - } - /* inform metronom we've received the package */ - if (buf->pts) { - metronom_t *metronom = this->stream->metronom; - this->vpts = metronom->got_spu_packet(metronom, buf->pts); - } - - /* process the pes section */ - if(this->show) - if(((this->pes_pkt_wrptr - this->pes_pkt) == this->pes_pkt_size) && this->pes_pkt_rec) - { - char *buf=this->pes_pkt; - int page_id; + } + + } + else { + if (buf->type & 0xffff) { + if (this->pes_pkt) + free (this->pes_pkt); + this->pes_pkt = malloc (buf->type & 0xffff); + memset (this->pes_pkt, 0xff, buf->type & 0xffff); + + this->pes_pkt_wrptr = this->pes_pkt; + this->pes_pkt_size = (buf->type & 0xffff); + this->pts = buf->pts; + + xine_fast_memcpy (this->pes_pkt, buf->content, buf->size); + this->pes_pkt_wrptr += buf->size; + } + else { + if (this->pes_pkt) { + xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size); + this->pes_pkt_wrptr += buf->size; + } + } + } + /* inform metronom we've received the package */ + if (buf->pts) { + metronom_t *metronom = this->stream->metronom; + this->vpts = metronom->got_spu_packet (metronom, buf->pts); + } + + /* process the pes section */ + if (this->show) + if (((this->pes_pkt_wrptr - this->pes_pkt) == this->pes_pkt_size)) { + char *buf = this->pes_pkt; int new_i; - int data_identifier,subtitle_stream_id; + int data_identifier, subtitle_stream_id; int segment_length, segment_type; int PES_header_data_length; - int PES_packet_length=this->pes_pkt_size; + int PES_packet_length = this->pes_pkt_size; this->dvbsub->buf = this->pes_pkt; - - PES_header_data_length=0; - this->dvbsub->i=0; + + PES_header_data_length = 0; + this->dvbsub->i = 0; data_identifier = buf[this->dvbsub->i++]; subtitle_stream_id = buf[this->dvbsub->i++]; - while(this->dvbsub->i <= (PES_packet_length)) { - /* SUBTITLING SEGMENT */ - this->dvbsub->i++; - segment_type=buf[this->dvbsub->i++]; - - page_id=(buf[this->dvbsub->i]<<8)|buf[this->dvbsub->i+1]; - segment_length=(buf[this->dvbsub->i+2]<<8)|buf[this->dvbsub->i+3]; - new_i=this->dvbsub->i+segment_length+4; - - /* SEGMENT_DATA_FIELD */ - switch(segment_type & 0xff) { - case 0x10: process_page_composition_segment(this); - break; - case 0x11: process_region_composition_segment(this); - break; - case 0x12: /* process_CLUT_definition_segment(this); */ - break; - case 0x13: process_object_data_segment(this); - break; - case 0x80: /* we have enough data to decode */ - break; - default: - return; - } - - this->dvbsub->i=new_i; - } - - } + while (this->dvbsub->i <= (PES_packet_length)) { + /* SUBTITLING SEGMENT */ + this->dvbsub->i++; + segment_type = buf[this->dvbsub->i++]; + + this->dvbsub->page.page_id = (buf[this->dvbsub->i] << 8) | buf[this->dvbsub->i + 1]; + segment_length = (buf[this->dvbsub->i + 2] << 8) | buf[this->dvbsub->i + 3]; + new_i = this->dvbsub->i + segment_length + 4; + + /* SEGMENT_DATA_FIELD */ + switch (segment_type & 0xff) { + case 0x10: + process_page_composition_segment (this); + break; + case 0x11: + process_region_composition_segment (this); + break; + case 0x12: /* process_CLUT_definition_segment(this); */ + break; + case 0x13: + process_object_data_segment (this); + break; + case 0x80: /* we have enough data to decode */ + break; + default: + return; + } + + this->dvbsub->i = new_i; + } + + } return; } -static void spudec_reset (spu_decoder_t *this_gen) { +static void spudec_reset (spu_decoder_t * this_gen) +{ dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - if(this->osd) - this->stream->osd_renderer->hide(this->osd,0); + if (this->osd) + this->stream->osd_renderer->hide (this->osd, 0); } - -static void spudec_discontinuity (spu_decoder_t *this_gen) { - /* do nothing */ + +static void spudec_discontinuity (spu_decoder_t * this_gen) +{ + /* do nothing */ } - -static void spudec_dispose (spu_decoder_t *this_gen) { - dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; - if (this->osd) { - this->stream->osd_renderer->free_object (this->osd); - this->osd = NULL; - } +static void spudec_dispose (spu_decoder_t * this_gen) +{ + dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; + + if (this->osd) { + this->stream->osd_renderer->free_object (this->osd); + this->osd = NULL; + } - if(this->pes_pkt) - free(this->pes_pkt); + if (this->pes_pkt) + free (this->pes_pkt); - if(this->dvbsub) - free(this->dvbsub); + if (this->dvbsub) + free (this->dvbsub); - free(this); + free (this); } -static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { +static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream) +{ int i; - dvb_spu_decoder_t *this ; - dvb_spu_class_t *class = (dvb_spu_class_t *)class_gen; - + dvb_spu_decoder_t *this; + dvb_spu_class_t *class = (dvb_spu_class_t *) class_gen; + this = (dvb_spu_decoder_t *) xine_xmalloc (sizeof (dvb_spu_decoder_t)); - - this->spu_decoder.decode_data = spudec_decode_data; - this->spu_decoder.reset = spudec_reset; - this->spu_decoder.discontinuity = spudec_discontinuity; - this->spu_decoder.dispose = spudec_dispose; - this->spu_decoder.get_interact_info = NULL; - this->spu_decoder.set_button = NULL; - - this->class = class; + + this->spu_decoder.decode_data = spudec_decode_data; + this->spu_decoder.reset = spudec_reset; + this->spu_decoder.discontinuity = spudec_discontinuity; + this->spu_decoder.dispose = spudec_dispose; + this->spu_decoder.get_interact_info = NULL; + this->spu_decoder.set_button = NULL; + + this->class = class; this->stream = stream; - - this->event_queue = NULL; - this->dvbsub=malloc(sizeof(sub_image_t)); + this->event_queue = NULL; + + this->dvbsub = malloc (sizeof (dvbsub_func_t)); - for (i=0;i<MAX_REGIONS;i++) { - this->dvbsub->page.regions[i].is_visible=0; - this->dvbsub->regions[i].win=-1; + for (i = 0; i < MAX_REGIONS; i++) { + this->dvbsub->page.regions[i].is_visible = 0; + this->dvbsub->regions[i].win = -1; } - this->osd = this->stream->osd_renderer->new_object(this->stream->osd_renderer, 720, 600); - this->stream->osd_renderer->set_position(this->osd, 1, 1); - this->stream->osd_renderer->set_font(this->osd, "cetus", 26); - this->stream->osd_renderer->set_encoding(this->osd, NULL); - this->stream->osd_renderer->set_text_palette(this->osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1); + this->osd = this->stream->osd_renderer->new_object (this->stream->osd_renderer, 720, 600); + this->stream->osd_renderer->set_position (this->osd, 1, 1); + this->stream->osd_renderer->set_font (this->osd, "cetus", 26); + this->stream->osd_renderer->set_encoding (this->osd, NULL); + this->stream->osd_renderer->set_text_palette (this->osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1); - return (spu_decoder_t *) this; -} + return (spu_decoder_t *) this; +} -static void dvb_spu_class_dispose (spu_decoder_class_t *this) { +static void dvb_spu_class_dispose (spu_decoder_class_t * this) +{ free (this); } -static char *dvb_spu_class_get_identifier (spu_decoder_class_t *this) { +static char *dvb_spu_class_get_identifier (spu_decoder_class_t * this) +{ return "spudvb"; } - -static char *dvb_spu_class_get_description (spu_decoder_class_t *this) { + +static char *dvb_spu_class_get_description (spu_decoder_class_t * this) +{ return "DVB subtitle decoder plugin"; } - -static void *init_spu_decoder_plugin (xine_t *xine, void *data) { + +static void *init_spu_decoder_plugin (xine_t * xine, void *data) +{ dvb_spu_class_t *this; this = (dvb_spu_class_t *) xine_xmalloc (sizeof (dvb_spu_class_t)); - - this->class.open_plugin = dvb_spu_class_open_plugin; - this->class.get_identifier = dvb_spu_class_get_identifier; - this->class.get_description = dvb_spu_class_get_description; - this->class.dispose = dvb_spu_class_dispose; - - this->xine = xine; - - return &this->class; + + this->class.open_plugin = dvb_spu_class_open_plugin; + this->class.get_identifier = dvb_spu_class_get_identifier; + this->class.get_description = dvb_spu_class_get_description; + this->class.dispose = dvb_spu_class_dispose; + + this->xine = xine; + + return &this->class; } @@ -684,13 +701,13 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) { static uint32_t supported_types[] = { BUF_SPU_DVB, 0 }; static decoder_info_t spudec_info = { - supported_types, /* supported types */ - 1 /* priority */ + supported_types, /* supported types */ + 1 /* priority */ }; - + plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_SPU_DECODER, 16, "spudvb", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } + {PLUGIN_SPU_DECODER, 16, "spudvb", XINE_VERSION_CODE, &spudec_info, + &init_spu_decoder_plugin}, + {PLUGIN_NONE, 0, "", 0, NULL, NULL} }; - |