Ticket #1095: eia708-v3.patch

File eia708-v3.patch, 87.7 KB (added by danielk, 20 years ago)

minor update, an OSD now displays show text of captions

  • libs/libmythtv/NuppelVideoPlayer.h

     
    1515#include "videooutbase.h"
    1616#include "tv_play.h"
    1717#include "yuv2rgb.h"
     18#include "ccdecoder.h"
     19#include "cc708decoder.h"
     20#include "cc708window.h"
    1821
    1922extern "C" {
    2023#include "filter.h"
     
    5760};
    5861#define TCTYPESMAX 4
    5962
    60 class NuppelVideoPlayer
     63class NuppelVideoPlayer : public CCReader, public CC708Reader
    6164{
    6265 public:
    6366    NuppelVideoPlayer(QString inUseID = "Unknown",
     
    112115    void Zoom(int direction);
    113116    void ClearBookmark(void);
    114117
     118    void SetOSDFontName(const QString osdfonts[22], const QString &prefix);
     119    void SetOSDThemeName(const QString themename);
     120
    115121    // Toggle Sets
    116122    void ToggleLetterbox(int letterboxMode = -1);
    117123
     
    227233    void AddAudioData(char *buffer, int len, long long timecode);
    228234    void AddAudioData(short int *lbuffer, short int *rbuffer, int samples,
    229235                      long long timecode);
    230     void AddTextData(char *buffer, int len, long long timecode, char type);
     236    void AddTextData(unsigned char *buffer, int len,
     237                     long long timecode, char type);
    231238    void AddSubtitle(const AVSubtitle& subtitle);
    232239
     240    // ATSC EIA-708 Captions
     241    CC708Window &GetCCWin(uint service_num, uint window_id)
     242        { return CC708services[service_num].windows[window_id]; }
     243    CC708Window &GetCCWin(uint svc_num)
     244        { return GetCCWin(svc_num, CC708services[svc_num].current_window); }
     245
     246    void SetCurrentWindow(uint service_num, int window_id);
     247    void DefineWindow(uint service_num,     int window_id,
     248                      int priority,         int visible,
     249                      int anchor_point,     int relative_pos,
     250                      int anchor_vertical,  int anchor_horizontal,
     251                      int row_count,        int column_count,
     252                      int row_lock,         int column_lock,
     253                      int pen_style,        int window_style);
     254    void DeleteWindows( uint service_num,   int window_map);
     255    void DisplayWindows(uint service_num,   int window_map);
     256    void HideWindows(   uint service_num,   int window_map);
     257    void ClearWindows(  uint service_num,   int window_map);
     258    void ToggleWindows( uint service_num,   int window_map);
     259    void SetWindowAttributes(uint service_num,
     260                             int fill_color,     int fill_opacity,
     261                             int border_color,   int border_type,
     262                             int scroll_dir,     int print_dir,
     263                             int effect_dir,
     264                             int display_effect, int effect_speed,
     265                             int justify,        int word_wrap);
     266    void SetPenAttributes(uint service_num, int pen_size,
     267                          int offset,       int text_tag,  int font_tag,
     268                          int edge_type,    int underline, int italics);
     269    void SetPenColor(uint service_num,
     270                     int fg_color, int fg_opacity,
     271                     int bg_color, int bg_opacity,
     272                     int edge_color);
     273    void SetPenLocation(uint service_num, int row, int column);
     274
     275    void Delay(uint service_num, int tenths_of_seconds);
     276    void DelayCancel(uint service_num);
     277    void Reset(uint service_num);
     278    void TextWrite(uint service_num, short* unicode_string, short len);
     279
    233280    // Audio Track Selection
    234281    void incCurrentAudioTrack(void);
    235282    void decCurrentAudioTrack(void);
     
    479526    long long osdSubtitlesExpireAt;
    480527    MythDeque<AVSubtitle> nonDisplayedSubtitles;
    481528
     529    CC708Service CC708services[64];
     530    QString    osdfontname;
     531    QString    osdccfontname;
     532    QString    osd708fontnames[20];
     533    QString    osdprefix;
     534    QString    osdtheme;
     535
    482536    // OSD stuff
    483537    OSD      *osd;
    484538    OSDSet   *timedisplay;
  • libs/libmythtv/cc708window.cpp

     
     1// -*- Mode: c++ -*-
     2// Copyright (c) 2003-2005, Daniel Kristjansson
     3
     4#include <cassert>
     5#include <algorithm>
     6using namespace std;
     7
     8#include "cc708window.h"
     9#include "mythcontext.h"
     10
     11/************************************************************************
     12
     13    FCC Addons to EIA-708.
     14
     15    * Decoders must support the standard, large, and small caption sizes
     16      and must allow the caption provider to choose a size and allow the
     17      viewer to choose an alternative size.
     18
     19    * Decoders must support the eight fonts listed in EIA-708. Caption
     20      providers may specify 1 of these 8 font styles to be used to write
     21      caption text. Decoders must include the ability for consumers to
     22      choose among the eight fonts. The decoder must display the font
     23      chosen by the caption provider unless the viewer chooses a different
     24      font.
     25
     26    * Decoders must implement the same 8 character background colors
     27      as those that Section 9 requires be implemented for character
     28      foreground (white, black, red, green, blue, yellow, magenta and cyan).
     29
     30    * Decoders must implement options for altering the appearance of
     31      caption character edges.
     32
     33    * Decoders must display the color chosen by the caption provider,
     34      and must allow viewers to override the foreground and/or background
     35      color chosen by the caption provider and select alternate colors.
     36
     37    * Decoders must be capable of decoding and processing data for the
     38      six standard services, but information from only one service need
     39      be displayed at a given time.
     40
     41    * Decoders must include an option that permits a viewer to choose a
     42      setting that will display captions as intended by the caption
     43      provider (a default). Decoders must also include an option that
     44      allows a viewer's chosen settings to remain until the viewer
     45      chooses to alter these settings, including during periods when
     46      the television is turned off.
     47
     48    * Cable providers and other multichannel video programming
     49      distributors must transmit captions in a format that will be
     50      understandable to this decoder circuitry in digital cable
     51      television sets when transmitting programming to digital
     52      television devices.
     53
     54******************************************************************************/
     55
     56const uint k708JustifyLeft            = 0;
     57const uint k708JustifyRight           = 1;
     58const uint k708JustifyCenter          = 2;
     59const uint k708JustifyFull            = 3;
     60
     61const uint k708EffectSnap             = 0;
     62const uint k708EffectFade             = 1;
     63const uint k708EffectWipe             = 2;
     64
     65const uint k708BorderNone             = 0;
     66const uint k708BorderRaised           = 1;
     67const uint k708BorderDepressed        = 2;
     68const uint k708BorderUniform          = 3;
     69const uint k708BorderShadowLeft       = 4;
     70const uint k708BorderShadowRight      = 5;
     71
     72const uint k708DirLeftToRight         = 0;
     73const uint k708DirRightToLeft         = 1;
     74const uint k708DirTopToBottom         = 2;
     75const uint k708DirBottomToTop         = 3;
     76
     77const uint k708AttrSizeSmall          = 0;
     78const uint k708AttrSizeStandard       = 1;
     79const uint k708AttrSizeLarge          = 2;
     80
     81const uint k708AttrOffsetSubscript    = 0;
     82const uint k708AttrOffsetNormal       = 1;
     83const uint k708AttrOffsetSuperscript  = 2;
     84
     85const uint k708AttrFontDefault               = 1;
     86const uint k708AttrFontMonospacedSerif       = 1;
     87const uint k708AttrFontProportionalSerif     = 2;
     88const uint k708AttrFontMonospacedSansSerif   = 3;
     89const uint k708AttrFontProportionalSansSerif = 4;
     90const uint k708AttrFontCasual                = 5;
     91const uint k708AttrFontCursive               = 6;
     92const uint k708AttrFontSmallCaps             = 7;
     93
     94const uint k708AttrColorBlack         = 0;
     95const uint k708AttrColorWhite         = 63;
     96
     97const uint k708AttrOpacitySolid       = 0;
     98const uint k708AttrOpacityFlash       = 1;
     99const uint k708AttrOpacityTranslucent = 2;
     100const uint k708AttrOpacityTransparent = 3;
     101
     102CC708Window::CC708Window()
     103    : priority(0),              visible(0),
     104      anchor_point(0),
     105      anchor_vertical(0),       anchor_horizontal(0),
     106      row_count(0),             column_count(0),
     107      row_lock(0),              column_lock(0),
     108      pen_style(0),             window_style(0),
     109
     110      fill_color(0),            fill_opacity(0),
     111      border_color(0),          border_type(0),
     112      scroll_dir(0),            print_dir(0),
     113      effect_dir(0),            display_effect(0),
     114      effect_speed(0),
     115      justify(0),               word_wrap(0),
     116
     117      true_row_count(0),        true_column_count(0),
     118      text(NULL),               exists(false),
     119      lock(true)
     120{
     121}
     122
     123CC708Window::~CC708Window()
     124{
     125    if (text)
     126        delete [] text;
     127}
     128
     129void CC708Window::Clear(void)
     130{
     131    // TODO
     132}
     133
     134CC708Character &CC708Window::GetCCChar(void) const
     135{
     136    QMutexLocker locker(&lock);
     137    assert(exists);
     138    assert(text);
     139    assert(pen.row    < true_row_count);
     140    assert(pen.column < true_column_count);
     141    return text[pen.row * true_column_count + pen.column];
     142}
     143
     144vector<CC708String*> CC708Window::GetStrings(void) const
     145{
     146    vector<CC708String*> list;
     147
     148    CC708String *cur = NULL;
     149
     150    for (uint j = 0; j < true_row_count; j++)
     151    {
     152        for (uint i = 0; i < true_column_count; i++)
     153        {
     154            CC708Character &chr = text[j * true_column_count + i];
     155            if (!cur)
     156            {
     157                cur = new CC708String;
     158                cur->x    = i;
     159                cur->y    = j;
     160                cur->str  = QString("%1").arg(chr.character);
     161                cur->attr = chr.attr;
     162            }
     163            else if (cur->attr == chr.attr)
     164            {
     165                cur->str = QString("%1%2").arg(cur->str).arg(chr.character);
     166            }
     167            else// if (cur->attr != chr.attr)
     168            {
     169                list.push_back(cur);
     170                cur = NULL;
     171                i--;
     172            }
     173        }
     174        if (cur)
     175        {
     176            list.push_back(cur);
     177            cur = NULL;
     178        }
     179    }
     180    return list;
     181}
     182
     183void CC708Window::SetWindowStyle(uint style)
     184{
     185    const uint style2justify[] =
     186    {
     187        k708JustifyLeft, k708JustifyLeft, k708JustifyLeft,   k708JustifyCenter,
     188        k708JustifyLeft, k708JustifyLeft, k708JustifyCenter, k708JustifyLeft,
     189    };
     190
     191    if ((style < 1) || (style > 7))
     192        return;
     193
     194    fill_color     = k708AttrColorBlack;
     195    fill_opacity   = ((2 == style) || (5 == style)) ?
     196        k708AttrOpacityTransparent : k708AttrOpacitySolid;
     197    border_color   = k708AttrColorBlack;
     198    border_type    = k708BorderNone;
     199    scroll_dir     = (style < 7) ? k708DirBottomToTop : k708DirRightToLeft;
     200    print_dir      = (style < 7) ? k708DirLeftToRight : k708DirTopToBottom;
     201    effect_dir     = scroll_dir;
     202    display_effect = k708EffectSnap;
     203    effect_speed   = 0;
     204    justify        = style2justify[style];
     205    word_wrap      = (style > 3) && (style < 7) ? 1 : 0;
     206}
     207
     208void CC708Window::AddChar(QChar ch)
     209{
     210    if (exists)
     211    {
     212        GetCCChar().attr      = pen.attr;
     213        GetCCChar().character = ch;
     214        int c = pen.column;
     215        int r = pen.row;
     216        IncrPenLocation();
     217
     218        VERBOSE(VB_IMPORTANT, QString("AddChar(%1) at (%2,%3) -> (%4,%5)")
     219                .arg(ch).arg(c).arg(r).arg(pen.column).arg(pen.row));
     220    }
     221}
     222
     223void CC708Window::IncrPenLocation(void)
     224{
     225    VERBOSE(VB_IMPORTANT, QString("dir %1: col %2, row %3")
     226            .arg(print_dir).arg(pen.column).arg(pen.row));
     227    // TODO: Scroll direction and up/down printing,
     228    // and word wrap not handled yet...
     229    int new_column = pen.column, new_row = pen.row;
     230
     231    new_column += (print_dir == k708DirLeftToRight) ? +1 : 0;
     232    new_column += (print_dir == k708DirRightToLeft) ? -1 : 0;
     233    new_row    += (print_dir == k708DirTopToBottom) ? +1 : 0;
     234    new_row    += (print_dir == k708DirBottomToTop) ? -1 : 0;
     235
     236    if (1)
     237    {
     238        // basic wrapping for l->r, r->l languages
     239        if (new_column > (int)true_column_count - 1)
     240        {
     241            new_column  = 0;
     242            new_row    += 1;
     243        }
     244        else if (new_column < 0)
     245        {
     246            new_column  = (int)true_column_count - 1;
     247            new_row    -= 1;
     248        }
     249    }
     250    pen.column = max(new_column, 0);
     251    pen.row    = max(new_row,    0);
     252   
     253    LimitPenLocation();
     254}
     255
     256void CC708Window::SetPenLocation(uint row, uint column)
     257{
     258    pen.row    = row;
     259    pen.column = column;
     260
     261    LimitPenLocation();
     262}
     263
     264void CC708Window::LimitPenLocation(void)
     265{
     266    // basic limiting
     267    uint max_col = max((int)true_column_count - 1, 0);
     268    uint max_row = max((int)true_row_count    - 1, 0);
     269    pen.column   = min(pen.column, max_col);
     270    pen.row      = min(pen.row,    max_row);
     271}
     272
     273/***************************************************************************/
     274
     275void CC708Pen::SetPenStyle(uint style)
     276{
     277    static const uint style2font[] = { 1, 1, 2, 3, 4, 5, 4, 5 };
     278
     279    if ((style < 1) || (style > 7))
     280        return;
     281
     282    attr.pen_size   = k708AttrSizeStandard;
     283    attr.offset     = k708AttrOffsetNormal;
     284    attr.font_tag   = style2font[style];
     285    attr.italics    = 0;
     286    attr.underline  = 0;
     287    attr.edge_type  = 0;
     288    attr.fg_color   = k708AttrColorWhite;
     289    attr.fg_opacity = k708AttrOpacitySolid;
     290    attr.bg_color   = k708AttrColorBlack;
     291    attr.bg_opacity = (style<6) ?
     292        k708AttrOpacitySolid : k708AttrOpacityTransparent;
     293    attr.edge_color = k708AttrColorBlack;
     294}
     295
     296CC708Character::CC708Character(const CC708Window &win)
     297{
     298    attr = win.pen.attr;
     299    character = ' ';
     300}
     301
     302bool CC708CharacterAttribute::operator==(
     303    const CC708CharacterAttribute &other) const
     304{
     305    return ((pen_size   == other.pen_size)   &&
     306            (offset     == other.offset)     &&
     307            (text_tag   == other.text_tag)   &&
     308            (font_tag   == other.font_tag)   &&
     309            (edge_type  == other.edge_type)  &&
     310            (underline  == other.underline)  &&
     311            (italics    == other.italics)    &&
     312            (fg_color   == other.fg_color)   &&
     313            (fg_opacity == other.fg_opacity) &&
     314            (bg_color   == other.bg_color)   &&
     315            (bg_opacity == other.bg_opacity) &&
     316            (edge_color == other.edge_color));
     317}
  • libs/libmythtv/nuppeldecoder.cpp

     
    11481148            if (getrawframes)
    11491149                StoreRawData(strm);
    11501150
    1151             GetNVP()->AddTextData((char *)strm, frameheader.packetlength,
     1151            GetNVP()->AddTextData(strm, frameheader.packetlength,
    11521152                                  frameheader.timecode, frameheader.comptype);
    11531153        }
    11541154    }
     
    11661166            .arg(newKey).arg(skipFrames)
    11671167            .arg((doFlush) ? "do" : "don't")
    11681168            .arg((discardFrames) ? "do" : "don't"));
    1169    
     1169
    11701170    DecoderBase::SeekReset(newKey, skipFrames, doFlush, discardFrames);
    11711171
    11721172    if (mpa_codec && doFlush)
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    912912    videoOutput->DrawSlice(frame, x, y, w, h);
    913913}
    914914
    915 void NuppelVideoPlayer::AddTextData(char *buffer, int len,
     915void NuppelVideoPlayer::AddTextData(unsigned char *buffer, int len,
    916916                                    long long timecode, char type)
    917917{
    918918    WrapTimecode(timecode, TC_CC);
     
    940940    }
    941941}
    942942
     943void NuppelVideoPlayer::SetCurrentWindow(uint service_num, int window_id)
     944{
     945    VERBOSE(VB_IMPORTANT, LOC + QString("SetCurrentWindow(%1, %2)")
     946            .arg(service_num).arg(window_id));
     947    CC708services[service_num].current_window = window_id;
     948}
     949
     950void NuppelVideoPlayer::DefineWindow(
     951    uint service_num,     int window_id,
     952    int priority,         int visible,
     953    int anchor_point,     int relative_pos,
     954    int anchor_vertical,  int anchor_horizontal,
     955    int row_count,        int column_count,
     956    int row_lock,         int column_lock,
     957    int pen_style,        int window_style)
     958{
     959    VERBOSE(VB_IMPORTANT, LOC +
     960            QString("DefineWindow(%1, %2)")
     961            .arg(service_num).arg(window_id) +
     962            QString("\n\t\t\t     prio %1, vis %2, ap %3, rp %4, av %5, ah %6")
     963            .arg(priority).arg(visible).arg(anchor_point).arg(relative_pos)
     964            .arg(anchor_vertical).arg(anchor_horizontal) +
     965            QString("\n\t\t\t     row_cnt %1, row_lck %2, "
     966                    "col_cnt %3, col_lck %4 ")
     967            .arg(row_count).arg(row_lock)
     968            .arg(column_count).arg(column_lock) +
     969            QString("\n\t\t\t     pen style %1, win style %2")
     970            .arg(pen_style).arg(window_style));
     971
     972    CC708services[service_num].current_window = window_id;
     973    CC708Window &win = GetCCWin(service_num, window_id);
     974
     975    QMutexLocker locker(&win.lock);
     976
     977    win.priority          = priority;
     978    win.visible           = visible;
     979    win.anchor_point      = anchor_point;
     980    win.relative_pos      = relative_pos;
     981    win.anchor_vertical   = anchor_vertical;
     982    win.anchor_horizontal = anchor_horizontal;
     983    win.row_count         = row_count;
     984    win.column_count      = column_count;
     985    win.row_lock          = row_lock;
     986    win.column_lock       = column_lock;
     987
     988    if ((!pen_style && !win.exists) || pen_style)
     989        win.pen.SetPenStyle(pen_style ? pen_style : 1);
     990
     991    if ((!window_style && !win.exists) || window_style)
     992        win.SetWindowStyle(window_style ? window_style : 1);
     993
     994    // these could be bigger if row/column lock is false, resp.
     995    win.true_row_count        = row_count;
     996    win.true_column_count     = column_count;
     997
     998    if (win.text)
     999        delete [] win.text;
     1000    uint num = win.true_row_count * win.true_column_count;
     1001    win.text = new CC708Character[num](win);
     1002
     1003    win.exists            = true;
     1004}
     1005
     1006void NuppelVideoPlayer::DeleteWindows(uint service_num, int window_map)
     1007{
     1008    VERBOSE(VB_IMPORTANT, LOC + QString("DeleteWindows(%1, 0x%2)")
     1009            .arg(service_num).arg(window_map,0,16));
     1010
     1011    for (uint i=0; i<8; i++)
     1012    {
     1013        if (i & window_map)
     1014            GetCCWin(service_num, i).exists = false;
     1015    }
     1016}
     1017
     1018void NuppelVideoPlayer::DisplayWindows(uint service_num, int window_map)
     1019{
     1020    VERBOSE(VB_IMPORTANT, LOC + QString("DisplayWindows(%1, 0x%2)")
     1021            .arg(service_num).arg(window_map,0,16));
     1022
     1023    for (uint i=0; i<8; i++)
     1024    {
     1025        if (i & window_map)
     1026            GetCCWin(service_num, i).visible = true;
     1027    }
     1028}
     1029
     1030void NuppelVideoPlayer::HideWindows(uint service_num, int window_map)
     1031{
     1032    VERBOSE(VB_IMPORTANT, LOC + QString("HideWindows(%1, 0x%2)")
     1033            .arg(service_num).arg(window_map,0,16));
     1034
     1035    for (uint i=0; i<8; i++)
     1036    {
     1037        if (i & window_map)
     1038            GetCCWin(service_num, i).visible = false;
     1039    }
     1040}
     1041
     1042void NuppelVideoPlayer::ClearWindows(uint service_num, int window_map)
     1043{
     1044    VERBOSE(VB_IMPORTANT, LOC + QString("ClearWindows(%1, 0x%2)")
     1045            .arg(service_num).arg(window_map,0,16));
     1046
     1047    for (uint i=0; i<8; i++)
     1048    {
     1049        if (i & window_map)
     1050            GetCCWin(service_num, i).Clear();
     1051    }
     1052}
     1053
     1054void NuppelVideoPlayer::ToggleWindows(uint service_num, int window_map)
     1055{
     1056    VERBOSE(VB_IMPORTANT, LOC + QString("ToggleWindows(%1, 0x%2)")
     1057            .arg(service_num).arg(window_map,0,16));
     1058
     1059    for (uint i=0; i<8; i++)
     1060    {
     1061        if (i & window_map)
     1062        {
     1063            GetCCWin(service_num, i).visible =
     1064                !GetCCWin(service_num, i).visible;
     1065        }
     1066    }
     1067}
     1068
     1069void NuppelVideoPlayer::SetWindowAttributes(
     1070    uint service_num,
     1071    int fill_color,     int fill_opacity,
     1072    int border_color,   int border_type,
     1073    int scroll_dir,     int print_dir,
     1074    int effect_dir,
     1075    int display_effect, int effect_speed,
     1076    int justify,        int word_wrap)
     1077{
     1078    VERBOSE(VB_IMPORTANT, LOC + QString("SetWindowAttributes(%1...)")
     1079            .arg(service_num));
     1080
     1081    CC708Window &win = GetCCWin(service_num);
     1082
     1083    win.fill_color     = fill_color;
     1084    win.fill_opacity   = fill_opacity;
     1085    win.border_color   = border_color;
     1086    win.border_type    = border_type;
     1087    win.scroll_dir     = scroll_dir;
     1088    win.print_dir      = print_dir;
     1089    win.effect_dir     = effect_dir;
     1090    win.display_effect = display_effect;
     1091    win.effect_speed   = effect_speed;
     1092    win.justify        = justify;
     1093    win.word_wrap      = word_wrap;
     1094}
     1095
     1096void NuppelVideoPlayer::SetPenAttributes(
     1097    uint service_num, int pen_size,
     1098    int offset,       int text_tag,  int font_tag,
     1099    int edge_type,    int underline, int italics)
     1100{
     1101    VERBOSE(VB_IMPORTANT, LOC + QString("SetPenAttributes(%1...)")
     1102            .arg(service_num));
     1103
     1104    CC708CharacterAttribute &attr = GetCCWin(service_num).pen.attr;
     1105
     1106    attr.pen_size  = pen_size;
     1107    attr.offset    = offset;
     1108    attr.text_tag  = text_tag;
     1109    attr.font_tag  = font_tag;
     1110    attr.edge_type = edge_type;
     1111    attr.underline = underline;
     1112    attr.italics   = italics;
     1113}
     1114
     1115void NuppelVideoPlayer::SetPenColor(
     1116    uint service_num,
     1117    int fg_color, int fg_opacity,
     1118    int bg_color, int bg_opacity,
     1119    int edge_color)
     1120{
     1121    VERBOSE(VB_IMPORTANT, LOC + QString("SetPenColor(%1...)")
     1122            .arg(service_num));
     1123
     1124    CC708CharacterAttribute &attr = GetCCWin(service_num).pen.attr;
     1125
     1126    attr.fg_color   = fg_color;
     1127    attr.fg_opacity = fg_opacity;
     1128    attr.bg_color   = bg_color;
     1129    attr.bg_opacity = bg_opacity;
     1130    attr.edge_color = edge_color;
     1131}
     1132
     1133void NuppelVideoPlayer::SetPenLocation(uint service_num, int row, int column)
     1134{
     1135    VERBOSE(VB_IMPORTANT, LOC + QString("SetPenLocation(%1, (%2x%3))")
     1136            .arg(service_num).arg(row).arg(column));
     1137    GetCCWin(service_num).SetPenLocation(row, column);
     1138}
     1139
     1140void NuppelVideoPlayer::Delay(uint service_num, int tenths_of_seconds)
     1141{
     1142    VERBOSE(VB_IMPORTANT, LOC + QString("Delay(%1, %2 seconds)")
     1143            .arg(service_num).arg(tenths_of_seconds * 0.1f));
     1144}
     1145
     1146void NuppelVideoPlayer::DelayCancel(uint service_num)
     1147{
     1148    VERBOSE(VB_IMPORTANT, LOC + QString("DelayCancel(%1)").arg(service_num));
     1149}
     1150
     1151void NuppelVideoPlayer::Reset(uint service_num)
     1152{
     1153    VERBOSE(VB_IMPORTANT, LOC + QString("Reset(%1)").arg(service_num));
     1154    DeleteWindows(service_num, 0x7);
     1155    DelayCancel(service_num);
     1156}
     1157
     1158void NuppelVideoPlayer::TextWrite(uint service_num,
     1159                                  short* unicode_string, short len)
     1160{
     1161    for (uint i = 0; i < (uint)len; i++)
     1162        GetCCWin(service_num).AddChar(QChar(unicode_string[i]));
     1163
     1164    if (GetOSD())
     1165        GetOSD()->CC708Updated();
     1166}
     1167
     1168void NuppelVideoPlayer::SetOSDFontName(const QString osdfonts[22],
     1169                                       const QString &prefix)
     1170{
     1171    osdfontname   = QDeepCopy<QString>(osdfonts[0]);
     1172    osdccfontname = QDeepCopy<QString>(osdfonts[1]);
     1173    for (int i = 2; i < 22; i++)
     1174        osd708fontnames[i - 2] = QDeepCopy<QString>(osdfonts[i]);
     1175    osdprefix = QDeepCopy<QString>(prefix);
     1176}
     1177
     1178void NuppelVideoPlayer::SetOSDThemeName(const QString themename)
     1179{
     1180    osdtheme = QDeepCopy<QString>(themename);
     1181}
     1182
     1183
    9431184void NuppelVideoPlayer::CheckPrebuffering(void)
    9441185{
    9451186    if (kVideoOutput_IVTV == forceVideoOutput)
     
    23752616        {           
    23762617            osd->DisableFade();
    23772618        }
     2619        osd->SetCC708Service(&CC708services[1]);
    23782620    }
    23792621
    23802622    playing = true;
     
    50575299    usleep(100000);
    50585300    ClearAfterSeek();
    50595301}
    5060 
  • libs/libmythtv/osd.h

     
    4646class QKeyEvent;
    4747class OSDGenericTree;
    4848class ccText;
     49class CC708Service;
    4950
    5051class OSD : public QObject
    5152{
     
    6869                     const QString &callsign, const QString &iconpath,
    6970                     int length);
    7071    void SetChannumText(const QString &text, int length);
     72
     73    // CC-608 and DVB text captions (not DVB/DVD subtitles).
    7174    void AddCCText(const QString &text, int x, int y, int color,
    7275                   bool teletextmode = false);
    7376    void ClearAllCCText();
    7477    void UpdateCCText(vector<ccText*> *ccbuf,
    75                       int replace = 0, int scroll = 0, bool scroll_prsv = false,
     78                      int replace = 0, int scroll = 0,
     79                      bool scroll_prsv = false,
    7680                      int scroll_yoff = 0, int scroll_ymax = 15);
     81    // CC-708 text captions (for ATSC)
     82    void SetCC708Service(const CC708Service *service);
     83    void CC708Updated(void);
     84
    7785    void SetSettingsText(const QString &text, int length);
    7886
    7987    void NewDialogBox(const QString &name, const QString &message,
     
    140148    QRect GetSubtitleBounds();
    141149
    142150 private:
    143     void SetDefaults();
     151    bool InitDefaults(void);
     152    bool InitCC608(void);
     153    bool InitCC708(void);
     154    bool InitDVBSub(void);
     155    bool InitMenu(void);
     156
    144157    TTFFont *LoadFont(QString name, int size);
    145158    QString FindTheme(QString name);
    146159
     
    201214
    202215    OSDListTreeType *runningTreeMenu;
    203216    QString treeMenuContainer;
     217
     218    // EIA-708 captions
     219    QString fontname;
     220    QString ccfontname;
     221    QString cc708fontnames[20];
     222    QString fontSizeType;
    204223};
    205224   
    206225#endif
  • libs/libmythtv/avformatdecoder.cpp

     
    1818#include "mythdbcon.h"
    1919#include "iso639.h"
    2020#include "pespacket.h"
     21#include "cc708decoder.h"
    2122
    2223#ifdef USING_XVMC
    2324#include "videoout_xv.h"
     
    5455void render_slice_xvmc(struct AVCodecContext *s, const AVFrame *src,
    5556                       int offset[4], int y, int type, int height);
    5657void decode_cc_dvd(struct AVCodecContext *c, const uint8_t *buf, int buf_size);
    57 void decode_cc_atsc(struct AVCodecContext *c, const uint8_t *buf, int buf_size);
     58void decode_cc_atsc(struct AVCodecContext *c,const uint8_t *buf, int buf_size);
    5859
    5960static void align_dimensions(AVCodecContext *avctx, uint &width, uint &height)
    6061{
     
    261262      lastccptsu(0),
    262263      using_null_videoout(use_null_videoout),
    263264      video_codec_id(kCodec_NONE),
    264       maxkeyframedist(-1),
    265       ccd(new CCDecoder(this)),
     265      maxkeyframedist(-1),
     266      // Closed Caption decoders
     267      ccd(new CCDecoder(parent)),     ccd708(new CC708Decoder(parent)),
    266268      // Audio
    267269      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    268270      allow_ac3_passthru(false),    allow_dts_passthru(false),
     
    13831385    nd->lastccptsu = utc;
    13841386}
    13851387
    1386 void decode_cc_atsc(struct AVCodecContext *s, const uint8_t *buf, int buf_size)
     1388void decode_cc_atsc(struct AVCodecContext *s, const uint8_t *buf, int sz)
    13871389{
    1388     AvFormatDecoder *nd = (AvFormatDecoder *)(s->opaque);
     1390    if (sz < 2)
     1391        return;
     1392
     1393    AvFormatDecoder *nd    = (AvFormatDecoder *)(s->opaque);
    13891394    unsigned long long utc = nd->lastccptsu;
     1395    uint buf_size          = sz;
    13901396
    1391     const uint8_t *current = buf;
    1392     int curbytes = 0;
    1393     int curcount = 0;
    1394     uint8_t data1, data2;
    1395     uint8_t cc_count;
    1396     uint8_t cc_code;
    1397     int  cc_state;
     1397    // closed caption data
     1398    //cc_data() {
     1399    // reserved                1 0.0   1 
     1400    // process_cc_data_flag    1 0.1   bslbf
     1401    bool process_cc_data = buf[0] & 0x40;
     1402    if (!process_cc_data)
     1403        return; // early exit if process_cc_data_flag false
    13981404
    1399     if (buf_size < 2)
    1400         return;
     1405    // additional_data_flag    1 0.2   bslbf
     1406    //bool additional_data = buf[0] & 0x20;
     1407    // cc_count                5 0.3   uimsbf
     1408    uint cc_count = buf[0] & 0x1f;
     1409    // reserved                8 1.0   0xff
     1410    // em_data                 8 2.0
    14011411
    1402     // check process_cc_data_flag
    1403     if (!(*current & 0x40))
    1404         return;
    1405     cc_count = *current & 0x1f;
    1406     current++;  curbytes++;
     1412    uint index    = 2; // skip reserved & em_data
     1413    uint curcount = 0;
     1414    uint cc_state = 0;
    14071415
    1408     // skip em_data
    1409     current++;  curbytes++;
    1410 
    1411     cc_state = 0;
    1412     while (curbytes < buf_size && curcount < cc_count)
     1416    while (index < buf_size && curcount < cc_count)
    14131417    {
    1414         cc_code = *current++;
    1415         curbytes++;
    1416    
    1417         if (buf_size - curbytes < 2)
     1418        if (buf_size < index + 3)
    14181419            break;
    14191420   
    1420         data1 = *current++;
    1421         data2 = *current++;
    1422         curbytes += 2;
     1421        uint cc_code = buf[index];
     1422        uint data1   = buf[index+1];
     1423        uint data2   = buf[index+2];
     1424
     1425        index += 3;
    14231426        curcount++;
    14241427
     1428        bool cc_valid = cc_code & 0x04;
     1429        uint cc_type  = cc_code & 0x03;
     1430
    14251431        // check cc_valid
    1426         if (!(cc_code & 0x04))
     1432        if (!cc_valid)
    14271433            continue;
    14281434
    1429         cc_code &= 0x03;
    1430         if (cc_code <= 0x1)
     1435        if (cc_type <= 0x1)
    14311436        {
    14321437            // EIA-608 field-1/2
    14331438            int data = (data2 << 8) | data1;
    14341439            unsigned int tc;
    14351440
    1436             if ((cc_state & cc_code) == cc_code)
     1441            if ((cc_state & cc_type) == cc_type)
    14371442            {
    14381443                // another field of same type -- assume
    14391444                // it's for the next frame
    14401445                utc += 33367;
    14411446                cc_state = 0;
    14421447            }
    1443             cc_state |= cc_code;
     1448            cc_state |= cc_type;
    14441449            tc = utc / 1000;
    14451450
    14461451            // For some reason, one frame can be out of order.
     
    14481453            // frame so we can send the correct sequence to the
    14491454            // decoder.
    14501455
    1451             if (nd->save_cctc[cc_code])
     1456            if (nd->save_cctc[cc_type])
    14521457            {
    1453                 if (nd->save_cctc[cc_code] < tc)
     1458                if (nd->save_cctc[cc_type] < tc)
    14541459                {
    14551460                    // send saved code to decoder
    1456                     nd->ccd->FormatCCField(nd->save_cctc[cc_code],
    1457                                            cc_code,
    1458                                            nd->save_ccdata[cc_code]);
    1459                     nd->save_cctc[cc_code] = 0;
     1461                    nd->ccd->FormatCCField(nd->save_cctc[cc_type],
     1462                                           cc_type,
     1463                                           nd->save_ccdata[cc_type]);
     1464                    nd->save_cctc[cc_type] = 0;
    14601465                }
    1461                 else if ((nd->save_cctc[cc_code] - tc) > 1000)
     1466                else if ((nd->save_cctc[cc_type] - tc) > 1000)
    14621467                {
    14631468                    // saved code is too far in the future; probably bad
    14641469                    // - discard it
    1465                     nd->save_cctc[cc_code] = 0;
     1470                    nd->save_cctc[cc_type] = 0;
    14661471                }
    14671472                else
    14681473                {
    14691474                    // send new code to decoder
    1470                     nd->ccd->FormatCCField(tc, cc_code, data);
     1475                    nd->ccd->FormatCCField(tc, cc_type, data);
    14711476                }
    14721477            }
    1473             if (!nd->save_cctc[cc_code])
     1478            if (!nd->save_cctc[cc_type])
    14741479            {
    14751480                // no saved code
    14761481                // - save new code since it may be out of order
    1477                 nd->save_cctc[cc_code] = tc;
    1478                 nd->save_ccdata[cc_code] = data;
     1482                nd->save_cctc[cc_type] = tc;
     1483                nd->save_ccdata[cc_type] = data;
    14791484            }
    14801485        }
    1481         else
    1482         {
    1483             // TODO:  EIA-708 DTVCC packet data
    1484         }
    1485 
     1486        else // EIA-708 CC data
     1487            nd->ccd708->decode_cc_data(cc_type, data1, data2);
    14861488    }
    14871489    nd->lastccptsu = utc;
    14881490}
     
    25212523                        continue;
    25222524                    }
    25232525
     2526#if 0
     2527                    if (mpa_pic.captions.size) {
     2528                        av_log(NULL, AV_LOG_ERROR, "picture # (%i, %i)\n",
     2529                               mpa_pic.coded_picture_number,
     2530                               mpa_pic.display_picture_number);
     2531                        m_parent->ParseATSCCaptions(&mpa_pic.captions);
     2532                    }
     2533#endif
    25242534                    VideoFrame *picframe = (VideoFrame *)(mpa_pic.opaque);
    25252535
    25262536                    if (!directrendering)
     
    28252835    return enc_len;
    28262836}
    28272837
    2828 void AvFormatDecoder::AddTextData(unsigned char *buf, int len,
    2829                                   long long timecode, char type)
    2830 {
    2831     m_parent->AddTextData((char*)buf, len, timecode, type);
    2832 }
    2833  
    28342838static int DTS_SAMPLEFREQS[16] =
    28352839{
    28362840    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
  • libs/libmythtv/osdtypes.cpp

     
    11#include <qimage.h>
    22#include <qmap.h>
    33#include <qregexp.h>
    4 #include <math.h>
     4#include <cmath>
    55
    66#include <iostream>
    77using namespace std;
     
    216216        {
    217217            item->Reinit(xoff, yoff, displaywidth, displayheight);
    218218        }
     219        else if (OSDType708CC *item = dynamic_cast<OSDType708CC*>(type))
     220        {
     221            item->Reinit(xoff, yoff, displaywidth, displayheight);
     222        }
    219223        else if (OSDListTreeType *item = dynamic_cast<OSDListTreeType*>(type))
    220224        {
    221225            item->Reinit(wchange, hchange, wmult, hmult);
     
    18971901        }
    18981902    }
    18991903}
     1904
     1905void OSDType708CC::Reinit(int x, int y, int dispw, int disph)
     1906{
     1907    xoffset = x;
     1908    yoffset = y;
     1909    displaywidth = dispw;
     1910    displayheight = disph;
     1911}
     1912
     1913OSDType708CC::OSDType708CC(const QString &name, TTFFont *fonts[60],
     1914                           int xoff, int yoff, int dispw, int disph) :
     1915    OSDType(name)
     1916{
     1917    xoffset = xoff;
     1918    yoffset = yoff;
     1919    displaywidth  = dispw;
     1920    displayheight = disph;
     1921
     1922    int c[4] = {0, 85, 170, 255};
     1923
     1924    for (int i = 0; i < 64; i++)
     1925        colors[i].setRgb(c[(i>>4)&3], c[(i>>2)&3], c[i&3]);
     1926
     1927    for (int i = 0; i < 60; i++)
     1928    {
     1929        m_fonts[i] = fonts[i];
     1930    }
     1931}
     1932
     1933QRect OSDType708CC::CalcBounds(const OSDSurface *surface,
     1934                               const CC708Window &win,
     1935                               const vector<CC708String*> &list)
     1936{
     1937    uint max_width = 0, total_height = 0, i = 0;
     1938    for (uint row = 0; (row < win.true_row_count) && (i < list.size()); row++)
     1939    {
     1940        uint tot_width = 0, max_height = 0;
     1941        for (; list[i] && (list[i]->y <= row) && (i < list.size()); i++)
     1942        {
     1943            int text_length;
     1944            if (list[i]->y < row)
     1945                continue;
     1946            if (list[i]->str.stripWhiteSpace().isEmpty())
     1947                continue;
     1948
     1949            TTFFont *font = m_fonts[0];
     1950            font->CalcWidth(list[i]->str, &text_length);
     1951
     1952            VERBOSE(VB_IMPORTANT, "Row#"<<i<<" w/x("<<list[i]->x<<"): WxH "
     1953                    <<text_length<<"x"
     1954                    <<max_height<<" '"<<list[i]->str<<"'");
     1955            tot_width  += max(text_length, 0);
     1956            max_height  = max(max_height, (uint)font->Size() * 3 / 2);
     1957        }
     1958        max_width     = max(max_width, tot_width);
     1959        total_height += max_height;
     1960    }
     1961    if (!max_width && !total_height)
     1962        return QRect(0,0,0,0);
     1963
     1964    // add some padding..
     1965    max_width    += 4;
     1966    total_height += 4;
     1967
     1968    // 16:9
     1969    float xrange = 210.0f;
     1970    float yrange = 75.0f;
     1971    // 4:3
     1972    //float xrange = 160.0f;
     1973    //float yrange = 75.0f;
     1974
     1975    // relative position
     1976    xrange = (win.relative_pos) ? 100.0f : xrange;
     1977    yrange = (win.relative_pos) ? 100.0f : yrange;
     1978
     1979    float xmult = (surface->width  - 4) / xrange;
     1980    float ymult = (surface->height - 4) / yrange;
     1981
     1982    uint anchor_x = (uint) xmult * win.anchor_horizontal + 2;
     1983    uint anchor_y = (uint) ymult * win.anchor_vertical   + 2;
     1984
     1985    VERBOSE(VB_IMPORTANT, "Anchor loc:  "<<anchor_x<<"x"<<anchor_y);
     1986    VERBOSE(VB_IMPORTANT, "Window size: ("
     1987            <<max_width<<", "<<total_height<<")");
     1988
     1989    // Make sure bounds are within window by adjusting anchor point
     1990    int x_adj = (int)(anchor_x + max_width) - (surface->width  - 4);
     1991    if (x_adj > 0)
     1992        anchor_x = max(0, (int)anchor_x - x_adj);
     1993
     1994    int y_adj = (int)(anchor_y + total_height) - (surface->height  - 4);
     1995    if (y_adj > 0)
     1996        anchor_y = max(0, (int)anchor_y - y_adj);
     1997
     1998    // If it is still out of bounds, shrink the surface
     1999    if (anchor_x + max_width > (uint)surface->width)
     2000        max_width = surface->width - anchor_x;
     2001
     2002    if (anchor_y + total_height > (uint)surface->height)
     2003        total_height = surface->height - anchor_y;
     2004
     2005    return QRect(anchor_x, anchor_y, max_width, total_height);
     2006}
     2007
     2008void OSDType708CC::Draw(OSDSurface *surface,
     2009                        const QPoint &ul, /* upper left corner */
     2010                        const CC708Window &win,
     2011                        const vector<CC708String*> &list)
     2012{
     2013    int maxx = surface->width;
     2014    int maxy = surface->height;
     2015    uint max_width = 0, total_height = 0, i = 0;
     2016    for (uint row = 0; (row < win.true_row_count) && (i < list.size()); row++)
     2017    {
     2018        uint tot_width = 0, max_height = 0;
     2019        for (; list[i] && (list[i]->y == row) && (i < list.size()); i++)
     2020        {
     2021            int text_length;
     2022
     2023            if (list[i]->str.isEmpty())
     2024                continue;
     2025
     2026            TTFFont *font = m_fonts[0];
     2027
     2028            font->CalcWidth(list[i]->str, &text_length);
     2029            font->setColor(Qt::white, kTTF_Normal);
     2030            font->DrawString(surface,
     2031                             ul.x() + tot_width, ul.y() + total_height + 2,
     2032                             list[i]->str, maxx, maxy, 255);
     2033
     2034            tot_width  += max(text_length, 0);
     2035            max_height  = max(max_height, (uint)font->Size() * 3 / 2);
     2036        }
     2037        max_width     = max(max_width, tot_width);
     2038        total_height += max_height;
     2039    }
     2040}
     2041
     2042void OSDType708CC::Draw(OSDSurface *surface, int /*fade*/, int /*maxfade*/,
     2043                        int /*xoff*/, int /*yoff*/)
     2044{
     2045    if (!cc708data || surface->width < 4 || surface->height < 4)
     2046        return;
     2047
     2048    for (uint i = 0; i < 8; i++)
     2049    {
     2050        const CC708Window &win = cc708data->windows[i];
     2051        if (!win.exists)
     2052            continue;
     2053
     2054        QMutexLocker locker(&win.lock);
     2055
     2056        VERBOSE(VB_IMPORTANT, "Window #"<<i);
     2057        vector<CC708String*> list = win.GetStrings();
     2058        QRect bounds = CalcBounds(surface, win, list);
     2059        QPoint ul(0,0);
     2060        if (bounds.width())
     2061        {
     2062            QRect rect(0,0, bounds.width(), bounds.height());
     2063            OSDTypeBox box(QString("cc708_background%1").arg(i), rect);
     2064            box.SetRect(rect);
     2065            box.Draw(surface, 0/*fade*/, 0/*maxfade*/,
     2066                     bounds.left()/*xoff*/, bounds.bottom()/*yoff*/);
     2067            Draw(surface, bounds.topLeft(), win, list);
     2068        }
     2069        VERBOSE(VB_IMPORTANT, "");
     2070
     2071        for (uint i = 0; i < list.size(); i++)
     2072            delete list[i];
     2073    }
     2074}
     2075
     2076
     2077
     2078
     2079
     2080
     2081
     2082
     2083
     2084
     2085
     2086
     2087
     2088
     2089
     2090
     2091
     2092
     2093
     2094
     2095
     2096
     2097
     2098#if 0
     2099void OSDType708CC::DefineWindow(
     2100    int window_id,    int priority,        int visible,
     2101    int anchor_id,    int anchor_vertical, int anchor_horizontal,
     2102    int row_count,    int col_count,       int row_lock, int col_lock,
     2103    int pen_style,    int window_style)
     2104{
     2105    QString str("DefineWindow(%1, %2, %3,  %4, %5, %6");
     2106    str.arg(window_id).arg(priority).arg(visible)
     2107       .arg(anchor_id).arg(anchor_vertical).arg(anchor_horizontal);
     2108    str.append(QString("%1, %2, %3, %4, %5, %6)")
     2109               .arg(row_count).arg(col_count).arg(row_lock).arg(col_lock)
     2110               .arg(pen_style).arg(window_style));
     2111
     2112    m_current_window = window_id;
     2113
     2114    Window708 win = m_windows[m_current_window];
     2115    win.anchorPoint =
     2116    QPoint(anchor_horizontal, anchor_vertical);
     2117    win.priority  = priority;
     2118    win.visible   = visible;
     2119    win.anchor_id = anchor_id;
     2120    win.row_count = row_count;
     2121    win.col_count = col_count;
     2122    win.row_lock  = row_lock;
     2123    win.col_lock  = col_lock;
     2124
     2125    if (pen_style>0)
     2126    {
     2127        win.curPen.font.setStyleHint(
     2128            (pen_style<4) ? QFont::Serif : QFont::SansSerif);
     2129        win.curPen.font.setFixedPitch((pen_style&1));
     2130        win.curPen.textTag           = 0;    // dialog text
     2131        win.curPen.font.setPointSize(24);    // standard font size
     2132        win.curPen.offset            = 1;    // normal
     2133        win.curPen.font.setItalic(false);
     2134        win.curPen.font.setUnderline(false);
     2135        win.curPen.edgeType          = 0;    // none
     2136        win.curPen.foregroundColor   = Qt::white;
     2137        win.curPen.edgeColor         = Qt::black;
     2138        win.curPen.backgroundColor   = Qt::black;
     2139        win.curPen.foregroundOpacity = 3;    // solid
     2140        win.curPen.backgroundOpacity = (pen_style>5) ? 0:3; // transparent:solid
     2141    }
     2142
     2143    if (window_style>0)
     2144    {
     2145        win.justify   = (3==window_style || 6==window_style) ? 2:0; // center:left
     2146        win.printDir  = (7==window_style) ? 2 : 0; // Top-to-Bottom:Left-to-Right
     2147        win.scrollDir = (7==window_style) ? 1 : 3; // Right-to-Left:Bottom-to-Top
     2148        win.wordWrap  = (4<=window_style && window_style<=6) ? true : false;
     2149        win.displayEffect = 0; // Snap
     2150        win.effectDir     = 0;
     2151        win.effectSpeed   = 0;
     2152        win.fillColor     = Qt::black;
     2153        win.fillOpacity   = (2==window_style || 5==window_style) ? 0:3; // transparent:solid
     2154        win.borderType    = 0; // none
     2155    }
     2156    VERBOSE(VB_IMPORTANT, str);
     2157}
     2158#endif
     2159/*
     2160void OSDType708CC::SetWindowAttributes(int fill_color,     int fill_opacity,
     2161                                       int border_color,   int border_type,
     2162                                       int scroll_dir,     int print_dir,
     2163                                       int effect_dir,
     2164                                       int display_effect, int effect_speed,
     2165                                       int justify,        int word_wrap)
     2166{
     2167    VERBOSE(VB_IMPORTANT, "SetWindowAttributes()");
     2168    if (m_current_window>=0)
     2169    {
     2170        Window708 &win = m_windows[m_current_window];
     2171        win.fillColor     = colors[fill_color&0x3f];
     2172        win.borderColor   = colors[border_color&0x3f];
     2173        win.fillOpacity   = fill_opacity;
     2174        win.borderType    = border_type;
     2175        win.scrollDir     = scroll_dir;
     2176        win.printDir      = print_dir;
     2177        win.effectDir     = effect_dir;
     2178        win.displayEffect = display_effect;
     2179        win.effectSpeed   = effect_speed;
     2180        win.justify       = justify;
     2181        win.wordWrap      = word_wrap;
     2182    }
     2183}
     2184
     2185void OSDType708CC::SetPenAttributes(int pen_size,
     2186                                    int offset,    int text_tag,  int font_tag,
     2187                                    int edge_type, int underline, int italics)
     2188{
     2189    int pointSize[4] = { 18, 24, 30, 24 };
     2190    VERBOSE(VB_IMPORTANT, "SetPenAttributes()");
     2191    if (m_current_window>=0)
     2192    {
     2193        QFont::StyleHint stylemap[8] =
     2194        {
     2195            QFont::AnyStyle,  QFont::Serif,     QFont::Serif,
     2196            QFont::SansSerif, QFont::SansSerif, QFont::Decorative,
     2197            QFont::Decorative, QFont::Decorative
     2198        };
     2199        bool mono[8] = { true, true, false, true, false, false, false, false };
     2200        Pen708 &pen = m_windows[m_current_window].curPen;
     2201        pen.font.setStyleHint(stylemap[font_tag]);
     2202        pen.font.setFixedPitch(mono[font_tag]);
     2203
     2204        pen.font.setPointSize(pointSize[pen_size]);
     2205        pen.font.setUnderline(underline);
     2206        pen.font.setItalic(italics);
     2207        pen.offset = offset;
     2208        pen.textTag = text_tag;
     2209        pen.edgeType = edge_type;
     2210    }
     2211}
     2212*/
     2213/*
     2214void OSDType708CC::SetPenColor(int fg_color,   int fg_opacity,
     2215                               int bg_color,   int bg_opacity,
     2216                               int edge_color)
     2217{
     2218    VERBOSE(VB_IMPORTANT, QString("SetPenColor()"));
     2219    if (m_current_window>=0)
     2220    {
     2221        Pen708 &pen = m_windows[m_current_window].curPen;
     2222        pen.foregroundColor   = colors[fg_color&0x3f];
     2223        pen.backgroundColor   = colors[bg_color&0x3f];
     2224        pen.edgeColor         = colors[edge_color&0x3f];
     2225        pen.foregroundOpacity = fg_opacity;
     2226        pen.backgroundOpacity = bg_opacity;
     2227    }
     2228}
     2229*/
     2230/*
     2231void OSDType708CC::SetPenLocation(int row, int column)
     2232{
     2233    VERBOSE(VB_IMPORTANT, QString("SetPenLocation(%1, %2)").arg(row).arg(column));
     2234    m_windows[m_current_window].cursorPoint = QPoint(column, row);
     2235}
     2236*/
     2237/*
     2238void OSDType708CC::Delay(int tenths_of_seconds)
     2239{
     2240    VERBOSE(VB_IMPORTANT, QString("Delay(%1)").arg(0.1*tenths_of_seconds));
     2241}
     2242
     2243void OSDType708CC::DelayCancel()
     2244{
     2245    VERBOSE(VB_IMPORTANT, "DelayCancel()");
     2246}
     2247*/
     2248/*
     2249void OSDType708CC::Reset()
     2250{
     2251    VERBOSE(VB_IMPORTANT, "Reset()");
     2252    for (int i=0; i<8; i++)
     2253    {
     2254        Pen708 &pen = m_windows[i].curPen;
     2255        pen.offset   = 1;
     2256        pen.textTag  = 0;
     2257        pen.edgeType = 0;
     2258        pen.font.setStyleHint(QFont::Serif);
     2259        pen.font.setFixedPitch(false);
     2260        pen.font.setItalic(false);
     2261        pen.font.setBold(false);
     2262        pen.font.setUnderline(false);
     2263        pen.font.setPointSize(24);
     2264    }
     2265}
     2266*/
     2267/*
     2268void OSDType708CC::AddCCText(QString str)
     2269{
     2270    VERBOSE(VB_IMPORTANT, QString("AddCCText(%1)").arg(str));
     2271}
     2272*/
  • libs/libmythtv/libmythtv.pro

     
    9191HEADERS += recordingtypes.h         jobqueue.h
    9292HEADERS += filtermanager.h          recordingprofile.h
    9393HEADERS += remoteencoder.h          videosource.h
    94 HEADERS += ccdecoder.h
     94HEADERS += ccdecoder.h              cc708decoder.h
     95HEADERS += cc708window.h
    9596HEADERS += sr_dialog.h              sr_root.h
    9697HEADERS += sr_items.h               scheduledrecording.h
    9798HEADERS += signalmonitorvalue.h     viewschdiff.h
     
    108109SOURCES += recordingtypes.cpp       jobqueue.cpp
    109110SOURCES += filtermanager.cpp        recordingprofile.cpp
    110111SOURCES += remoteencoder.cpp        videosource.cpp
    111 SOURCES += ccdecoder.cpp
     112SOURCES += ccdecoder.cpp            cc708decoder.cpp
     113SOURCES += cc708window.cpp
    112114SOURCES += sr_dialog.cpp            sr_root.cpp
    113115SOURCES += sr_items.cpp             scheduledrecording.cpp
    114116SOURCES += signalmonitorvalue.cpp
  • libs/libmythtv/osdtypes.h

     
    88#include <vector>
    99#include <qobject.h>
    1010#include <qregexp.h>
     11#include <qcolor.h>
     12#include <qfont.h>
     13#include "cc708window.h"
    1114
    1215using namespace std;
    1316
     
    467470
    468471    int xoffset, yoffset, displaywidth, displayheight;
    469472};
     473/*
     474class Pen708 {
     475    friend class OSDType708CC;
     476  private:
     477    QFont  font;
     478    QColor foregroundColor;
     479    QColor backgroundColor;
     480    QColor edgeColor;
     481    int offset;
     482    int textTag;
     483    int edgeType;
     484    int foregroundOpacity; // also used for edge opacity
     485    int backgroundOpacity;
     486};
    470487
     488class Window708 {
     489    friend class OSDType708CC;
     490  private:
     491    Window708() : anchorPoint(0,0), fillColor("black"), borderColor("white") {}
     492    ~Window708() {}
     493
     494    // Pen Attributes
     495    QPoint cursorPoint;
     496    QPoint anchorPoint;
     497    Pen708 curPen;
     498
     499    QColor fillColor;
     500    QColor borderColor;
     501    int fillOpacity;
     502    int borderType;
     503    int scrollDir;
     504    int printDir;
     505    int effectDir;
     506    int displayEffect;
     507    int effectSpeed;
     508    int justify;
     509    bool wordWrap;
     510
     511    int priority; // higher is better
     512    int visible;
     513    int anchor_id;
     514    int row_count;
     515    int col_count;
     516    bool row_lock;
     517    bool col_lock;
     518};
     519*/
     520class OSDType708CC : public OSDType
     521{
     522  public:
     523    OSDType708CC(const QString &name, TTFFont *fonts[60],
     524                 int xoff, int yoff, int dispw, int disph);
     525    virtual ~OSDType708CC() {}
     526
     527    void Reinit(int xoff, int yoff, int dispw, int disph);
     528
     529    void SetCCService(const CC708Service *service)
     530        { cc708data = service; }
     531
     532    void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
     533
     534  private:
     535    QRect CalcBounds(const OSDSurface*, const CC708Window&,
     536                     const vector<CC708String*>&);
     537    void  Draw(OSDSurface*,        const QPoint&,
     538               const CC708Window&, const vector<CC708String*>&);
     539
     540    const CC708Service *cc708data;
     541
     542    TTFFont *m_fonts[60];
     543    QColor   colors[64];
     544
     545    int xoffset, yoffset, displaywidth, displayheight;
     546};
     547
    471548#endif
  • libs/libmythtv/avformatdecoder.h

     
    1515#include "../libavformat/avformat.h"
    1616}
    1717
     18class CC708Decoder;
    1819class ProgramInfo;
    1920class MythSqlDatabase;
    2021
     
    7677/// The AvFormatDecoder is used to decode non-NuppleVideo files.
    7778/// It's used a a decoder of last resort after trying the NuppelDecoder
    7879/// and IvtvDecoder (if "USING_IVTV" is defined).
    79 class AvFormatDecoder : public DecoderBase, public CCReader
     80class AvFormatDecoder : public DecoderBase
    8081{
    8182    friend void HandleStreamChange(void*);
    8283  public:
     
    232233
    233234    // Caption/Subtitle/Teletext decoders
    234235    CCDecoder        *ccd;
     236    CC708Decoder     *ccd708;
    235237
    236238    // Audio
    237239    short int        *audioSamples;
  • libs/libmythtv/cc708window.h

     
     1// -*- Mode: c++ -*-
     2// Copyright (c) 2003-2005, Daniel Kristjansson
     3
     4#ifndef _CC708_WINDOW_
     5#define _CC708_WINDOW_
     6
     7#include <vector>
     8using namespace std;
     9
     10#include <qstring.h>
     11#include <qmutex.h>
     12
     13class CC708CharacterAttribute
     14{
     15  public:
     16    uint pen_size;
     17    uint offset;
     18    uint text_tag;
     19    uint font_tag;
     20    uint edge_type;
     21    uint underline;
     22    uint italics;
     23
     24    uint fg_color;
     25    uint fg_opacity;
     26    uint bg_color;
     27    uint bg_opacity;
     28    uint edge_color;
     29    bool operator==(const CC708CharacterAttribute &other) const;
     30    bool operator!=(const CC708CharacterAttribute &other) const
     31        { return !(*this == other); }
     32};
     33
     34class CC708Pen
     35{
     36  public:
     37    void SetPenStyle(uint style);
     38  public:
     39    CC708CharacterAttribute attr;
     40
     41    uint row;
     42    uint column;
     43};
     44
     45class CC708Window;
     46class CC708Character
     47{
     48  public:
     49    CC708Character(const CC708Window &win);
     50    CC708CharacterAttribute attr;
     51    QChar character;
     52};
     53
     54class CC708String
     55{
     56  public:
     57    uint x;
     58    uint y;
     59    QString str;
     60    CC708CharacterAttribute attr;
     61};
     62
     63class CC708Window
     64{
     65  public:
     66    CC708Window();
     67    ~CC708Window();
     68
     69    void Clear(void);
     70    void SetWindowStyle(uint);
     71
     72    void AddChar(QChar);
     73    void IncrPenLocation(void);
     74    void SetPenLocation(uint, uint);
     75    void LimitPenLocation(void);
     76
     77    CC708Character &GetCCChar(void) const;
     78    vector<CC708String*> GetStrings(void) const;
     79
     80  public:
     81    uint priority;
     82    uint visible;
     83    uint anchor_point;
     84    uint relative_pos;
     85    uint anchor_vertical;
     86    uint anchor_horizontal;
     87    uint row_count;
     88    uint column_count;
     89    uint row_lock;
     90    uint column_lock;
     91    uint pen_style;
     92    uint window_style;
     93
     94    uint fill_color;
     95    uint fill_opacity;
     96    uint border_color;
     97    uint border_type;
     98    uint scroll_dir;
     99    uint print_dir;
     100    uint effect_dir;
     101    uint display_effect;
     102    uint effect_speed;
     103    uint justify;
     104    uint word_wrap;
     105
     106    uint true_row_count;
     107    uint true_column_count;
     108    CC708Character *text;
     109    CC708Pen        pen;
     110
     111    /// set to false when DeleteWindow is called on the window.
     112    bool            exists;
     113
     114    mutable QMutex  lock;
     115};
     116
     117class CC708Service
     118{
     119  public:
     120    CC708Service() { current_window = 0; }
     121
     122  public:
     123    uint current_window;
     124    CC708Window windows[8];
     125};
     126
     127#endif // _CC708_WINDOW_
  • libs/libmythtv/cc708decoder.cpp

     
     1// -*- Mode: c++ -*-
     2// Copyright (c) 2003-2005, Daniel Kristjansson
     3
     4#include <cassert>
     5
     6#include "mythcontext.h"
     7#include "cc708decoder.h"
     8
     9#define LOC QString("CC708: ")
     10#define LOC_ERR QString("CC708, Error: ")
     11
     12#define DEBUG_CC_SERVICE_2     0
     13#define DEBUG_CC_RAWPACKET     0
     14#define DEBUG_CC_SERVICE_BLOCK 0
     15
     16typedef enum
     17{
     18    NTSC_CC_f1         = 0,
     19    NTSC_CC_f2         = 1,
     20    DTVCC_PACKET_DATA  = 2,
     21    DTVCC_PACKET_START = 3,
     22};
     23
     24const char* cc_types[4] =
     25{
     26    "NTSC line 21 field 1 closed captions"
     27    "NTSC line 21 field 2 closed captions"
     28    "DTVCC Channel Packet Data"
     29    "DTVCC Channel Packet Start"
     30};
     31
     32static void parse_cc_packet(CC708Reader *cb_cbs, CaptionPacket *pkt);
     33
     34CC708Reader::CC708Reader()
     35{
     36    for (uint i=0; i<64; i++)
     37    {
     38        buf_alloc[i] = 512;
     39        buf[i]       = (unsigned char*) malloc(buf_alloc[i]);
     40        buf_size[i]  = 0;
     41        delayed[i]   = 0;
     42
     43        temp_str_alloc[i] = 512;
     44        temp_str_size[i]  = 0;
     45        temp_str[i]       = (short*) malloc(temp_str_alloc[i] * sizeof(short));
     46    }
     47}
     48
     49CC708Reader::~CC708Reader()
     50{
     51    for (uint i=0; i<64; i++)
     52    {
     53        free(buf[i]);
     54        free(temp_str[i]);
     55    }
     56}
     57
     58void CC708Decoder::decode_cc_data(uint cc_type, uint data1, uint data2)
     59{
     60    if (DTVCC_PACKET_START == cc_type)
     61    {
     62        //VERBOSE(VB_IMPORTANT, LOC + QString("CC ST data(0x%1 0x%2)")
     63        //        .arg(data1,0,16).arg(data2,0,16));
     64
     65        if (partialPacket.size && reader)
     66            parse_cc_packet(reader, &partialPacket);
     67
     68        partialPacket.data[0] = data1;
     69        partialPacket.data[1] = data2;
     70        partialPacket.size   = 2;
     71    }
     72    else if (DTVCC_PACKET_DATA == cc_type)
     73    {
     74        //VERBOSE(VB_IMPORTANT, LOC + QString("CC Ex data(0x%1 0x%2)")
     75        //        .arg(data1,0,16).arg(data2,0,16));
     76
     77        partialPacket.data[partialPacket.size + 0] = data1;
     78        partialPacket.data[partialPacket.size + 1] = data2;
     79        partialPacket.size += 2;
     80    }
     81}
     82
     83#define DEBUG_CAPTIONS 0
     84
     85typedef enum
     86{
     87    NUL  = 0x00,
     88    EXT1 = 0x01,
     89    ETX  = 0x03,
     90    BS   = 0x08,
     91    FF   = 0x0C,
     92    CR   = 0x0D,
     93    HCR  = 0x0E,
     94    P16  = 0x18,
     95} C0;
     96
     97typedef enum
     98{
     99    CW0=0x80, CW1, CW2, CW3, CW4, CW5, CW6, CW7,     
     100    CLW,      DSW, HDW, TGW, DLW, DLY, DLC, RST,
     101    SPA=0x90, SPC, SPL,                     SWA=0x97,
     102    DF0,      DF1, DF2, DF3, DF4, DF5, DF6, DF7,
     103} C1;
     104
     105extern ushort CCtableG0[0x60];
     106extern ushort CCtableG1[0x60];
     107extern ushort CCtableG2[0x60];
     108extern ushort CCtableG3[0x60];
     109
     110static void append_character(CC708Reader *cc, uint service_num, short ch);
     111static void parse_cc_service_stream(CC708Reader *cc, uint service_num);
     112static int handle_cc_c0_ext1_p16(CC708Reader *cc, uint service_num, int i);
     113static int handle_cc_c1(CC708Reader *cc, uint service_num, int i);
     114static int handle_cc_c2(CC708Reader *cc, uint service_num, int i);
     115static int handle_cc_c3(CC708Reader *cc, uint service_num, int i);
     116
     117#define SEND_STR \
     118do { \
     119    if (cc->temp_str_size[service_num]) \
     120    { \
     121        cc->TextWrite(service_num, \
     122                      cc->temp_str[service_num], \
     123                      cc->temp_str_size[service_num]); \
     124        cc->temp_str_size[service_num] = 0; \
     125    } \
     126} while (0)
     127
     128static void parse_cc_service_stream(CC708Reader* cc, uint service_num)
     129{
     130    const int blk_size = cc->buf_size[service_num];
     131    int blk_start = 0, i = 0;
     132
     133    for (i = 0; i < blk_size; i++)
     134    {
     135        if (RST == cc->buf[service_num][i])
     136        {       
     137            fprintf(stderr, "Reset i(%i)\n", i);
     138            cc->Reset(service_num);
     139            blk_start = i+1;
     140            cc->delayed[service_num] = 0;
     141            break;
     142        }
     143        else if (DLC == cc->buf[service_num][i])
     144        {
     145            fprintf(stderr, "DelayCancel i(%i)\n", i);
     146            cc->DelayCancel(service_num);
     147            cc->delayed[service_num] = 0;
     148            break;
     149        }
     150    }
     151    if (cc->buf_size[service_num] >= 126)
     152        cc->delayed[service_num] = 0;
     153   
     154/*
     155  av_log(NULL, AV_LOG_ERROR,
     156  "cc_ss delayed(%i) blk_start(%i) blk_size(%i)\n",
     157  cc->delayed, blk_start, blk_size);
     158*/
     159
     160    for (int i = (cc->delayed[service_num]) ? blk_size : blk_start;
     161         i < blk_size; )
     162    {
     163        const int old_i = i;
     164        const int code = cc->buf[service_num][i];
     165        //fprintf(stderr, "cc(0x%x,i%i) ", code, i);
     166        if (0x0 == code)
     167        {
     168            i++;
     169        }
     170        else if (code <= 0x1f)
     171        {
     172            // C0 code -- ASCII commands + ext1: C2,C3,G2,G3 + p16: 16 chars
     173            i = handle_cc_c0_ext1_p16(cc, service_num, i);
     174        }
     175        else if (code <= 0x7f)
     176        {
     177            // G0 code -- mostly ASCII printables
     178            short character = CCtableG0[code-0x20];
     179            append_character(cc, service_num, character);
     180            i++;
     181        }
     182        else if (code <= 0x9f)
     183        {
     184            // C1 code -- caption control codes
     185            i = handle_cc_c1(cc, service_num, i);
     186        }
     187        else if (code <= 0xff)
     188        {
     189            // G1 code -- ISO 8859-1 Latin 1 characters
     190            short character = CCtableG1[code-0xA0];
     191            append_character(cc, service_num, character);
     192            i++;
     193        }
     194        if ((old_i == i) || cc->delayed[service_num])
     195            break;
     196    }
     197
     198    assert(((int)cc->buf_size[service_num] - i) >= 0);
     199    if ((cc->buf_size[service_num] - i)>0)
     200    {
     201        memmove(cc->buf[service_num], cc->buf[service_num] + i,
     202                cc->buf_size[service_num] - i);
     203        cc->buf_size[service_num] -= i;
     204    }
     205    else
     206    {
     207        if (0!=(cc->buf_size[service_num] - i))
     208        {
     209            fprintf(stderr, "parse_cc_service_stream buffer error "
     210                    "i(%i) buf_size(%i)\n", i, cc->buf_size[service_num]);
     211            for (i=0; (uint)i < cc->buf_size[service_num]; i++)
     212                fprintf(stderr, "0x%x ", cc->buf[service_num][i]);
     213            fprintf(stderr, "\n");
     214        }
     215        cc->buf_size[service_num] = 0;
     216    }
     217}
     218
     219static int handle_cc_c0_ext1_p16(CC708Reader* cc, uint service_num, int i)
     220{
     221    // C0 code -- subset of ASCII misc. control codes
     222    const int code = cc->buf[service_num][i];
     223    if (code<=0xf)
     224    {
     225        // single byte code
     226        if (ETX==code)
     227            SEND_STR;
     228        else if (BS==code)
     229            append_character(cc, service_num, 0x08);
     230        else if (FF==code)
     231            append_character(cc, service_num, 0x0c);
     232        else if (CR==code)
     233            append_character(cc, service_num, 0x0d);
     234        else if (HCR==code)
     235            append_character(cc, service_num, 0x0d);
     236        i++;
     237    }
     238    else if (code<=0x17)
     239    {
     240        // double byte code
     241        const int blk_size = cc->buf_size[service_num];
     242        if (EXT1==code && ((i+1)<blk_size))
     243        {
     244            const int code2 = cc->buf[service_num][i+1];
     245            if (code2<=0x1f)
     246            {
     247                // C2 code -- nothing in EIA-708-A
     248                i = handle_cc_c2(cc, service_num, i+1);
     249            }
     250            else if (code2<=0x7f)
     251            {
     252                // G2 code -- fractions, drawing, symbols
     253                append_character(cc, service_num, CCtableG2[code2-0x20]);
     254                i+=2;
     255            }
     256            else if (code2<=0x9f)
     257            {
     258                // C3 code -- nothing in EIA-708-A
     259                i = handle_cc_c3(cc, service_num, i);
     260            }
     261            else if (code2<=0xff)
     262            {
     263                // G3 code -- one symbol in EIA-708-A "[cc]"
     264                append_character(cc, service_num, CCtableG3[code2-0xA0]);
     265                i+=2;
     266            }
     267        }
     268        else if ((i+1)<blk_size)
     269            i+=2;
     270    }
     271    else if (code<=0x1f)
     272    {
     273        // triple byte code
     274        const int blk_size = cc->buf_size[service_num];
     275        if (P16==code && ((i+2)<blk_size))
     276        {
     277            // reserved for large alphabets, but not yet defined
     278        }
     279        if ((i+2)<blk_size)
     280            i+=3;
     281    }
     282    return i;
     283}
     284
     285static int handle_cc_c1(CC708Reader* cc, uint service_num, int i)
     286{
     287    const int blk_size = cc->buf_size[service_num];
     288    const int code = cc->buf[service_num][i];
     289
     290    //fprintf(stderr, "handle_cc_c1(0x%x, %i, %i)\n", code, i, blk_size);
     291    const unsigned char* blk_buf = cc->buf[service_num];
     292    if (code<=CW7)
     293    { // no paramaters
     294        SEND_STR;
     295        cc->SetCurrentWindow(service_num, code-0x80);
     296        i+=1;
     297    }
     298    else if (DLC == cc->buf[service_num][i])
     299    {
     300        fprintf(stderr, "DelayCancel i(%i)\n", i);
     301        cc->DelayCancel(service_num);
     302        cc->delayed[service_num] = 0;
     303        i+=1;
     304    }
     305    else if (code>=CLW && code<=DLY && ((i+1)<blk_size))
     306    { // 1 byte of paramaters
     307        int param1 = blk_buf[i+1];
     308        SEND_STR;
     309        if (CLW==code)
     310            cc->ClearWindows(service_num, param1);
     311        else if (DSW==code)
     312            cc->DisplayWindows(service_num, param1);
     313        else if (HDW==code)
     314            cc->HideWindows(service_num, param1);
     315        else if (TGW==code)
     316            cc->ToggleWindows(service_num, param1);
     317        else if (DLW==code)
     318            cc->DeleteWindows(service_num, param1);
     319        else if (DLY==code)
     320        {
     321            fprintf(stderr, "Delay()");
     322            cc->Delay(service_num, param1);
     323            cc->delayed[service_num] = 1;
     324        }
     325        i+=2;
     326    }
     327    else if (SPA==code && ((i+2)<blk_size))
     328    {
     329        int pen_size  = (blk_buf[i+1]   ) & 0x3;
     330        int offset    = (blk_buf[i+1]>>2) & 0x3;
     331        int text_tag  = (blk_buf[i+1]>>4) & 0xf;
     332        int font_tag  = (blk_buf[i+2]   ) & 0x7;
     333        int edge_type = (blk_buf[i+2]>>3) & 0x7;
     334        int underline = (blk_buf[i+2]>>4) & 0x1;
     335        int italic    = (blk_buf[i+2]>>5) & 0x1;
     336        SEND_STR;
     337        //fprintf(stderr, "set_pen_attr(0x%08x)(0x%08x, 0x%02x, 0x%02x)\n",
     338        //        cc->SetPenAttributes, cc, blk_buf[i+1], blk_buf[i+2]);
     339        cc->SetPenAttributes(service_num, pen_size, offset, text_tag,
     340                             font_tag, edge_type, underline, italic);
     341        i+=3;
     342    }
     343    else if (SPC==code && ((i+3)<blk_size))
     344    {
     345        int fg_color   = (blk_buf[i+1]   ) & 0x3f;
     346        int fg_opacity = (blk_buf[i+1]>>6) & 0x03;
     347        int bg_color   = (blk_buf[i+2]   ) & 0x3f;
     348        int bg_opacity = (blk_buf[i+2]>>6) & 0x03;
     349        int edge_color = (blk_buf[i+3]>>6) & 0x3f;
     350        SEND_STR;
     351        //fprintf(stderr, "set_pen_color(0x%08x)(0x%08x, 0x%02x, 0x%02x, 0x%02x)\n",
     352        //        cc->SetPenColor, cc, blk_buf[i+1], blk_buf[i+2], blk_buf[i+3]);
     353        cc->SetPenColor(service_num, fg_color, fg_opacity,
     354                        bg_color, bg_opacity, edge_color);
     355        i+=4;
     356    }
     357    else if (SPL==code && ((i+2)<blk_size))
     358    {
     359        int row = blk_buf[i+1] & 0x0f;
     360        int col = blk_buf[i+2] & 0x3f;
     361        SEND_STR;
     362        //fprintf(stderr, "set_pen_loc(0x%08x)(0x%08x, 0x%02x, 0x%02x)\n",
     363        //        cc->SetPenLocation, cc, blk_buf[i+1], blk_buf[i+2]);
     364        cc->SetPenLocation(service_num, row, col);
     365        i+=3;
     366    }
     367    else if (SWA==code && ((i+4)<blk_size))
     368    {
     369        int fill_color    = (blk_buf[i+1]   ) & 0x3f;
     370        int fill_opacity  = (blk_buf[i+1]>>6) & 0x03;
     371        int border_color  = (blk_buf[i+2]   ) & 0x3f;
     372        int border_type01 = (blk_buf[i+2]>>6) & 0x03;
     373        int justify       = (blk_buf[i+3]   ) & 0x03;
     374        int scroll_dir    = (blk_buf[i+3]>>2) & 0x03;
     375        int print_dir     = (blk_buf[i+3]>>4) & 0x03;
     376        int word_wrap     = (blk_buf[i+3]>>6) & 0x01;
     377        int border_type   = (blk_buf[i+3]>>5) | border_type01;
     378        int display_eff   = (blk_buf[i+4]   ) & 0x03;
     379        int effect_dir    = (blk_buf[i+4]>>2) & 0x03;
     380        int effect_speed  = (blk_buf[i+4]>>4) & 0x0f;
     381        SEND_STR;
     382        //fprintf(stderr, "set_win_attr(0x%08x)(0x%08x, 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n",
     383        //        cc->SetWindowAttributes, cc, blk_buf[i+1], blk_buf[i+2], blk_buf[i+3], blk_buf[i+4]);
     384        cc->SetWindowAttributes(
     385            service_num, fill_color, fill_opacity, border_color, border_type,
     386            scroll_dir,     print_dir,    effect_dir,
     387            display_eff,    effect_speed, justify, word_wrap);
     388        i+=5;
     389    }
     390    else if ((code>=DF0) && (code<=DF7) && ((i+6)<blk_size))
     391    {
     392        //fprintf(stderr, "define_window(%i)\n", code-0x98);
     393        // param1
     394        int priority = ( blk_buf[i+1]  ) & 0x7;
     395        int col_lock = (blk_buf[i+1]>>3) & 0x1;
     396        int row_lock = (blk_buf[i+1]>>4) & 0x1;
     397        int visible  = (blk_buf[i+1]>>5) & 0x1;
     398        // param2
     399        int anchor_vertical = blk_buf[i+2] & 0x7f;
     400        int relative_pos = (blk_buf[i+2]>>7);
     401        // param3
     402        int anchor_horizontal = blk_buf[i+3];
     403        // param4
     404        int row_count = blk_buf[i+4] & 0xf;
     405        int anchor_point = blk_buf[i+4]>>4;
     406        // param5
     407        int col_count = blk_buf[i+5] & 0x3f;
     408        // param6
     409        int pen_style = blk_buf[i+6] & 0x7;
     410        int win_style = (blk_buf[i+6]>>3) & 0x7;
     411        SEND_STR;
     412        cc->DefineWindow(service_num, code-0x98, priority, visible,
     413                         anchor_point, relative_pos,
     414                         anchor_vertical, anchor_horizontal,
     415                         row_count, col_count, row_lock, col_lock,
     416                         pen_style, win_style);
     417        i+=7;
     418    }
     419    else
     420    {
     421        fprintf(stderr, "handle_cc_c1: (NOT HANDLED) "
     422                "code(0x%02x) i(%i) blk_size(%i)\n", code, i, blk_size);
     423    }
     424    //fprintf(stderr, "handle_cc_c1, returning %i\n", i);
     425    return i;
     426}
     427
     428static int handle_cc_c2(CC708Reader* cc, uint service_num, int i)
     429{
     430    const int blk_size = cc->buf_size[service_num];
     431    const int code = cc->buf[service_num][i+1];
     432    fprintf(stderr, "handle_cc_C2(0x%x)\n", code);
     433    if ((code<=0x7) && ((i+1)<blk_size)){
     434        i+=2;
     435        SEND_STR;
     436    }
     437    else if ((code<=0xf) && ((i+2)<blk_size))
     438    {
     439        i+=3;
     440        SEND_STR;
     441    }
     442    else if ((code<=0x17) && ((i+3)<blk_size))
     443    {
     444        i+=4;
     445        SEND_STR;
     446    }
     447    else if ((code<=0x1f) && ((i+4)<blk_size))
     448    {
     449        i+=5;
     450        SEND_STR;
     451    }
     452    return i;
     453}
     454
     455static int handle_cc_c3(CC708Reader* cc, uint service_num, int i)
     456{
     457    const unsigned char* blk_buf = cc->buf[service_num];
     458    const int blk_size = cc->buf_size[service_num];
     459    const int code = cc->buf[service_num][i+1];
     460
     461    fprintf(stderr, "handle_cc_C3(0x%x)\n", code);
     462    if ((code<=0x87) && ((i+5)<blk_size))
     463    {
     464        i+=6;
     465        SEND_STR;
     466    }
     467    else if ((code<=0x8f) && ((i+6)<blk_size))
     468    {
     469        i+=7;
     470        SEND_STR;
     471    }
     472    else if ((i+2)<blk_size)
     473    { // varible length commands
     474        int length = blk_buf[i+2]&0x3f;
     475        if ((i+length)<blk_size)
     476        {
     477            i+=1+length;
     478            SEND_STR;
     479        }
     480    }
     481    return i;
     482}
     483
     484static void append_cc(CC708Reader* cc, uint service_num,
     485                      const unsigned char* blk_buf, int block_size)
     486{
     487    assert(cc);
     488    assert(block_size + cc->buf_size[service_num] <
     489           cc->buf_alloc[service_num]);
     490
     491    memcpy(cc->buf[service_num] + cc->buf_size[service_num],
     492           blk_buf, block_size);
     493
     494    cc->buf_size[service_num] += block_size;
     495#if DEBUG_CC_SERVICE_2
     496    {
     497        uint i;
     498        fprintf(stderr, "append_cc: ");
     499        for (i = 0; i < cc->buf_size[service_num]; i++)
     500            fprintf(stderr, "0x%x ", cc->buf[service_num][i]);
     501        fprintf(stderr, "\n");
     502    }
     503#endif
     504    parse_cc_service_stream(cc, service_num);
     505}
     506
     507static void parse_cc_packet(CC708Reader* cb_cbs, CaptionPacket* pkt)
     508{
     509    const unsigned char* pkt_buf = pkt->data;
     510    const int pkt_size = pkt->size;
     511    int off = 1;
     512    int service_number = 0;
     513    int block_data_offset = 0;
     514    int len = ((((int)pkt_buf[0])&0x3f)*2-1)&0xff;
     515    int seq_num = (((int)pkt_buf[0])>>6)&0x3;
     516
     517#if DEBUG_CC_RAWPACKET
     518    {
     519        int j;
     520        fprintf(stderr, "CC length(%2i) seq_num(%i) ", len, seq_num);
     521        for (j=1; j<pkt_size; j++)
     522            fprintf(stderr, "0x%x ", pkt_buf[j]);
     523        fprintf(stderr, "\n");
     524    }
     525#else
     526    (void) seq_num;
     527#endif
     528
     529    assert(pkt_size<127);
     530    assert(len<128);
     531
     532    while (pkt_buf[off] && off<pkt_size)
     533    { // service_block
     534        int block_size = pkt_buf[off] & 0x1f;
     535        service_number = (pkt_buf[off]>>5) & 0x7;
     536        block_data_offset = (0x7==service_number && block_size!=0) ? off+2 : off+1;
     537#if DEBUG_CC_SERVICE_BLOCK
     538        fprintf(stderr, "service_block size(%i) num(%i) off(%i) ",
     539                block_size, service_number, block_data_offset);
     540#endif
     541        if (off+2 == block_data_offset)
     542        {
     543            int extended_service_number = pkt_buf[off+2] & 0x3f;
     544#if DEBUG_CC_SERVICE_BLOCK
     545            fprintf(stderr, "ext_svc_num(%i) ", extended_service_number);
     546#endif
     547            service_number =  extended_service_number;
     548        }
     549        if (service_number)
     550        {
     551#if DEBUG_CC_SERVICE
     552            int i;
     553            if (!(2==block_size &&
     554                  0==pkt_buf[block_data_offset] &&
     555                  0==pkt_buf[block_data_offset+1]))
     556            {
     557                fprintf(stderr, "service %i: ", service_number);
     558                for (i=0; i<block_size; i++)
     559                    fprintf(stderr, "0x%x ", pkt_buf[block_data_offset+i]);
     560                fprintf(stderr, "\n");
     561            }
     562#endif
     563            append_cc(cb_cbs, service_number,
     564                      &pkt_buf[block_data_offset], block_size);
     565        }
     566        off+=block_size+1;
     567    }
     568    if (off<pkt_size) // must end in null service block, if packet is not full.
     569        assert(pkt_buf[off]==0);
     570}
     571
     572static void append_character(CC708Reader *cc, uint service_num, short ch)
     573{
     574    if (cc->temp_str_size[service_num]+2 > cc->temp_str_alloc[service_num])
     575    {
     576        int new_alloc = (cc->temp_str_alloc[service_num]) ?
     577            cc->temp_str_alloc[service_num] * 2 : 64;
     578
     579        cc->temp_str[service_num] = (short*)
     580            realloc(cc->temp_str[service_num], new_alloc * sizeof(short));
     581
     582        assert(cc->temp_str[service_num]);
     583        cc->temp_str_alloc[service_num] = new_alloc; // shorts allocated
     584    }
     585
     586    if (cc->temp_str[service_num])
     587    {
     588        int i = cc->temp_str_size[service_num];
     589        cc->temp_str[service_num][i] = ch;
     590        cc->temp_str_size[service_num]++;
     591    }
     592    else
     593    {
     594        cc->temp_str_size[service_num] = 0;
     595        cc->temp_str_alloc[service_num]=0;
     596    }
     597}
     598
     599ushort CCtableG0[0x60] =
     600{
     601//   0    1    2    3       4    5    6    7
     602//   8    9    a    b       c    d    e    f 
     603    ' ', '!','\"', '#',    '$', '%', '&', '\'', /* 0x20-0x27 */
     604    '(', ')', '*', '+',    ',', '-', '.', '/',  /* 0x28-0x2f */
     605    '0', '1', '2', '3',    '4', '5', '6', '7',  /* 0x30-0x37 */
     606    '8', '9', ':', ';',    '<', '=', '>', '?',  /* 0x38-0x3f */
     607
     608    '@', 'A', 'B', 'C',    'D', 'E', 'F', 'G',  /* 0x40-0x47 */
     609    'H', 'I', 'J', 'K',    'L', 'M', 'N', 'O',  /* 0x48-0x4f */
     610    'P', 'Q', 'R', 'S',    'T', 'U', 'V', 'W',  /* 0x50-0x57 */
     611    'X', 'Y', 'Z', '[',    '\\',']', '^', '_',  /* 0x58-0x5f */
     612
     613    '`', 'a', 'b', 'c',    'd', 'e', 'f', 'g',  /* 0x60-0x67 */
     614    'h', 'i', 'j', 'k',    'l', 'm', 'n', 'o',  /* 0x68-0x6f */
     615    'p', 'q', 'r', 's',    't', 'u', 'v', 'w',  /* 0x70-0x77 */
     616    'x', 'y', 'z', '{',    '|', '}', '~',  0x1d16, // music note /* 0x78-0x7f */
     617};
     618
     619ushort CCtableG1[0x60] =
     620{
     621//   0    1    2    3       4    5    6    7
     622//   8    9    a    b       c    d    e    f 
     623    0xA0, // unicode non-breaking space
     624         '¡', '¢', '£',    '€', '¥', 'Š', '§', /* 0xa0-0xa7 */
     625    'š', '©', 'ª', '«',    '¬', '­', '®', '¯', /* 0xa8-0xaf */
     626    '°', '±', '²', '³',    'Ž', 'µ', '¶', '·', /* 0xb0-0xb7 */
     627    'ž', '¹', 'º', '»',    'Œ', 'œ', 'Ÿ', '¿', /* 0xbf-0xbf */
     628
     629    'À', 'Á', 'Â', 'Ã',    'Ä', 'Å', 'Æ', 'Ç', /* 0xc0-0xc7 */
     630    'È', 'É', 'Ê', 'Ë',    'Ì', 'Í', 'Î', 'Ï', /* 0xcf-0xcf */
     631    'Ð', 'Ñ', 'Ò', 'Ó',    'Ô', 'Õ', 'Ö', '×', /* 0xd0-0xd7 */
     632    'Ø', 'Ù', 'Ú', 'Û',    'Ü', 'Ý', 'Þ', 'ß', /* 0xdf-0xdf */
     633
     634    'à', 'á', 'â', 'ã',    'ä', 'å', 'æ', 'ç', /* 0xe0-0xe7 */
     635    'è', 'é', 'ê', 'ë',    'ì', 'í', 'î', 'ï', /* 0xef-0xef */
     636    'ð', 'ñ', 'ò', 'ó',    'ô', 'õ', 'ö', '÷', /* 0xf0-0xf7 */
     637    'ø', 'ù', 'ú', 'û',    'ü', 'ý', 'þ', 'ÿ', /* 0xff-0xff */
     638};
     639
     640ushort CCtableG2[0x60] =
     641{
     642    ' ', /* transparent space */
     643                        0xA0, /* non-breaking transparent space */
     644    0,                  0,                     /* 0x20-0x23 */
     645    0,                  0x2026,/* elipsis */
     646    0,                  0,                     /* 0x24-0x27 */
     647    0,                  0,
     648    0x160,/*S under \/*/0,                     /* 0x28-0x2b */
     649    0x152, /* CE */     0,
     650    0,                  0,                     /* 0x2c-0x2f */
     651    0x2DA, /*super dot*/0x2018,/* open ' */
     652    0x2019,/*close ' */ 0x201c,/* open " */    /* 0x30-0x33 */
     653    0x201d,/*close " */ '*',   /* dot */
     654    0,                  0,                     /* 0x34-0x37 */
     655    0,                  '#',   /* super TM */
     656    0x161,/*s under \/*/0,                     /* 0x38-0x3b */
     657    0x153, /* ce */     '#',   /* super SM */
     658    0,                  0x178,/*Y w/umlout*/   /* 0x3c-0x3f */
     659   
     660//  0         1         2         3
     661//  4         5         6         7
     662//  8         9         a         b
     663//  c         d         e         f 
     664    0,        0,        0,        0,
     665    0,        0,        0,        0, /* 0x40-0x47 */
     666    0,        0,        0,        0,
     667    0,        0,        0,        0, /* 0x48-0x4f */
     668
     669    0,        0,        0,        0,
     670    0,        0,        0,        0, /* 0x50-0x57 */
     671    0,        0,        0,        0,
     672    0,        0,        0,        0, /* 0x58-0x5f */
     673
     674    0,        0,        0,        0,
     675    0,        0,        0,        0, /* 0x60-0x67 */
     676    0,        0,        0,        0,
     677    0,        0,        0,        0, /* 0x68-0x6f */
     678
     679    0,                  0,
     680    0,                  0,           /* 0x70-0x73 */
     681    0,                  0,
     682    0x215b, /* 1/8 */   0x215c, /* 3/8 */    /* 0x74-0x77 */
     683    0x215d, /* 5/8 */   0x215e, /* 7/8 */
     684    0x2502, /*line | */ 0x2510, /*line ~| */ /* 0x78-0x7b */
     685    0x2514, /*line |_*/ 0x2500, /*line -*/
     686    0x2518, /*line _|*/ 0x250c, /*line |~ */ /* 0x7c-0x7f */
     687};
     688
     689ushort CCtableG3[0x60] =
     690{
     691//   0 1  2  3    4  5  6  7     8  9  a  b    c  d  e  f 
     692    '#', /* [CC] closed captioning logo */
     693       0, 0, 0,   0, 0, 0, 0,    0, 0, 0, 0,   0, 0, 0, 0, /* 0xa0-0xaf */
     694    0, 0, 0, 0,   0, 0, 0, 0,    0, 0, 0, 0,   0, 0, 0, 0, /* 0xb0-0xbf */
     695
     696    0, 0, 0, 0,   0, 0, 0, 0,    0, 0, 0, 0,   0, 0, 0, 0, /* 0xc0-0xcf */
     697    0, 0, 0, 0,   0, 0, 0, 0,    0, 0, 0, 0,   0, 0, 0, 0, /* 0xd0-0xdf */
     698
     699    0, 0, 0, 0,   0, 0, 0, 0,    0, 0, 0, 0,   0, 0, 0, 0, /* 0xe0-0xff */
     700    0, 0, 0, 0,   0, 0, 0, 0,    0, 0, 0, 0,   0, 0, 0, 0, /* 0xf0-0xff */
     701};
  • libs/libmythtv/osd.cpp

     
    2828
    2929#include "osdlistbtntype.h"
    3030
     31static char  *cc708_default_font_names[20];
     32static bool   cc708_defaults_initialized = false;
     33static QMutex cc708_init_lock;
     34static void initialize_osd_fonts(void);
     35
    3136static float sq(float a) { return a*a; }
    3237
     38#define LOC QString("OSD: ")
     39#define LOC_ERR QString("OSD, Error: ")
     40
    3341OSD::OSD(const QRect &osd_bounds, int   frameRate,
    3442         const QRect &vis_bounds, float visibleAspect, float fontScaling)
    3543    : QObject(),
     
    4856      changed(false),                     runningTreeMenu(NULL),
    4957      treeMenuContainer("")
    5058{
     59    if (!cc708_defaults_initialized)
     60        initialize_osd_fonts();
     61
     62    for (uint i = 0; i < 20; i++)
     63        cc708fontnames[i] = cc708_default_font_names[i];
     64
    5165    needPillarBox = visibleAspect > 1.51f;
    5266    wscale = visibleAspect / 1.3333f;
    5367    // adjust for wscale font size scaling
     
    5771    {
    5872        VERBOSE(VB_IMPORTANT, "Couldn't find OSD theme: "
    5973                <<gContext->GetSetting("OSDTheme"));
    60         SetDefaults();
     74        InitDefaults();
    6175        return;
    6276    }
    6377
     
    6781        VERBOSE(VB_IMPORTANT, "Couldn't load OSD theme: "
    6882                <<gContext->GetSetting("OSDTheme")<<" at "<<themepath);
    6983    }
    70     SetDefaults();
     84    InitDefaults();
    7185
    72     // Reinit since LoadThemes and SetDefaults() appear to mess things up.
     86    // Reinit since LoadThemes and InitDefaults() appear to mess things up.
    7387    Reinit(osd_bounds, frameRate, vis_bounds, visibleAspect, fontScaling);
    7488}
    7589
     
    113127    }
    114128}
    115129
    116 void OSD::SetDefaults(void)
     130bool OSD::InitDefaults(void)
    117131{
     132    bool ok = true;
     133    ok &= InitCC608();
     134    ok &= InitCC708();
     135    ok &= InitMenu();
     136    ok &= InitDVBSub();
     137    return ok;
     138}
     139
     140bool OSD::InitCC608(void)
     141{
     142    // EIA-608 captions
    118143    TTFFont *ccfont = GetFont("cc_font");
    119144    if (!ccfont)
    120145    {
     
    128153    }
    129154
    130155    if (!ccfont)
    131         return;
     156        return false;
    132157
    133158    OSDSet *container = GetSet("cc_page");
    134159    if (!container)
     
    157182                                          sub_dispw, sub_disph);
    158183        container->AddType(ccpage);
    159184    }
     185    return true;
     186}
    160187
    161     container = GetSet("menu");
     188bool OSD::InitCC708(void)
     189{
     190    VERBOSE(VB_IMPORTANT, LOC + "InitCC708() -- begin");
     191    // EIA-708 captions
     192    // Check if cc708 osd already exits, exit early if it does
     193    QString name("cc708_page");
     194    OSDSet *container = GetSet(name);
     195    if (container)
     196    {
     197        VERBOSE(VB_IMPORTANT, LOC + "InitCC708() -- end (already exits)");
     198        return true;
     199    }
     200
     201    // Create fonts...
     202    TTFFont* ccfonts[60];
     203    for (uint i = 0; i < 60; i++)
     204    {
     205        TTFFont *ccfont = GetFont("cc_font");
     206        //TTFFont *ccfont = GetFont(QString("cc708_font%1").arg(i));
     207        if (!ccfont)
     208        {
     209            QString name = QString("cc708_font%1").arg(i);
     210            int fontsizes[3] = { 480/36, 480/27, 480/20 };
     211            int fontsize = fontsizes[i%3];
     212            ccfont = LoadFont(gContext->GetSetting("OSDCCFont")
     213                              /*cc708fontnames[i/3]*/, fontsize);
     214            if (ccfont)
     215                fontMap[name] = ccfont;
     216            if (!ccfont)
     217            {
     218                VERBOSE(VB_IMPORTANT, LOC_ERR + "A CC708 font is missing");
     219                return false;
     220            }
     221        }
     222        ccfonts[i] = ccfont;
     223    }
     224
     225    // Create a container for one service
     226    container = new OSDSet(
     227        name, true, osdBounds.width(), osdBounds.height(),
     228        wmult, hmult, frameint);
     229    container->SetPriority(30);
     230
     231    AddSet(container, name);
     232    OSDType708CC *ccpage =
     233        new OSDType708CC(name, ccfonts, xoffset, yoffset,
     234                         displaywidth, displayheight);
     235    container->AddType(ccpage);
     236
     237    VERBOSE(VB_IMPORTANT, LOC + "InitCC708() -- end");
     238    return true;
     239}
     240
     241bool OSD::InitMenu(void)
     242{
     243    // Menu
     244    OSDSet *container = GetSet("menu");
    162245    if (!container)
    163246    {
    164247        QString name = "menu";
     
    208291
    209292        container->AddType(lb);
    210293    }
     294    return true;
     295}
    211296
     297bool OSD::InitDVBSub(void)
     298{
    212299    // Create container for subtitles
    213     container = GetSet("subtitles");
     300    OSDSet *container = GetSet("subtitles");
    214301    if (!container)
    215302    {
    216303        QString name = "subtitles";
     
    220307        container->SetPriority(30);
    221308        AddSet(container, name);
    222309    }
     310    return true;
    223311}
    224312
    225313void OSD::Reinit(const QRect &totalBounds,   int   frameRate,
     
    16641752    osdlock.unlock();
    16651753}
    16661754
     1755void OSD::SetCC708Service(const CC708Service *service)
     1756{
     1757    QMutexLocker locker(&osdlock);
     1758
     1759    VERBOSE(VB_IMPORTANT, "SetCC708Service() -- 1");
     1760
     1761    OSDSet *container = GetSet("cc708_page");
     1762    if (!container)
     1763    {
     1764        VERBOSE(VB_IMPORTANT, "SetCC708Service() -- can't find container");
     1765        return;
     1766    }
     1767
     1768    OSDType *type = container->GetType("cc708_page");
     1769    OSDType708CC *ccpage = (OSDType708CC*) type;
     1770    if (!ccpage)
     1771    {
     1772        VERBOSE(VB_IMPORTANT, "SetCC708Service() -- no OSDType708CC");
     1773        return;
     1774    }
     1775
     1776    VERBOSE(VB_IMPORTANT, "SetCC708Service() -- 2");
     1777    ccpage->SetCCService(service);
     1778    container->Display(1/*visible*/);
     1779    m_setsvisible = true;
     1780    changed = true;
     1781}
     1782
     1783void OSD::CC708Updated(void)
     1784{
     1785    QMutexLocker locker(&osdlock);
     1786
     1787    OSDSet *container = GetSet("cc708_page");
     1788    if (!container)
     1789        return;
     1790
     1791    OSDType *type = container->GetType("cc708_page");
     1792    OSDType708CC *ccpage = dynamic_cast<OSDType708CC*>(type);
     1793    if (ccpage)
     1794    {
     1795        container->Display(1/*visible*/);
     1796        m_setsvisible = true;
     1797        changed = true;
     1798    }
     1799}
     1800
    16671801void OSD::SetSettingsText(const QString &text, int length)
    16681802{
    16691803    HideAllExcept("settings");
     
    24132547{
    24142548    return QRect(xoffset, yoffset, displaywidth, displayheight);
    24152549}
     2550
     2551static void initialize_osd_fonts(void)
     2552{
     2553    QMutexLocker locker(&cc708_init_lock);
     2554    if (cc708_defaults_initialized)
     2555        return;
     2556    cc708_defaults_initialized = true;
     2557
     2558    cc708_default_font_names[0]  = strdup(gContext->GetSetting(
     2559        "OSDCC708MonoSerifFont"));
     2560    cc708_default_font_names[1]  = strdup(gContext->GetSetting(
     2561        "OSDCC708MonoSerifItalicFont"));
     2562    cc708_default_font_names[2]  = strdup(gContext->GetSetting(
     2563        "OSDCC708PropSerifFont"));
     2564    cc708_default_font_names[3]  = strdup(gContext->GetSetting(
     2565        "OSDCC708PropSerifItalicFont"));
     2566
     2567    cc708_default_font_names[4]  = strdup(gContext->GetSetting(
     2568        "OSDCC708MonoSansSerifFont"));
     2569    cc708_default_font_names[5]  = strdup(gContext->GetSetting(
     2570        "OSDCC708MonoSansSerifItalicFont"));
     2571    cc708_default_font_names[6]  = strdup(gContext->GetSetting(
     2572        "OSDCC708PropSansSerifFont"));
     2573    cc708_default_font_names[7]  = strdup(gContext->GetSetting(
     2574        "OSDCC708PropSansSerifItalicFont"));
     2575
     2576    cc708_default_font_names[8]  = strdup(gContext->GetSetting(
     2577        "OSDCC708MonoCasualFont"));
     2578    cc708_default_font_names[9]  = strdup(gContext->GetSetting(
     2579        "OSDCC708MonoCasualItalicFont"));
     2580    cc708_default_font_names[10] = strdup(gContext->GetSetting(
     2581        "OSDCC708PropCasualFont"));
     2582    cc708_default_font_names[11] = strdup(gContext->GetSetting(
     2583        "OSDCC708PropCasualItalicFont"));
     2584
     2585    cc708_default_font_names[12] = strdup(gContext->GetSetting(
     2586        "OSDCC708MonoCursiveFont"));
     2587    cc708_default_font_names[13] = strdup(gContext->GetSetting(
     2588        "OSDCC708MonoCursiveItalicFont"));
     2589    cc708_default_font_names[14] = strdup(gContext->GetSetting(
     2590        "OSDCC708PropCursiveFont"));
     2591    cc708_default_font_names[15] = strdup(gContext->GetSetting(
     2592        "OSDCC708PropCursiveItalicFont"));
     2593
     2594    cc708_default_font_names[16] = strdup(gContext->GetSetting(
     2595        "OSDCC708MonoCapitalsFont"));
     2596    cc708_default_font_names[17] = strdup(gContext->GetSetting(
     2597        "OSDCC708MonoCapitalsItalicFont"));
     2598    cc708_default_font_names[18] = strdup(gContext->GetSetting(
     2599        "OSDCC708PropCapitalsFont"));
     2600    cc708_default_font_names[19] = strdup(gContext->GetSetting(
     2601        "OSDCC708PropCapitalsItalicFont"));
     2602}
  • libs/libmythtv/cc708decoder.h

     
     1// -*- Mode: c++ -*-
     2// Copyright (c) 2003-2005, Daniel Kristjansson
     3
     4#ifndef CC708DECODER_H_
     5#define CC708DECODER_H_
     6
     7#include <stdint.h>
     8
     9#include <qstringlist.h>
     10
     11#include "format.h"
     12
     13#ifndef __CC_CALLBACKS_H__
     14/** EIA-708-A closed caption packet */
     15typedef struct CaptionPacket
     16{
     17    unsigned char data[128+16];
     18    int size;
     19} CaptionPacket;
     20#endif
     21
     22class CC708Reader
     23{
     24  public:
     25    CC708Reader();
     26    virtual ~CC708Reader();
     27
     28    // Window settings
     29    virtual void SetCurrentWindow(uint service_num, int window_id) = 0;
     30    virtual void DefineWindow(uint service_num,     int window_id,
     31                              int priority,         int visible,
     32                              int anchor_point,     int relative_pos,
     33                              int anchor_vertical,  int anchor_horizontal,
     34                              int row_count,        int column_count,
     35                              int row_lock,         int column_lock,
     36                              int pen_style,        int window_style) = 0;
     37    virtual void DeleteWindows( uint service_num,   int window_map) = 0;
     38    virtual void DisplayWindows(uint service_num,   int window_map) = 0;
     39    virtual void HideWindows(   uint service_num,   int window_map) = 0;
     40    virtual void ClearWindows(  uint service_num,   int window_map) = 0;
     41    virtual void ToggleWindows( uint service_num,   int window_map) = 0;
     42    virtual void SetWindowAttributes(uint service_num,
     43                                     int fill_color,     int fill_opacity,
     44                                     int border_color,   int border_type,
     45                                     int scroll_dir,     int print_dir,
     46                                     int effect_dir,
     47                                     int display_effect, int effect_speed,
     48                                     int justify,        int word_wrap) = 0;
     49
     50    // Pen settings
     51    virtual void SetPenAttributes(uint service_num,
     52                                  int pen_size,  int offset,
     53                                  int text_tag,  int font_tag,
     54                                  int edge_type,
     55                                  int underline, int italics) = 0;
     56    virtual void SetPenColor(uint service_num,
     57                             int fg_color, int fg_opacity,
     58                             int bg_color, int bg_opacity,
     59                             int edge_color) = 0;
     60    virtual void SetPenLocation(uint service_num, int row, int column) = 0;
     61
     62    // Display State
     63    virtual void Delay(uint service_num, int tenths_of_seconds) = 0;
     64    virtual void DelayCancel(uint service_num) = 0;
     65    virtual void Reset(uint service_num) = 0;
     66
     67    // Text
     68    virtual void TextWrite(uint service_num,
     69                           short* unicode_string, short len) = 0;
     70
     71    // Data
     72    unsigned char* buf[64];
     73    uint   buf_alloc[64];
     74    uint   buf_size[64];
     75    bool   delayed[64];
     76
     77    short* temp_str[64];
     78    int    temp_str_alloc[64];
     79    int    temp_str_size[64];
     80};
     81
     82class CC708Decoder
     83{
     84  public:
     85    CC708Decoder(CC708Reader *ccr) : reader(ccr)
     86        { bzero(&partialPacket, sizeof(CaptionPacket)); }
     87
     88    ~CC708Decoder();
     89
     90    void decode_cc_data(uint cc_type, uint data1, uint data2);
     91
     92  private:
     93    CaptionPacket  partialPacket;
     94    CC708Reader   *reader;
     95};
     96
     97#endif // CC708DECODER_H_
  • libs/libavcodec/mpeg12.c

     
    29892989        }
    29902990    } else if (len >= 3 &&
    29912991               p[0] == 'C' && p[1] == 'C') {
     2992        /* parse DVD Closed Caption data */
    29922993        p += 2;
    29932994        len -= 2;
    29942995        avctx->decode_cc_dvd(avctx, p, len);
    29952996    } else if (len >= 6 &&
    2996                p[0] == 0x47 && p[1] == 0x41 && p[2] == 0x39 && p[3] == 0x34 &&
    2997                p[4] == 0x03) {
    2998         p += 5;
    2999         len -= 5;
    3000         avctx->decode_cc_atsc(avctx, p, len);
     2997               p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4') {
     2998        /* parse ATSC info (EIA-708 Closed Captions && letterbox info) */
     2999        int user_data_type_code = p[4];
     3000        if (user_data_type_code == 0x03) { // caption data
     3001            p += 5;
     3002            len -= 5;
     3003            avctx->decode_cc_atsc(avctx, p, len);
     3004        }
     3005        else if (user_data_type_code == 0x06) {
     3006            // bar data (letterboxing info)
     3007        }
    30013008    }
    30023009}
    30033010