Skip to content

Commit

Permalink
[Updated] Optimized DVB subtitles handling code
Browse files Browse the repository at this point in the history
  • Loading branch information
DimitarCC committed Oct 22, 2024
1 parent 763122c commit d1c7ba6
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 1,063 deletions.
56 changes: 44 additions & 12 deletions lib/dvb/subtitle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, sub
return 0;
}

int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)
int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment, bool isBufferProcess)
{
int segment_type, page_id, segment_length, processed_length;
if (*segment++ != 0x0F)
if (*segment++ != DVB_SUB_SYNC_BYTE)
{
eDebug("[eDVBSubtitleParser] out of sync.");
return -1;
Expand All @@ -267,9 +267,9 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)
page_id |= *segment++;
segment_length = *segment++ << 8;
segment_length |= *segment++;
if (segment_type == 0xFF)
if (segment_type == DVB_SUB_SEGMENT_STUFFING)
return segment_length + 6;
if (page_id != m_composition_page_id && page_id != m_ancillary_page_id)
if (page_id != m_composition_page_id && page_id != m_ancillary_page_id && !isBufferProcess)
return segment_length + 6;

subtitle_page *page, **ppage;
Expand All @@ -288,7 +288,7 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)

switch (segment_type)
{
case 0x10: // page composition segment
case DVB_SUB_SEGMENT_PAGE_COMPOSITION:
{
int page_time_out = *segment++; processed_length++;
int page_version_number = *segment >> 4;
Expand Down Expand Up @@ -380,7 +380,7 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)

break;
}
case 0x11: // region composition segment
case DVB_SUB_SEGMENT_REGION_COMPOSITION:
{
int region_id = *segment++; processed_length++;
int version_number = *segment >> 4;
Expand Down Expand Up @@ -518,7 +518,7 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)

break;
}
case 0x12: // CLUT definition segment
case DVB_SUB_SEGMENT_CLUT_DEFINITION:
{
int CLUT_id, CLUT_version_number;
subtitle_clut *clut, **pclut;
Expand Down Expand Up @@ -620,7 +620,7 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)
}
break;
}
case 0x13: // object data segment
case DVB_SUB_SEGMENT_OBJECT_DATA:
{
int object_id;
int object_coding_method;
Expand Down Expand Up @@ -717,7 +717,7 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)
}
break;
}
case 0x14: // display definition segment
case DVB_SUB_SEGMENT_DISPLAY_DEFINITION:
{
if (segment_length > 4)
{
Expand Down Expand Up @@ -749,12 +749,12 @@ int eDVBSubtitleParser::subtitle_process_segment(uint8_t *segment)
eDebug("[eDVBSubtitleParser] display definition segment to short %d!", segment_length);
break;
}
case 0x80: // end of display set segment
case DVB_SUB_SEGMENT_END_OF_DISPLAY_SET:
{
subtitle_redraw_all();
m_seen_eod = true;
}
case 0xFF: // stuffing
case DVB_SUB_SEGMENT_STUFFING:
break;
default:
eDebug("[eDVBSubtitleParser] unhandled segment type %02x", segment_type);
Expand Down Expand Up @@ -787,7 +787,7 @@ void eDVBSubtitleParser::subtitle_process_pes(uint8_t *pkt, int len)

m_seen_eod = false;

while (len && *pkt == 0x0F)
while (len && *pkt == DVB_SUB_SYNC_BYTE)
{
int l = subtitle_process_segment(pkt);
if (l < 0)
Expand All @@ -801,6 +801,34 @@ void eDVBSubtitleParser::subtitle_process_pes(uint8_t *pkt, int len)
}
}

void eDVBSubtitleParser::processBuffer(uint8_t *data, size_t len, pts_t pts)
{
m_show_time = pts;

if (*data != 0x20) {
eWarning("[eDVBSubtitleParser] Tried to handle a PES packet private data that isn't a subtitle packet (does not start with 0x20)");
return;
}

data++; len--; // data identifier
data++; len--; // stream id;


m_seen_eod = false;
while (len && *data == DVB_SUB_SYNC_BYTE)
{
int l = subtitle_process_segment(data, true);
if (l < 0)
break;
data += l;
len -= l;
}

if (len && *data != DVB_SUB_SEGMENT_STUFFING)
eDebug("[eDVBSubtitleParser] strange data at the end");

}


void eDVBSubtitleParser::subtitle_redraw_all()
{
Expand Down Expand Up @@ -1067,6 +1095,10 @@ void eDVBSubtitleParser::subtitle_redraw(int page_id)

DEFINE_REF(eDVBSubtitleParser);

eDVBSubtitleParser::eDVBSubtitleParser()
:m_pages(0), m_display_size(720,576)
{ }

eDVBSubtitleParser::eDVBSubtitleParser(iDVBDemux *demux)
:m_pages(0), m_display_size(720,576)
{
Expand Down
14 changes: 13 additions & 1 deletion lib/dvb/subtitle.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
#include <lib/dvb/pesparse.h>
#include <lib/gdi/gpixmap.h>

#define DVB_SUB_SEGMENT_PAGE_COMPOSITION 0x10
#define DVB_SUB_SEGMENT_REGION_COMPOSITION 0x11
#define DVB_SUB_SEGMENT_CLUT_DEFINITION 0x12
#define DVB_SUB_SEGMENT_OBJECT_DATA 0x13
#define DVB_SUB_SEGMENT_DISPLAY_DEFINITION 0x14
#define DVB_SUB_SEGMENT_END_OF_DISPLAY_SET 0x80
#define DVB_SUB_SEGMENT_STUFFING 0xFF

#define DVB_SUB_SYNC_BYTE 0x0F

struct subtitle_clut_entry
{
uint8_t Y, Cr, Cb, T;
Expand Down Expand Up @@ -121,15 +131,17 @@ class eDVBSubtitleParser
bool m_seen_eod;
eSize m_display_size;
public:
eDVBSubtitleParser();
eDVBSubtitleParser(iDVBDemux *demux);
virtual ~eDVBSubtitleParser();
int start(int pid, int composition_page_id, int ancillary_page_id);
void processBuffer(uint8_t *data, size_t len, pts_t pts);
int stop();
void connectNewPage(const sigc::slot<void(const eDVBSubtitlePage&)> &slot, ePtr<eConnection> &connection);
private:
void subtitle_process_line(subtitle_region *region, subtitle_region_object *object, int line, uint8_t *data, int len);
int subtitle_process_pixel_data(subtitle_region *region, subtitle_region_object *object, int *linenr, int *linep, uint8_t *data);
int subtitle_process_segment(uint8_t *segment);
int subtitle_process_segment(uint8_t *segment, bool isBufferProcess=false);
void subtitle_process_pes(uint8_t *buffer, int len);
void subtitle_redraw_all();
void subtitle_reset();
Expand Down
Loading

0 comments on commit d1c7ba6

Please sign in to comment.