diff --git a/azbox/dmx.cpp b/azbox/dmx.cpp index 1353cfd..80d500a 100644 --- a/azbox/dmx.cpp +++ b/azbox/dmx.cpp @@ -95,6 +95,10 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe int flags = O_RDWR; if (fd > -1) lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd); + + if (pes_type != DMX_PSI_CHANNEL) + flags |= O_NONBLOCK; + fd = open(devname[devnum], flags); if (fd < 0) { diff --git a/azbox/video.cpp b/azbox/video.cpp index f561f40..0e679c2 100644 --- a/azbox/video.cpp +++ b/azbox/video.cpp @@ -112,6 +112,7 @@ cVideo::cVideo(int, void *, void *) close(blankfd); } openDevice(); + Pig(-1, -1, -1, -1); } cVideo::~cVideo(void) diff --git a/libspark/dmx.cpp b/libspark/dmx.cpp index eae4aee..8e2c1f6 100644 --- a/libspark/dmx.cpp +++ b/libspark/dmx.cpp @@ -98,6 +98,9 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe int flags = O_RDWR; if (fd > -1) lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd); + + if (pes_type != DMX_PSI_CHANNEL) + flags |= O_NONBLOCK; #if 0 if (pes_type == DMX_TP_CHANNEL) { diff --git a/libspark/video.cpp b/libspark/video.cpp index 4ee8388..2922e19 100644 --- a/libspark/video.cpp +++ b/libspark/video.cpp @@ -490,8 +490,34 @@ void cVideo::Standby(unsigned int bOn) int cVideo::getBlank(void) { - lt_debug("%s\n", __FUNCTION__); - return 0; + static unsigned int lastcount = 0; + unsigned int count = 0; + size_t n = 0; + ssize_t r; + char *line = NULL; + char *p; + /* hack: the "mailbox" irq is not increasing if + * no audio or video is decoded... */ + FILE *f = fopen("/proc/interrupts", "r"); + if (! f) /* huh? */ + return 0; + while ((r = getline(&line, &n, f)) != -1) + { + if (r <= strlen("mailbox")) /* should not happen... */ + continue; + line[r - 1] = 0; /* remove \n */ + if (!strcmp(&line[r - 1 - strlen("mailbox")], "mailbox")) + { + count = atoi(line + 5); + break; + } + } + free(line); + fclose(f); + int ret = (count == lastcount); /* no new decode -> return 1 */ + lt_debug("%s: %d (irq++: %d)\n", __func__, ret, count - lastcount); + lastcount = count; + return ret; } /* this function is regularly called, checks if video parameters diff --git a/libtriple/playback_td.cpp b/libtriple/playback_td.cpp index ed8684c..e5c8e19 100644 --- a/libtriple/playback_td.cpp +++ b/libtriple/playback_td.cpp @@ -28,6 +28,7 @@ static pthread_cond_t playback_ready_cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t playback_ready_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t currpos_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t inbufpos_mutex = PTHREAD_MUTEX_INITIALIZER; static int dvrfd = -1; static int streamtype; @@ -295,7 +296,10 @@ void cPlayback::playthread(void) if (playstate == STATE_INIT) { /* hack for timeshift to determine start PTS */ - if (inbuf_read() < 0) + pthread_mutex_lock(&inbufpos_mutex); + ret = inbuf_read(); + pthread_mutex_unlock(&inbufpos_mutex); + if (ret < 0) break; usleep(100000); if (pts_start == -1) @@ -308,7 +312,10 @@ void cPlayback::playthread(void) usleep(1); continue; } - if (inbuf_read() < 0) + pthread_mutex_lock(&inbufpos_mutex); + ret = inbuf_read(); + pthread_mutex_unlock(&inbufpos_mutex); + if (ret < 0) break; /* autoselect PID for PLAYMODE_FILE */ @@ -326,9 +333,13 @@ void cPlayback::playthread(void) } } + pthread_mutex_lock(&inbufpos_mutex); towrite = inbuf_pos / 188 * 188; /* TODO: smaller chunks? */ if (towrite == 0) + { + pthread_mutex_unlock(&inbufpos_mutex); continue; + } retry: ret = write(dvrfd, inbuf, towrite); if (ret < 0) @@ -340,6 +351,7 @@ void cPlayback::playthread(void) } memmove(inbuf, inbuf + ret, inbuf_pos - ret); inbuf_pos -= ret; + pthread_mutex_unlock(&inbufpos_mutex); } pthread_cleanup_pop(1); @@ -597,12 +609,14 @@ off_t cPlayback::seek_to_pts(int64_t pts) newpos = mp_seekSync(newpos); if (newpos < 0) return newpos; + pthread_mutex_lock(&inbufpos_mutex); inbuf_pos = 0; inbuf_sync = 0; while (inbuf_pos < INBUF_SIZE * 8 / 10) { if (inbuf_read() <= 0) break; // EOF } + pthread_mutex_unlock(&inbufpos_mutex); if (pts_curr < pts_start) tmppts = pts_curr + 0x200000000ULL - pts_start; else @@ -786,6 +800,7 @@ int64_t cPlayback::get_PES_PTS(uint8_t *buf, int len, bool last) return pts; } +/* needs to be called with inbufpos_mutex locked! */ ssize_t cPlayback::inbuf_read() { if (filetype == FILETYPE_UNKNOWN) diff --git a/libtriple/video_td.cpp b/libtriple/video_td.cpp index 7bf7c5b..356b023 100644 --- a/libtriple/video_td.cpp +++ b/libtriple/video_td.cpp @@ -108,6 +108,11 @@ cVideo::cVideo(int, void *, void *) free(blank_data[i]); /* don't leak... */ blank_data[i] = NULL; } + else + { /* set framerate to 24fps... see getBlank() */ + ((char *)blank_data[i])[7] &= 0xF0; + ((char *)blank_data[i])[7] += 2; + } } close(blankfd); } @@ -497,8 +502,15 @@ void cVideo::Standby(unsigned int bOn) int cVideo::getBlank(void) { - lt_debug("%s\n", __FUNCTION__); - return 0; + VIDEOINFO v; + memset(&v, 0, sizeof(v)); + ioctl(fd, MPEG_VID_GET_V_INFO, &v); + /* HACK HACK HACK :-) + * setBlank() puts a 24fps black mpeg into the decoder... + * regular broadcast does not have 24fps, so if it is still + * there, video did not decode... */ + lt_debug("%s: %hu (blank = 2)\n", __func__, v.frame_rate); + return (v.frame_rate == 2); } /* set zoom in percent (100% == 1:1) */