From e607bae2402d1b93399593b0e2d7d3f75f1d0374 Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Fri, 3 Nov 2017 23:05:59 +0100 Subject: [PATCH] - tuxtxt: align to mp Signed-off-by: Thilo Graf --- lib/libtuxtxt/teletext.h | 5 ++ lib/libtuxtxt/tuxtxt.cpp | 119 ++++++++++++++++++------- lib/libtuxtxt/tuxtxt.h | 1 + lib/libtuxtxt/tuxtxt_common.h | 158 +++++++++++++++++++++++++++++++--- 4 files changed, 240 insertions(+), 43 deletions(-) diff --git a/lib/libtuxtxt/teletext.h b/lib/libtuxtxt/teletext.h index cb0037d1e..2966513b2 100644 --- a/lib/libtuxtxt/teletext.h +++ b/lib/libtuxtxt/teletext.h @@ -1,11 +1,16 @@ #ifndef __teletext_h__ #define __teletext_h__ +#include int tuxtxt_init(); void tuxtxt_close(); void tuxtxt_start(int tpid, int source = 0); // Start caching int tuxtxt_stop(); // Stop caching +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE +int tuxtx_main(int pid, int page = 0, int source = 0, bool _isEplayer = false); +#else int tuxtx_main(int pid, int page = 0, int source = 0); +#endif void tuxtx_stop_subtitle(); int tuxtx_subtitle_running(int *pid, int *page, int *running); void tuxtx_pause_subtitle(bool pause = 1); diff --git a/lib/libtuxtxt/tuxtxt.cpp b/lib/libtuxtxt/tuxtxt.cpp index 102efd4c1..3127bf5f6 100644 --- a/lib/libtuxtxt/tuxtxt.cpp +++ b/lib/libtuxtxt/tuxtxt.cpp @@ -29,7 +29,7 @@ #define KEY_TTZOOM KEY_FN_2 #define KEY_REVEAL KEY_FN_D -#ifdef HAVE_SPARK_HARDWARE +#ifdef HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE #define MARK_FB(a, b, c, d) if (p == lfb) CFrameBuffer::getInstance()->mark(a, b, (a) + (c), (b) + (d)) #else #define MARK_FB(a, b, c, d) @@ -44,6 +44,9 @@ static int ttx_req_pause; static int sub_pid, sub_page; static bool use_gui; static int cfg_national_subset; +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE +bool isTtxEplayer = false; +#endif static int screen_x, screen_y, screen_w, screen_h; @@ -1550,7 +1553,11 @@ void tuxtx_pause_subtitle(bool pause) //printf("TuxTxt subtitle unpause, running %d pid %d page %d\n", reader_running, sub_pid, sub_page); ttx_paused = 0; if(!reader_running && sub_pid && sub_page) +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + tuxtx_main(sub_pid, sub_page, 0, isTtxEplayer); +#else tuxtx_main(sub_pid, sub_page); +#endif } else { if(!reader_running) @@ -1608,10 +1615,21 @@ int tuxtx_subtitle_running(int *pid, int *page, int *running) return ret; } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE +int tuxtx_main(int pid, int page, int source, bool isEplayer) +#else int tuxtx_main(int pid, int page, int source) +#endif { char cvs_revision[] = "$Revision: 1.95 $"; +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (isTtxEplayer != isEplayer) { + tuxtxt_stop(); + tuxtxt_clear_cache(); + isTtxEplayer = isEplayer; + } +#endif use_gui = 1; boxed = 0; //printf("to init tuxtxt\n");fflush(stdout); @@ -1635,6 +1653,9 @@ int tuxtx_main(int pid, int page, int source) CFrameBuffer *fbp = CFrameBuffer::getInstance(); lfb = fbp->getFrameBufferPointer(); lbb = fbp->getBackBufferPointer(); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + fb_pixel_t old_border_color = fbp->getBorderColor(); +#endif tuxtxt_cache.vtxtpid = pid; @@ -1827,6 +1848,9 @@ int tuxtx_main(int pid, int page, int source) /* update page or timestring and lcd */ RenderPage(); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + fbp->blit(); +#endif } while ((RCCode != RC_HOME) && (RCCode != RC_STANDBY)); /* if transparent mode was selected, remember the original mode */ screenmode = prevscreenmode; @@ -1838,6 +1862,9 @@ int tuxtx_main(int pid, int page, int source) if ( initialized ) tuxtxt_close(); #endif +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + fbp->setBorderColor(old_border_color); +#endif printf("Tuxtxt: plugin ended\n"); return 1; @@ -2292,6 +2319,10 @@ void CleanUp() ******************************************************************************/ int GetTeletextPIDs() { +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (isTtxEplayer) + return 0; +#endif int pat_scan, pmt_scan, sdt_scan, desc_scan, pid_test, byte, diff, first_sdt_sec; unsigned char bufPAT[1024]; @@ -2301,22 +2332,21 @@ int GetTeletextPIDs() /* show infobar */ RenderMessage(ShowInfoBar); - unsigned char filter[DMX_FILTER_SIZE]; - unsigned char mask[DMX_FILTER_SIZE]; + unsigned char filter[DMX_FILTER_SIZE] = { 0 }; + unsigned char mask[DMX_FILTER_SIZE] = { 0 }; int res; - cDemux * dmx = new cDemux(1); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + cDemux * dmx = new cDemux(0); // live demux +#else + cDemux * dmx = new cDemux(1); +#endif dmx->Open(DMX_PSI_CHANNEL); - memset(filter, 0x00, DMX_FILTER_SIZE); - memset(mask, 0x00, DMX_FILTER_SIZE); + mask[0] = 0xFF; + mask[4] = 0xFF; - //filter[0] = 0x00; - //mask[0] = 0xFF; - mask[0] = 0xFF; - mask[4] = 0xFF; - - dmx->sectionFilter(0, filter, mask, 1); + dmx->sectionFilter(0, filter, mask, 1); res = dmx->Read(bufPAT, sizeof(bufPAT)); dmx->Stop(); if(res <= 0) { @@ -2785,6 +2815,7 @@ void Menu_Init(char *menu, int current_pid, int menuitem, int hotindex) national_subset = national_subset_bak; Menu_HighlightLine(menu, MenuLine[menuitem], 1); Menu_UpdateHotlist(menu, hotindex, menuitem); + CFrameBuffer::getInstance()->blit(); } void ConfigMenu(int Init) @@ -3370,6 +3401,9 @@ void ConfigMenu(int Init) break; } } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + CopyBB2FB(); +#endif UpdateLCD(); /* update number of cached pages */ } while ((RCCode != RC_HOME) && (RCCode != RC_DBOX) && (RCCode != RC_MUTE)); @@ -3662,6 +3696,9 @@ void PageCatching() RCCode = -1; return; } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + CopyBB2FB(); +#endif UpdateLCD(); } while (RCCode != RC_OK); @@ -3816,12 +3853,16 @@ void RenderCatchedPage() if (zoommode == 1 && catch_row > 11) { zoommode = 2; +#if !HAVE_SPARK_HARDWARE && !HAVE_DUCKBOX_HARDWARE CopyBB2FB(); +#endif } else if (zoommode == 2 && catch_row < 12) { zoommode = 1; +#if !HAVE_SPARK_HARDWARE && !HAVE_DUCKBOX_HARDWARE CopyBB2FB(); +#endif } SetPosX(catch_col); @@ -3844,6 +3885,9 @@ void RenderCatchedPage() RenderCharFB(page_char[catch_row*40 + catch_col ], &a0); RenderCharFB(page_char[catch_row*40 + catch_col + 1], &a1); RenderCharFB(page_char[catch_row*40 + catch_col + 2], &a2); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + CopyBB2FB(); +#endif } /****************************************************************************** @@ -3952,8 +3996,17 @@ void SwitchScreenMode(int newscreenmode) setfontwidth(fw); CFrameBuffer *f = CFrameBuffer::getInstance(); - videoDecoder->Pig(tx, ty, tw, th, - f->getScreenWidth(true), f->getScreenHeight(true)); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (!boxed && (f->get3DMode() == CFrameBuffer::Mode3D_off)) + videoDecoder->Pig(tx, ty, tw, th, + f->getScreenWidth(true), f->getScreenHeight(true), + g_settings.screen_StartX_int, + g_settings.screen_StartY_int, + g_settings.screen_EndX_int, + g_settings.screen_EndY_int); +#else + videoDecoder->Pig(tx, ty, tw, th, f->getScreenWidth(true), f->getScreenHeight(true)); +#endif } else /* not split */ { @@ -4840,7 +4893,12 @@ void RenderChar(int Char, tstPageAttr *Attribute, int zoom, int yoffset) void RenderCharFB(int Char, tstPageAttr *Attribute) { +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (zoommode != 2) + RenderCharBB(Char, Attribute); +#else RenderChar(Char, Attribute, zoommode, var_screeninfo.yoffset); +#endif } /****************************************************************************** @@ -4993,6 +5051,9 @@ void RenderMessage(int Message) for (byte = 0; byte < 38; byte++) RenderCharFB(message_6[byte], &atrtable[imenuatr + 2]); national_subset = national_subset_back; +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + CFrameBuffer::getInstance()->blit(); +#endif } /****************************************************************************** @@ -5102,6 +5163,9 @@ void DoFlashing(int startrow) } PosY += fontheight*factor; } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + CopyBB2FB(); +#endif } void RenderPage() @@ -5311,6 +5375,9 @@ void RenderPage() RenderCharFB(ns[0],&atrtable[ATR_WB]); RenderCharFB(ns[1],&atrtable[ATR_WB]); RenderCharFB(ns[2],&atrtable[ATR_WB]); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + CopyBB2FB(); +#endif tuxtxt_cache.pageupdate=0; } @@ -5528,7 +5595,7 @@ void CopyBB2FB() { fb_pixel_t *src, *dst, *topsrc; int fillcolor, i, screenwidth, swtmp; -#if defined(HAVE_SPARK_HARDWARE) || defined(HAVE_COOL_HARDWARE) +#if defined(HAVE_SPARK_HARDWARE) || defined(HAVE_COOL_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) CFrameBuffer *f = CFrameBuffer::getInstance(); #endif @@ -5539,7 +5606,7 @@ void CopyBB2FB() /* copy backbuffer to framebuffer */ if (!zoommode) { -#ifdef HAVE_SPARK_HARDWARE +#ifdef HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE f->blit2FB(lbb, var_screeninfo.xres, var_screeninfo.yres, 0, 0, 0, 0, true); #elif defined(HAVE_COOL_HARDWARE) f->fbCopyArea(var_screeninfo.xres, var_screeninfo.yres, 0, 0, 0, var_screeninfo.yres); @@ -5562,6 +5629,9 @@ void CopyBB2FB() FillBorder(*lbb, true); // ClearBB(*(lfb + var_screeninfo.xres * var_screeninfo.yoffset)); } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + f->blit(); +#endif if (clearbbcolor >= 0) { @@ -5590,13 +5660,11 @@ void CopyBB2FB() if (screenmode == 1) { screenwidth = ( TV43STARTX ); -#if defined(HAVE_SPARK_HARDWARE) +#if defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) int cx = var_screeninfo.xres - TV43STARTX; /* x start */ int cw = TV43STARTX; /* width */ int cy = StartY; int ch = 24*fontheight; -#endif -#ifdef HAVE_SPARK_HARDWARE f->blit2FB(lbb, cw, ch, cx, cy, cx, cy, true); #else fb_pixel_t *topdst = dst; @@ -5637,8 +5705,9 @@ void CopyBB2FB() for (swtmp=0; swtmp<= screenwidth;swtmp++) *(dst + stride * (fontheight + i) + swtmp) = bgra[fillcolor]; } -#ifdef HAVE_SPARK_HARDWARE +#ifdef HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE f->mark(0, 0, var_screeninfo.xres, var_screeninfo.yres); + f->blit(); #endif } @@ -6271,8 +6340,6 @@ void DecodePage() int o = 0; char bitmask ; - - for (r = 0; r < 25; r++) { for (c = 0; c < 40; c++) @@ -6342,11 +6409,3 @@ int GetRCCode() } return 0; } - -/* Local Variables: */ -/* indent-tabs-mode:t */ -/* tab-width:3 */ -/* c-basic-offset:3 */ -/* comment-column:0 */ -/* fill-column:120 */ -/* End: */ diff --git a/lib/libtuxtxt/tuxtxt.h b/lib/libtuxtxt/tuxtxt.h index 4d8e3c452..305bc6a4b 100644 --- a/lib/libtuxtxt/tuxtxt.h +++ b/lib/libtuxtxt/tuxtxt.h @@ -56,6 +56,7 @@ extern void tuxtxt_decode_adip(); /* additional information table */ extern void tuxtxt_compress_page(int p, int sp, unsigned char* buffer); extern void tuxtxt_decompress_page(int p, int sp, unsigned char* buffer); extern void tuxtxt_clear_p26(tstExtData* extData); +extern void tuxtxt_clear_cache(void); #if TUXTXT_DEBUG extern int tuxtxt_get_zipsize(int p, int sp); #endif diff --git a/lib/libtuxtxt/tuxtxt_common.h b/lib/libtuxtxt/tuxtxt_common.h index 68b6d76bc..6127a4b76 100644 --- a/lib/libtuxtxt/tuxtxt_common.h +++ b/lib/libtuxtxt/tuxtxt_common.h @@ -1,12 +1,16 @@ /* tuxtxt_common.h * for license info see the other tuxtxt files */ +#include +#include #include #include #include #include #include #include +#include +#include #if TUXTXT_COMPRESS == 1 #include #endif @@ -567,9 +571,101 @@ void tuxtxt_allocate_cache(int magazine) pthread_mutex_unlock(&tuxtxt_cache_lock); } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE +/****************************************************************************** + * Handling of packets injected by libeplayer3 * + ******************************************************************************/ + +struct injected_page +{ + uint8_t *data; + int size; + injected_page() : data(NULL){}; +}; + +#define INJECT_QUEUE_LIMIT 64 +static struct injected_page inject_queue[INJECT_QUEUE_LIMIT]; +static int inject_queue_index_read = 0; +static int inject_queue_index_write = 0; +static pthread_mutex_t inject_mutex = PTHREAD_MUTEX_INITIALIZER; +static sem_t inject_sem; +static int last_injected_pid = -1; + +static void clear_inject_queue(void) +{ + pthread_mutex_lock(&inject_mutex); + while (!sem_trywait(&inject_sem)) { + if (inject_queue[inject_queue_index_read].data) { + free(inject_queue[inject_queue_index_read].data); + inject_queue[inject_queue_index_read].data = NULL; + } + inject_queue_index_read++; + inject_queue_index_read %= INJECT_QUEUE_LIMIT; + } + pthread_mutex_unlock(&inject_mutex); +} + +void teletext_write(int pid, uint8_t *data, int size) +{ + if (last_injected_pid != pid) { + clear_inject_queue(); + last_injected_pid = pid; + } + bool do_sem_post = true; + pthread_mutex_lock(&inject_mutex); + if (inject_queue[inject_queue_index_write].data && inject_queue[inject_queue_index_write].size != size) { + free(inject_queue[inject_queue_index_write].data); + do_sem_post = false; + } + if (!inject_queue[inject_queue_index_write].data) { + inject_queue[inject_queue_index_write].data = (uint8_t *) malloc(size); + inject_queue[inject_queue_index_write].size = size; + } + if (inject_queue[inject_queue_index_write].data) { + memcpy(inject_queue[inject_queue_index_write].data, data, size); + inject_queue_index_write++; + inject_queue_index_write %= INJECT_QUEUE_LIMIT; + if (do_sem_post) + sem_post(&inject_sem); + } + pthread_mutex_unlock(&inject_mutex); +} + +static bool read_injected_packet(unsigned char * &packet, int &size, int timeout_in_ms) +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += timeout_in_ms * 1000000; + if (ts.tv_nsec > 999999999) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000; + } + bool res = !sem_timedwait(&inject_sem, &ts); + if (res) { + pthread_mutex_lock(&inject_mutex); + packet = inject_queue[inject_queue_index_read].data; + if (packet) { + size = inject_queue[inject_queue_index_read].size; + inject_queue[inject_queue_index_read].data = NULL; + inject_queue_index_read++; + inject_queue_index_read %= INJECT_QUEUE_LIMIT; + } + else + res = false; + pthread_mutex_unlock(&inject_mutex); + } else + packet = NULL; + + return res; +} +#endif + /****************************************************************************** * CacheThread * ******************************************************************************/ +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE +extern bool isTtxEplayer; +#endif static int stop_cache = 0; void *tuxtxt_CacheThread(void * /*arg*/) { @@ -582,7 +678,11 @@ void *tuxtxt_CacheThread(void * /*arg*/) 0x20,0xa0,0x60,0xe0, 0x10,0x90,0x50,0xd0, 0x30,0xb0,0x70,0xf0 }; - unsigned char pes_packet[184*20]; + unsigned char pes_packet_dmx[184*20]; + unsigned char *pes_packet_ptr = NULL; +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + unsigned char *pes_packet_eplayer3 = NULL; +#endif unsigned char vtxt_row[42]; int line, byte/*, bit*/; int b1, b2, b3, b4; @@ -592,6 +692,9 @@ void *tuxtxt_CacheThread(void * /*arg*/) unsigned char pagedata[9][23*40]; tstPageinfo *pageinfo_thread; +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + sem_init(&inject_sem, 0, 0); +#endif set_threadname("tuxtxt:cache"); printf("TuxTxt running thread...(%04x)\n",tuxtxt_cache.vtxtpid); tuxtxt_cache.receiving = 1; @@ -607,15 +710,30 @@ void *tuxtxt_CacheThread(void * /*arg*/) /* read packet */ ssize_t readcnt = 0; - readcnt = dmx->Read(pes_packet, sizeof (pes_packet), 1000); - //if (readcnt != sizeof(pes_packet)) - if ((readcnt <= 0) || (readcnt % 184)) - { -#if TUXTXT_DEBUG - if(readcnt > 0) - printf ("TuxTxt: readerror: %d\n", readcnt); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (isTtxEplayer) { + pes_packet_ptr = NULL; + if (pes_packet_eplayer3) { + free(pes_packet_eplayer3); + pes_packet_eplayer3 = NULL; + } + if (!read_injected_packet(pes_packet_eplayer3, readcnt, 1000)) + continue; + pes_packet_ptr = pes_packet_eplayer3; + } + else #endif - continue; + { + readcnt = dmx->Read(pes_packet_dmx, sizeof(pes_packet_dmx), 1000); + pes_packet_ptr = pes_packet_dmx; + if ((readcnt <= 0) || (readcnt % 184)) + { +#if TUXTXT_DEBUG + if(readcnt > 0) + printf ("TuxTxt: readerror: %d\n", readcnt); +#endif + continue; + } } /* this "big hammer lock" is a hack: it avoids a crash if @@ -628,7 +746,8 @@ void *tuxtxt_CacheThread(void * /*arg*/) /* analyze it */ for (line = 0; line < readcnt/0x2e /*4*/; line++) { - unsigned char *vtx_rowbyte = &pes_packet[line*0x2e]; + unsigned char *vtx_rowbyte = pes_packet_ptr; + pes_packet_ptr += 0x2e; if ((vtx_rowbyte[1] == 0x2C) && (vtx_rowbyte[0] == 0x02 || vtx_rowbyte[0] == 0x03)) { /* clear rowbuffer */ @@ -1069,6 +1188,10 @@ void *tuxtxt_CacheThread(void * /*arg*/) } pthread_mutex_unlock(&tuxtxt_cache_biglock); } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (pes_packet_eplayer3) + free(pes_packet_eplayer3); +#endif pthread_exit(NULL); } @@ -1082,10 +1205,16 @@ int tuxtxt_start_thread(int source) return 0; tuxtxt_cache.thread_starting = 1; - tuxtxt_init_demuxer(source); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (!isTtxEplayer) { +#endif + tuxtxt_init_demuxer(source); - dmx->pesFilter(tuxtxt_cache.vtxtpid); - dmx->Start(); + dmx->pesFilter(tuxtxt_cache.vtxtpid); + dmx->Start(); +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + } +#endif stop_cache = 0; /* create decode-thread */ @@ -1131,6 +1260,9 @@ int tuxtxt_stop_thread() delete dmx; dmx = NULL; } +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + clear_inject_queue(); +#endif #if 1//TUXTXT_DEBUG printf("TuxTxt stopped service %x\n", tuxtxt_cache.vtxtpid); #endif