⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvbsubdec.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * DVB subtitle decoding for ffmpeg * Copyright (c) 2005 Ian Caulfield. * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "avcodec.h"#include "dsputil.h"#include "bitstream.h"#include "colorspace.h"//#define DEBUG//#define DEBUG_PACKET_CONTENTS//#define DEBUG_SAVE_IMAGES#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)#ifdef DEBUG_SAVE_IMAGES#undef fprintf#if 0static void png_save(const char *filename, uint8_t *bitmap, int w, int h,                     uint32_t *rgba_palette){    int x, y, v;    FILE *f;    char fname[40], fname2[40];    char command[1024];    snprintf(fname, 40, "%s.ppm", filename);    f = fopen(fname, "w");    if (!f) {        perror(fname);        exit(1);    }    fprintf(f, "P6\n"            "%d %d\n"            "%d\n",            w, h, 255);    for(y = 0; y < h; y++) {        for(x = 0; x < w; x++) {            v = rgba_palette[bitmap[y * w + x]];            putc((v >> 16) & 0xff, f);            putc((v >> 8) & 0xff, f);            putc((v >> 0) & 0xff, f);        }    }    fclose(f);    snprintf(fname2, 40, "%s-a.pgm", filename);    f = fopen(fname2, "w");    if (!f) {        perror(fname2);        exit(1);    }    fprintf(f, "P5\n"            "%d %d\n"            "%d\n",            w, h, 255);    for(y = 0; y < h; y++) {        for(x = 0; x < w; x++) {            v = rgba_palette[bitmap[y * w + x]];            putc((v >> 24) & 0xff, f);        }    }    fclose(f);    snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);    system(command);    snprintf(command, 1024, "rm %s %s", fname, fname2);    system(command);}#endifstatic void png_save2(const char *filename, uint32_t *bitmap, int w, int h){    int x, y, v;    FILE *f;    char fname[40], fname2[40];    char command[1024];    snprintf(fname, sizeof(fname), "%s.ppm", filename);    f = fopen(fname, "w");    if (!f) {        perror(fname);        exit(1);    }    fprintf(f, "P6\n"            "%d %d\n"            "%d\n",            w, h, 255);    for(y = 0; y < h; y++) {        for(x = 0; x < w; x++) {            v = bitmap[y * w + x];            putc((v >> 16) & 0xff, f);            putc((v >> 8) & 0xff, f);            putc((v >> 0) & 0xff, f);        }    }    fclose(f);    snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);    f = fopen(fname2, "w");    if (!f) {        perror(fname2);        exit(1);    }    fprintf(f, "P5\n"            "%d %d\n"            "%d\n",            w, h, 255);    for(y = 0; y < h; y++) {        for(x = 0; x < w; x++) {            v = bitmap[y * w + x];            putc((v >> 24) & 0xff, f);        }    }    fclose(f);    snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);    system(command);    snprintf(command, sizeof(command), "rm %s %s", fname, fname2);    system(command);}#endif#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))typedef struct DVBSubCLUT {    int id;    uint32_t clut4[4];    uint32_t clut16[16];    uint32_t clut256[256];    struct DVBSubCLUT *next;} DVBSubCLUT;static DVBSubCLUT default_clut;typedef struct DVBSubObjectDisplay {    int object_id;    int region_id;    int x_pos;    int y_pos;    int fgcolor;    int bgcolor;    struct DVBSubObjectDisplay *region_list_next;    struct DVBSubObjectDisplay *object_list_next;} DVBSubObjectDisplay;typedef struct DVBSubObject {    int id;    int type;    DVBSubObjectDisplay *display_list;    struct DVBSubObject *next;} DVBSubObject;typedef struct DVBSubRegionDisplay {    int region_id;    int x_pos;    int y_pos;    struct DVBSubRegionDisplay *next;} DVBSubRegionDisplay;typedef struct DVBSubRegion {    int id;    int width;    int height;    int depth;    int clut;    int bgcolor;    uint8_t *pbuf;    int buf_size;    DVBSubObjectDisplay *display_list;    struct DVBSubRegion *next;} DVBSubRegion;typedef struct DVBSubContext {    int composition_id;    int ancillary_id;    int time_out;    DVBSubRegion *region_list;    DVBSubCLUT   *clut_list;    DVBSubObject *object_list;    int display_list_size;    DVBSubRegionDisplay *display_list;} DVBSubContext;static DVBSubObject* get_object(DVBSubContext *ctx, int object_id){    DVBSubObject *ptr = ctx->object_list;    while (ptr && ptr->id != object_id) {        ptr = ptr->next;    }    return ptr;}static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id){    DVBSubCLUT *ptr = ctx->clut_list;    while (ptr && ptr->id != clut_id) {        ptr = ptr->next;    }    return ptr;}static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id){    DVBSubRegion *ptr = ctx->region_list;    while (ptr && ptr->id != region_id) {        ptr = ptr->next;    }    return ptr;}static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region){    DVBSubObject *object, *obj2, **obj2_ptr;    DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;    while (region->display_list) {        display = region->display_list;        object = get_object(ctx, display->object_id);        if (object) {            obj_disp = object->display_list;            obj_disp_ptr = &object->display_list;            while (obj_disp && obj_disp != display) {                obj_disp_ptr = &obj_disp->object_list_next;                obj_disp = obj_disp->object_list_next;            }            if (obj_disp) {                *obj_disp_ptr = obj_disp->object_list_next;                if (!object->display_list) {                    obj2 = ctx->object_list;                    obj2_ptr = &ctx->object_list;                    while (obj2 && obj2 != object) {                        obj2_ptr = &obj2->next;                        obj2 = obj2->next;                    }                    *obj2_ptr = obj2->next;                    av_free(obj2);                }            }        }        region->display_list = display->region_list_next;        av_free(display);    }}static void delete_state(DVBSubContext *ctx){    DVBSubRegion *region;    DVBSubCLUT *clut;    while (ctx->region_list) {        region = ctx->region_list;        ctx->region_list = region->next;        delete_region_display_list(ctx, region);        if (region->pbuf)            av_free(region->pbuf);        av_free(region);    }    while (ctx->clut_list) {        clut = ctx->clut_list;        ctx->clut_list = clut->next;        av_free(clut);    }    /* Should already be null */    if (ctx->object_list)        av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");}static int dvbsub_init_decoder(AVCodecContext *avctx){    int i, r, g, b, a = 0;    DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;    memset(avctx->priv_data, 0, sizeof(DVBSubContext));    ctx->composition_id = avctx->sub_id & 0xffff;    ctx->ancillary_id = avctx->sub_id >> 16;    default_clut.id = -1;    default_clut.next = NULL;    default_clut.clut4[0] = RGBA(  0,   0,   0,   0);    default_clut.clut4[1] = RGBA(255, 255, 255, 255);    default_clut.clut4[2] = RGBA(  0,   0,   0, 255);    default_clut.clut4[3] = RGBA(127, 127, 127, 255);    default_clut.clut16[0] = RGBA(  0,   0,   0,   0);    for (i = 1; i < 16; i++) {        if (i < 8) {            r = (i & 1) ? 255 : 0;            g = (i & 2) ? 255 : 0;            b = (i & 4) ? 255 : 0;        } else {            r = (i & 1) ? 127 : 0;            g = (i & 2) ? 127 : 0;            b = (i & 4) ? 127 : 0;        }        default_clut.clut16[i] = RGBA(r, g, b, 255);    }    default_clut.clut256[0] = RGBA(  0,   0,   0,   0);    for (i = 1; i < 256; i++) {        if (i < 8) {            r = (i & 1) ? 255 : 0;            g = (i & 2) ? 255 : 0;            b = (i & 4) ? 255 : 0;            a = 63;        } else {            switch (i & 0x88) {            case 0x00:                r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);                g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);                b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);                a = 255;                break;            case 0x08:                r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);                g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);                b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);                a = 127;                break;            case 0x80:                r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);                g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);                b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);                a = 255;                break;            case 0x88:                r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);                g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);                b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);                a = 255;                break;            }        }        default_clut.clut256[i] = RGBA(r, g, b, a);    }    return 0;}static int dvbsub_close_decoder(AVCodecContext *avctx){    DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;    DVBSubRegionDisplay *display;    delete_state(ctx);    while (ctx->display_list) {        display = ctx->display_list;        ctx->display_list = display->next;        av_free(display);    }    return 0;}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){    GetBitContext gb;    int bits;    int run_length;    int pixels_read = 0;    init_get_bits(&gb, *srcbuf, buf_size << 8);    while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) {        bits = get_bits(&gb, 2);        if (bits) {            if (non_mod != 1 || bits != 1) {                if (map_table)                    *destbuf++ = map_table[bits];                else                    *destbuf++ = bits;            }            pixels_read++;        } else {            bits = get_bits1(&gb);            if (bits == 1) {                run_length = get_bits(&gb, 3) + 3;                bits = get_bits(&gb, 2);                if (non_mod == 1 && bits == 1)                    pixels_read += run_length;                else {                    if (map_table)                        bits = map_table[bits];                    while (run_length-- > 0 && pixels_read < dbuf_len) {                        *destbuf++ = bits;                        pixels_read++;                    }                }            } else {                bits = get_bits1(&gb);                if (bits == 0) {                    bits = get_bits(&gb, 2);                    if (bits == 2) {                        run_length = get_bits(&gb, 4) + 12;                        bits = get_bits(&gb, 2);                        if (non_mod == 1 && bits == 1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -