Hi On Thu, Jan 25, 2007 at 11:51:04AM +0000, Ian Caulfield wrote: > Hi, > > The attached patches add support for HD DVD subtitles (both 2-bit and 8-bit) > to the dvdsub decoder. The patches depend on my earlier bugfix/tidy patches, > which I've reattached as dvdsub1.patch and dvdsub2.patch. 1 patch per mail is prefered, 2patches (1 functional + 1 cosmetic is ok too) but reposting all the prerequisites together with 5 new patches really makes our work hard > > dvdsubdec-rename.patch renames one of the internal functions and some local > variable in order to avoid confusion between the 2-bit and 8-bit RLE modes. > > dvdsubdec-hd.patch adds the HD DVD subtitle support > > dvdsubdec-retab.patch retabulates the code > > I'm not sure about the yuvtorgb code - I lifted this from dvbsubdec.c, but I > reckon it should probably live somewhere else, though I couldn't decide > where. well choose a filename you like and put it there, copy and paste is not ok ideally the yuv2rgb code from libswscale/ should be used / or the code should be moved into libswscale/ but thats not so important and can be done later [...] > @@ -78,6 +117,55 @@ > return 0; > } > > +static int decode_rle_8bit(uint8_t *bitmap, int linesize, int w, int h, > + const uint8_t *buf, int start, int buf_size) > +{ > + GetBitContext gb; > + int bit_len; > + int x, y, len, color, has_run; > + uint8_t *d; > + > + bit_len = (buf_size - start) * 8; > + init_get_bits(&gb, buf + start, bit_len); > + > + x = 0; > + y = 0; > + d = bitmap; > + for(;;) { > + if (get_bits_count(&gb) > bit_len) > + return -1; > + has_run = get_bits1(&gb); > + if (get_bits1(&gb)) > + color = get_bits(&gb, 8); > + else > + color = get_bits(&gb, 2); > + if (has_run) { > + if (get_bits1(&gb)) { > + len = get_bits(&gb, 7); > + if (len == 0) > + len = w - x; > + else > + len += 9; > + } else > + len = get_bits(&gb, 3) + 2; > + } else > + len = 1; > + > + len = FFMIN(len, w - x); > + memset(d + x, color, len); > + x += len; > + if (x >= w) { > + y++; > + if (y >= h) > + break; > + d += linesize; > + x = 0; > + align_get_bits(&gb); this looks duplicated, maybe this can be factored out into its own function? > + } > + } > + return 0; > +} > + > static void guess_palette(uint32_t *rgba_palette, > uint8_t *palette, > uint8_t *alpha, > @@ -125,27 +213,39 @@ > const uint8_t *buf, int buf_size) > { > int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; > + int big_offsets = 0, is_8bit = 0; > uint8_t colormap_2bit[4], alpha_2bit[4]; > + uint32_t palette_8bit[256]; > int date; > int i; > int is_menu = 0; > > - if (buf_size < 4) > + if (buf_size < 10) > return -1; > sub_header->rects = NULL; > sub_header->num_rects = 0; > sub_header->start_display_time = 0; > sub_header->end_display_time = 0; > > + if (AV_RB16(buf) == 0) /* HD subpicture with 4-byte offsets */ > + big_offsets = 1; > + > + if (big_offsets) > + cmd_pos = AV_RB32(buf + 6); > + else > cmd_pos = AV_RB16(buf + 2); > - while ((cmd_pos + 4) < buf_size) { > + > + while ((cmd_pos + (big_offsets ? 6 : 4)) < buf_size) { > date = AV_RB16(buf + cmd_pos); > + if (big_offsets) > + next_cmd_pos = AV_RB32(buf + cmd_pos + 2); > + else > next_cmd_pos = AV_RB16(buf + cmd_pos + 2); > #ifdef DEBUG > av_log(NULL, AV_LOG_INFO, "cmd_pos=0x%04x next=0x%04x date=%d\n", > cmd_pos, next_cmd_pos, date); > #endif > - pos = cmd_pos + 4; > + pos = cmd_pos + (big_offsets ? 6 : 4); > offset1 = -1; > offset2 = -1; > x1 = y1 = x2 = y2 = 0; > @@ -191,6 +291,7 @@ > #endif > break; > case 0x05: > + case 0x85: > if ((buf_size - pos) < 6) > goto fail; > x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4); > @@ -213,6 +314,40 @@ > #endif > pos += 4; > break; > + case 0x86: > + if ((buf_size - pos) < 8) > + goto fail; > + offset1 = AV_RB32(buf + pos); > + offset2 = AV_RB32(buf + pos + 4); > +#ifdef DEBUG > + av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); > +#endif > + pos += 8; > + break; > + > + case 0x83: > + /* HD set palette */ > + if ((buf_size - pos) < 768) > + goto fail; > + for (i = 0; i < 256; i++) > + palette_8bit[i] = (palette_8bit[i] & 0xff000000) > + | yuv_to_rgb32(buf[pos+i*3], > + buf[pos+i*3+1], > + buf[pos+i*3+2]); > + is_8bit = 1; > + pos += 768; > + break; > + case 0x84: > + /* HD set contrast (alpha) */ > + if ((buf_size - pos) < 256) > + goto fail; > + for (i = 0; i < 256; i++) > + palette_8bit[i] = (palette_8bit[i] & 0x00ffffff) > + | ((0xFF - buf[pos+i]) << 24); > + is_8bit = 1; > + pos += 256; > + break; > + something like if(big_palette){ nb_colors= 256; pal_entry_size= 24; alpha_entry_size= 8; }else{ nb_colors= 4; pal_entry_size= 4; alpha_entry_size= 4; } case 0x03: case 0x83: /* set palette */ if ((buf_size - pos) < pal_entry_size*nb_colors/8) goto fail; for(i=0; i<nb_colors; i++) palette[i]= get_bits(pal_entry_size); break; case 0x04: case 0x04: /* set alpha */ if ((buf_size - pos) < alpha_entry_size*nb_colors/8) goto fail; for(i=0; i<nb_colors; i++) alpha[i]= get_bits(alpha_entry_size); break; the same can be done with case 0x86/6 and guess_palette() could then do the yuv->rgb which is IMHO cleaner then your code where the 2bit palette is "converted" in guess_palette() while the 8bit one is handled while it is read [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No snowflake in an avalanche ever feels responsible. -- Voltaire -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070127/303f8a9b/attachment.pgp>
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4