Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * DVB subtitle encoding
  3.  * Copyright (c) 2005 Fabrice Bellard
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21. #include "avcodec.h"
  22. #include "bytestream.h"
  23. #include "libavutil/colorspace.h"
  24.  
  25. typedef struct DVBSubtitleContext {
  26.     int object_version;
  27. } DVBSubtitleContext;
  28.  
  29. #define PUTBITS2(val)\
  30. {\
  31.     bitbuf |= (val) << bitcnt;\
  32.     bitcnt -= 2;\
  33.     if (bitcnt < 0) {\
  34.         bitcnt = 6;\
  35.         *q++ = bitbuf;\
  36.         bitbuf = 0;\
  37.     }\
  38. }
  39.  
  40. static void dvb_encode_rle2(uint8_t **pq,
  41.                             const uint8_t *bitmap, int linesize,
  42.                             int w, int h)
  43. {
  44.     uint8_t *q;
  45.     unsigned int bitbuf;
  46.     int bitcnt;
  47.     int x, y, len, x1, v, color;
  48.  
  49.     q = *pq;
  50.  
  51.     for(y = 0; y < h; y++) {
  52.         *q++ = 0x10;
  53.         bitbuf = 0;
  54.         bitcnt = 6;
  55.  
  56.         x = 0;
  57.         while (x < w) {
  58.             x1 = x;
  59.             color = bitmap[x1++];
  60.             while (x1 < w && bitmap[x1] == color)
  61.                 x1++;
  62.             len = x1 - x;
  63.             if (color == 0 && len == 2) {
  64.                 PUTBITS2(0);
  65.                 PUTBITS2(0);
  66.                 PUTBITS2(1);
  67.             } else if (len >= 3 && len <= 10) {
  68.                 v = len - 3;
  69.                 PUTBITS2(0);
  70.                 PUTBITS2((v >> 2) | 2);
  71.                 PUTBITS2(v & 3);
  72.                 PUTBITS2(color);
  73.             } else if (len >= 12 && len <= 27) {
  74.                 v = len - 12;
  75.                 PUTBITS2(0);
  76.                 PUTBITS2(0);
  77.                 PUTBITS2(2);
  78.                 PUTBITS2(v >> 2);
  79.                 PUTBITS2(v & 3);
  80.                 PUTBITS2(color);
  81.             } else if (len >= 29) {
  82.                 /* length = 29 ... 284 */
  83.                 if (len > 284)
  84.                     len = 284;
  85.                 v = len - 29;
  86.                 PUTBITS2(0);
  87.                 PUTBITS2(0);
  88.                 PUTBITS2(3);
  89.                 PUTBITS2((v >> 6));
  90.                 PUTBITS2((v >> 4) & 3);
  91.                 PUTBITS2((v >> 2) & 3);
  92.                 PUTBITS2(v & 3);
  93.                 PUTBITS2(color);
  94.             } else {
  95.                 PUTBITS2(color);
  96.                 if (color == 0) {
  97.                     PUTBITS2(1);
  98.                 }
  99.                 len = 1;
  100.             }
  101.             x += len;
  102.         }
  103.         /* end of line */
  104.         PUTBITS2(0);
  105.         PUTBITS2(0);
  106.         PUTBITS2(0);
  107.         if (bitcnt != 6) {
  108.             *q++ = bitbuf;
  109.         }
  110.         *q++ = 0xf0;
  111.         bitmap += linesize;
  112.     }
  113.     *pq = q;
  114. }
  115.  
  116. #define PUTBITS4(val)\
  117. {\
  118.     bitbuf |= (val) << bitcnt;\
  119.     bitcnt -= 4;\
  120.     if (bitcnt < 0) {\
  121.         bitcnt = 4;\
  122.         *q++ = bitbuf;\
  123.         bitbuf = 0;\
  124.     }\
  125. }
  126.  
  127. /* some DVB decoders only implement 4 bits/pixel */
  128. static void dvb_encode_rle4(uint8_t **pq,
  129.                             const uint8_t *bitmap, int linesize,
  130.                             int w, int h)
  131. {
  132.     uint8_t *q;
  133.     unsigned int bitbuf;
  134.     int bitcnt;
  135.     int x, y, len, x1, v, color;
  136.  
  137.     q = *pq;
  138.  
  139.     for(y = 0; y < h; y++) {
  140.         *q++ = 0x11;
  141.         bitbuf = 0;
  142.         bitcnt = 4;
  143.  
  144.         x = 0;
  145.         while (x < w) {
  146.             x1 = x;
  147.             color = bitmap[x1++];
  148.             while (x1 < w && bitmap[x1] == color)
  149.                 x1++;
  150.             len = x1 - x;
  151.             if (color == 0 && len == 2) {
  152.                 PUTBITS4(0);
  153.                 PUTBITS4(0xd);
  154.             } else if (color == 0 && (len >= 3 && len <= 9)) {
  155.                 PUTBITS4(0);
  156.                 PUTBITS4(len - 2);
  157.             } else if (len >= 4 && len <= 7) {
  158.                 PUTBITS4(0);
  159.                 PUTBITS4(8 + len - 4);
  160.                 PUTBITS4(color);
  161.             } else if (len >= 9 && len <= 24) {
  162.                 PUTBITS4(0);
  163.                 PUTBITS4(0xe);
  164.                 PUTBITS4(len - 9);
  165.                 PUTBITS4(color);
  166.             } else if (len >= 25) {
  167.                 if (len > 280)
  168.                     len = 280;
  169.                 v = len - 25;
  170.                 PUTBITS4(0);
  171.                 PUTBITS4(0xf);
  172.                 PUTBITS4(v >> 4);
  173.                 PUTBITS4(v & 0xf);
  174.                 PUTBITS4(color);
  175.             } else {
  176.                 PUTBITS4(color);
  177.                 if (color == 0) {
  178.                     PUTBITS4(0xc);
  179.                 }
  180.                 len = 1;
  181.             }
  182.             x += len;
  183.         }
  184.         /* end of line */
  185.         PUTBITS4(0);
  186.         PUTBITS4(0);
  187.         if (bitcnt != 4) {
  188.             *q++ = bitbuf;
  189.         }
  190.         *q++ = 0xf0;
  191.         bitmap += linesize;
  192.     }
  193.     *pq = q;
  194. }
  195.  
  196. static void dvb_encode_rle8(uint8_t **pq,
  197.                             const uint8_t *bitmap, int linesize,
  198.                             int w, int h)
  199. {
  200.     uint8_t *q;
  201.     int x, y, len, x1, color;
  202.  
  203.     q = *pq;
  204.  
  205.     for (y = 0; y < h; y++) {
  206.         *q++ = 0x12;
  207.  
  208.         x = 0;
  209.         while (x < w) {
  210.             x1 = x;
  211.             color = bitmap[x1++];
  212.             while (x1 < w && bitmap[x1] == color)
  213.                 x1++;
  214.             len = x1 - x;
  215.             if (len == 1 && color) {
  216.                 // 00000001 to 11111111           1 pixel in colour x
  217.                 *q++ = color;
  218.             } else {
  219.                 if (color == 0x00) {
  220.                     // 00000000 0LLLLLLL          L pixels (1-127) in colour 0 (L > 0)
  221.                     len = FFMIN(len, 127);
  222.                     *q++ = 0x00;
  223.                     *q++ = len;
  224.                 } else if (len > 2) {
  225.                     // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2)
  226.                     len = FFMIN(len, 127);
  227.                     *q++ = 0x00;
  228.                     *q++ = 0x80+len;
  229.                     *q++ = color;
  230.                 }
  231.                 else if (len == 2) {
  232.                     *q++ = color;
  233.                     *q++ = color;
  234.                 } else {
  235.                     *q++ = color;
  236.                     len = 1;
  237.                 }
  238.             }
  239.             x += len;
  240.         }
  241.         /* end of line */
  242.         // 00000000 00000000 end of 8-bit/pixel_code_string
  243.         *q++ = 0x00;
  244.         *q++ = 0x00;
  245.         bitmap += linesize;
  246.     }
  247.     *pq = q;
  248. }
  249.  
  250. static int encode_dvb_subtitles(DVBSubtitleContext *s,
  251.                                 uint8_t *outbuf, const AVSubtitle *h)
  252. {
  253.     uint8_t *q, *pseg_len;
  254.     int page_id, region_id, clut_id, object_id, i, bpp_index, page_state;
  255.  
  256.  
  257.     q = outbuf;
  258.  
  259.     page_id = 1;
  260.  
  261.     if (h->num_rects && h->rects == NULL)
  262.         return -1;
  263.  
  264.     *q++ = 0x00; /* subtitle_stream_id */
  265.  
  266.     /* page composition segment */
  267.  
  268.     *q++ = 0x0f; /* sync_byte */
  269.     *q++ = 0x10; /* segment_type */
  270.     bytestream_put_be16(&q, page_id);
  271.     pseg_len = q;
  272.     q += 2; /* segment length */
  273.     *q++ = 30; /* page_timeout (seconds) */
  274.     page_state = 2; /* mode change */
  275.     /* page_version = 0 + page_state */
  276.     *q++ = (s->object_version << 4) | (page_state << 2) | 3;
  277.  
  278.     for (region_id = 0; region_id < h->num_rects; region_id++) {
  279.         *q++ = region_id;
  280.         *q++ = 0xff; /* reserved */
  281.         bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
  282.         bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
  283.     }
  284.  
  285.     bytestream_put_be16(&pseg_len, q - pseg_len - 2);
  286.  
  287.     if (h->num_rects) {
  288.         for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
  289.  
  290.             /* CLUT segment */
  291.  
  292.             if (h->rects[clut_id]->nb_colors <= 4) {
  293.                 /* 2 bpp, some decoders do not support it correctly */
  294.                 bpp_index = 0;
  295.             } else if (h->rects[clut_id]->nb_colors <= 16) {
  296.                 /* 4 bpp, standard encoding */
  297.                 bpp_index = 1;
  298.             } else if (h->rects[clut_id]->nb_colors <= 256) {
  299.                 /* 8 bpp, standard encoding */
  300.                 bpp_index = 2;
  301.             } else {
  302.                 return -1;
  303.             }
  304.  
  305.  
  306.             /* CLUT segment */
  307.             *q++ = 0x0f; /* sync byte */
  308.             *q++ = 0x12; /* CLUT definition segment */
  309.             bytestream_put_be16(&q, page_id);
  310.             pseg_len = q;
  311.             q += 2; /* segment length */
  312.             *q++ = clut_id;
  313.             *q++ = (0 << 4) | 0xf; /* version = 0 */
  314.  
  315.             for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
  316.                 *q++ = i; /* clut_entry_id */
  317.                 *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
  318.                 {
  319.                     int a, r, g, b;
  320.                     uint32_t x= ((uint32_t*)h->rects[clut_id]->pict.data[1])[i];
  321.                     a = (x >> 24) & 0xff;
  322.                     r = (x >> 16) & 0xff;
  323.                     g = (x >>  8) & 0xff;
  324.                     b = (x >>  0) & 0xff;
  325.  
  326.                     *q++ = RGB_TO_Y_CCIR(r, g, b);
  327.                     *q++ = RGB_TO_V_CCIR(r, g, b, 0);
  328.                     *q++ = RGB_TO_U_CCIR(r, g, b, 0);
  329.                     *q++ = 255 - a;
  330.                 }
  331.             }
  332.  
  333.             bytestream_put_be16(&pseg_len, q - pseg_len - 2);
  334.         }
  335.     }
  336.  
  337.     for (region_id = 0; region_id < h->num_rects; region_id++) {
  338.  
  339.         /* region composition segment */
  340.  
  341.         if (h->rects[region_id]->nb_colors <= 4) {
  342.             /* 2 bpp, some decoders do not support it correctly */
  343.             bpp_index = 0;
  344.         } else if (h->rects[region_id]->nb_colors <= 16) {
  345.             /* 4 bpp, standard encoding */
  346.             bpp_index = 1;
  347.         } else {
  348.             return -1;
  349.         }
  350.  
  351.         *q++ = 0x0f; /* sync_byte */
  352.         *q++ = 0x11; /* segment_type */
  353.         bytestream_put_be16(&q, page_id);
  354.         pseg_len = q;
  355.         q += 2; /* segment length */
  356.         *q++ = region_id;
  357.         *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
  358.         bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
  359.         bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
  360.         *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
  361.         *q++ = region_id; /* clut_id == region_id */
  362.         *q++ = 0; /* 8 bit fill colors */
  363.         *q++ = 0x03; /* 4 bit and 2 bit fill colors */
  364.  
  365.         bytestream_put_be16(&q, region_id); /* object_id == region_id */
  366.         *q++ = (0 << 6) | (0 << 4);
  367.         *q++ = 0;
  368.         *q++ = 0xf0;
  369.         *q++ = 0;
  370.  
  371.         bytestream_put_be16(&pseg_len, q - pseg_len - 2);
  372.     }
  373.  
  374.     if (h->num_rects) {
  375.  
  376.         for (object_id = 0; object_id < h->num_rects; object_id++) {
  377.             void (*dvb_encode_rle)(uint8_t **pq,
  378.                                     const uint8_t *bitmap, int linesize,
  379.                                     int w, int h);
  380.  
  381.             /* bpp_index maths */
  382.             if (h->rects[object_id]->nb_colors <= 4) {
  383.                 /* 2 bpp, some decoders do not support it correctly */
  384.                 dvb_encode_rle = dvb_encode_rle2;
  385.             } else if (h->rects[object_id]->nb_colors <= 16) {
  386.                 /* 4 bpp, standard encoding */
  387.                 dvb_encode_rle = dvb_encode_rle4;
  388.             } else if (h->rects[object_id]->nb_colors <= 256) {
  389.                 /* 8 bpp, standard encoding */
  390.                 dvb_encode_rle = dvb_encode_rle8;
  391.             } else {
  392.                 return -1;
  393.             }
  394.  
  395.             /* Object Data segment */
  396.             *q++ = 0x0f; /* sync byte */
  397.             *q++ = 0x13;
  398.             bytestream_put_be16(&q, page_id);
  399.             pseg_len = q;
  400.             q += 2; /* segment length */
  401.  
  402.             bytestream_put_be16(&q, object_id);
  403.             *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
  404.                                                                        onject_coding_method,
  405.                                                                        non_modifying_color_flag */
  406.             {
  407.                 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
  408.  
  409.                 ptop_field_len = q;
  410.                 q += 2;
  411.                 pbottom_field_len = q;
  412.                 q += 2;
  413.  
  414.                 top_ptr = q;
  415.                 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0], h->rects[object_id]->w * 2,
  416.                                     h->rects[object_id]->w, h->rects[object_id]->h >> 1);
  417.                 bottom_ptr = q;
  418.                 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0] + h->rects[object_id]->w,
  419.                                     h->rects[object_id]->w * 2, h->rects[object_id]->w,
  420.                                     h->rects[object_id]->h >> 1);
  421.  
  422.                 bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
  423.                 bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
  424.             }
  425.  
  426.             bytestream_put_be16(&pseg_len, q - pseg_len - 2);
  427.         }
  428.     }
  429.  
  430.     /* end of display set segment */
  431.  
  432.     *q++ = 0x0f; /* sync_byte */
  433.     *q++ = 0x80; /* segment_type */
  434.     bytestream_put_be16(&q, page_id);
  435.     pseg_len = q;
  436.     q += 2; /* segment length */
  437.  
  438.     bytestream_put_be16(&pseg_len, q - pseg_len - 2);
  439.  
  440.     *q++ = 0xff; /* end of PES data */
  441.  
  442.     s->object_version = (s->object_version + 1) & 0xf;
  443.     return q - outbuf;
  444. }
  445.  
  446. static int dvbsub_encode(AVCodecContext *avctx,
  447.                          unsigned char *buf, int buf_size,
  448.                          const AVSubtitle *sub)
  449. {
  450.     DVBSubtitleContext *s = avctx->priv_data;
  451.     int ret;
  452.  
  453.     ret = encode_dvb_subtitles(s, buf, sub);
  454.     return ret;
  455. }
  456.  
  457. AVCodec ff_dvbsub_encoder = {
  458.     .name           = "dvbsub",
  459.     .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
  460.     .type           = AVMEDIA_TYPE_SUBTITLE,
  461.     .id             = AV_CODEC_ID_DVB_SUBTITLE,
  462.     .priv_data_size = sizeof(DVBSubtitleContext),
  463.     .encode_sub     = dvbsub_encode,
  464. };
  465.