#include <lib/base/eerror.h>
#include <lib/gdi/gpixmap.h>
-void bitstream_init(struct bitstream *bit, const void *buffer, int size)
+void bitstream_init(bitstream *bit, const void *buffer, int size)
{
bit->data = (__u8*) buffer;
bit->size = size;
bit->consumed = 0;
}
-int bitstream_get(struct bitstream *bit)
+int bitstream_get(bitstream *bit)
{
int val;
bit->avail -= bit->size;
return -1;
}
-void eDVBSubtitleParser::subtitle_process_line(struct subtitle_page *page, int object_id, int line, __u8 *data, int len)
+void eDVBSubtitleParser::subtitle_process_line(subtitle_page *page, int object_id, int line, __u8 *data, int len)
{
- struct subtitle_region *region = page->regions;
+ subtitle_region *region = page->regions;
// eDebug("line for %d:%d", page->page_id, object_id);
while (region)
{
- struct subtitle_region_object *object = region->region_objects;
+ subtitle_region_object *object = region->region_objects;
while (object)
{
if (object->object_id == object_id)
}
}
-int eDVBSubtitleParser::subtitle_process_pixel_data(struct subtitle_page *page, int object_id, int *linenr, int *linep, __u8 *data)
+int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_page *page, int object_id, int *linenr, int *linep, __u8 *data)
{
int data_type = *data++;
static __u8 line[720];
- struct bitstream bit;
+ bitstream bit;
bit.size=0;
switch (data_type)
{
// //eDebug("page_id %d, segtype %02x", page_id, segment_type);
- struct subtitle_page *page, **ppage;
+ subtitle_page *page, **ppage;
page = this->pages; ppage = &this->pages;
{
while (page->page_regions)
{
- struct subtitle_page_region *p = page->page_regions->next;
+ subtitle_page_region *p = page->page_regions->next;
delete page->page_regions;
page->page_regions = p;
}
page->page_version_number = page_version_number;
- struct subtitle_page_region **r = &page->page_regions;
+ subtitle_page_region **r = &page->page_regions;
//eDebug("%d / %d data left", processed_length, segment_length);
while (processed_length < segment_length)
{
- struct subtitle_page_region *pr;
+ subtitle_page_region *pr;
// append new entry to list
pr = new subtitle_page_region;
break;
}
- struct subtitle_region *region, **pregion;
+ subtitle_region *region, **pregion;
region = page->regions; pregion = &page->regions;
}
else if (region->region_version_number != region_version_number)
{
- struct subtitle_region_object *objects = region->region_objects;
+ subtitle_region_object *objects = region->region_objects;
while (objects)
{
- struct subtitle_region_object *n = objects->next;
+ subtitle_region_object *n = objects->next;
delete objects;
objects = n;
}
//eDebug("region %02x, version %d, %dx%d", region->region_id, region->region_version_number, region->region_width, region->region_height);
region->region_objects = 0;
- struct subtitle_region_object **pobject = ®ion->region_objects;
+ subtitle_region_object **pobject = ®ion->region_objects;
while (processed_length < segment_length)
{
-
- struct subtitle_region_object *object;
+ subtitle_region_object *object;
object = new subtitle_region_object;
case 0x12: // CLUT definition segment
{
int CLUT_id, CLUT_version_number;
- struct subtitle_clut *clut, **pclut;
+ subtitle_clut *clut, **pclut;
if (!page)
break;
break;
clut->CLUT_version_number=CLUT_version_number;
- clut->size_2 = clut->size_4 = clut->size_8 = 0;
- /* invalidate CLUT if updated. */
- if ((this->current_clut_page_id == page_id) && (this->current_clut_id == CLUT_id))
- this->current_clut_id = -1;
+ memset(clut->entries_2bit, 0, sizeof(clut->entries_2bit));
+ memset(clut->entries_4bit, 0, sizeof(clut->entries_4bit));
+ memset(clut->entries_8bit, 0, sizeof(clut->entries_8bit));
//eDebug("new clut");
while (processed_length < segment_length)
if (entry_CLUT_flag & 1) // 8bit
{
ASSERT(CLUT_entry_id < 256);
- ++clut->size_8;
clut->entries_8bit[CLUT_entry_id].Y = v_Y;
clut->entries_8bit[CLUT_entry_id].Cr = v_Cr;
clut->entries_8bit[CLUT_entry_id].Cb = v_Cb;
clut->entries_8bit[CLUT_entry_id].T = v_T;
+ clut->entries_8bit[CLUT_entry_id].valid = 1;
}
if (entry_CLUT_flag & 2) // 4bit
{
ASSERT(CLUT_entry_id < 16);
- ++clut->size_4;
clut->entries_4bit[CLUT_entry_id].Y = v_Y;
clut->entries_4bit[CLUT_entry_id].Cr = v_Cr;
clut->entries_4bit[CLUT_entry_id].Cb = v_Cb;
clut->entries_4bit[CLUT_entry_id].T = v_T;
+ clut->entries_4bit[CLUT_entry_id].valid = 1;
}
if (entry_CLUT_flag & 4) // 2bit
{
ASSERT(CLUT_entry_id < 4);
- ++clut->size_2;
clut->entries_2bit[CLUT_entry_id].Y = v_Y;
clut->entries_2bit[CLUT_entry_id].Cr = v_Cr;
clut->entries_2bit[CLUT_entry_id].Cb = v_Cb;
clut->entries_2bit[CLUT_entry_id].T = v_T;
+ clut->entries_2bit[CLUT_entry_id].valid = 1;
}
//eDebug(" %04x %02x %02x %02x %02x", CLUT_entry_id, v_Y, v_Cb, v_Cr, v_T);
}
void eDVBSubtitleParser::subtitle_process_pes(__u8 *pkt, int len)
{
- eDebug("subtitle_process_pes");
+// eDebug("subtitle_process_pes");
if (!extract_pts(show_time, pkt))
{
pkt += 6; len -= 6;
eDebug("dvb subtitle packet without PTS.. ignore!!");
}
-void eDVBSubtitleParser::subtitle_clear_screen()
-{
- /* clear bbox */
- int y;
-
- //eDebug("BBOX clear %d:%d -> %d:%d", this->bbox_left, this->bbox_top, this->bbox_right, this->bbox_bottom);
-
- // do not draw when anyone has locked the
- // framebuffer ( non enigma plugins... )
- this->bbox_right = 720;
- if (this->bbox_right > this->bbox_left)
- for (y=this->bbox_top; y < this->bbox_bottom; ++y)
- ; // TODO fixmee clear subtitle screen
-
- this->bbox_right = 0;
- this->bbox_left = this->screen_width;
- this->bbox_top = this->screen_height;
- this->bbox_bottom = 0;
-}
-
void eDVBSubtitleParser::subtitle_redraw_all()
{
#if 1
- struct subtitle_page *page = this->pages;
- if ( page )
- {
- struct subtitle_page_region *region = page->page_regions;
- if ( region )
- subtitle_clear_screen();
- }
+ subtitle_page *page = this->pages;
while(page)
{
subtitle_redraw(page->page_id);
page = page->next;
}
#else
- subtitle_clear_screen();
-
- struct subtitle_page *page = this->pages;
+ subtitle_page *page = this->pages;
//eDebug("----------- end of display set");
//eDebug("active pages:");
while (page)
//eDebug(" page_version_number: %d", page->page_version_number);
//eDebug(" active regions:");
{
- struct subtitle_page_region *region = page->page_regions;
+ subtitle_page_region *region = page->page_regions;
while (region)
{
//eDebug(" region_id: %04x", region->region_id);
subtitle_redraw(page->page_id);
//eDebug("defined regions:");
- struct subtitle_region *region = page->regions;
+ subtitle_region *region = page->regions;
while (region)
{
//eDebug(" region_id %04x, version %d, %dx%d", region->region_id, region->region_version_number, region->region_width, region->region_height);
- struct subtitle_region_object *object = region->region_objects;
+ subtitle_region_object *object = region->region_objects;
while (object)
{
//eDebug(" object %02x, type %d, %d:%d", object->object_id, object->object_type, object->object_horizontal_position, object->object_vertical_position);
void eDVBSubtitleParser::subtitle_reset()
{
- while (struct subtitle_page *page = this->pages)
+ while (subtitle_page *page = this->pages)
{
/* free page regions */
while (page->page_regions)
{
- struct subtitle_page_region *p = page->page_regions->next;
+ subtitle_page_region *p = page->page_regions->next;
delete page->page_regions;
page->page_regions = p;
}
/* free regions */
while (page->regions)
{
- struct subtitle_region *region = page->regions;
+ subtitle_region *region = page->regions;
while (region->region_objects)
{
- struct subtitle_region_object *obj = region->region_objects;
+ subtitle_region_object *obj = region->region_objects;
region->region_objects = obj->next;
delete obj;
}
/* free CLUTs */
while (page->cluts)
{
- struct subtitle_clut *clut = page->cluts;
+ subtitle_clut *clut = page->cluts;
page->cluts = clut->next;
delete clut;
}
void eDVBSubtitleParser::subtitle_redraw(int page_id)
{
- struct subtitle_page *page = this->pages;
+ subtitle_page *page = this->pages;
//eDebug("displaying page id %d", page_id);
return;
}
-
//eDebug("iterating regions..");
/* iterate all regions in this pcs */
- struct subtitle_page_region *region = page->page_regions;
- while (region)
+ subtitle_page_region *region = page->page_regions;
+
+ eDVBSubtitlePage Page;
+ Page.m_show_time = show_time;
+ for (; region; region=region->next)
{
- //eDebug("region %d", region->region_id);
+// eDebug("region %d", region->region_id);
/* find corresponding region */
- struct subtitle_region *reg = page->regions;
+ subtitle_region *reg = page->regions;
while (reg)
{
if (reg->region_id == region->region_id)
}
if (reg)
{
- int y;
- //eDebug("copy region %d to %d, %d", region->region_id, region->region_horizontal_address, region->region_vertical_address);
+// eDebug("copy region %d to %d, %d", region->region_id, region->region_horizontal_address, region->region_vertical_address);
int x0 = region->region_horizontal_address;
int y0 = region->region_vertical_address;
int x1 = x0 + reg->region_width;
int y1 = y0 + reg->region_height;
- if ((x0 < 0) || (y0 < 0) || (x0 > this->screen_width) || (x0 > this->screen_height))
+ if ((x0 < 0) || (y0 < 0))
+ {
+// eDebug("x0 %d, y0 %d",
+// x0, y0);
continue;
-
- /* adjust bbox */
- if (x0 < this->bbox_left)
- this->bbox_left = x0;
- if (y0 < this->bbox_top)
- this->bbox_top = y0;
- if (x1 > this->bbox_right)
- this->bbox_right = x1;
- if (y1 > this->bbox_bottom)
- this->bbox_bottom = y1;
-
- int timeout = page->page_time_out;
+ }
/* find corresponding clut */
- struct subtitle_clut *clut = page->cluts;
+ subtitle_clut *clut = page->cluts;
while (clut)
{
//eDebug("have %d, want %d", clut->clut_id, main_clut_id);
break;
clut = clut->next;
}
- if (clut)
+
+ int clut_size = reg->region_buffer->surface->clut.colors = reg->region_depth == subtitle_region::bpp2 ?
+ 4 : reg->region_depth == subtitle_region::bpp4 ? 16 : 256;
+
+ if (reg->region_buffer->surface->clut.data &&
+ clut_size != reg->region_buffer->surface->clut.colors)
{
- // TODO fill region->surface->clut !!!!!
+ delete [] reg->region_buffer->surface->clut.data;
+ reg->region_buffer->surface->clut.data = 0;
}
- else
+
+ if (!reg->region_buffer->surface->clut.data)
+ reg->region_buffer->surface->clut.data = new gRGB[clut_size];
+
+ gRGB *palette = reg->region_buffer->surface->clut.data;
+
+ subtitle_clut_entry *entries=0;
+ switch(reg->region_depth)
{
- // apply default clut depending on region->region_depth
- // TODO fill region->surface->clut !!!!!
+ case subtitle_region::bpp2:
+// eDebug("2BPP");
+ entries = clut->entries_2bit;
+ memset(palette, 0, 4*sizeof(gRGB));
+ palette[0].a = 0xFF;
+ palette[2].r = palette[2].g = palette[2].b = 0xFF;
+ palette[3].r = palette[3].g = palette[3].b = 0x80;
+ break;
+ case subtitle_region::bpp4:
+// eDebug("4BPP");
+ entries = clut->entries_4bit;
+ memset(palette, 0, 16*sizeof(gRGB));
+ for (int i=0; i < 16; ++i)
+ {
+ if (!i)
+ palette[i].a = 0xFF;
+ else if (i & 1)
+ {
+ if (i & 8)
+ palette[i].r = 0x80;
+ if (i & 4)
+ palette[i].g = 0x80;
+ if (i & 2)
+ palette[i].b = 0x80;
+ }
+ else
+ {
+ if (i & 8)
+ palette[i].r = 0xFF;
+ if (i & 4)
+ palette[i].g = 0xFF;
+ if (i & 2)
+ palette[i].b = 0xFF;
+ }
+ }
+ break;
+ case subtitle_region::bpp8:
+// eDebug("8BPP");
+ entries = clut->entries_8bit;
+ memset(palette, 0, 16*sizeof(gRGB));
+ for (int i=0; i < 256; ++i)
+ {
+ switch (i & 17)
+ {
+ case 0: // b1 == 0 && b5 == 0
+ if (!(i & 14)) // b2 == 0 && b3 == 0 && b4 == 0
+ {
+ if (!(i & 224)) // b6 == 0 && b7 == 0 && b8 == 0
+ palette[i].a = 0xFF;
+ else
+ {
+ if (i & 128) // R = 100% x b8
+ palette[i].r = 0xFF;
+ if (i & 64) // G = 100% x b7
+ palette[i].g = 0xFF;
+ if (i & 32) // B = 100% x b6
+ palette[i].b = 0xFF;
+ palette[i].a = 0xBF; // T = 75%
+ }
+ break;
+ }
+ // fallthrough !!
+ case 16: // b1 == 0 && b5 == 1
+ if (i & 128) // R = 33% x b8
+ palette[i].r = 0x55;
+ if (i & 64) // G = 33% x b7
+ palette[i].g = 0x55;
+ if (i & 32) // B = 33% x b6
+ palette[i].b = 0x55;
+ if (i & 8) // R + 66,7% x b4
+ palette[i].r += 0xAA;
+ if (i & 4) // G + 66,7% x b3
+ palette[i].g += 0xAA;
+ if (i & 2) // B + 66,7% x b2
+ palette[i].b += 0xAA;
+ if (i & 16) // needed for fall through from case 0!!
+ palette[i].a = 0x80; // T = 50%
+ break;
+ case 1: // b1 == 1 && b5 == 0
+ palette[i].r =
+ palette[i].g =
+ palette[i].b = 0x80; // 50%
+ // fall through!!
+ case 17: // b1 == 1 && b5 == 1
+ if (i & 128) // R += 16.7% x b8
+ palette[i].r += 0x2A;
+ if (i & 64) // G += 16.7% x b7
+ palette[i].g += 0x2A;
+ if (i & 32) // B += 16.7% x b6
+ palette[i].b += 0x2A;
+ if (i & 8) // R += 33% x b4
+ palette[i].r += 0x55;
+ if (i & 4) // G += 33% x b3
+ palette[i].g += 0x55;
+ if (i & 2) // B += 33% x b2
+ palette[i].b += 0x55;
+ break;
+ }
+ }
+ break;
}
- // TODO Blit Region Pixmap !!!
- eDebug("blit region");
+
+ if (clut)
+ {
+ for (int i=0; i<clut_size; ++i)
+ {
+ if (entries[i].valid)
+ {
+ int y = entries[i].Y,
+ cr = entries[i].Cr,
+ cb = entries[i].Cb;
+ if (y > 0)
+ {
+ y -= 16;
+ cr -= 128;
+ cb -= 128;
+ palette[i].r = MAX(MIN(((298 * y + 460 * cr) / 256), 255), 0);
+ palette[i].g = MAX(MIN(((298 * y - 55 * cb - 137 * cr) / 256), 255), 0);
+ palette[i].b = MAX(MIN(((298 * y + 543 * cb ) / 256), 255), 0);
+ palette[i].a = (entries[i].T) & 0xFF;
+// eDebug("override clut entry %d RGBA %02x%02x%02x%02x", i,
+// palette[i].r, palette[i].g, palette[i].b, palette[i].a);
+ }
+ else
+ {
+// eDebug("mist %d", i);
+ palette[i].r = 0;
+ palette[i].g = 0;
+ palette[i].b = 0;
+ palette[i].a = 0xFF;
+ }
+ }
+ }
+ }
+
+ eDVBSubtitleRegion Region;
+ Region.m_pixmap = reg->region_buffer;
+ Region.m_position.setX(x0);
+ Region.m_position.setY(y0);
+ Page.m_regions.push_back(Region);
}
else
eDebug("region not found");
- region = region->next;
}
+ m_new_subtitle_page(Page);
+ Page.m_regions.clear();
+// eDebug("page timeout is %d", page->page_time_out);
+// Page.m_show_time += (page->page_time_out * 90000);
+// m_new_subtitle_page(Page);
//eDebug("schon gut.");
}
int eDVBSubtitleParser::start(int pid)
{
-#if 0
+#if 1
eDebug("eDVBSubtitleParser::start(%04x)", pid);
if (m_pes_reader)
return m_pes_reader->start(pid);
#endif
}
-void eDVBSubtitleParser::connectNewRegion(const Slot1<void, const eDVBSubtitleRegion&> &slot, ePtr<eConnection> &connection)
+void eDVBSubtitleParser::connectNewPage(const Slot1<void, const eDVBSubtitlePage&> &slot, ePtr<eConnection> &connection)
{
- connection = new eConnection(this, m_new_subtitle_region.connect(slot));
+ connection = new eConnection(this, m_new_subtitle_page.connect(slot));
}
struct subtitle_clut_entry
{
__u8 Y, Cr, Cb, T;
+ __u8 valid;
};
struct subtitle_clut
{
unsigned char clut_id;
- unsigned char size_2, size_4, size_8;
unsigned char CLUT_version_number;
- struct subtitle_clut_entry entries_2bit[4];
- struct subtitle_clut_entry entries_4bit[16];
- struct subtitle_clut_entry entries_8bit[256];
- struct subtitle_clut *next;
+ subtitle_clut_entry entries_2bit[4];
+ subtitle_clut_entry entries_4bit[16];
+ subtitle_clut_entry entries_8bit[256];
+ subtitle_clut *next;
};
struct subtitle_page_region
int region_id;
int region_horizontal_address;
int region_vertical_address;
- struct subtitle_page_region *next;
+ subtitle_page_region *next;
};
struct subtitle_region_object
int foreground_pixel_value;
int background_pixel_value;
- struct subtitle_region_object *next;
+ subtitle_region_object *next;
};
struct subtitle_region
int clut_id;
- struct subtitle_region_object *region_objects;
+ subtitle_region_object *region_objects;
- struct subtitle_region *next;
+ subtitle_region *next;
};
struct subtitle_page
time_t page_time_out;
int page_version_number;
int pcs_size;
- struct subtitle_page_region *page_regions;
+ subtitle_page_region *page_regions;
- struct subtitle_region *regions;
+ subtitle_region *regions;
- struct subtitle_clut *cluts;
+ subtitle_clut *cluts;
- struct subtitle_page *next;
+ subtitle_page *next;
};
struct bitstream
struct eDVBSubtitleRegion
{
- pts_t show_time;
- int timeout;
- ePtr<gPixmap> region;
+ ePtr<gPixmap> m_pixmap;
+ ePoint m_position;
+ eDVBSubtitleRegion &operator=(const eDVBSubtitleRegion &s)
+ {
+ m_pixmap = s.m_pixmap;
+ m_position = s.m_position;
+ return *this;
+ }
+};
+
+struct eDVBSubtitlePage
+{
+ std::list<eDVBSubtitleRegion> m_regions;
+ pts_t m_show_time;
};
class eDVBSubtitleParser
:public iObject, public ePESParser, public Object
{
DECLARE_REF(eDVBSubtitleParser);
- struct subtitle_page *pages;
- int current_clut_id, current_clut_page_id;
- int screen_width, screen_height;
- int bbox_left, bbox_top, bbox_right, bbox_bottom;
+ subtitle_page *pages;
ePtr<iDVBPESReader> m_pes_reader;
ePtr<eConnection> m_read_connection;
pts_t show_time;
- Signal1<void,const eDVBSubtitleRegion&> m_new_subtitle_region;
+ Signal1<void,const eDVBSubtitlePage&> m_new_subtitle_page;
public:
eDVBSubtitleParser(iDVBDemux *demux);
virtual ~eDVBSubtitleParser();
int start(int pid);
- void connectNewRegion(const Slot1<void, const eDVBSubtitleRegion&> &slot, ePtr<eConnection> &connection);
+ void connectNewPage(const Slot1<void, const eDVBSubtitlePage&> &slot, ePtr<eConnection> &connection);
private:
- void subtitle_process_line(struct subtitle_page *page, int object_id, int line, __u8 *data, int len);
- int subtitle_process_pixel_data(struct subtitle_page *page, int object_id, int *linenr, int *linep, __u8 *data);
+ void subtitle_process_line(subtitle_page *page, int object_id, int line, __u8 *data, int len);
+ int subtitle_process_pixel_data(subtitle_page *page, int object_id, int *linenr, int *linep, __u8 *data);
int subtitle_process_segment(__u8 *segment);
void subtitle_process_pes(__u8 *buffer, int len);
- void subtitle_clear_screen();
void subtitle_redraw_all();
void subtitle_reset();
void subtitle_redraw(int page_id);
m_teletext_parser = 0;
m_radiotext_parser = 0;
m_subtitle_parser = 0;
- m_new_dvb_subtitle_region_connection = 0;
+ m_new_dvb_subtitle_page_connection = 0;
m_new_subtitle_page_connection = 0;
m_radiotext_updated_connection = 0;
/* free the timeshift service handler, we need the resources */
m_service_handler_timeshift.free();
m_timeshift_active = 0;
-
+
m_event((iPlayableService*)this, evSeekableStatusChanged);
-
+
updateDecoder();
}
{
if (m_timeshift_active)
return;
-
+
m_decode_demux = 0;
m_decoder = 0;
m_teletext_parser = 0;
m_radiotext_parser = 0;
m_subtitle_parser = 0;
m_new_subtitle_page_connection = 0;
- m_new_dvb_subtitle_region_connection = 0;
+ m_new_dvb_subtitle_page_connection = 0;
m_radiotext_updated_connection = 0;
m_timeshift_active = 1;
m_event((iPlayableService*)this, evSeekableStatusChanged);
-
+
eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
r.path = m_timeshift_file;
-
+
m_cue = new eCueSheet();
m_service_handler_timeshift.tune(r, 1, m_cue); /* use the decoder demux for everything */
updateDecoder(); /* mainly to switch off PCR */
{
eDebugNoNewLine(" (");
for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
- i(program.videoStreams.begin());
+ i(program.videoStreams.begin());
i != program.videoStreams.end(); ++i)
{
if (vpid == -1)
{
eDebugNoNewLine(" (");
for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
- i(program.audioStreams.begin());
+ i(program.audioStreams.begin());
i != program.audioStreams.end(); ++i)
{
if (apid == -1 || (apidtype == eDVBAudio::aMPEG && defaultac3))
m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
#endif
m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
- m_subtitle_parser->connectNewRegion(slot(*this, &eDVBServicePlay::newDVBSubtitleRegion), m_new_dvb_subtitle_region_connection);
+ m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
}
if (m_decoder)
m_decoder->setTextPID(tpid);
- if (m_teletext_parser)
- m_teletext_parser->start(tpid);
-
-// if (m_subtitle_parser && program.subtitleStreams.size() > 0)
-// m_subtitle_parser->start(program.subtitleStreams[0].pid);
-
if (!m_is_primary)
m_decoder->setTrickmode(1);
if (m_subtitle_widget)
disableSubtitles(parent);
- if (!m_teletext_parser)
- return -1;
-
if (!PyInt_Check(entry))
return -1;
-
+
+ int page = PyInt_AsLong(entry);
+
+ if (page > 0 && !m_teletext_parser)
+ return -1;
+ if (page < 0 && !m_subtitle_parser)
+ return -1;
+
m_subtitle_widget = new eSubtitleWidget(parent);
m_subtitle_widget->resize(parent->size()); /* full size */
-
- int page = PyInt_AsLong(entry);
-
- m_teletext_parser->setPage(page);
+
+ if (page > 0)
+ {
+ eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
+ eDVBServicePMTHandler::program program;
+ if (h.getProgramInfo(program))
+ eDebug("getting program info failed.");
+ else
+ {
+ eDebug("start teletext on pid %04x, page %d", program.textPid, page);
+ m_teletext_parser->start(program.textPid);
+ m_teletext_parser->setPage(page);
+ }
+ }
+ else
+ {
+ int pid = -page;
+ eDebug("start dvb subtitles on pid %04x", pid);
+ m_subtitle_parser->start(pid);
+ }
return 0;
}
PyTuple_SetItem(tuple, 0, PyString_FromString(desc));
PyTuple_SetItem(tuple, 1, PyInt_FromLong(*i));
PyList_Append(l, tuple);
+ Py_DECREF(tuple);
}
-
+
+ eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
+ eDVBServicePMTHandler::program program;
+ if (h.getProgramInfo(program))
+ eDebug("getting program info failed.");
+ else
+ {
+ for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
+ it != program.subtitleStreams.end(); ++it)
+ {
+ PyObject *tuple = PyTuple_New(2);
+ char desc[20];
+ sprintf(desc, "DVB %s", it->language_code.c_str());
+ PyTuple_SetItem(tuple, 0, PyString_FromString(desc));
+ PyTuple_SetItem(tuple, 1, PyInt_FromLong(-it->pid));
+ PyList_Append(l, tuple);
+ Py_DECREF(tuple);
+ }
+ }
+
return l;
}
if (m_subtitle_widget)
{
m_subtitle_pages.push_back(page);
-
checkSubtitleTiming();
}
}
void eDVBServicePlay::checkSubtitleTiming()
{
+// eDebug("checkSubtitleTiming");
while (1)
{
- if (m_subtitle_pages.empty())
+ enum { TELETEXT, DVB } type;
+ eDVBTeletextSubtitlePage page;
+ eDVBSubtitlePage dvb_page;
+ pts_t show_time;
+ if (!m_subtitle_pages.empty())
+ {
+ page = m_subtitle_pages.front();
+ type = TELETEXT;
+ show_time = page.m_pts;
+ }
+ else if (!m_dvb_subtitle_pages.empty())
+ {
+ dvb_page = m_dvb_subtitle_pages.front();
+ type = DVB;
+ show_time = dvb_page.m_show_time;
+ }
+ else
return;
- eDVBTeletextSubtitlePage p = m_subtitle_pages.front();
-
pts_t pos = 0;
if (m_decoder)
m_decoder->getPTS(0, pos);
-
- int diff = p.m_pts - pos;
+
+// eDebug("%lld %lld", pos, show_time);
+ int diff = show_time - pos;
if (diff < 0)
{
eDebug("[late (%d ms)]", -diff / 90);
if (!diff)
{
- m_subtitle_widget->setPage(p);
- m_subtitle_pages.pop_front();
+ if (type == TELETEXT)
+ {
+ eDebug("display teletext subtitle page");
+ m_subtitle_widget->setPage(page);
+ m_subtitle_pages.pop_front();
+ }
+ else
+ {
+ eDebug("display dvb subtitle Page");
+ m_subtitle_widget->setPage(dvb_page);
+ m_dvb_subtitle_pages.pop_front();
+ }
} else
{
+ eDebug("start subtitle delay %d", diff / 90);
m_subtitle_sync_timer.start(diff / 90, 1);
break;
}
}
}
-void eDVBServicePlay::newDVBSubtitleRegion(const eDVBSubtitleRegion &p)
-{
- eDebug("new dvb subtitle region");
-}
-
-void eDVBServicePlay::checkDvbSubtitleTiming()
+void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
{
- eDebug("check dvb subtitle timing");
+ if (m_subtitle_widget)
+ {
+ m_dvb_subtitle_pages.push_back(p);
+ checkSubtitleTiming();
+ }
}
int eDVBServicePlay::getAC3Delay()