dvbsubdec.c File Reference

#include "avcodec.h"
#include "dsputil.h"
#include "bitstream.h"
#include "colorspace.h"

Go to the source code of this file.

Data Structures

struct  DVBSubCLUT
struct  DVBSubObjectDisplay
struct  DVBSubObject
struct  DVBSubRegionDisplay
struct  DVBSubRegion
struct  DVBSubContext

Defines

#define DVBSUB_PAGE_SEGMENT   0x10
#define DVBSUB_REGION_SEGMENT   0x11
#define DVBSUB_CLUT_SEGMENT   0x12
#define DVBSUB_OBJECT_SEGMENT   0x13
#define DVBSUB_DISPLAY_SEGMENT   0x80
#define cm   (ff_cropTbl + MAX_NEG_CROP)
#define RGBA(r, g, b, a)   (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))

Functions

static DVBSubObjectget_object (DVBSubContext *ctx, int object_id)
static DVBSubCLUTget_clut (DVBSubContext *ctx, int clut_id)
static DVBSubRegionget_region (DVBSubContext *ctx, int region_id)
static void delete_region_display_list (DVBSubContext *ctx, DVBSubRegion *region)
static void delete_state (DVBSubContext *ctx)
static av_cold int dvbsub_init_decoder (AVCodecContext *avctx)
static av_cold int dvbsub_close_decoder (AVCodecContext *avctx)
static int dvbsub_read_2bit_string (uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table)
static int dvbsub_read_4bit_string (uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table)
static int dvbsub_read_8bit_string (uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table)
static void dvbsub_parse_pixel_data_block (AVCodecContext *avctx, DVBSubObjectDisplay *display, const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
static void dvbsub_parse_object_segment (AVCodecContext *avctx, const uint8_t *buf, int buf_size)
static void dvbsub_parse_clut_segment (AVCodecContext *avctx, const uint8_t *buf, int buf_size)
static void dvbsub_parse_region_segment (AVCodecContext *avctx, const uint8_t *buf, int buf_size)
static void dvbsub_parse_page_segment (AVCodecContext *avctx, const uint8_t *buf, int buf_size)
static int dvbsub_display_end_segment (AVCodecContext *avctx, const uint8_t *buf, int buf_size, AVSubtitle *sub)
static int dvbsub_decode (AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)

Variables

static DVBSubCLUT default_clut
AVCodec dvbsub_decoder


Define Documentation

#define cm   (ff_cropTbl + MAX_NEG_CROP)

Definition at line 36 of file dvbsubdec.c.

Referenced by add_pixels_clamped2_c(), add_pixels_clamped4_c(), add_pixels_clamped_c(), cavs_idct8_add_c(), deinterlace_line(), deinterlace_line_inplace(), ff_bfin_vp3_idct_put(), ff_h264_idct8_add_c(), ff_h264_idct8_dc_add_c(), ff_h264_idct_dc_add_c(), ff_idct_put_mlib(), ff_jref_idct1_add(), ff_jref_idct1_put(), h_block_filter(), idct(), idct4col_add(), idct4col_put(), idct_add(), idct_internal(), idct_put(), idctSparseColAdd(), idctSparseColPut(), img_convert_init(), intra_pred_plane(), mp_yuv_to_rgb(), pred16x16_plane_compat_c(), pred8x8_plane_c(), Process(), put_pixels_clamped2_c(), put_pixels_clamped4_c(), put_pixels_clamped_c(), svq3_add_idct_c(), v_block_filter(), vc1_inv_trans_4x4_c(), vc1_inv_trans_4x8_c(), vc1_inv_trans_8x4_c(), wmv2_mspel8_h_lowpass(), wmv2_mspel8_v_lowpass(), and yuv_a_to_rgba().

#define DVBSUB_CLUT_SEGMENT   0x12

Definition at line 32 of file dvbsubdec.c.

Referenced by dvbsub_decode().

#define DVBSUB_DISPLAY_SEGMENT   0x80

Definition at line 34 of file dvbsubdec.c.

Referenced by dvbsub_decode().

#define DVBSUB_OBJECT_SEGMENT   0x13

Definition at line 33 of file dvbsubdec.c.

Referenced by dvbsub_decode().

#define DVBSUB_PAGE_SEGMENT   0x10

Definition at line 30 of file dvbsubdec.c.

Referenced by dvbsub_decode().

#define DVBSUB_REGION_SEGMENT   0x11

Definition at line 31 of file dvbsubdec.c.

Referenced by dvbsub_decode().

#define RGBA ( r,
g,
b,
 )     (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))

Definition at line 154 of file dvbsubdec.c.

Referenced by dvbsub_init_decoder(), and dvbsub_parse_clut_segment().


Function Documentation

static void delete_region_display_list ( DVBSubContext ctx,
DVBSubRegion region 
) [static]

Definition at line 266 of file dvbsubdec.c.

References av_free(), DVBSubObject::display_list, DVBSubRegion::display_list, get_object(), DVBSubObject::next, DVBSubObjectDisplay::object_id, DVBSubContext::object_list, DVBSubObjectDisplay::object_list_next, and DVBSubObjectDisplay::region_list_next.

Referenced by delete_state(), and dvbsub_parse_region_segment().

00267 {
00268     DVBSubObject *object, *obj2, **obj2_ptr;
00269     DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
00270 
00271     while (region->display_list) {
00272         display = region->display_list;
00273 
00274         object = get_object(ctx, display->object_id);
00275 
00276         if (object) {
00277             obj_disp_ptr = &object->display_list;
00278             obj_disp = *obj_disp_ptr;
00279 
00280             while (obj_disp && obj_disp != display) {
00281                 obj_disp_ptr = &obj_disp->object_list_next;
00282                 obj_disp = *obj_disp_ptr;
00283             }
00284 
00285             if (obj_disp) {
00286                 *obj_disp_ptr = obj_disp->object_list_next;
00287 
00288                 if (!object->display_list) {
00289                     obj2_ptr = &ctx->object_list;
00290                     obj2 = *obj2_ptr;
00291 
00292                     while (obj2 != object) {
00293                         assert(obj2);
00294                         obj2_ptr = &obj2->next;
00295                         obj2 = *obj2_ptr;
00296                     }
00297 
00298                     *obj2_ptr = obj2->next;
00299 
00300                     av_free(obj2);
00301                 }
00302             }
00303         }
00304 
00305         region->display_list = display->region_list_next;
00306 
00307         av_free(display);
00308     }
00309 
00310 }

static void delete_state ( DVBSubContext ctx  )  [static]

Definition at line 312 of file dvbsubdec.c.

References av_free(), av_log(), AV_LOG_ERROR, DVBSubContext::clut_list, delete_region_display_list(), DVBSubCLUT::next, DVBSubRegion::next, DVBSubContext::object_list, DVBSubRegion::pbuf, and DVBSubContext::region_list.

Referenced by dvbsub_close_decoder(), and dvbsub_parse_page_segment().

00313 {
00314     DVBSubRegion *region;
00315     DVBSubCLUT *clut;
00316 
00317     while (ctx->region_list) {
00318         region = ctx->region_list;
00319 
00320         ctx->region_list = region->next;
00321 
00322         delete_region_display_list(ctx, region);
00323         if (region->pbuf)
00324             av_free(region->pbuf);
00325 
00326         av_free(region);
00327     }
00328 
00329     while (ctx->clut_list) {
00330         clut = ctx->clut_list;
00331 
00332         ctx->clut_list = clut->next;
00333 
00334         av_free(clut);
00335     }
00336 
00337     /* Should already be null */
00338     if (ctx->object_list)
00339         av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");
00340 }

static av_cold int dvbsub_close_decoder ( AVCodecContext avctx  )  [static]

Definition at line 415 of file dvbsubdec.c.

References av_free(), delete_state(), and AVCodecContext::priv_data.

00416 {
00417     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00418     DVBSubRegionDisplay *display;
00419 
00420     delete_state(ctx);
00421 
00422     while (ctx->display_list) {
00423         display = ctx->display_list;
00424         ctx->display_list = display->next;
00425 
00426         av_free(display);
00427     }
00428 
00429     return 0;
00430 }

static int dvbsub_decode ( AVCodecContext avctx,
void *  data,
int *  data_size,
const uint8_t *  buf,
int  buf_size 
) [static]

Definition at line 1343 of file dvbsubdec.c.

References DVBSubContext::ancillary_id, av_log(), AV_LOG_INFO, AV_RB16, DVBSubContext::composition_id, DVBSUB_CLUT_SEGMENT, dvbsub_display_end_segment(), DVBSUB_DISPLAY_SEGMENT, DVBSUB_OBJECT_SEGMENT, DVBSUB_PAGE_SEGMENT, dvbsub_parse_clut_segment(), dvbsub_parse_object_segment(), dvbsub_parse_page_segment(), dvbsub_parse_region_segment(), DVBSUB_REGION_SEGMENT, and AVCodecContext::priv_data.

01346 {
01347     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01348     AVSubtitle *sub = (AVSubtitle*) data;
01349     const uint8_t *p, *p_end;
01350     int segment_type;
01351     int page_id;
01352     int segment_length;
01353 
01354 #ifdef DEBUG_PACKET_CONTENTS
01355     int i;
01356 
01357     av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n");
01358 
01359     for (i=0; i < buf_size; i++) {
01360         av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
01361         if (i % 16 == 15)
01362             av_log(avctx, AV_LOG_INFO, "\n");
01363     }
01364 
01365     if (i % 16)
01366         av_log(avctx, AV_LOG_INFO, "\n");
01367 
01368 #endif
01369 
01370     if (buf_size <= 2)
01371         return -1;
01372 
01373     p = buf;
01374     p_end = buf + buf_size;
01375 
01376     while (p < p_end && *p == 0x0f) {
01377         p += 1;
01378         segment_type = *p++;
01379         page_id = AV_RB16(p);
01380         p += 2;
01381         segment_length = AV_RB16(p);
01382         p += 2;
01383 
01384         if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) {
01385             switch (segment_type) {
01386             case DVBSUB_PAGE_SEGMENT:
01387                 dvbsub_parse_page_segment(avctx, p, segment_length);
01388                 break;
01389             case DVBSUB_REGION_SEGMENT:
01390                 dvbsub_parse_region_segment(avctx, p, segment_length);
01391                 break;
01392             case DVBSUB_CLUT_SEGMENT:
01393                 dvbsub_parse_clut_segment(avctx, p, segment_length);
01394                 break;
01395             case DVBSUB_OBJECT_SEGMENT:
01396                 dvbsub_parse_object_segment(avctx, p, segment_length);
01397                 break;
01398             case DVBSUB_DISPLAY_SEGMENT:
01399                 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
01400                 break;
01401             default:
01402 #ifdef DEBUG
01403                 av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n",
01404                         segment_type, page_id, segment_length);
01405 #endif
01406                 break;
01407             }
01408         }
01409 
01410         p += segment_length;
01411     }
01412 
01413     if (p != p_end) {
01414 #ifdef DEBUG
01415         av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
01416 #endif
01417         return -1;
01418     }
01419 
01420     return buf_size;
01421 }

static int dvbsub_display_end_segment ( AVCodecContext avctx,
const uint8_t *  buf,
int  buf_size,
AVSubtitle sub 
) [static]

Definition at line 1269 of file dvbsubdec.c.

References av_malloc(), av_mallocz(), DVBSubRegion::buf_size, DVBSubRegion::clut, DVBSubCLUT::clut16, DVBSubCLUT::clut256, DVBSubCLUT::clut4, default_clut, DVBSubRegion::depth, DVBSubContext::display_list, DVBSubContext::display_list_size, AVSubtitle::end_display_time, AVSubtitle::format, get_clut(), get_region(), DVBSubRegion::height, DVBSubRegionDisplay::next, NULL, AVSubtitle::num_rects, DVBSubRegion::pbuf, AVCodecContext::priv_data, AVSubtitle::rects, DVBSubRegionDisplay::region_id, AVSubtitle::start_display_time, DVBSubContext::time_out, DVBSubRegion::width, AVSubtitleRect::x, DVBSubRegionDisplay::x_pos, and DVBSubRegionDisplay::y_pos.

Referenced by dvbsub_decode().

01271 {
01272     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01273 
01274     DVBSubRegion *region;
01275     DVBSubRegionDisplay *display;
01276     AVSubtitleRect *rect;
01277     DVBSubCLUT *clut;
01278     uint32_t *clut_table;
01279     int i;
01280 
01281     sub->rects = NULL;
01282     sub->start_display_time = 0;
01283     sub->end_display_time = ctx->time_out * 1000;
01284     sub->format = 0;
01285 
01286     sub->num_rects = ctx->display_list_size;
01287 
01288     if (sub->num_rects > 0)
01289         sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects);
01290 
01291     i = 0;
01292 
01293     for (display = ctx->display_list; display; display = display->next) {
01294         region = get_region(ctx, display->region_id);
01295         rect = &sub->rects[i];
01296 
01297         if (!region)
01298             continue;
01299 
01300         rect->x = display->x_pos;
01301         rect->y = display->y_pos;
01302         rect->w = region->width;
01303         rect->h = region->height;
01304         rect->nb_colors = 16;
01305         rect->linesize = region->width;
01306 
01307         clut = get_clut(ctx, region->clut);
01308 
01309         if (!clut)
01310             clut = &default_clut;
01311 
01312         switch (region->depth) {
01313         case 2:
01314             clut_table = clut->clut4;
01315             break;
01316         case 8:
01317             clut_table = clut->clut256;
01318             break;
01319         case 4:
01320         default:
01321             clut_table = clut->clut16;
01322             break;
01323         }
01324 
01325         rect->rgba_palette = av_malloc((1 << region->depth) * sizeof(uint32_t));
01326         memcpy(rect->rgba_palette, clut_table, (1 << region->depth) * sizeof(uint32_t));
01327 
01328         rect->bitmap = av_malloc(region->buf_size);
01329         memcpy(rect->bitmap, region->pbuf, region->buf_size);
01330 
01331         i++;
01332     }
01333 
01334     sub->num_rects = i;
01335 
01336 #ifdef DEBUG_SAVE_IMAGES
01337     save_display_set(ctx);
01338 #endif
01339 
01340     return 1;
01341 }

static av_cold int dvbsub_init_decoder ( AVCodecContext avctx  )  [static]

Definition at line 342 of file dvbsubdec.c.

References DVBSubContext::ancillary_id, DVBSubCLUT::clut16, DVBSubCLUT::clut256, DVBSubCLUT::clut4, DVBSubContext::composition_id, default_clut, g, DVBSubCLUT::id, DVBSubCLUT::next, NULL, AVCodecContext::priv_data, RGBA, and AVCodecContext::sub_id.

00343 {
00344     int i, r, g, b, a = 0;
00345     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00346 
00347     memset(avctx->priv_data, 0, sizeof(DVBSubContext));
00348 
00349     ctx->composition_id = avctx->sub_id & 0xffff;
00350     ctx->ancillary_id = avctx->sub_id >> 16;
00351 
00352     default_clut.id = -1;
00353     default_clut.next = NULL;
00354 
00355     default_clut.clut4[0] = RGBA(  0,   0,   0,   0);
00356     default_clut.clut4[1] = RGBA(255, 255, 255, 255);
00357     default_clut.clut4[2] = RGBA(  0,   0,   0, 255);
00358     default_clut.clut4[3] = RGBA(127, 127, 127, 255);
00359 
00360     default_clut.clut16[0] = RGBA(  0,   0,   0,   0);
00361     for (i = 1; i < 16; i++) {
00362         if (i < 8) {
00363             r = (i & 1) ? 255 : 0;
00364             g = (i & 2) ? 255 : 0;
00365             b = (i & 4) ? 255 : 0;
00366         } else {
00367             r = (i & 1) ? 127 : 0;
00368             g = (i & 2) ? 127 : 0;
00369             b = (i & 4) ? 127 : 0;
00370         }
00371         default_clut.clut16[i] = RGBA(r, g, b, 255);
00372     }
00373 
00374     default_clut.clut256[0] = RGBA(  0,   0,   0,   0);
00375     for (i = 1; i < 256; i++) {
00376         if (i < 8) {
00377             r = (i & 1) ? 255 : 0;
00378             g = (i & 2) ? 255 : 0;
00379             b = (i & 4) ? 255 : 0;
00380             a = 63;
00381         } else {
00382             switch (i & 0x88) {
00383             case 0x00:
00384                 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
00385                 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
00386                 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
00387                 a = 255;
00388                 break;
00389             case 0x08:
00390                 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
00391                 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
00392                 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
00393                 a = 127;
00394                 break;
00395             case 0x80:
00396                 r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
00397                 g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
00398                 b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
00399                 a = 255;
00400                 break;
00401             case 0x88:
00402                 r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
00403                 g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
00404                 b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
00405                 a = 255;
00406                 break;
00407             }
00408         }
00409         default_clut.clut256[i] = RGBA(r, g, b, a);
00410     }
00411 
00412     return 0;
00413 }

static void dvbsub_parse_clut_segment ( AVCodecContext avctx,
const uint8_t *  buf,
int  buf_size 
) [static]

Definition at line 895 of file dvbsubdec.c.

References av_log(), AV_LOG_ERROR, AV_LOG_INFO, av_malloc(), DVBSubContext::clut_list, default_clut, depth, g, get_clut(), AVCodecContext::priv_data, RGBA, YUV_TO_RGB1_CCIR, and YUV_TO_RGB2_CCIR.

Referenced by dvbsub_decode().

00897 {
00898     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00899 
00900     const uint8_t *buf_end = buf + buf_size;
00901     int clut_id;
00902     DVBSubCLUT *clut;
00903     int entry_id, depth , full_range;
00904     int y, cr, cb, alpha;
00905     int r, g, b, r_add, g_add, b_add;
00906 
00907 #ifdef DEBUG_PACKET_CONTENTS
00908     int i;
00909 
00910     av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n");
00911 
00912     for (i=0; i < buf_size; i++) {
00913         av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
00914         if (i % 16 == 15)
00915             av_log(avctx, AV_LOG_INFO, "\n");
00916     }
00917 
00918     if (i % 16)
00919         av_log(avctx, AV_LOG_INFO, "\n");
00920 
00921 #endif
00922 
00923     clut_id = *buf++;
00924     buf += 1;
00925 
00926     clut = get_clut(ctx, clut_id);
00927 
00928     if (!clut) {
00929         clut = av_malloc(sizeof(DVBSubCLUT));
00930 
00931         memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
00932 
00933         clut->id = clut_id;
00934 
00935         clut->next = ctx->clut_list;
00936         ctx->clut_list = clut;
00937     }
00938 
00939     while (buf + 4 < buf_end) {
00940         entry_id = *buf++;
00941 
00942         depth = (*buf) & 0xe0;
00943 
00944         if (depth == 0) {
00945             av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
00946             return;
00947         }
00948 
00949         full_range = (*buf++) & 1;
00950 
00951         if (full_range) {
00952             y = *buf++;
00953             cr = *buf++;
00954             cb = *buf++;
00955             alpha = *buf++;
00956         } else {
00957             y = buf[0] & 0xfc;
00958             cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
00959             cb = (buf[1] << 2) & 0xf0;
00960             alpha = (buf[1] << 6) & 0xc0;
00961 
00962             buf += 2;
00963         }
00964 
00965         if (y == 0)
00966             alpha = 0xff;
00967 
00968         YUV_TO_RGB1_CCIR(cb, cr);
00969         YUV_TO_RGB2_CCIR(r, g, b, y);
00970 
00971 #ifdef DEBUG
00972         av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
00973 #endif
00974 
00975         if (depth & 0x80)
00976             clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
00977         if (depth & 0x40)
00978             clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
00979         if (depth & 0x20)
00980             clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
00981     }
00982 }

static void dvbsub_parse_object_segment ( AVCodecContext avctx,
const uint8_t *  buf,
int  buf_size 
) [static]

Definition at line 836 of file dvbsubdec.c.

References av_log(), AV_LOG_ERROR, AV_RB16, dvbsub_parse_pixel_data_block(), get_object(), and AVCodecContext::priv_data.

Referenced by dvbsub_decode().

00838 {
00839     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00840 
00841     const uint8_t *buf_end = buf + buf_size;
00842     const uint8_t *block;
00843     int object_id;
00844     DVBSubObject *object;
00845     DVBSubObjectDisplay *display;
00846     int top_field_len, bottom_field_len;
00847 
00848     int coding_method, non_modifying_color;
00849 
00850     object_id = AV_RB16(buf);
00851     buf += 2;
00852 
00853     object = get_object(ctx, object_id);
00854 
00855     if (!object)
00856         return;
00857 
00858     coding_method = ((*buf) >> 2) & 3;
00859     non_modifying_color = ((*buf++) >> 1) & 1;
00860 
00861     if (coding_method == 0) {
00862         top_field_len = AV_RB16(buf);
00863         buf += 2;
00864         bottom_field_len = AV_RB16(buf);
00865         buf += 2;
00866 
00867         if (buf + top_field_len + bottom_field_len > buf_end) {
00868             av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
00869             return;
00870         }
00871 
00872         for (display = object->display_list; display; display = display->object_list_next) {
00873             block = buf;
00874 
00875             dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
00876                                             non_modifying_color);
00877 
00878             if (bottom_field_len > 0)
00879                 block = buf + top_field_len;
00880             else
00881                 bottom_field_len = top_field_len;
00882 
00883             dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1,
00884                                             non_modifying_color);
00885         }
00886 
00887 /*  } else if (coding_method == 1) {*/
00888 
00889     } else {
00890         av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
00891     }
00892 
00893 }

static void dvbsub_parse_page_segment ( AVCodecContext avctx,
const uint8_t *  buf,
int  buf_size 
) [static]

Definition at line 1101 of file dvbsubdec.c.

References av_free(), av_log(), AV_LOG_INFO, av_mallocz(), AV_RB16, delete_state(), DVBSubContext::display_list, DVBSubContext::display_list_size, NULL, AVCodecContext::priv_data, and DVBSubContext::time_out.

Referenced by dvbsub_decode().

01103 {
01104     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01105     DVBSubRegionDisplay *display;
01106     DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
01107 
01108     const uint8_t *buf_end = buf + buf_size;
01109     int region_id;
01110     int page_state;
01111 
01112     if (buf_size < 1)
01113         return;
01114 
01115     ctx->time_out = *buf++;
01116     page_state = ((*buf++) >> 2) & 3;
01117 
01118 #ifdef DEBUG
01119     av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state);
01120 #endif
01121 
01122     if (page_state == 2) {
01123         delete_state(ctx);
01124     }
01125 
01126     tmp_display_list = ctx->display_list;
01127     ctx->display_list = NULL;
01128     ctx->display_list_size = 0;
01129 
01130     while (buf + 5 < buf_end) {
01131         region_id = *buf++;
01132         buf += 1;
01133 
01134         display = tmp_display_list;
01135         tmp_ptr = &tmp_display_list;
01136 
01137         while (display && display->region_id != region_id) {
01138             tmp_ptr = &display->next;
01139             display = display->next;
01140         }
01141 
01142         if (!display)
01143             display = av_mallocz(sizeof(DVBSubRegionDisplay));
01144 
01145         display->region_id = region_id;
01146 
01147         display->x_pos = AV_RB16(buf);
01148         buf += 2;
01149         display->y_pos = AV_RB16(buf);
01150         buf += 2;
01151 
01152         *tmp_ptr = display->next;
01153 
01154         display->next = ctx->display_list;
01155         ctx->display_list = display;
01156         ctx->display_list_size++;
01157 
01158 #ifdef DEBUG
01159         av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
01160 #endif
01161     }
01162 
01163     while (tmp_display_list) {
01164         display = tmp_display_list;
01165 
01166         tmp_display_list = display->next;
01167 
01168         av_free(display);
01169     }
01170 
01171 }

static void dvbsub_parse_pixel_data_block ( AVCodecContext avctx,
DVBSubObjectDisplay display,
const uint8_t *  buf,
int  buf_size,
int  top_bottom,
int  non_mod 
) [static]

Definition at line 717 of file dvbsubdec.c.

References av_log(), AV_LOG_ERROR, AV_LOG_INFO, dvbsub_read_2bit_string(), dvbsub_read_4bit_string(), dvbsub_read_8bit_string(), get_region(), NULL, AVCodecContext::priv_data, DVBSubObjectDisplay::region_id, DVBSubObjectDisplay::x_pos, and DVBSubObjectDisplay::y_pos.

Referenced by dvbsub_parse_object_segment().

00719 {
00720     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00721 
00722     DVBSubRegion *region = get_region(ctx, display->region_id);
00723     const uint8_t *buf_end = buf + buf_size;
00724     uint8_t *pbuf;
00725     int x_pos, y_pos;
00726     int i;
00727 
00728     uint8_t map2to4[] = { 0x0,  0x7,  0x8,  0xf};
00729     uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
00730     uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
00731                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
00732     uint8_t *map_table;
00733 
00734 #ifdef DEBUG
00735     av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size,
00736                 top_bottom ? "bottom" : "top");
00737 #endif
00738 
00739 #ifdef DEBUG_PACKET_CONTENTS
00740     for (i = 0; i < buf_size; i++) {
00741         if (i % 16 == 0)
00742             av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i);
00743 
00744         av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
00745         if (i % 16 == 15)
00746             av_log(avctx, AV_LOG_INFO, "\n");
00747     }
00748 
00749     if (i % 16)
00750         av_log(avctx, AV_LOG_INFO, "\n");
00751 
00752 #endif
00753 
00754     if (region == 0)
00755         return;
00756 
00757     pbuf = region->pbuf;
00758 
00759     x_pos = display->x_pos;
00760     y_pos = display->y_pos;
00761 
00762     if ((y_pos & 1) != top_bottom)
00763         y_pos++;
00764 
00765     while (buf < buf_end) {
00766         if (x_pos > region->width || y_pos > region->height) {
00767             av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n");
00768             return;
00769         }
00770 
00771         switch (*buf++) {
00772         case 0x10:
00773             if (region->depth == 8)
00774                 map_table = map2to8;
00775             else if (region->depth == 4)
00776                 map_table = map2to4;
00777             else
00778                 map_table = NULL;
00779 
00780             x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos,
00781                                                 region->width - x_pos, &buf, buf_size,
00782                                                 non_mod, map_table);
00783             break;
00784         case 0x11:
00785             if (region->depth < 4) {
00786                 av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
00787                 return;
00788             }
00789 
00790             if (region->depth == 8)
00791                 map_table = map4to8;
00792             else
00793                 map_table = NULL;
00794 
00795             x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos,
00796                                                 region->width - x_pos, &buf, buf_size,
00797                                                 non_mod, map_table);
00798             break;
00799         case 0x12:
00800             if (region->depth < 8) {
00801                 av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
00802                 return;
00803             }
00804 
00805             x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos,
00806                                                 region->width - x_pos, &buf, buf_size,
00807                                                 non_mod, NULL);
00808             break;
00809 
00810         case 0x20:
00811             map2to4[0] = (*buf) >> 4;
00812             map2to4[1] = (*buf++) & 0xf;
00813             map2to4[2] = (*buf) >> 4;
00814             map2to4[3] = (*buf++) & 0xf;
00815             break;
00816         case 0x21:
00817             for (i = 0; i < 4; i++)
00818                 map2to8[i] = *buf++;
00819             break;
00820         case 0x22:
00821             for (i = 0; i < 16; i++)
00822                 map4to8[i] = *buf++;
00823             break;
00824 
00825         case 0xf0:
00826             x_pos = display->x_pos;
00827             y_pos += 2;
00828             break;
00829         default:
00830             av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
00831         }
00832     }
00833 
00834 }

static void dvbsub_parse_region_segment ( AVCodecContext avctx,
const uint8_t *  buf,
int  buf_size 
) [static]

Definition at line 985 of file dvbsubdec.c.

References av_free(), av_log(), AV_LOG_ERROR, AV_LOG_INFO, av_malloc(), av_mallocz(), AV_RB16, delete_region_display_list(), get_object(), get_region(), DVBSubContext::object_list, AVCodecContext::priv_data, DVBSubContext::region_list, DVBSubObject::type, and DVBSubRegion::width.

Referenced by dvbsub_decode().

00987 {
00988     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00989 
00990     const uint8_t *buf_end = buf + buf_size;
00991     int region_id, object_id;
00992     DVBSubRegion *region;
00993     DVBSubObject *object;
00994     DVBSubObjectDisplay *display;
00995     int fill;
00996 
00997     if (buf_size < 10)
00998         return;
00999 
01000     region_id = *buf++;
01001 
01002     region = get_region(ctx, region_id);
01003 
01004     if (!region) {
01005         region = av_mallocz(sizeof(DVBSubRegion));
01006 
01007         region->id = region_id;
01008 
01009         region->next = ctx->region_list;
01010         ctx->region_list = region;
01011     }
01012 
01013     fill = ((*buf++) >> 3) & 1;
01014 
01015     region->width = AV_RB16(buf);
01016     buf += 2;
01017     region->height = AV_RB16(buf);
01018     buf += 2;
01019 
01020     if (region->width * region->height != region->buf_size) {
01021         if (region->pbuf)
01022             av_free(region->pbuf);
01023 
01024         region->buf_size = region->width * region->height;
01025 
01026         region->pbuf = av_malloc(region->buf_size);
01027 
01028         fill = 1;
01029     }
01030 
01031     region->depth = 1 << (((*buf++) >> 2) & 7);
01032     if(region->depth<2 || region->depth>8){
01033         av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
01034         region->depth= 4;
01035     }
01036     region->clut = *buf++;
01037 
01038     if (region->depth == 8)
01039         region->bgcolor = *buf++;
01040     else {
01041         buf += 1;
01042 
01043         if (region->depth == 4)
01044             region->bgcolor = (((*buf++) >> 4) & 15);
01045         else
01046             region->bgcolor = (((*buf++) >> 2) & 3);
01047     }
01048 
01049 #ifdef DEBUG
01050     av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
01051 #endif
01052 
01053     if (fill) {
01054         memset(region->pbuf, region->bgcolor, region->buf_size);
01055 #ifdef DEBUG
01056         av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolor);
01057 #endif
01058     }
01059 
01060     delete_region_display_list(ctx, region);
01061 
01062     while (buf + 5 < buf_end) {
01063         object_id = AV_RB16(buf);
01064         buf += 2;
01065 
01066         object = get_object(ctx, object_id);
01067 
01068         if (!object) {
01069             object = av_mallocz(sizeof(DVBSubObject));
01070 
01071             object->id = object_id;
01072             object->next = ctx->object_list;
01073             ctx->object_list = object;
01074         }
01075 
01076         object->type = (*buf) >> 6;
01077 
01078         display = av_mallocz(sizeof(DVBSubObjectDisplay));
01079 
01080         display->object_id = object_id;
01081         display->region_id = region_id;
01082 
01083         display->x_pos = AV_RB16(buf) & 0xfff;
01084         buf += 2;
01085         display->y_pos = AV_RB16(buf) & 0xfff;
01086         buf += 2;
01087 
01088         if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
01089             display->fgcolor = *buf++;
01090             display->bgcolor = *buf++;
01091         }
01092 
01093         display->region_list_next = region->display_list;
01094         region->display_list = display;
01095 
01096         display->object_list_next = object->display_list;
01097         object->display_list = display;
01098     }
01099 }

static int dvbsub_read_2bit_string ( uint8_t *  destbuf,
int  dbuf_len,
const uint8_t **  srcbuf,
int  buf_size,
int  non_mod,
uint8_t *  map_table 
) [static]

Definition at line 432 of file dvbsubdec.c.

References av_log(), AV_LOG_ERROR, bits, get_bits(), get_bits1(), get_bits_count(), and init_get_bits().

Referenced by dvbsub_parse_pixel_data_block().

00435 {
00436     GetBitContext gb;
00437 
00438     int bits;
00439     int run_length;
00440     int pixels_read = 0;
00441 
00442     init_get_bits(&gb, *srcbuf, buf_size << 8);
00443 
00444     while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) {
00445         bits = get_bits(&gb, 2);
00446 
00447         if (bits) {
00448             if (non_mod != 1 || bits != 1) {
00449                 if (map_table)
00450                     *destbuf++ = map_table[bits];
00451                 else
00452                     *destbuf++ = bits;
00453             }
00454             pixels_read++;
00455         } else {
00456             bits = get_bits1(&gb);
00457             if (bits == 1) {
00458                 run_length = get_bits(&gb, 3) + 3;
00459                 bits = get_bits(&gb, 2);
00460 
00461                 if (non_mod == 1 && bits == 1)
00462                     pixels_read += run_length;
00463                 else {
00464                     if (map_table)
00465                         bits = map_table[bits];
00466                     while (run_length-- > 0 && pixels_read < dbuf_len) {
00467                         *destbuf++ = bits;
00468                         pixels_read++;
00469                     }
00470                 }
00471             } else {
00472                 bits = get_bits1(&gb);
00473                 if (bits == 0) {
00474                     bits = get_bits(&gb, 2);
00475                     if (bits == 2) {
00476                         run_length = get_bits(&gb, 4) + 12;
00477                         bits = get_bits(&gb, 2);
00478 
00479                         if (non_mod == 1 && bits == 1)
00480                             pixels_read += run_length;
00481                         else {
00482                             if (map_table)
00483                                 bits = map_table[bits];
00484                             while (run_length-- > 0 && pixels_read < dbuf_len) {
00485                                 *destbuf++ = bits;
00486                                 pixels_read++;
00487                             }
00488                         }
00489                     } else if (bits == 3) {
00490                         run_length = get_bits(&gb, 8) + 29;
00491                         bits = get_bits(&gb, 2);
00492 
00493                         if (non_mod == 1 && bits == 1)
00494                             pixels_read += run_length;
00495                         else {
00496                             if (map_table)
00497                                 bits = map_table[bits];
00498                             while (run_length-- > 0 && pixels_read < dbuf_len) {
00499                                 *destbuf++ = bits;
00500                                 pixels_read++;
00501                             }
00502                         }
00503                     } else if (bits == 1) {
00504                         pixels_read += 2;
00505                         if (map_table)
00506                             bits = map_table[0];
00507                         else
00508                             bits = 0;
00509                         if (pixels_read <= dbuf_len) {
00510                             *destbuf++ = bits;
00511                             *destbuf++ = bits;
00512                         }
00513                     } else {
00514                         (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
00515                         return pixels_read;
00516                     }
00517                 } else {
00518                     if (map_table)
00519                         bits = map_table[0];
00520                     else
00521                         bits = 0;
00522                     *destbuf++ = bits;
00523                     pixels_read++;
00524                 }
00525             }
00526         }
00527     }
00528 
00529     if (get_bits(&gb, 6))
00530         av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
00531 
00532     (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
00533 
00534     return pixels_read;
00535 }

static int dvbsub_read_4bit_string ( uint8_t *  destbuf,
int  dbuf_len,
const uint8_t **  srcbuf,
int