mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
sync with seife
This commit is contained in:
101
Makefile.am
101
Makefile.am
@@ -1,16 +1,16 @@
|
|||||||
noinst_LIBRARIES = libstb-hal.a
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
libstb_hal_a_SOURCES =
|
|
||||||
|
lib_LTLIBRARIES = libstb-hal.la
|
||||||
|
libstb_hal_la_SOURCES =
|
||||||
SUBDIRS = common tools
|
SUBDIRS = common tools
|
||||||
bin_PROGRAMS = libstb-hal-test
|
bin_PROGRAMS = libstb-hal-test
|
||||||
|
|
||||||
libstb_hal_a_LIBADD = \
|
libstb_hal_la_LIBADD = \
|
||||||
common/ca.o \
|
common/libcommon.la
|
||||||
common/lt_debug.o \
|
|
||||||
common/proc_tools.o
|
|
||||||
|
|
||||||
libstb_hal_test_SOURCES = libtest.cpp
|
libstb_hal_test_SOURCES = libtest.cpp
|
||||||
libstb_hal_test_LDADD = \
|
libstb_hal_test_LDADD = \
|
||||||
libstb-hal.a \
|
libstb-hal.la \
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
if BOXTYPE_TRIPLE
|
if BOXTYPE_TRIPLE
|
||||||
@@ -21,92 +21,23 @@ endif
|
|||||||
# there has to be a better way to do this...
|
# there has to be a better way to do this...
|
||||||
if BOXTYPE_TRIPLE
|
if BOXTYPE_TRIPLE
|
||||||
SUBDIRS += libtriple
|
SUBDIRS += libtriple
|
||||||
libstb_hal_a_LIBADD += \
|
libstb_hal_la_LIBADD += \
|
||||||
libtriple/audio_td.o \
|
libtriple/libtriple.la
|
||||||
libtriple/dmx_td.o \
|
|
||||||
libtriple/hardware_caps.o \
|
|
||||||
libtriple/init_td.o \
|
|
||||||
libtriple/lt_dfbinput.o \
|
|
||||||
libtriple/playback_td.o \
|
|
||||||
libtriple/pwrmngr.o \
|
|
||||||
libtriple/record_td.o \
|
|
||||||
libtriple/video_td.o
|
|
||||||
endif
|
endif
|
||||||
if BOXTYPE_AZBOX
|
if BOXTYPE_AZBOX
|
||||||
SUBDIRS += azbox
|
SUBDIRS += azbox
|
||||||
libstb_hal_a_LIBADD += \
|
libstb_hal_la_LIBADD += \
|
||||||
azbox/audio.o \
|
azbox/libazbox.la
|
||||||
azbox/dmx.o \
|
|
||||||
azbox/hardware_caps.o \
|
|
||||||
azbox/init.o \
|
|
||||||
azbox/playback.o \
|
|
||||||
azbox/pwrmngr.o \
|
|
||||||
azbox/record.o \
|
|
||||||
azbox/video.o
|
|
||||||
endif
|
endif
|
||||||
if BOXTYPE_GENERIC
|
if BOXTYPE_GENERIC
|
||||||
SUBDIRS += generic-pc
|
SUBDIRS += generic-pc
|
||||||
libstb_hal_a_LIBADD += \
|
libstb_hal_la_LIBADD += \
|
||||||
generic-pc/audio.o \
|
generic-pc/libgeneric.la
|
||||||
generic-pc/dmx.o \
|
|
||||||
generic-pc/hardware_caps.o \
|
|
||||||
generic-pc/init.o \
|
|
||||||
generic-pc/playback.o \
|
|
||||||
generic-pc/pwrmngr.o \
|
|
||||||
generic-pc/record.o \
|
|
||||||
generic-pc/video.o
|
|
||||||
endif
|
endif
|
||||||
if BOXTYPE_SPARK
|
if BOXTYPE_SPARK
|
||||||
libstb_hal_test_LDADD += -lasound
|
libstb_hal_test_LDADD += -lasound
|
||||||
SUBDIRS += libspark libeplayer3
|
SUBDIRS += libspark libeplayer3
|
||||||
libstb_hal_a_LIBADD += \
|
libstb_hal_la_LIBADD += \
|
||||||
libspark/audio.o \
|
libspark/libspark.la \
|
||||||
libspark/audio_mixer.o \
|
libeplayer3/libeplayer3.la
|
||||||
libspark/dmx.o \
|
|
||||||
libspark/hardware_caps.o \
|
|
||||||
libspark/init.o \
|
|
||||||
libspark/irmp.o \
|
|
||||||
libspark/lirmp_input.o \
|
|
||||||
libspark/playback_libeplayer3.o \
|
|
||||||
libspark/pwrmngr.o \
|
|
||||||
libspark/record.o \
|
|
||||||
libspark/video.o
|
|
||||||
|
|
||||||
# this is a hack to build the libeplayer3 objs statically into
|
|
||||||
# libstb-hal...
|
|
||||||
libstb_hal_a_LIBADD += \
|
|
||||||
libeplayer3/container.o \
|
|
||||||
libeplayer3/container_ffmpeg.o \
|
|
||||||
libeplayer3/text_srt.o \
|
|
||||||
libeplayer3/text_ssa.o \
|
|
||||||
libeplayer3/container_ass.o \
|
|
||||||
libeplayer3/audio.o \
|
|
||||||
libeplayer3/manager.o \
|
|
||||||
libeplayer3/subtitle.o \
|
|
||||||
libeplayer3/video.o \
|
|
||||||
libeplayer3/output_pipe.o \
|
|
||||||
libeplayer3/dvbsubtitle.o \
|
|
||||||
libeplayer3/teletext.o \
|
|
||||||
libeplayer3/output_subtitle.o \
|
|
||||||
libeplayer3/linuxdvb.o \
|
|
||||||
libeplayer3/output.o \
|
|
||||||
libeplayer3/playback.o \
|
|
||||||
libeplayer3/writer.o \
|
|
||||||
libeplayer3/aac.o \
|
|
||||||
libeplayer3/wmv.o \
|
|
||||||
libeplayer3/ac3.o \
|
|
||||||
libeplayer3/divx.o \
|
|
||||||
libeplayer3/wma.o \
|
|
||||||
libeplayer3/pes.o \
|
|
||||||
libeplayer3/dts.o \
|
|
||||||
libeplayer3/mpeg2.o \
|
|
||||||
libeplayer3/mp3.o \
|
|
||||||
libeplayer3/misc.o \
|
|
||||||
libeplayer3/h264.o \
|
|
||||||
libeplayer3/h263.o \
|
|
||||||
libeplayer3/vc1.o \
|
|
||||||
libeplayer3/framebuffer.o \
|
|
||||||
libeplayer3/vorbis.o \
|
|
||||||
libeplayer3/flac.o \
|
|
||||||
libeplayer3/pcm.o
|
|
||||||
endif
|
endif
|
||||||
|
@@ -1,13 +1,12 @@
|
|||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
# this library is not used for linking, so call it libdummy...
|
noinst_LTLIBRARIES = libazbox.la
|
||||||
noinst_LIBRARIES = libdummy.a
|
|
||||||
|
|
||||||
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
||||||
AM_LDFLAGS = -lpthread
|
AM_LDFLAGS = -lpthread
|
||||||
|
|
||||||
libdummy_a_SOURCES = \
|
libazbox_la_SOURCES = \
|
||||||
hardware_caps.c \
|
hardware_caps.c \
|
||||||
dmx.cpp \
|
dmx.cpp \
|
||||||
video.cpp \
|
video.cpp \
|
||||||
|
@@ -211,17 +211,31 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
|
|||||||
__FUNCTION__, num, fd, DMX_T[dmx_type], len, timeout);
|
__FUNCTION__, num, fd, DMX_T[dmx_type], len, timeout);
|
||||||
#endif
|
#endif
|
||||||
int rc;
|
int rc;
|
||||||
|
int to = timeout;
|
||||||
struct pollfd ufds;
|
struct pollfd ufds;
|
||||||
ufds.fd = fd;
|
ufds.fd = fd;
|
||||||
ufds.events = POLLIN|POLLPRI|POLLERR;
|
ufds.events = POLLIN|POLLPRI|POLLERR;
|
||||||
ufds.revents = 0;
|
ufds.revents = 0;
|
||||||
|
|
||||||
if (timeout > 0)
|
/* hack: if the frontend loses and regains lock, the demuxer often will not
|
||||||
|
* return from read(), so as a "emergency exit" for e.g. NIT scan, set a (long)
|
||||||
|
* timeout here */
|
||||||
|
if (dmx_type == DMX_PSI_CHANNEL && timeout <= 0)
|
||||||
|
to = 60 * 1000;
|
||||||
|
|
||||||
|
if (to > 0)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
rc = ::poll(&ufds, 1, timeout);
|
rc = ::poll(&ufds, 1, to);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
|
{
|
||||||
|
if (timeout == 0) /* we took the emergency exit */
|
||||||
|
{
|
||||||
|
dmx_err("timed out for timeout=0!, %s", "", 0);
|
||||||
|
return -1; /* this timeout is an error */
|
||||||
|
}
|
||||||
return 0; // timeout
|
return 0; // timeout
|
||||||
|
}
|
||||||
else if (rc < 0)
|
else if (rc < 0)
|
||||||
{
|
{
|
||||||
dmx_err("poll: %s,", strerror(errno), 0)
|
dmx_err("poll: %s,", strerror(errno), 0)
|
||||||
@@ -323,6 +337,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
|
|||||||
/* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */
|
/* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */
|
||||||
case 0x70: /* time_date_section */
|
case 0x70: /* time_date_section */
|
||||||
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
|
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
|
||||||
|
s_flt.flags |= DMX_ONESHOT;
|
||||||
//s_flt.pid = 0x0014;
|
//s_flt.pid = 0x0014;
|
||||||
to = 30000;
|
to = 30000;
|
||||||
break;
|
break;
|
||||||
@@ -335,6 +350,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
|
|||||||
to = 0;
|
to = 0;
|
||||||
break;
|
break;
|
||||||
case 0x73: /* time_offset_section */
|
case 0x73: /* time_offset_section */
|
||||||
|
s_flt.flags |= DMX_ONESHOT;
|
||||||
//s_flt.pid = 0x0014;
|
//s_flt.pid = 0x0014;
|
||||||
to = 30000;
|
to = 30000;
|
||||||
break;
|
break;
|
||||||
|
@@ -80,4 +80,4 @@ EVENT_MSG_EOS,
|
|||||||
EVENT_MSG_SUB_CHANGED,
|
EVENT_MSG_SUB_CHANGED,
|
||||||
};
|
};
|
||||||
|
|
||||||
int fd_cmd, fd_in, fd_out, fd_event, msg;
|
//int fd_cmd, fd_in, fd_out, fd_event, msg;
|
||||||
|
@@ -1,15 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* cPlayback implementation for azbox
|
||||||
|
* this is actually just a wrapper around rmfp_player which does
|
||||||
|
* all the heavy listing
|
||||||
|
*
|
||||||
|
* based on the original aztrino implementation, but almost
|
||||||
|
* completely rewritten since then
|
||||||
|
*
|
||||||
|
* some of the methods and constants were found by stracing the
|
||||||
|
* AZPlay enigma2 plugin...
|
||||||
|
*
|
||||||
|
* (C) 2012 Stefan Seyfried
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <pty.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#define FIFO_CMD "/tmp/rmfp.cmd"
|
#include "lt_debug.h"
|
||||||
#define FIFO_IN "/tmp/rmfp.in"
|
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PLAYBACK, this, args)
|
||||||
#define FIFO_OUT "/tmp/rmfp.out"
|
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_PLAYBACK, this, args)
|
||||||
#define FIFO_EVENT "/tmp/rmfp.event"
|
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_PLAYBACK, NULL, args)
|
||||||
|
|
||||||
|
#include <proc_tools.h>
|
||||||
|
|
||||||
|
/* the file-based commands work better than the FIFOs... */
|
||||||
|
#define CMD_FILE "/tmp/rmfp.cmd2"
|
||||||
|
#define IN_FILE "/tmp/rmfp.in2"
|
||||||
|
#define OUT_FILE "/tmp/rmfp.out2"
|
||||||
|
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
|
||||||
@@ -17,118 +56,167 @@ extern "C"{
|
|||||||
#include "e2mruainclude.h"
|
#include "e2mruainclude.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * FILENAME = "playback_cs.cpp";
|
#if 0
|
||||||
|
/* useful for debugging */
|
||||||
|
static time_t monotonic_ms(void)
|
||||||
void cPlayback::RuaThread()
|
|
||||||
{
|
{
|
||||||
printf("Starting RUA thread\n");
|
struct timespec t;
|
||||||
|
time_t ret;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &t))
|
||||||
|
{
|
||||||
|
perror("monotonic_ms clock_gettime");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = ((t.tv_sec + 604800)& 0x01FFFFF) * 1000; /* avoid overflow */
|
||||||
|
ret += t.tv_nsec / 1000000;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the mutex makes sure that commands are not interspersed */
|
||||||
|
bool cPlayback::rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen)
|
||||||
//Watch for the space at the end
|
|
||||||
std::string base = "/usr/bin/rmfp_player -dram 1 -ve 1 -waitexit ";
|
|
||||||
std::string filename(mfilename);
|
|
||||||
std::string file = '"' + filename + '"';
|
|
||||||
std::string final = base + file;
|
|
||||||
|
|
||||||
if ( setduration == 1 && mduration != 0)
|
|
||||||
{
|
{
|
||||||
mduration *= 60000;
|
lt_info("%s: %d %d %d %d\n", __func__, cmd, param, has_param, buflen);
|
||||||
|
bool ret = true;
|
||||||
|
int fd;
|
||||||
|
if (cmd == 222)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_trylock(&rmfp_cmd_mutex))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pthread_mutex_lock(&rmfp_cmd_mutex);
|
||||||
|
unlink(OUT_FILE);
|
||||||
|
if (has_param)
|
||||||
|
{
|
||||||
|
fd = open(IN_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||||
|
dprintf(fd, "%i", param);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
fd = open(CMD_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||||
|
dprintf(fd, "%i", cmd);
|
||||||
|
close(fd);
|
||||||
|
int n = 0, m = 0;
|
||||||
|
if (buflen > 0)
|
||||||
|
{
|
||||||
|
while ((fd = open(OUT_FILE, O_RDONLY)) == -1) {
|
||||||
|
if (++m > 500) { /* don't wait more than 5 seconds */
|
||||||
|
lt_info("%s: timed out waiting for %s (cmd %d par %d buflen %d\n",
|
||||||
|
__func__, OUT_FILE, cmd, param, buflen);
|
||||||
|
ret = false;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
unlink(OUT_FILE);
|
||||||
|
n = read(fd, buf, buflen);
|
||||||
|
close(fd);
|
||||||
|
/* some commands (CUSTOM_COMMAND_GET_AUDIO_BY_ID for example) actually
|
||||||
|
* return the answer in two successive writes, as we are not using the
|
||||||
|
* FIFO, we need to make sure that the file is deleted immediately, because
|
||||||
|
* rmfp_player will not overwrite it if it exists */
|
||||||
|
while ((fd = open(OUT_FILE, O_RDONLY)) == -1) {
|
||||||
|
if (++m > 10)
|
||||||
|
break;
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
if (fd > -1)
|
||||||
|
{
|
||||||
|
read(fd, buf + n, buflen - n);
|
||||||
|
unlink(OUT_FILE);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
buf[buflen - 1] = '0';
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
pthread_mutex_unlock(&rmfp_cmd_mutex);
|
||||||
|
if (cmd != 222) /* called tooo often :-) */
|
||||||
|
lt_info("%s: reply: '%s' ret: %d m:%d\n", __func__, buf?buf:"(none)", ret, m);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* runs the rmfp_player in a terminal
|
||||||
|
* just doing popen() or similar does not work because then
|
||||||
|
* the output will be buffered after starting up and we will only
|
||||||
|
* see "Playback has started..." after the player exits
|
||||||
|
*/
|
||||||
|
void cPlayback::run_rmfp()
|
||||||
|
{
|
||||||
|
lt_debug("%s: starting\n", __func__);
|
||||||
|
thread_started = true;
|
||||||
|
//Watch for the space at the end
|
||||||
|
std::string base = "rmfp_player -dram 1 -ve 1 -waitexit ";
|
||||||
|
std::string filename(mfilename);
|
||||||
|
std::string file = '"' + filename + '"';
|
||||||
|
std::string final = base + file;
|
||||||
|
|
||||||
|
if (playMode == PLAYMODE_TS && mduration != 0)
|
||||||
|
{
|
||||||
std::stringstream duration;
|
std::stringstream duration;
|
||||||
duration << mduration;
|
duration << (mduration /** 60000LL*/);
|
||||||
final = base + "-duration " + duration.str() + " " + file;
|
final = base + "-duration " + duration.str() + " " + file;
|
||||||
}
|
|
||||||
|
|
||||||
system(final.c_str());
|
|
||||||
|
|
||||||
printf("Terminating RUA thread\n");
|
|
||||||
thread_active = 0;
|
|
||||||
playing = false;
|
|
||||||
eof_reached = 1;
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* helper function to call the cpp thread loop */
|
|
||||||
void* execute_rua_thread(void *c)
|
|
||||||
{
|
|
||||||
cPlayback *obj=(cPlayback*)c;
|
|
||||||
|
|
||||||
printf("Executing RUA Thread\n");
|
|
||||||
|
|
||||||
obj->RuaThread();
|
|
||||||
|
|
||||||
free(obj);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cPlayback::EventThread()
|
|
||||||
{
|
|
||||||
|
|
||||||
printf("Starting Event thread\n");
|
|
||||||
|
|
||||||
thread_active = 1;
|
|
||||||
eof_reached = 0;
|
|
||||||
while (thread_active == 1)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
fd_set readfds;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
tv.tv_sec = 1;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
|
||||||
FD_SET(fd_event, &readfds);
|
|
||||||
retval = select(fd_event + 1, &readfds, NULL, NULL, &tv);
|
|
||||||
|
|
||||||
//printf("retval is %i\n", retval);
|
|
||||||
if (retval)
|
|
||||||
{
|
|
||||||
|
|
||||||
char eventstring[4];
|
|
||||||
int event;
|
|
||||||
|
|
||||||
read(fd_event, &eventstring, 3);
|
|
||||||
eventstring[3] = '\0';
|
|
||||||
event = atoi(eventstring);
|
|
||||||
|
|
||||||
printf("Got event message %i\n", event);
|
|
||||||
|
|
||||||
switch(event)
|
|
||||||
{
|
|
||||||
case EVENT_MSG_FDOPEN:
|
|
||||||
fd_cmd = open(FIFO_CMD, O_WRONLY);
|
|
||||||
fd_in = open(FIFO_IN, O_WRONLY);
|
|
||||||
printf("Message FD Opened %i", fd_in);
|
|
||||||
break;
|
|
||||||
case EVENT_MSG_PLAYBACK_STARTED:
|
|
||||||
printf("Got playing event \n");
|
|
||||||
playing = true;
|
|
||||||
break;
|
|
||||||
case EVENT_MSG_EOS:
|
|
||||||
printf("Got EOF event \n");
|
|
||||||
eof_reached = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usleep(100000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Terminating Event thread\n");
|
pid_t pid = 0;
|
||||||
playing = false;
|
int master;
|
||||||
|
pid = forkpty(&master, NULL, NULL, NULL);
|
||||||
|
if (! pid) {
|
||||||
|
execl("/bin/sh", "sh", "-c", final.c_str(), (char *)0);
|
||||||
|
lt_info("%s: execl returned: %m\n", __func__);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid > 0) {
|
||||||
|
char *output=NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
ssize_t len;
|
||||||
|
FILE *f = fdopen(master, "r");
|
||||||
|
while ((len = getline(&output, &n, f)) != -1)
|
||||||
|
{
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
if (!isspace(output[len]))
|
||||||
|
break;
|
||||||
|
output[len] = '\0';
|
||||||
|
}
|
||||||
|
lt_info("%s out: '%s'\n", __func__, output);
|
||||||
|
if (strstr(output, "Playback has started..."))
|
||||||
|
{
|
||||||
|
playing = 1;
|
||||||
|
lt_info("%s: ===================> playing = true\n", __func__);
|
||||||
|
}
|
||||||
|
else if (strstr(output, "End of file..."))
|
||||||
|
{
|
||||||
|
playing = 1; /* this can happen without "Playback has started..." */
|
||||||
|
eof_reached = true;
|
||||||
|
lt_info("%s: ===================> eof_reached = true\n", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
int s;
|
||||||
|
while (waitpid(pid, &s, WNOHANG) > 0) {};
|
||||||
|
if (output)
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
lt_info("%s: terminating\n", __func__);
|
||||||
|
if (playing == 0) /* playback did not start */
|
||||||
|
playing = 2;
|
||||||
|
else
|
||||||
|
playing = 0;
|
||||||
|
eof_reached = true;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helper function to call the cpp thread loop */
|
/* helper function to call the cpp thread loop */
|
||||||
void* execute_event_thread(void *c)
|
void *execute_rua_thread(void *c)
|
||||||
{
|
{
|
||||||
cPlayback *obj=(cPlayback*)c;
|
cPlayback *obj = (cPlayback *)c;
|
||||||
|
lt_info_c("%s\n", __func__);
|
||||||
printf("Executing RUA Thread\n");
|
obj->run_rmfp();
|
||||||
|
/* free(obj); // this is most likely wrong */
|
||||||
obj->EventThread();
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -136,364 +224,290 @@ void* execute_event_thread(void *c)
|
|||||||
//Used by Fileplay
|
//Used by Fileplay
|
||||||
bool cPlayback::Open(playmode_t PlayMode)
|
bool cPlayback::Open(playmode_t PlayMode)
|
||||||
{
|
{
|
||||||
const char *aPLAYMODE[] = {
|
static const char *aPLAYMODE[] = {
|
||||||
"PLAYMODE_TS",
|
"PLAYMODE_TS",
|
||||||
"PLAYMODE_FILE"
|
"PLAYMODE_FILE"
|
||||||
};
|
};
|
||||||
|
playMode = PlayMode;
|
||||||
setduration = 0;
|
if (playMode > 1)
|
||||||
if (PlayMode == 0)
|
|
||||||
{
|
{
|
||||||
printf("RECORDING PLAYING BACK\n");
|
lt_info("%s: PlayMode %d out of range!\n", __func__, PlayMode);
|
||||||
setduration = 1;
|
playMode = PLAYMODE_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s:%s - PlayMode=%s\n", FILENAME, __FUNCTION__, aPLAYMODE[PlayMode]);
|
lt_info("%s: mode %d (%s)\n", __func__, PlayMode, aPLAYMODE[PlayMode]);
|
||||||
|
#if 0
|
||||||
|
while (access("/tmp/continue", R_OK))
|
||||||
|
sleep(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
//Making Fifo's for message pipes
|
char c[2] = "0";
|
||||||
mknod(FIFO_CMD, S_IFIFO | 0666, 0);
|
int i = 0;
|
||||||
mknod(FIFO_IN, S_IFIFO | 0666, 0);
|
|
||||||
mknod(FIFO_OUT, S_IFIFO | 0666, 0);
|
|
||||||
mknod(FIFO_EVENT, S_IFIFO | 0666, 0);
|
|
||||||
|
|
||||||
//Open pipes we read from. The fd_in pipe will be created once test_rmfp has been started
|
for(;;)
|
||||||
fd_out = open(FIFO_OUT, O_RDONLY | O_NONBLOCK);
|
{
|
||||||
fd_event = open(FIFO_EVENT, O_RDONLY | O_NONBLOCK);
|
proc_get("/proc/player", c, 2);
|
||||||
|
if (c[0] != '0')
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
if (i > 10)
|
||||||
|
{
|
||||||
|
lt_info("%s: ERROR - player is not idle after 10 seconds!\n", __func__);
|
||||||
|
open_success = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc_put("/proc/player", "2", 2);
|
||||||
|
lt_info("%s: /proc/player switched to '2'\n", __func__);
|
||||||
|
|
||||||
|
unlink(CMD_FILE);
|
||||||
|
unlink(IN_FILE);
|
||||||
|
unlink(OUT_FILE);
|
||||||
|
|
||||||
|
open_success = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Used by Fileplay
|
//Used by Fileplay
|
||||||
void cPlayback::Close(void)
|
bool cPlayback::Start(char *filename, unsigned short vpid, int vtype, unsigned short _apid,
|
||||||
{
|
int ac3, unsigned int duration)
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
|
||||||
|
|
||||||
//Dagobert: movieplayer does not call stop, it calls close ;)
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Used by Fileplay
|
|
||||||
bool cPlayback::Start(char * filename, unsigned short vpid, int vtype, unsigned short apid, bool ac3, int duration)
|
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
printf("%s:%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d duration=%i\n",
|
lt_info("%s: filename=%s\n", __func__, filename);
|
||||||
FILENAME, __FUNCTION__, filename, vpid, vtype, apid, ac3, duration);
|
lt_info("%s: vpid=%u vtype=%d apid=%u ac3=%d duration=%i open_success=%d\n",
|
||||||
|
__func__, vpid, vtype, _apid, ac3, duration, open_success);
|
||||||
|
|
||||||
|
if (!open_success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
eof_reached = false;
|
||||||
//create playback path
|
//create playback path
|
||||||
mAudioStream=0;
|
apid = 0;
|
||||||
|
subpid = 0;
|
||||||
mfilename = filename;
|
mfilename = filename;
|
||||||
mduration = duration;
|
mduration = duration;
|
||||||
if (pthread_create(&rua_thread, 0, execute_rua_thread, this) != 0)
|
if (pthread_create(&thread, 0, execute_rua_thread, this) != 0)
|
||||||
{
|
{
|
||||||
printf("[movieplayer]: error creating file_thread! (out of memory?)\n");
|
lt_info("%s: error creating rmfp_player thread! (out of memory?)\n", __func__);
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
if (pthread_create(&event_thread, 0, execute_event_thread, this) != 0)
|
while (! playing)
|
||||||
{
|
sleep(1);
|
||||||
printf("[movieplayer]: error creating file_thread! (out of memory?)\n");
|
if (playing == 2)
|
||||||
ret = false;
|
playing = 0;
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Used by Fileplay
|
void cPlayback::Close(void)
|
||||||
bool cPlayback::Stop(void)
|
|
||||||
{
|
{
|
||||||
printf("%s:%s playing %d %d\n", FILENAME, __FUNCTION__, playing, thread_active);
|
lt_info("%s: playing %d thread_started %d\n", __func__, playing, thread_started);
|
||||||
if(playing==false && thread_active == 0) return false;
|
|
||||||
|
|
||||||
msg = KEY_COMMAND_QUIT_ALL;
|
if (thread_started)
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
|
|
||||||
if (pthread_join(rua_thread, NULL))
|
|
||||||
{
|
{
|
||||||
printf("error joining rua thread\n");
|
rmfp_command(KEY_COMMAND_QUIT_ALL, 0, false, NULL, 0);
|
||||||
}
|
|
||||||
|
|
||||||
if (pthread_join(event_thread, NULL))
|
if (pthread_join(thread, NULL))
|
||||||
|
lt_info("%s: error joining rmfp thread (%m)\n", __func__);
|
||||||
|
playing = 0;
|
||||||
|
thread_started = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lt_info("%s: Warning: thread_started == false!\n", __func__);
|
||||||
|
|
||||||
|
if (open_success)
|
||||||
{
|
{
|
||||||
printf("error joining event thread\n");
|
proc_put("/proc/player", "1", 2);
|
||||||
|
open_success = false;
|
||||||
|
lt_info("%s: /proc/player switched to '1'\n", __func__);
|
||||||
|
usleep(1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
playing = false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPlayback::SetAPid(unsigned short pid, bool /*ac3*/)
|
bool cPlayback::SetAPid(unsigned short pid, int /*ac3*/)
|
||||||
{
|
{
|
||||||
printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid);
|
lt_info("%s: pid %i\n", __func__, pid);
|
||||||
if (pid != mAudioStream) {
|
if (pid != apid) {
|
||||||
msg = KEY_COMMAND_SWITCH_AUDIO;
|
rmfp_command(KEY_COMMAND_SWITCH_AUDIO, pid, true, NULL, 0);
|
||||||
dprintf(fd_cmd, "%i", msg);
|
apid = pid;
|
||||||
dprintf(fd_in, "%i", pid);
|
|
||||||
mAudioStream = pid;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPlayback::SetSPid(int pid)
|
bool cPlayback::SetSPid(int pid)
|
||||||
{
|
{
|
||||||
printf("%s:%s pid %i\n", FILENAME, __FUNCTION__, pid);
|
lt_info("%s: pid %i\n", __func__, pid);
|
||||||
if(pid!=mSubStream)
|
if (pid != subpid)
|
||||||
{
|
{
|
||||||
msg = KEY_COMMAND_SWITCH_SUBS;
|
rmfp_command(KEY_COMMAND_SWITCH_SUBS, pid, true, NULL, 0);
|
||||||
dprintf(fd_cmd, "%i", msg);
|
subpid = pid;
|
||||||
dprintf(fd_in, "%i", pid);
|
|
||||||
mSubStream=pid;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPlayback::SetSpeed(int speed)
|
bool cPlayback::SetSpeed(int speed)
|
||||||
{
|
{
|
||||||
printf("%s:%s playing %d speed %d\n", FILENAME, __FUNCTION__, playing, speed);
|
lt_info("%s: playing %d speed %d\n", __func__, playing, speed);
|
||||||
|
|
||||||
if(playing==false)
|
if (!playing)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// int result = 0;
|
playback_speed = speed;
|
||||||
|
|
||||||
nPlaybackSpeed = speed;
|
|
||||||
|
|
||||||
if (speed > 1 || speed < 0)
|
if (speed > 1 || speed < 0)
|
||||||
{
|
rmfp_command(CUSTOM_COMMAND_TRICK_SEEK, speed, true, NULL, 0);
|
||||||
msg = CUSTOM_COMMAND_TRICK_SEEK;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
dprintf(fd_in, "%i", speed);
|
|
||||||
}
|
|
||||||
else if (speed == 0)
|
else if (speed == 0)
|
||||||
{
|
rmfp_command(KEY_COMMAND_PAUSE, 0, false, NULL, 0);
|
||||||
msg = KEY_COMMAND_PAUSE;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
rmfp_command(KEY_COMMAND_PLAY, 0, false, NULL, 0);
|
||||||
msg = KEY_COMMAND_PLAY;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (result != 0)
|
|
||||||
// {
|
|
||||||
// printf("returning false\n");
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPlayback::GetSpeed(int &/*speed*/) const
|
bool cPlayback::GetSpeed(int &/*speed*/) const
|
||||||
{
|
{
|
||||||
/* printf("%s:%s\n", FILENAME, __FUNCTION__);
|
#if 0
|
||||||
speed = nPlaybackSpeed;
|
lt_info("%s:\n", __func__);
|
||||||
*/ return true;
|
speed = playback_speed;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in milliseconds
|
// in milliseconds
|
||||||
bool cPlayback::GetPosition(int &position, int &duration)
|
bool cPlayback::GetPosition(int &position, int &duration)
|
||||||
{
|
{
|
||||||
printf("%s:%s %d %d\n", FILENAME, __FUNCTION__, position, duration);
|
lt_debug("%s: playing %d\n", __func__, playing);
|
||||||
|
|
||||||
//Azbox eof
|
if (eof_reached)
|
||||||
if (eof_reached == 1)
|
|
||||||
{
|
{
|
||||||
position = -5;
|
position = mduration;
|
||||||
duration = -5;
|
duration = mduration;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(playing==false) return false;
|
if (!playing)
|
||||||
|
return false;
|
||||||
|
|
||||||
//Position
|
char buf[32];
|
||||||
char timestring[11];
|
/* custom command 222 returns "12345\n1234\n",
|
||||||
|
* first line is duration, second line is position */
|
||||||
|
if (! rmfp_command(222, 0, false, buf, 32))
|
||||||
|
return false;
|
||||||
|
duration = atoi(buf);
|
||||||
|
char *p = strchr(buf, '\n');
|
||||||
|
if (!p)
|
||||||
|
return false;
|
||||||
|
position = atoi(++p);
|
||||||
|
/* some mpegs return length 0... which would lead to "eof" after 10 seconds */
|
||||||
|
if (duration == 0)
|
||||||
|
duration = position + 1000;
|
||||||
|
|
||||||
msg = CUSTOM_COMMAND_GETPOSITION;
|
if (playMode == PLAYMODE_TS)
|
||||||
dprintf(fd_cmd, "%i", msg);
|
{
|
||||||
|
if (position > mduration)
|
||||||
int n = 0;
|
mduration = position + 1000;
|
||||||
while ( n <= 0 ) {
|
duration = mduration;
|
||||||
n = read(fd_out, ×tring, 100);
|
return true;
|
||||||
}
|
}
|
||||||
timestring[10] = '\0';
|
|
||||||
position = atoi(timestring);
|
|
||||||
|
|
||||||
//Duration
|
|
||||||
int length;
|
|
||||||
char durationstring[11];
|
|
||||||
|
|
||||||
msg = CUSTOM_COMMAND_GETLENGTH;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while ( n <= 0 ) {
|
|
||||||
n = read(fd_out, &durationstring, 10);
|
|
||||||
}
|
|
||||||
durationstring[10] = '\0';
|
|
||||||
length = atoi(durationstring);
|
|
||||||
|
|
||||||
if(length <= 0) {
|
|
||||||
duration = duration+1000;
|
|
||||||
} else {
|
|
||||||
duration = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPlayback::SetPosition(int position, bool absolute)
|
bool cPlayback::SetPosition(int position, bool absolute)
|
||||||
{
|
{
|
||||||
printf("%s:%s %d\n", FILENAME, __FUNCTION__,position);
|
lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, playing);
|
||||||
if(playing==false) return false;
|
|
||||||
|
|
||||||
int seconds;
|
if (!playing)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (absolute == true)
|
int seconds = position / 1000;;
|
||||||
|
|
||||||
|
if (absolute)
|
||||||
{
|
{
|
||||||
msg = KEY_COMMAND_SEEK_TO_TIME;
|
rmfp_command(KEY_COMMAND_SEEK_TO_TIME, seconds, true, NULL, 0);
|
||||||
seconds = position / 1000;
|
return true;
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
dprintf(fd_in, "%i", seconds);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (position > 0 )
|
|
||||||
{
|
|
||||||
msg = CUSTOM_COMMAND_SEEK_RELATIVE_FWD;
|
|
||||||
seconds = position / 1000;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
dprintf(fd_in, "%i", seconds);
|
|
||||||
}
|
|
||||||
else if ( position < 0 )
|
|
||||||
{
|
|
||||||
msg = CUSTOM_COMMAND_SEEK_RELATIVE_BWD;
|
|
||||||
seconds = position / 1000;
|
|
||||||
seconds *= -1;
|
|
||||||
printf("sending seconds %i\n", seconds);
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
dprintf(fd_in, "%i", seconds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (position > 0)
|
||||||
|
rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_FWD, seconds, true, NULL, 0);
|
||||||
|
else if (position < 0)
|
||||||
|
rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_BWD, seconds, true, NULL, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language)
|
void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language)
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
lt_info("%s\n", __func__);
|
||||||
|
char buf[32];
|
||||||
unsigned int audio_count = 0;
|
rmfp_command(CUSTOM_COMMAND_AUDIO_COUNT, 0, false, buf, 3);
|
||||||
char audio_countstring[3];
|
unsigned int audio_count = atoi(buf);
|
||||||
|
|
||||||
msg = CUSTOM_COMMAND_AUDIO_COUNT;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
while ( n <= 0 ) {
|
|
||||||
n = read(fd_out, &audio_countstring, 2);
|
|
||||||
}
|
|
||||||
audio_countstring[2] = '\0';
|
|
||||||
audio_count = atoi(audio_countstring);
|
|
||||||
|
|
||||||
*numpida = audio_count;
|
*numpida = audio_count;
|
||||||
if (audio_count > 0 )
|
if (audio_count > 0)
|
||||||
{
|
{
|
||||||
for ( unsigned int audio_id = 0; audio_id < audio_count; audio_id++ )
|
for (unsigned int aid = 0; aid < audio_count; aid++)
|
||||||
{
|
{
|
||||||
char streamidstring[11];
|
char streamidstring[11];
|
||||||
char audio_lang[21];
|
char audio_lang[21];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
msg = CUSTOM_COMMAND_GET_AUDIO_BY_ID;
|
rmfp_command(CUSTOM_COMMAND_GET_AUDIO_BY_ID, aid, true, buf, 32);
|
||||||
dprintf(fd_cmd, "%i", msg);
|
memcpy(streamidstring, buf, 10);
|
||||||
dprintf(fd_in, "%i", audio_id);
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while ( n <= 0 ) {
|
|
||||||
n = read(fd_out, &streamidstring, 10);
|
|
||||||
}
|
|
||||||
read(fd_out, &audio_lang, 20);
|
|
||||||
streamidstring[10] = '\0';
|
streamidstring[10] = '\0';
|
||||||
|
memcpy(audio_lang, buf + 10, 20);
|
||||||
audio_lang[20] = '\0';
|
audio_lang[20] = '\0';
|
||||||
|
apids[aid] = atoi(streamidstring);
|
||||||
apids[audio_id] = atoi(streamidstring);
|
ac3flags[aid] = 0;
|
||||||
ac3flags[audio_id] = 0;
|
language[aid] = audio_lang;
|
||||||
language[audio_id] = audio_lang;
|
lt_info("%s: #%d apid:%d lang: %s\n", __func__, aid, apids[aid], audio_lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *language)
|
void cPlayback::FindAllSPids(int *spids, uint16_t *numpids, std::string *language)
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
lt_info("%s\n", __func__);
|
||||||
|
char buf[32];
|
||||||
unsigned int spu_count = 0;
|
|
||||||
char spu_countstring[3];
|
|
||||||
|
|
||||||
msg = CUSTOM_COMMAND_SUBS_COUNT;
|
|
||||||
dprintf(fd_cmd, "%i", msg);
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
while ( n <= 0 ) {
|
|
||||||
n = read(fd_out, &spu_countstring, 2);
|
|
||||||
}
|
|
||||||
spu_countstring[2] = '\0';
|
|
||||||
spu_count = atoi(spu_countstring);
|
|
||||||
|
|
||||||
|
rmfp_command(CUSTOM_COMMAND_SUBS_COUNT, 0, false, buf, 3);
|
||||||
|
unsigned int spu_count = atoi(buf);
|
||||||
*numpids = spu_count;
|
*numpids = spu_count;
|
||||||
|
|
||||||
if (spu_count > 0 )
|
if (spu_count > 0)
|
||||||
{
|
{
|
||||||
|
for (unsigned int sid = 0; sid < spu_count; sid++)
|
||||||
for ( unsigned int spu_id = 0; spu_id < spu_count; spu_id++ )
|
|
||||||
{
|
{
|
||||||
//int streamid;
|
|
||||||
char streamidstring[11];
|
char streamidstring[11];
|
||||||
char spu_lang[21];
|
char spu_lang[21];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
msg = CUSTOM_COMMAND_GET_SUB_BY_ID;
|
rmfp_command(CUSTOM_COMMAND_GET_SUB_BY_ID, sid, true, buf, 32);
|
||||||
dprintf(fd_cmd, "%i", msg);
|
memcpy(streamidstring, buf, 10);
|
||||||
dprintf(fd_in, "%i", spu_id);
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while ( n <= 0 ) {
|
|
||||||
n = read(fd_out, &streamidstring, 10);
|
|
||||||
}
|
|
||||||
read(fd_out, &spu_lang, 20);
|
|
||||||
streamidstring[10] = '\0';
|
streamidstring[10] = '\0';
|
||||||
|
memcpy(spu_lang, buf + 10, 20);
|
||||||
spu_lang[20] = '\0';
|
spu_lang[20] = '\0';
|
||||||
|
spids[sid] = atoi(streamidstring);
|
||||||
spids[spu_id] = atoi(streamidstring);
|
language[sid] = spu_lang;
|
||||||
language[spu_id] = spu_lang;
|
lt_info("%s: #%d apid:%d lang: %s\n", __func__, sid, spids[sid], spu_lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Add streamid -1 to be able to disable subtitles
|
//Add streamid -1 to be able to disable subtitles
|
||||||
*numpids = spu_count + 1;
|
*numpids = spu_count + 1;
|
||||||
spids[spu_count] = -1;
|
spids[spu_count] = -1;
|
||||||
language[spu_count] = "Disable";
|
language[spu_count] = "Disable";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cPlayback::cPlayback(int /*num*/)
|
cPlayback::cPlayback(int /*num*/)
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
lt_info("%s: constructor\n", __func__);
|
||||||
playing=false;
|
playing = 0;
|
||||||
thread_active = 0;
|
thread_started = false;
|
||||||
eof_reached=0;
|
eof_reached = false;
|
||||||
|
open_success = false;
|
||||||
|
pthread_mutex_init(&rmfp_cmd_mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
cPlayback::~cPlayback()
|
cPlayback::~cPlayback()
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
lt_info("%s\n", __func__);
|
||||||
}
|
pthread_mutex_destroy(&rmfp_cmd_mutex);
|
||||||
|
|
||||||
bool cPlayback::IsEOF(void) const
|
|
||||||
{
|
|
||||||
// printf("%s:%s\n", FILENAME, __FUNCTION__);
|
|
||||||
return eof_reached;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cPlayback::GetCurrPlaybackSpeed(void) const
|
|
||||||
{
|
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
|
||||||
return nPlaybackSpeed;
|
|
||||||
}
|
}
|
||||||
|
@@ -4,12 +4,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef CS_PLAYBACK_PDATA
|
|
||||||
typedef struct {
|
|
||||||
int nothing;
|
|
||||||
} CS_PLAYBACK_PDATA;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PLAYMODE_TS = 0,
|
PLAYMODE_TS = 0,
|
||||||
PLAYMODE_FILE,
|
PLAYMODE_FILE,
|
||||||
@@ -18,63 +12,50 @@ typedef enum {
|
|||||||
class cPlayback
|
class cPlayback
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int timeout;
|
pthread_mutex_t rmfp_cmd_mutex;
|
||||||
pthread_cond_t read_cond;
|
int playing;
|
||||||
pthread_mutex_t mutex;
|
bool eof_reached;
|
||||||
CS_PLAYBACK_PDATA * privateData;
|
int playback_speed;
|
||||||
|
|
||||||
pthread_t rua_thread;
|
|
||||||
pthread_t event_thread;
|
|
||||||
|
|
||||||
bool enabled;
|
|
||||||
bool paused;
|
|
||||||
bool playing;
|
|
||||||
int unit;
|
|
||||||
int nPlaybackFD;
|
|
||||||
int video_type;
|
|
||||||
int nPlaybackSpeed;
|
|
||||||
int mSpeed;
|
|
||||||
int mAudioStream;
|
|
||||||
int mSubStream;
|
|
||||||
char* mfilename;
|
|
||||||
int thread_active;
|
|
||||||
int eof_reached;
|
|
||||||
int setduration;
|
|
||||||
int mduration;
|
|
||||||
|
|
||||||
playmode_t playMode;
|
playmode_t playMode;
|
||||||
//
|
bool open_success;
|
||||||
|
uint16_t apid;
|
||||||
|
uint16_t subpid;
|
||||||
|
char *mfilename;
|
||||||
|
int mduration;
|
||||||
|
pthread_t thread;
|
||||||
|
bool thread_started;
|
||||||
|
/* private functions */
|
||||||
|
bool rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen);
|
||||||
public:
|
public:
|
||||||
bool Open(playmode_t PlayMode);
|
|
||||||
void Close(void);
|
|
||||||
bool Start(char * filename, unsigned short vpid, int vtype, unsigned short apid, bool ac3, int duration);
|
|
||||||
bool Stop(void);
|
|
||||||
bool SetAPid(unsigned short pid, bool ac3);
|
|
||||||
bool SetSPid(int pid);
|
|
||||||
bool SetSpeed(int speed);
|
|
||||||
bool GetSpeed(int &speed) const;
|
|
||||||
bool GetPosition(int &position, int &duration);
|
|
||||||
bool SetPosition(int position, bool absolute = false);
|
|
||||||
bool IsEOF(void) const;
|
|
||||||
int GetCurrPlaybackSpeed(void) const;
|
|
||||||
void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language);
|
|
||||||
void FindAllSPids(int *spids, uint16_t *numpids, std::string *language);
|
|
||||||
//
|
|
||||||
cPlayback(int num = 0);
|
cPlayback(int num = 0);
|
||||||
~cPlayback();
|
~cPlayback();
|
||||||
void RuaThread();
|
|
||||||
void EventThread();
|
|
||||||
|
|
||||||
|
void run_rmfp();
|
||||||
|
|
||||||
|
bool Open(playmode_t PlayMode);
|
||||||
|
void Close(void);
|
||||||
|
bool Start(char *filename, unsigned short vpid, int vtype, unsigned short apid,
|
||||||
|
int ac3, unsigned int duration);
|
||||||
|
bool SetAPid(unsigned short pid, int ac3);
|
||||||
|
bool SetSpeed(int speed);
|
||||||
|
bool GetSpeed(int &speed) const;
|
||||||
|
bool GetPosition(int &position, int &duration); /* pos: current time in ms, dur: file length in ms */
|
||||||
|
bool SetPosition(int position, bool absolute = false); /* position: jump in ms */
|
||||||
|
void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language);
|
||||||
|
// AZbox specific
|
||||||
|
void FindAllSPids(int *spids, uint16_t *numpids, std::string *language);
|
||||||
|
bool SetSPid(int pid);
|
||||||
#if 0
|
#if 0
|
||||||
/* not used */
|
// Functions that are not used by movieplayer.cpp:
|
||||||
|
bool Stop(void);
|
||||||
bool GetOffset(off64_t &offset);
|
bool GetOffset(off64_t &offset);
|
||||||
void PlaybackNotify (int Event, void *pData, void *pTag);
|
bool IsPlaying(void) const { return playing; }
|
||||||
void DMNotify(int Event, void *pTsBuf, void *Tag);
|
bool IsEnabled(void) const { return enabled; }
|
||||||
bool IsPlaying(void) const;
|
|
||||||
bool IsEnabled(void) const;
|
|
||||||
void * GetHandle(void);
|
void * GetHandle(void);
|
||||||
void * GetDmHandle(void);
|
void * GetDmHandle(void);
|
||||||
|
int GetCurrPlaybackSpeed(void) const { return nPlaybackSpeed; }
|
||||||
|
void PlaybackNotify (int Event, void *pData, void *pTag);
|
||||||
|
void DMNotify(int Event, void *pTsBuf, void *Tag);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -60,7 +60,6 @@
|
|||||||
cVideo * videoDecoder = NULL;
|
cVideo * videoDecoder = NULL;
|
||||||
int system_rev = 0;
|
int system_rev = 0;
|
||||||
|
|
||||||
static bool hdmi_enabled = true;
|
|
||||||
static bool stillpicture = false;
|
static bool stillpicture = false;
|
||||||
static unsigned char *blank_data;
|
static unsigned char *blank_data;
|
||||||
static ssize_t blank_size;
|
static ssize_t blank_size;
|
||||||
@@ -425,20 +424,11 @@ void cVideo::Standby(unsigned int bOn)
|
|||||||
if (bOn)
|
if (bOn)
|
||||||
{
|
{
|
||||||
closeDevice();
|
closeDevice();
|
||||||
//hdmi_out(false);
|
proc_put("/proc/stb/avs/0/input", "aux", 4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* only enable HDMI output when coming from standby, not on
|
proc_put("/proc/stb/avs/0/input", "encoder", 8);
|
||||||
* start. I have no idea why, but enabling it on startup leads
|
|
||||||
* to strange locking problems of the framebuffer driver :-( */
|
|
||||||
if (!hdmi_enabled)
|
|
||||||
{
|
|
||||||
//hdmi_out(true);
|
|
||||||
/* make sure the driver has time to settle.
|
|
||||||
* again - lame, but makes it work... */
|
|
||||||
//sleep(1);
|
|
||||||
}
|
|
||||||
openDevice();
|
openDevice();
|
||||||
}
|
}
|
||||||
video_standby = bOn;
|
video_standby = bOn;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
noinst_LIBRARIES = libcommon.a
|
noinst_LTLIBRARIES = libcommon.la
|
||||||
|
|
||||||
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
||||||
|
|
||||||
libcommon_a_SOURCES = \
|
libcommon_la_SOURCES = \
|
||||||
ca.cpp \
|
ca.cpp \
|
||||||
lt_debug.cpp \
|
lt_debug.cpp \
|
||||||
proc_tools.c
|
proc_tools.c
|
||||||
|
@@ -11,6 +11,16 @@
|
|||||||
#define TRIPLE_DEBUG_RECORD 7
|
#define TRIPLE_DEBUG_RECORD 7
|
||||||
#define TRIPLE_DEBUG_ALL ((1<<8)-1)
|
#define TRIPLE_DEBUG_ALL ((1<<8)-1)
|
||||||
|
|
||||||
|
#define HAL_DEBUG_AUDIO 0
|
||||||
|
#define HAL_DEBUG_VIDEO 1
|
||||||
|
#define HAL_DEBUG_DEMUX 2
|
||||||
|
#define HAL_DEBUG_PLAYBACK 3
|
||||||
|
#define HAL_DEBUG_PWRMNGR 4
|
||||||
|
#define HAL_DEBUG_INIT 5
|
||||||
|
#define HAL_DEBUG_CA 6
|
||||||
|
#define HAL_DEBUG_RECORD 7
|
||||||
|
#define HAL_DEBUG_ALL ((1<<8)-1)
|
||||||
|
|
||||||
extern int debuglevel;
|
extern int debuglevel;
|
||||||
|
|
||||||
void _lt_debug(int facility, const void *, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
void _lt_debug(int facility, const void *, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
||||||
|
@@ -2,6 +2,10 @@ AC_INIT(libstb-hal,0.1.1)
|
|||||||
AM_INIT_AUTOMAKE(libstb-hal,0.1.1)
|
AM_INIT_AUTOMAKE(libstb-hal,0.1.1)
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
LT_INIT
|
||||||
|
|
||||||
|
## ugly, disables shared library build (not wanted yet)
|
||||||
|
enable_shared=no
|
||||||
|
|
||||||
TUXBOX_APPS
|
TUXBOX_APPS
|
||||||
TUXBOX_APPS_DIRECTORY
|
TUXBOX_APPS_DIRECTORY
|
||||||
|
@@ -1,13 +1,12 @@
|
|||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
# this library is not used for linking, so call it libdummy...
|
noinst_LTLIBRARIES = libgeneric.la
|
||||||
noinst_LIBRARIES = libdummy.a
|
|
||||||
|
|
||||||
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
||||||
AM_LDFLAGS = -lpthread
|
AM_LDFLAGS = -lpthread
|
||||||
|
|
||||||
libdummy_a_SOURCES = \
|
libgeneric_la_SOURCES = \
|
||||||
hardware_caps.c \
|
hardware_caps.c \
|
||||||
dmx.cpp \
|
dmx.cpp \
|
||||||
video.cpp \
|
video.cpp \
|
||||||
|
@@ -10,3 +10,7 @@
|
|||||||
#else
|
#else
|
||||||
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
|
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if STB_HAL_VIDEO_HAS_GETSCREENIMAGE
|
||||||
|
#define SCREENSHOT 1
|
||||||
|
#endif
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
noinst_LIBRARIES = libeplayer3.a
|
noinst_LTLIBRARIES = libeplayer3.la
|
||||||
|
|
||||||
CXXFLAGS = -Wall
|
CXXFLAGS = -Wall
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(srcdir)/include
|
-I$(srcdir)/include
|
||||||
|
|
||||||
libeplayer3_a_SOURCES = \
|
libeplayer3_la_SOURCES = \
|
||||||
container/container.c container/container_ffmpeg.c container/text_srt.c \
|
container/container.c container/container_ffmpeg.c container/text_srt.c \
|
||||||
container/text_ssa.c container/container_ass.c \
|
container/text_ssa.c container/container_ass.c \
|
||||||
manager/audio.c manager/manager.c manager/subtitle.c manager/video.c \
|
manager/audio.c manager/manager.c manager/subtitle.c manager/video.c \
|
||||||
@@ -29,7 +29,7 @@ AM_CPPFLAGS = -Dattribute_deprecated=''
|
|||||||
|
|
||||||
#libeplayer3_la_LIBADD = -lpthread -lavformat -lavcodec -lavutil -lz -lass -lm -lpng
|
#libeplayer3_la_LIBADD = -lpthread -lavformat -lavcodec -lavutil -lz -lass -lm -lpng
|
||||||
|
|
||||||
LIBEPLAYER3_LIBS = libeplayer3.a -lpthread -lavformat -lavcodec -lavutil -lz -lass -lm -lpng
|
LIBEPLAYER3_LIBS = libeplayer3.la -lpthread -lavformat -lavcodec -lavutil -lz -lass -lm -lpng
|
||||||
bin_PROGRAMS = eplayer3 meta
|
bin_PROGRAMS = eplayer3 meta
|
||||||
eplayer3_SOURCES = tools/eplayer2.c
|
eplayer3_SOURCES = tools/eplayer2.c
|
||||||
eplayer3_LDADD = $(LIBEPLAYER3_LIBS)
|
eplayer3_LDADD = $(LIBEPLAYER3_LIBS)
|
||||||
|
@@ -2,12 +2,12 @@ INCLUDES = \
|
|||||||
-I$(top_srcdir)/common \
|
-I$(top_srcdir)/common \
|
||||||
-I$(top_srcdir)/libeplayer3/include
|
-I$(top_srcdir)/libeplayer3/include
|
||||||
|
|
||||||
noinst_LIBRARIES = libspark.a
|
noinst_LTLIBRARIES = libspark.la
|
||||||
|
|
||||||
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
||||||
AM_LDFLAGS = -lpthread -lasound
|
AM_LDFLAGS = -lpthread -lasound
|
||||||
|
|
||||||
libspark_a_SOURCES = \
|
libspark_la_SOURCES = \
|
||||||
irmp.c \
|
irmp.c \
|
||||||
hardware_caps.c \
|
hardware_caps.c \
|
||||||
lirmp_input.cpp \
|
lirmp_input.cpp \
|
||||||
|
@@ -115,7 +115,7 @@ static int hdmi_out(bool enable)
|
|||||||
int fb = open("/dev/fb0", O_RDWR);
|
int fb = open("/dev/fb0", O_RDWR);
|
||||||
if (fb < 0)
|
if (fb < 0)
|
||||||
{
|
{
|
||||||
lt_debug_c("%s: can't open /dev/fb/0 (%m)\n", __func__);
|
lt_debug_c("%s: can't open /dev/fb0 (%m)\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
out.outputid = STMFBIO_OUTPUTID_MAIN;
|
out.outputid = STMFBIO_OUTPUTID_MAIN;
|
||||||
|
@@ -2,11 +2,11 @@ INCLUDES = \
|
|||||||
-I$(top_srcdir)/common \
|
-I$(top_srcdir)/common \
|
||||||
@DIRECTFB_CFLAGS@
|
@DIRECTFB_CFLAGS@
|
||||||
|
|
||||||
noinst_LIBRARIES = libtriple.a
|
noinst_LTLIBRARIES = libtriple.la
|
||||||
|
|
||||||
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
|
||||||
|
|
||||||
libtriple_a_SOURCES = \
|
libtriple_la_SOURCES = \
|
||||||
hardware_caps.c \
|
hardware_caps.c \
|
||||||
lt_dfbinput.cpp \
|
lt_dfbinput.cpp \
|
||||||
dmx_td.cpp \
|
dmx_td.cpp \
|
||||||
|
@@ -91,13 +91,14 @@ cDemux::~cDemux()
|
|||||||
|
|
||||||
bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize)
|
bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize)
|
||||||
{
|
{
|
||||||
int devnum = num;
|
devnum = num;
|
||||||
int flags = O_RDWR;
|
int flags = O_RDWR;
|
||||||
if (fd > -1)
|
if (fd > -1)
|
||||||
lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd);
|
lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd);
|
||||||
if (pes_type == DMX_TP_CHANNEL)
|
if (pes_type == DMX_TP_CHANNEL)
|
||||||
{
|
{
|
||||||
if (num == 0) /* streaminfo measurement, let's cheat... */
|
/* see neutrino's src/gui/streaminfo2.cpp for the buffer size */
|
||||||
|
if (num == 0 && uBufferSize == 3 * 3008 * 62) /* streaminfo measurement, let's cheat... */
|
||||||
{
|
{
|
||||||
lt_info("%s num=0 and DMX_TP_CHANNEL => measurement demux\n", __func__);
|
lt_info("%s num=0 and DMX_TP_CHANNEL => measurement demux\n", __func__);
|
||||||
devnum = 2; /* demux 0 is used for live, demux 1 for recording */
|
devnum = 2; /* demux 0 is used for live, demux 1 for recording */
|
||||||
@@ -244,6 +245,8 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
|
|||||||
|
|
||||||
if (measure)
|
if (measure)
|
||||||
{
|
{
|
||||||
|
if (timeout)
|
||||||
|
usleep(timeout * 1000);
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||||
@@ -535,7 +538,7 @@ bool cDemux::addPid(unsigned short Pid)
|
|||||||
}
|
}
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid);
|
lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid);
|
||||||
pfd.fd = open(devname[num], O_RDWR);
|
pfd.fd = open(devname[devnum], O_RDWR);
|
||||||
if (pfd.fd < 0)
|
if (pfd.fd < 0)
|
||||||
{
|
{
|
||||||
lt_info("%s #%d Pid = %hx open failed (%m)\n", __FUNCTION__, num, Pid);
|
lt_info("%s #%d Pid = %hx open failed (%m)\n", __FUNCTION__, num, Pid);
|
||||||
|
@@ -36,6 +36,7 @@ class cDemux
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int num;
|
int num;
|
||||||
|
int devnum;
|
||||||
int fd;
|
int fd;
|
||||||
int buffersize;
|
int buffersize;
|
||||||
bool measure;
|
bool measure;
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* (C) 2002-2003 Andreas Oberritter <obi@tuxbox.org>
|
* (C) 2002-2003 Andreas Oberritter <obi@tuxbox.org>
|
||||||
* (C) 2010-2011 Stefan Seyfried
|
* (C) 2010-2013 Stefan Seyfried
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
@@ -13,12 +13,13 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
|
|
||||||
#include <avs/avs_inf.h>
|
#include <avs/avs_inf.h>
|
||||||
#include <clip/clipinfo.h>
|
#include <clip/clipinfo.h>
|
||||||
|
#include <hw/hardware.h>
|
||||||
#include "video_td.h"
|
#include "video_td.h"
|
||||||
#include <hardware/tddevices.h>
|
#include <hardware/tddevices.h>
|
||||||
#define VIDEO_DEVICE "/dev/" DEVICE_NAME_VIDEO
|
#define VIDEO_DEVICE "/dev/" DEVICE_NAME_VIDEO
|
||||||
@@ -732,3 +734,367 @@ void cVideo::FastForwardMode(int mode)
|
|||||||
lt_debug("%s\n", __FUNCTION__);
|
lt_debug("%s\n", __FUNCTION__);
|
||||||
fop(ioctl, MPEG_VID_FASTFORWARD, mode);
|
fop(ioctl, MPEG_VID_FASTFORWARD, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get an image of the video screen
|
||||||
|
* this code is inspired by dreambox AIO-grab,
|
||||||
|
* git://schwerkraft.elitedvb.net/aio-grab/aio-grab.git */
|
||||||
|
/* static lookup tables for faster yuv2rgb conversion */
|
||||||
|
static const int yuv2rgbtable_y[256] = {
|
||||||
|
0xFFED5EA0, 0xFFEE88B6, 0xFFEFB2CC, 0xFFF0DCE2, 0xFFF206F8, 0xFFF3310E, 0xFFF45B24, 0xFFF5853A,
|
||||||
|
0xFFF6AF50, 0xFFF7D966, 0xFFF9037C, 0xFFFA2D92, 0xFFFB57A8, 0xFFFC81BE, 0xFFFDABD4, 0xFFFED5EA,
|
||||||
|
0x00000000, 0x00012A16, 0x0002542C, 0x00037E42, 0x0004A858, 0x0005D26E, 0x0006FC84, 0x0008269A,
|
||||||
|
0x000950B0, 0x000A7AC6, 0x000BA4DC, 0x000CCEF2, 0x000DF908, 0x000F231E, 0x00104D34, 0x0011774A,
|
||||||
|
0x0012A160, 0x0013CB76, 0x0014F58C, 0x00161FA2, 0x001749B8, 0x001873CE, 0x00199DE4, 0x001AC7FA,
|
||||||
|
0x001BF210, 0x001D1C26, 0x001E463C, 0x001F7052, 0x00209A68, 0x0021C47E, 0x0022EE94, 0x002418AA,
|
||||||
|
0x002542C0, 0x00266CD6, 0x002796EC, 0x0028C102, 0x0029EB18, 0x002B152E, 0x002C3F44, 0x002D695A,
|
||||||
|
0x002E9370, 0x002FBD86, 0x0030E79C, 0x003211B2, 0x00333BC8, 0x003465DE, 0x00358FF4, 0x0036BA0A,
|
||||||
|
0x0037E420, 0x00390E36, 0x003A384C, 0x003B6262, 0x003C8C78, 0x003DB68E, 0x003EE0A4, 0x00400ABA,
|
||||||
|
0x004134D0, 0x00425EE6, 0x004388FC, 0x0044B312, 0x0045DD28, 0x0047073E, 0x00483154, 0x00495B6A,
|
||||||
|
0x004A8580, 0x004BAF96, 0x004CD9AC, 0x004E03C2, 0x004F2DD8, 0x005057EE, 0x00518204, 0x0052AC1A,
|
||||||
|
0x0053D630, 0x00550046, 0x00562A5C, 0x00575472, 0x00587E88, 0x0059A89E, 0x005AD2B4, 0x005BFCCA,
|
||||||
|
0x005D26E0, 0x005E50F6, 0x005F7B0C, 0x0060A522, 0x0061CF38, 0x0062F94E, 0x00642364, 0x00654D7A,
|
||||||
|
0x00667790, 0x0067A1A6, 0x0068CBBC, 0x0069F5D2, 0x006B1FE8, 0x006C49FE, 0x006D7414, 0x006E9E2A,
|
||||||
|
0x006FC840, 0x0070F256, 0x00721C6C, 0x00734682, 0x00747098, 0x00759AAE, 0x0076C4C4, 0x0077EEDA,
|
||||||
|
0x007918F0, 0x007A4306, 0x007B6D1C, 0x007C9732, 0x007DC148, 0x007EEB5E, 0x00801574, 0x00813F8A,
|
||||||
|
0x008269A0, 0x008393B6, 0x0084BDCC, 0x0085E7E2, 0x008711F8, 0x00883C0E, 0x00896624, 0x008A903A,
|
||||||
|
0x008BBA50, 0x008CE466, 0x008E0E7C, 0x008F3892, 0x009062A8, 0x00918CBE, 0x0092B6D4, 0x0093E0EA,
|
||||||
|
0x00950B00, 0x00963516, 0x00975F2C, 0x00988942, 0x0099B358, 0x009ADD6E, 0x009C0784, 0x009D319A,
|
||||||
|
0x009E5BB0, 0x009F85C6, 0x00A0AFDC, 0x00A1D9F2, 0x00A30408, 0x00A42E1E, 0x00A55834, 0x00A6824A,
|
||||||
|
0x00A7AC60, 0x00A8D676, 0x00AA008C, 0x00AB2AA2, 0x00AC54B8, 0x00AD7ECE, 0x00AEA8E4, 0x00AFD2FA,
|
||||||
|
0x00B0FD10, 0x00B22726, 0x00B3513C, 0x00B47B52, 0x00B5A568, 0x00B6CF7E, 0x00B7F994, 0x00B923AA,
|
||||||
|
0x00BA4DC0, 0x00BB77D6, 0x00BCA1EC, 0x00BDCC02, 0x00BEF618, 0x00C0202E, 0x00C14A44, 0x00C2745A,
|
||||||
|
0x00C39E70, 0x00C4C886, 0x00C5F29C, 0x00C71CB2, 0x00C846C8, 0x00C970DE, 0x00CA9AF4, 0x00CBC50A,
|
||||||
|
0x00CCEF20, 0x00CE1936, 0x00CF434C, 0x00D06D62, 0x00D19778, 0x00D2C18E, 0x00D3EBA4, 0x00D515BA,
|
||||||
|
0x00D63FD0, 0x00D769E6, 0x00D893FC, 0x00D9BE12, 0x00DAE828, 0x00DC123E, 0x00DD3C54, 0x00DE666A,
|
||||||
|
0x00DF9080, 0x00E0BA96, 0x00E1E4AC, 0x00E30EC2, 0x00E438D8, 0x00E562EE, 0x00E68D04, 0x00E7B71A,
|
||||||
|
0x00E8E130, 0x00EA0B46, 0x00EB355C, 0x00EC5F72, 0x00ED8988, 0x00EEB39E, 0x00EFDDB4, 0x00F107CA,
|
||||||
|
0x00F231E0, 0x00F35BF6, 0x00F4860C, 0x00F5B022, 0x00F6DA38, 0x00F8044E, 0x00F92E64, 0x00FA587A,
|
||||||
|
0x00FB8290, 0x00FCACA6, 0x00FDD6BC, 0x00FF00D2, 0x01002AE8, 0x010154FE, 0x01027F14, 0x0103A92A,
|
||||||
|
0x0104D340, 0x0105FD56, 0x0107276C, 0x01085182, 0x01097B98, 0x010AA5AE, 0x010BCFC4, 0x010CF9DA,
|
||||||
|
0x010E23F0, 0x010F4E06, 0x0110781C, 0x0111A232, 0x0112CC48, 0x0113F65E, 0x01152074, 0x01164A8A
|
||||||
|
};
|
||||||
|
static const int yuv2rgbtable_ru[256] = {
|
||||||
|
0xFEFDA500, 0xFEFFA9B6, 0xFF01AE6C, 0xFF03B322, 0xFF05B7D8, 0xFF07BC8E, 0xFF09C144, 0xFF0BC5FA,
|
||||||
|
0xFF0DCAB0, 0xFF0FCF66, 0xFF11D41C, 0xFF13D8D2, 0xFF15DD88, 0xFF17E23E, 0xFF19E6F4, 0xFF1BEBAA,
|
||||||
|
0xFF1DF060, 0xFF1FF516, 0xFF21F9CC, 0xFF23FE82, 0xFF260338, 0xFF2807EE, 0xFF2A0CA4, 0xFF2C115A,
|
||||||
|
0xFF2E1610, 0xFF301AC6, 0xFF321F7C, 0xFF342432, 0xFF3628E8, 0xFF382D9E, 0xFF3A3254, 0xFF3C370A,
|
||||||
|
0xFF3E3BC0, 0xFF404076, 0xFF42452C, 0xFF4449E2, 0xFF464E98, 0xFF48534E, 0xFF4A5804, 0xFF4C5CBA,
|
||||||
|
0xFF4E6170, 0xFF506626, 0xFF526ADC, 0xFF546F92, 0xFF567448, 0xFF5878FE, 0xFF5A7DB4, 0xFF5C826A,
|
||||||
|
0xFF5E8720, 0xFF608BD6, 0xFF62908C, 0xFF649542, 0xFF6699F8, 0xFF689EAE, 0xFF6AA364, 0xFF6CA81A,
|
||||||
|
0xFF6EACD0, 0xFF70B186, 0xFF72B63C, 0xFF74BAF2, 0xFF76BFA8, 0xFF78C45E, 0xFF7AC914, 0xFF7CCDCA,
|
||||||
|
0xFF7ED280, 0xFF80D736, 0xFF82DBEC, 0xFF84E0A2, 0xFF86E558, 0xFF88EA0E, 0xFF8AEEC4, 0xFF8CF37A,
|
||||||
|
0xFF8EF830, 0xFF90FCE6, 0xFF93019C, 0xFF950652, 0xFF970B08, 0xFF990FBE, 0xFF9B1474, 0xFF9D192A,
|
||||||
|
0xFF9F1DE0, 0xFFA12296, 0xFFA3274C, 0xFFA52C02, 0xFFA730B8, 0xFFA9356E, 0xFFAB3A24, 0xFFAD3EDA,
|
||||||
|
0xFFAF4390, 0xFFB14846, 0xFFB34CFC, 0xFFB551B2, 0xFFB75668, 0xFFB95B1E, 0xFFBB5FD4, 0xFFBD648A,
|
||||||
|
0xFFBF6940, 0xFFC16DF6, 0xFFC372AC, 0xFFC57762, 0xFFC77C18, 0xFFC980CE, 0xFFCB8584, 0xFFCD8A3A,
|
||||||
|
0xFFCF8EF0, 0xFFD193A6, 0xFFD3985C, 0xFFD59D12, 0xFFD7A1C8, 0xFFD9A67E, 0xFFDBAB34, 0xFFDDAFEA,
|
||||||
|
0xFFDFB4A0, 0xFFE1B956, 0xFFE3BE0C, 0xFFE5C2C2, 0xFFE7C778, 0xFFE9CC2E, 0xFFEBD0E4, 0xFFEDD59A,
|
||||||
|
0xFFEFDA50, 0xFFF1DF06, 0xFFF3E3BC, 0xFFF5E872, 0xFFF7ED28, 0xFFF9F1DE, 0xFFFBF694, 0xFFFDFB4A,
|
||||||
|
0x00000000, 0x000204B6, 0x0004096C, 0x00060E22, 0x000812D8, 0x000A178E, 0x000C1C44, 0x000E20FA,
|
||||||
|
0x001025B0, 0x00122A66, 0x00142F1C, 0x001633D2, 0x00183888, 0x001A3D3E, 0x001C41F4, 0x001E46AA,
|
||||||
|
0x00204B60, 0x00225016, 0x002454CC, 0x00265982, 0x00285E38, 0x002A62EE, 0x002C67A4, 0x002E6C5A,
|
||||||
|
0x00307110, 0x003275C6, 0x00347A7C, 0x00367F32, 0x003883E8, 0x003A889E, 0x003C8D54, 0x003E920A,
|
||||||
|
0x004096C0, 0x00429B76, 0x0044A02C, 0x0046A4E2, 0x0048A998, 0x004AAE4E, 0x004CB304, 0x004EB7BA,
|
||||||
|
0x0050BC70, 0x0052C126, 0x0054C5DC, 0x0056CA92, 0x0058CF48, 0x005AD3FE, 0x005CD8B4, 0x005EDD6A,
|
||||||
|
0x0060E220, 0x0062E6D6, 0x0064EB8C, 0x0066F042, 0x0068F4F8, 0x006AF9AE, 0x006CFE64, 0x006F031A,
|
||||||
|
0x007107D0, 0x00730C86, 0x0075113C, 0x007715F2, 0x00791AA8, 0x007B1F5E, 0x007D2414, 0x007F28CA,
|
||||||
|
0x00812D80, 0x00833236, 0x008536EC, 0x00873BA2, 0x00894058, 0x008B450E, 0x008D49C4, 0x008F4E7A,
|
||||||
|
0x00915330, 0x009357E6, 0x00955C9C, 0x00976152, 0x00996608, 0x009B6ABE, 0x009D6F74, 0x009F742A,
|
||||||
|
0x00A178E0, 0x00A37D96, 0x00A5824C, 0x00A78702, 0x00A98BB8, 0x00AB906E, 0x00AD9524, 0x00AF99DA,
|
||||||
|
0x00B19E90, 0x00B3A346, 0x00B5A7FC, 0x00B7ACB2, 0x00B9B168, 0x00BBB61E, 0x00BDBAD4, 0x00BFBF8A,
|
||||||
|
0x00C1C440, 0x00C3C8F6, 0x00C5CDAC, 0x00C7D262, 0x00C9D718, 0x00CBDBCE, 0x00CDE084, 0x00CFE53A,
|
||||||
|
0x00D1E9F0, 0x00D3EEA6, 0x00D5F35C, 0x00D7F812, 0x00D9FCC8, 0x00DC017E, 0x00DE0634, 0x00E00AEA,
|
||||||
|
0x00E20FA0, 0x00E41456, 0x00E6190C, 0x00E81DC2, 0x00EA2278, 0x00EC272E, 0x00EE2BE4, 0x00F0309A,
|
||||||
|
0x00F23550, 0x00F43A06, 0x00F63EBC, 0x00F84372, 0x00FA4828, 0x00FC4CDE, 0x00FE5194, 0x00100564A
|
||||||
|
};
|
||||||
|
static const int yuv2rgbtable_gu[256] = {
|
||||||
|
0xFFCDD300, 0xFFCE375A, 0xFFCE9BB4, 0xFFCF000E, 0xFFCF6468, 0xFFCFC8C2, 0xFFD02D1C, 0xFFD09176,
|
||||||
|
0xFFD0F5D0, 0xFFD15A2A, 0xFFD1BE84, 0xFFD222DE, 0xFFD28738, 0xFFD2EB92, 0xFFD34FEC, 0xFFD3B446,
|
||||||
|
0xFFD418A0, 0xFFD47CFA, 0xFFD4E154, 0xFFD545AE, 0xFFD5AA08, 0xFFD60E62, 0xFFD672BC, 0xFFD6D716,
|
||||||
|
0xFFD73B70, 0xFFD79FCA, 0xFFD80424, 0xFFD8687E, 0xFFD8CCD8, 0xFFD93132, 0xFFD9958C, 0xFFD9F9E6,
|
||||||
|
0xFFDA5E40, 0xFFDAC29A, 0xFFDB26F4, 0xFFDB8B4E, 0xFFDBEFA8, 0xFFDC5402, 0xFFDCB85C, 0xFFDD1CB6,
|
||||||
|
0xFFDD8110, 0xFFDDE56A, 0xFFDE49C4, 0xFFDEAE1E, 0xFFDF1278, 0xFFDF76D2, 0xFFDFDB2C, 0xFFE03F86,
|
||||||
|
0xFFE0A3E0, 0xFFE1083A, 0xFFE16C94, 0xFFE1D0EE, 0xFFE23548, 0xFFE299A2, 0xFFE2FDFC, 0xFFE36256,
|
||||||
|
0xFFE3C6B0, 0xFFE42B0A, 0xFFE48F64, 0xFFE4F3BE, 0xFFE55818, 0xFFE5BC72, 0xFFE620CC, 0xFFE68526,
|
||||||
|
0xFFE6E980, 0xFFE74DDA, 0xFFE7B234, 0xFFE8168E, 0xFFE87AE8, 0xFFE8DF42, 0xFFE9439C, 0xFFE9A7F6,
|
||||||
|
0xFFEA0C50, 0xFFEA70AA, 0xFFEAD504, 0xFFEB395E, 0xFFEB9DB8, 0xFFEC0212, 0xFFEC666C, 0xFFECCAC6,
|
||||||
|
0xFFED2F20, 0xFFED937A, 0xFFEDF7D4, 0xFFEE5C2E, 0xFFEEC088, 0xFFEF24E2, 0xFFEF893C, 0xFFEFED96,
|
||||||
|
0xFFF051F0, 0xFFF0B64A, 0xFFF11AA4, 0xFFF17EFE, 0xFFF1E358, 0xFFF247B2, 0xFFF2AC0C, 0xFFF31066,
|
||||||
|
0xFFF374C0, 0xFFF3D91A, 0xFFF43D74, 0xFFF4A1CE, 0xFFF50628, 0xFFF56A82, 0xFFF5CEDC, 0xFFF63336,
|
||||||
|
0xFFF69790, 0xFFF6FBEA, 0xFFF76044, 0xFFF7C49E, 0xFFF828F8, 0xFFF88D52, 0xFFF8F1AC, 0xFFF95606,
|
||||||
|
0xFFF9BA60, 0xFFFA1EBA, 0xFFFA8314, 0xFFFAE76E, 0xFFFB4BC8, 0xFFFBB022, 0xFFFC147C, 0xFFFC78D6,
|
||||||
|
0xFFFCDD30, 0xFFFD418A, 0xFFFDA5E4, 0xFFFE0A3E, 0xFFFE6E98, 0xFFFED2F2, 0xFFFF374C, 0xFFFF9BA6,
|
||||||
|
0x00000000, 0x0000645A, 0x0000C8B4, 0x00012D0E, 0x00019168, 0x0001F5C2, 0x00025A1C, 0x0002BE76,
|
||||||
|
0x000322D0, 0x0003872A, 0x0003EB84, 0x00044FDE, 0x0004B438, 0x00051892, 0x00057CEC, 0x0005E146,
|
||||||
|
0x000645A0, 0x0006A9FA, 0x00070E54, 0x000772AE, 0x0007D708, 0x00083B62, 0x00089FBC, 0x00090416,
|
||||||
|
0x00096870, 0x0009CCCA, 0x000A3124, 0x000A957E, 0x000AF9D8, 0x000B5E32, 0x000BC28C, 0x000C26E6,
|
||||||
|
0x000C8B40, 0x000CEF9A, 0x000D53F4, 0x000DB84E, 0x000E1CA8, 0x000E8102, 0x000EE55C, 0x000F49B6,
|
||||||
|
0x000FAE10, 0x0010126A, 0x001076C4, 0x0010DB1E, 0x00113F78, 0x0011A3D2, 0x0012082C, 0x00126C86,
|
||||||
|
0x0012D0E0, 0x0013353A, 0x00139994, 0x0013FDEE, 0x00146248, 0x0014C6A2, 0x00152AFC, 0x00158F56,
|
||||||
|
0x0015F3B0, 0x0016580A, 0x0016BC64, 0x001720BE, 0x00178518, 0x0017E972, 0x00184DCC, 0x0018B226,
|
||||||
|
0x00191680, 0x00197ADA, 0x0019DF34, 0x001A438E, 0x001AA7E8, 0x001B0C42, 0x001B709C, 0x001BD4F6,
|
||||||
|
0x001C3950, 0x001C9DAA, 0x001D0204, 0x001D665E, 0x001DCAB8, 0x001E2F12, 0x001E936C, 0x001EF7C6,
|
||||||
|
0x001F5C20, 0x001FC07A, 0x002024D4, 0x0020892E, 0x0020ED88, 0x002151E2, 0x0021B63C, 0x00221A96,
|
||||||
|
0x00227EF0, 0x0022E34A, 0x002347A4, 0x0023ABFE, 0x00241058, 0x002474B2, 0x0024D90C, 0x00253D66,
|
||||||
|
0x0025A1C0, 0x0026061A, 0x00266A74, 0x0026CECE, 0x00273328, 0x00279782, 0x0027FBDC, 0x00286036,
|
||||||
|
0x0028C490, 0x002928EA, 0x00298D44, 0x0029F19E, 0x002A55F8, 0x002ABA52, 0x002B1EAC, 0x002B8306,
|
||||||
|
0x002BE760, 0x002C4BBA, 0x002CB014, 0x002D146E, 0x002D78C8, 0x002DDD22, 0x002E417C, 0x002EA5D6,
|
||||||
|
0x002F0A30, 0x002F6E8A, 0x002FD2E4, 0x0030373E, 0x00309B98, 0x0030FFF2, 0x0031644C, 0x0031C8A6
|
||||||
|
};
|
||||||
|
static const int yuv2rgbtable_gv[256] = {
|
||||||
|
0xFF97E900, 0xFF98B92E, 0xFF99895C, 0xFF9A598A, 0xFF9B29B8, 0xFF9BF9E6, 0xFF9CCA14, 0xFF9D9A42,
|
||||||
|
0xFF9E6A70, 0xFF9F3A9E, 0xFFA00ACC, 0xFFA0DAFA, 0xFFA1AB28, 0xFFA27B56, 0xFFA34B84, 0xFFA41BB2,
|
||||||
|
0xFFA4EBE0, 0xFFA5BC0E, 0xFFA68C3C, 0xFFA75C6A, 0xFFA82C98, 0xFFA8FCC6, 0xFFA9CCF4, 0xFFAA9D22,
|
||||||
|
0xFFAB6D50, 0xFFAC3D7E, 0xFFAD0DAC, 0xFFADDDDA, 0xFFAEAE08, 0xFFAF7E36, 0xFFB04E64, 0xFFB11E92,
|
||||||
|
0xFFB1EEC0, 0xFFB2BEEE, 0xFFB38F1C, 0xFFB45F4A, 0xFFB52F78, 0xFFB5FFA6, 0xFFB6CFD4, 0xFFB7A002,
|
||||||
|
0xFFB87030, 0xFFB9405E, 0xFFBA108C, 0xFFBAE0BA, 0xFFBBB0E8, 0xFFBC8116, 0xFFBD5144, 0xFFBE2172,
|
||||||
|
0xFFBEF1A0, 0xFFBFC1CE, 0xFFC091FC, 0xFFC1622A, 0xFFC23258, 0xFFC30286, 0xFFC3D2B4, 0xFFC4A2E2,
|
||||||
|
0xFFC57310, 0xFFC6433E, 0xFFC7136C, 0xFFC7E39A, 0xFFC8B3C8, 0xFFC983F6, 0xFFCA5424, 0xFFCB2452,
|
||||||
|
0xFFCBF480, 0xFFCCC4AE, 0xFFCD94DC, 0xFFCE650A, 0xFFCF3538, 0xFFD00566, 0xFFD0D594, 0xFFD1A5C2,
|
||||||
|
0xFFD275F0, 0xFFD3461E, 0xFFD4164C, 0xFFD4E67A, 0xFFD5B6A8, 0xFFD686D6, 0xFFD75704, 0xFFD82732,
|
||||||
|
0xFFD8F760, 0xFFD9C78E, 0xFFDA97BC, 0xFFDB67EA, 0xFFDC3818, 0xFFDD0846, 0xFFDDD874, 0xFFDEA8A2,
|
||||||
|
0xFFDF78D0, 0xFFE048FE, 0xFFE1192C, 0xFFE1E95A, 0xFFE2B988, 0xFFE389B6, 0xFFE459E4, 0xFFE52A12,
|
||||||
|
0xFFE5FA40, 0xFFE6CA6E, 0xFFE79A9C, 0xFFE86ACA, 0xFFE93AF8, 0xFFEA0B26, 0xFFEADB54, 0xFFEBAB82,
|
||||||
|
0xFFEC7BB0, 0xFFED4BDE, 0xFFEE1C0C, 0xFFEEEC3A, 0xFFEFBC68, 0xFFF08C96, 0xFFF15CC4, 0xFFF22CF2,
|
||||||
|
0xFFF2FD20, 0xFFF3CD4E, 0xFFF49D7C, 0xFFF56DAA, 0xFFF63DD8, 0xFFF70E06, 0xFFF7DE34, 0xFFF8AE62,
|
||||||
|
0xFFF97E90, 0xFFFA4EBE, 0xFFFB1EEC, 0xFFFBEF1A, 0xFFFCBF48, 0xFFFD8F76, 0xFFFE5FA4, 0xFFFF2FD2,
|
||||||
|
0x00000000, 0x0000D02E, 0x0001A05C, 0x0002708A, 0x000340B8, 0x000410E6, 0x0004E114, 0x0005B142,
|
||||||
|
0x00068170, 0x0007519E, 0x000821CC, 0x0008F1FA, 0x0009C228, 0x000A9256, 0x000B6284, 0x000C32B2,
|
||||||
|
0x000D02E0, 0x000DD30E, 0x000EA33C, 0x000F736A, 0x00104398, 0x001113C6, 0x0011E3F4, 0x0012B422,
|
||||||
|
0x00138450, 0x0014547E, 0x001524AC, 0x0015F4DA, 0x0016C508, 0x00179536, 0x00186564, 0x00193592,
|
||||||
|
0x001A05C0, 0x001AD5EE, 0x001BA61C, 0x001C764A, 0x001D4678, 0x001E16A6, 0x001EE6D4, 0x001FB702,
|
||||||
|
0x00208730, 0x0021575E, 0x0022278C, 0x0022F7BA, 0x0023C7E8, 0x00249816, 0x00256844, 0x00263872,
|
||||||
|
0x002708A0, 0x0027D8CE, 0x0028A8FC, 0x0029792A, 0x002A4958, 0x002B1986, 0x002BE9B4, 0x002CB9E2,
|
||||||
|
0x002D8A10, 0x002E5A3E, 0x002F2A6C, 0x002FFA9A, 0x0030CAC8, 0x00319AF6, 0x00326B24, 0x00333B52,
|
||||||
|
0x00340B80, 0x0034DBAE, 0x0035ABDC, 0x00367C0A, 0x00374C38, 0x00381C66, 0x0038EC94, 0x0039BCC2,
|
||||||
|
0x003A8CF0, 0x003B5D1E, 0x003C2D4C, 0x003CFD7A, 0x003DCDA8, 0x003E9DD6, 0x003F6E04, 0x00403E32,
|
||||||
|
0x00410E60, 0x0041DE8E, 0x0042AEBC, 0x00437EEA, 0x00444F18, 0x00451F46, 0x0045EF74, 0x0046BFA2,
|
||||||
|
0x00478FD0, 0x00485FFE, 0x0049302C, 0x004A005A, 0x004AD088, 0x004BA0B6, 0x004C70E4, 0x004D4112,
|
||||||
|
0x004E1140, 0x004EE16E, 0x004FB19C, 0x005081CA, 0x005151F8, 0x00522226, 0x0052F254, 0x0053C282,
|
||||||
|
0x005492B0, 0x005562DE, 0x0056330C, 0x0057033A, 0x0057D368, 0x0058A396, 0x005973C4, 0x005A43F2,
|
||||||
|
0x005B1420, 0x005BE44E, 0x005CB47C, 0x005D84AA, 0x005E54D8, 0x005F2506, 0x005FF534, 0x0060C562,
|
||||||
|
0x00619590, 0x006265BE, 0x006335EC, 0x0064061A, 0x0064D648, 0x0065A676, 0x006676A4, 0x006746D2
|
||||||
|
};
|
||||||
|
static const int yuv2rgbtable_bv[256] = {
|
||||||
|
0xFF33A280, 0xFF353B3B, 0xFF36D3F6, 0xFF386CB1, 0xFF3A056C, 0xFF3B9E27, 0xFF3D36E2, 0xFF3ECF9D,
|
||||||
|
0xFF406858, 0xFF420113, 0xFF4399CE, 0xFF453289, 0xFF46CB44, 0xFF4863FF, 0xFF49FCBA, 0xFF4B9575,
|
||||||
|
0xFF4D2E30, 0xFF4EC6EB, 0xFF505FA6, 0xFF51F861, 0xFF53911C, 0xFF5529D7, 0xFF56C292, 0xFF585B4D,
|
||||||
|
0xFF59F408, 0xFF5B8CC3, 0xFF5D257E, 0xFF5EBE39, 0xFF6056F4, 0xFF61EFAF, 0xFF63886A, 0xFF652125,
|
||||||
|
0xFF66B9E0, 0xFF68529B, 0xFF69EB56, 0xFF6B8411, 0xFF6D1CCC, 0xFF6EB587, 0xFF704E42, 0xFF71E6FD,
|
||||||
|
0xFF737FB8, 0xFF751873, 0xFF76B12E, 0xFF7849E9, 0xFF79E2A4, 0xFF7B7B5F, 0xFF7D141A, 0xFF7EACD5,
|
||||||
|
0xFF804590, 0xFF81DE4B, 0xFF837706, 0xFF850FC1, 0xFF86A87C, 0xFF884137, 0xFF89D9F2, 0xFF8B72AD,
|
||||||
|
0xFF8D0B68, 0xFF8EA423, 0xFF903CDE, 0xFF91D599, 0xFF936E54, 0xFF95070F, 0xFF969FCA, 0xFF983885,
|
||||||
|
0xFF99D140, 0xFF9B69FB, 0xFF9D02B6, 0xFF9E9B71, 0xFFA0342C, 0xFFA1CCE7, 0xFFA365A2, 0xFFA4FE5D,
|
||||||
|
0xFFA69718, 0xFFA82FD3, 0xFFA9C88E, 0xFFAB6149, 0xFFACFA04, 0xFFAE92BF, 0xFFB02B7A, 0xFFB1C435,
|
||||||
|
0xFFB35CF0, 0xFFB4F5AB, 0xFFB68E66, 0xFFB82721, 0xFFB9BFDC, 0xFFBB5897, 0xFFBCF152, 0xFFBE8A0D,
|
||||||
|
0xFFC022C8, 0xFFC1BB83, 0xFFC3543E, 0xFFC4ECF9, 0xFFC685B4, 0xFFC81E6F, 0xFFC9B72A, 0xFFCB4FE5,
|
||||||
|
0xFFCCE8A0, 0xFFCE815B, 0xFFD01A16, 0xFFD1B2D1, 0xFFD34B8C, 0xFFD4E447, 0xFFD67D02, 0xFFD815BD,
|
||||||
|
0xFFD9AE78, 0xFFDB4733, 0xFFDCDFEE, 0xFFDE78A9, 0xFFE01164, 0xFFE1AA1F, 0xFFE342DA, 0xFFE4DB95,
|
||||||
|
0xFFE67450, 0xFFE80D0B, 0xFFE9A5C6, 0xFFEB3E81, 0xFFECD73C, 0xFFEE6FF7, 0xFFF008B2, 0xFFF1A16D,
|
||||||
|
0xFFF33A28, 0xFFF4D2E3, 0xFFF66B9E, 0xFFF80459, 0xFFF99D14, 0xFFFB35CF, 0xFFFCCE8A, 0xFFFE6745,
|
||||||
|
0x00000000, 0x000198BB, 0x00033176, 0x0004CA31, 0x000662EC, 0x0007FBA7, 0x00099462, 0x000B2D1D,
|
||||||
|
0x000CC5D8, 0x000E5E93, 0x000FF74E, 0x00119009, 0x001328C4, 0x0014C17F, 0x00165A3A, 0x0017F2F5,
|
||||||
|
0x00198BB0, 0x001B246B, 0x001CBD26, 0x001E55E1, 0x001FEE9C, 0x00218757, 0x00232012, 0x0024B8CD,
|
||||||
|
0x00265188, 0x0027EA43, 0x002982FE, 0x002B1BB9, 0x002CB474, 0x002E4D2F, 0x002FE5EA, 0x00317EA5,
|
||||||
|
0x00331760, 0x0034B01B, 0x003648D6, 0x0037E191, 0x00397A4C, 0x003B1307, 0x003CABC2, 0x003E447D,
|
||||||
|
0x003FDD38, 0x004175F3, 0x00430EAE, 0x0044A769, 0x00464024, 0x0047D8DF, 0x0049719A, 0x004B0A55,
|
||||||
|
0x004CA310, 0x004E3BCB, 0x004FD486, 0x00516D41, 0x005305FC, 0x00549EB7, 0x00563772, 0x0057D02D,
|
||||||
|
0x005968E8, 0x005B01A3, 0x005C9A5E, 0x005E3319, 0x005FCBD4, 0x0061648F, 0x0062FD4A, 0x00649605,
|
||||||
|
0x00662EC0, 0x0067C77B, 0x00696036, 0x006AF8F1, 0x006C91AC, 0x006E2A67, 0x006FC322, 0x00715BDD,
|
||||||
|
0x0072F498, 0x00748D53, 0x0076260E, 0x0077BEC9, 0x00795784, 0x007AF03F, 0x007C88FA, 0x007E21B5,
|
||||||
|
0x007FBA70, 0x0081532B, 0x0082EBE6, 0x008484A1, 0x00861D5C, 0x0087B617, 0x00894ED2, 0x008AE78D,
|
||||||
|
0x008C8048, 0x008E1903, 0x008FB1BE, 0x00914A79, 0x0092E334, 0x00947BEF, 0x009614AA, 0x0097AD65,
|
||||||
|
0x00994620, 0x009ADEDB, 0x009C7796, 0x009E1051, 0x009FA90C, 0x00A141C7, 0x00A2DA82, 0x00A4733D,
|
||||||
|
0x00A60BF8, 0x00A7A4B3, 0x00A93D6E, 0x00AAD629, 0x00AC6EE4, 0x00AE079F, 0x00AFA05A, 0x00B13915,
|
||||||
|
0x00B2D1D0, 0x00B46A8B, 0x00B60346, 0x00B79C01, 0x00B934BC, 0x00BACD77, 0x00BC6632, 0x00BDFEED,
|
||||||
|
0x00BF97A8, 0x00C13063, 0x00C2C91E, 0x00C461D9, 0x00C5FA94, 0x00C7934F, 0x00C92C0A, 0x00CAC4C5
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLAMP(x) ((x < 0) ? 0 : ((x > 255) ? 255 : x))
|
||||||
|
#define SWAP(x,y) { x ^= y; y ^= x; x ^= y; }
|
||||||
|
#define VIDEO_MEM _MPEG_VIDEO_MEM_BASE
|
||||||
|
#define VIDEO_SIZE _MPEG_VIDEO_MEM_SIZE
|
||||||
|
#define WIDTH_OFF (VID_USER_MEM_BASE + 0x0100)
|
||||||
|
#define HEIGHT_OFF (VID_USER_MEM_BASE + 0x0102)
|
||||||
|
#define GFXFB_MEM _GFX_FB_MEM_BASE
|
||||||
|
#define GFXFB_SIZE _GFX_FB_MEM_SIZE
|
||||||
|
/* TODO: aspect ratio correction and PIP */
|
||||||
|
bool cVideo::GetScreenImage(unsigned char * &video, int &xres, int &yres, bool get_video, bool get_osd, bool /*scale_to_video*/)
|
||||||
|
{
|
||||||
|
lt_info("%s: get_video: %d get_osd: %d\n", __func__, get_video, get_osd);
|
||||||
|
uint8_t *map;
|
||||||
|
int mfd = open("/dev/mem", O_RDWR);
|
||||||
|
if (mfd < 0) {
|
||||||
|
lt_info("%s: cannot open open /dev/mem (%m)\n", __func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* this hints at incorrect usage */
|
||||||
|
if (video != NULL)
|
||||||
|
lt_info("%s: WARNING, video != NULL?\n", __func__);
|
||||||
|
|
||||||
|
if (get_video)
|
||||||
|
{
|
||||||
|
map = (uint8_t *)mmap(NULL, VIDEO_SIZE, PROT_READ, MAP_SHARED, mfd, VIDEO_MEM);
|
||||||
|
if (map == MAP_FAILED) {
|
||||||
|
lt_info("%s: cannot mmap /dev/mem vor VIDEO (%m)\n", __func__);
|
||||||
|
close(mfd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint16_t w = *(uint16_t *)(map + WIDTH_OFF);
|
||||||
|
uint16_t h = *(uint16_t *)(map + HEIGHT_OFF);
|
||||||
|
if (w > 720 || h > 576) {
|
||||||
|
lt_info("%s: unhandled resolution %dx%d, is the tuner locked?\n", __func__, w, h);
|
||||||
|
munmap(map, VIDEO_SIZE);
|
||||||
|
close(mfd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint8_t *luma, *chroma;
|
||||||
|
int needmem = w * h * 5 / 4; /* chroma is 1/4 in size of luma */
|
||||||
|
int lumasize = w * h;
|
||||||
|
int chromasize = needmem - lumasize;
|
||||||
|
uint8_t *buf = (uint8_t *)malloc(needmem);
|
||||||
|
if (!buf) {
|
||||||
|
lt_info("%s: cannot allocate %d bytes (%m)\n", __func__, needmem);
|
||||||
|
munmap(map, VIDEO_SIZE);
|
||||||
|
close(mfd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* luma is at the beginning of the buffer */
|
||||||
|
memcpy(buf, map, lumasize);
|
||||||
|
/* it looks like the chroma plane is always 720*576 bytes offset to the luma plane */
|
||||||
|
memcpy(buf + lumasize, map + 720 * 576, chromasize);
|
||||||
|
/* release the video buffer */
|
||||||
|
munmap(map, VIDEO_SIZE);
|
||||||
|
|
||||||
|
if (get_osd)
|
||||||
|
{ /* in this case, the framebuffer determines the output resolution */
|
||||||
|
xres = 720;
|
||||||
|
yres = 576;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xres = w;
|
||||||
|
yres = h;
|
||||||
|
}
|
||||||
|
video = (unsigned char *)malloc(xres * yres * 4);
|
||||||
|
if (!video) {
|
||||||
|
lt_info("%s: cannot allocate %d bytes for video buffer (%m)\n", __func__, yres * yres * 4);
|
||||||
|
free(buf);
|
||||||
|
close(mfd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
luma = buf;
|
||||||
|
chroma = buf + lumasize;
|
||||||
|
|
||||||
|
int Y, U, V, y, x, out1, pos, RU, GU, GV, BV, rgbstride, i;
|
||||||
|
|
||||||
|
// yuv2rgb conversion (4:2:0)
|
||||||
|
lt_info("%s: converting Video from YUV to RGB color space\n", __func__);
|
||||||
|
out1 = pos = 0;
|
||||||
|
rgbstride = w * 4;
|
||||||
|
|
||||||
|
for (y = h; y != 0; y -= 2)
|
||||||
|
{
|
||||||
|
for (x = w; x != 0; x -= 4)
|
||||||
|
{
|
||||||
|
U = *chroma++;
|
||||||
|
V = *chroma++;
|
||||||
|
RU = yuv2rgbtable_ru[U]; // use lookup tables to speedup the whole thing
|
||||||
|
GU = yuv2rgbtable_gu[U];
|
||||||
|
GV = yuv2rgbtable_gv[V];
|
||||||
|
BV = yuv2rgbtable_bv[V];
|
||||||
|
// now we do 8 pixels on each iteration this is more code but much faster
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
Y = yuv2rgbtable_y[luma[pos]];
|
||||||
|
video[out1 ] = CLAMP((Y + RU) >> 16);
|
||||||
|
video[out1 + 1] = CLAMP((Y - GV - GU) >> 16);
|
||||||
|
video[out1 + 2] = CLAMP((Y + BV) >> 16);
|
||||||
|
video[out1 + 3] = 0xff;
|
||||||
|
|
||||||
|
Y = yuv2rgbtable_y[luma[w + pos]];
|
||||||
|
video[out1 + rgbstride] = CLAMP((Y + RU) >> 16);
|
||||||
|
video[out1 + 1 + rgbstride] = CLAMP((Y - GV - GU) >> 16);
|
||||||
|
video[out1 + 2 + rgbstride] = CLAMP((Y + BV) >> 16);
|
||||||
|
video[out1 + 3 + rgbstride] = 0xff;
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
out1 += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out1 += rgbstride;
|
||||||
|
pos += w;
|
||||||
|
}
|
||||||
|
if (get_osd && (w < xres || h < yres))
|
||||||
|
{
|
||||||
|
/* most trivial scaling algorithm:
|
||||||
|
* - no smoothing/antialiasing or similar
|
||||||
|
* - only upscaling
|
||||||
|
* more or less just memcpy
|
||||||
|
* works "backwards" (from bottom right up left),
|
||||||
|
* so that no extra buffer is needed */
|
||||||
|
int j, k;
|
||||||
|
uint32_t *v = (uint32_t *)video; /* int pointer to the video buffer */
|
||||||
|
uint32_t *srcline; /* the start of the current line (unscaled) */
|
||||||
|
uint32_t *dst = v + xres * yres; /* the current scaled pixel */
|
||||||
|
for (j = yres -1 ; j >= 0; j--)
|
||||||
|
{
|
||||||
|
srcline = v + (((j * h) / yres) * w);
|
||||||
|
for (k = xres - 1; k >= 0; k--) {
|
||||||
|
dst--;
|
||||||
|
*dst = *(srcline + ((k * w) / xres));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lt_info("%s: Video-Size: %d x %d\n", __func__, xres, yres);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
if (get_osd)
|
||||||
|
{
|
||||||
|
if (! get_video)
|
||||||
|
{
|
||||||
|
/* we don't use other framebuffer resolutions */
|
||||||
|
xres = 720;
|
||||||
|
yres = 576;
|
||||||
|
video = (unsigned char *)calloc(xres * yres, 4);
|
||||||
|
if (!video)
|
||||||
|
{
|
||||||
|
lt_info("%s: cannot allocate %d bytes for video buffer (%m)\n", __func__, yres * yres * 4);
|
||||||
|
close(mfd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* we don't need the framebufferdevice, we know where the FB is located */
|
||||||
|
map = (uint8_t *)mmap(NULL, GFXFB_SIZE, PROT_READ, MAP_SHARED, mfd, GFXFB_MEM);
|
||||||
|
if (map == MAP_FAILED) {
|
||||||
|
lt_info("%s: cannot mmap /dev/mem for GFXFB (%m)\n", __func__);
|
||||||
|
close(mfd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned int i, r, g, b, a, a2;
|
||||||
|
uint8_t *p = map;
|
||||||
|
uint8_t *q = video;
|
||||||
|
for (i = xres * yres; i != 0; i--)
|
||||||
|
{
|
||||||
|
a = *p++;
|
||||||
|
r = *p++;
|
||||||
|
g = *p++;
|
||||||
|
b = *p++;
|
||||||
|
a2 = 0xff - a;
|
||||||
|
/* blue */
|
||||||
|
*q = ((*q * a2 ) + (b * a)) >> 8;
|
||||||
|
q++;
|
||||||
|
/* green */
|
||||||
|
*q = ((*q * a2 ) + (g * a)) >> 8;
|
||||||
|
q++;
|
||||||
|
/* red */
|
||||||
|
*q = ((*q * a2 ) + (r * a)) >> 8;
|
||||||
|
q++;
|
||||||
|
q++; /* skip alpha byte */
|
||||||
|
}
|
||||||
|
munmap(map, GFXFB_SIZE);
|
||||||
|
}
|
||||||
|
close(mfd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
//#define video_displayformat_t vidDispMode_t
|
//#define video_displayformat_t vidDispMode_t
|
||||||
#include "../common/cs_types.h"
|
#include "../common/cs_types.h"
|
||||||
|
|
||||||
|
#define STB_HAL_VIDEO_HAS_GETSCREENIMAGE 1
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ANALOG_SD_RGB_SCART = 0x00,
|
ANALOG_SD_RGB_SCART = 0x00,
|
||||||
ANALOG_SD_YPRPB_SCART,
|
ANALOG_SD_YPRPB_SCART,
|
||||||
@@ -186,6 +188,7 @@ class cVideo
|
|||||||
int CloseVBI(void) { return 0; };
|
int CloseVBI(void) { return 0; };
|
||||||
int StartVBI(unsigned short) { return 0; };
|
int StartVBI(unsigned short) { return 0; };
|
||||||
int StopVBI(void) { return 0; };
|
int StopVBI(void) { return 0; };
|
||||||
|
bool GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video = true, bool get_osd = false, bool scale_to_video = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,3 +4,6 @@ if BOXTYPE_SPARK
|
|||||||
bin_PROGRAMS += spark_fp
|
bin_PROGRAMS += spark_fp
|
||||||
spark_fp_SOURCES = spark_fp.c
|
spark_fp_SOURCES = spark_fp.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
bin_PROGRAMS += pic2m2v
|
||||||
|
pic2m2v_SOURCES = pic2m2v.c
|
||||||
|
85
tools/pic2m2v.c
Normal file
85
tools/pic2m2v.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* (C) 2012 Stefan Seyfried
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <utime.h>
|
||||||
|
|
||||||
|
#if HAVE_TRIPLEDRAGON
|
||||||
|
#define TARGETRES "704x576"
|
||||||
|
#else
|
||||||
|
#define TARGETRES "1280x720"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char destname[512];
|
||||||
|
char cmd[512];
|
||||||
|
char *p;
|
||||||
|
char *fname;
|
||||||
|
struct stat st, st2;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: pic2m2v /path/pic1.jpg [/path/pic2.jpg...]\n\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strcpy(destname, "/var/cache");
|
||||||
|
mkdir(destname, 0755);
|
||||||
|
argv++;
|
||||||
|
for (fname = *argv; fname != NULL; fname = *++argv)
|
||||||
|
{
|
||||||
|
if (stat(fname, &st2))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "pic2m2v: could not stat '%s' (%m)\n", fname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
strcpy(destname, "/var/cache");
|
||||||
|
/* the cache filename is (example for /share/tuxbox/neutrino/icons/radiomode.jpg):
|
||||||
|
/var/cache/share.tuxbox.neutrino.icons.radiomode.jpg.m2v
|
||||||
|
build that filename first...
|
||||||
|
TODO: this could cause name clashes, use a hashing function instead... */
|
||||||
|
strcat(destname, fname);
|
||||||
|
p = &destname[strlen("/var/cache/")];
|
||||||
|
while ((p = strchr(p, '/')) != NULL)
|
||||||
|
*p = '.';
|
||||||
|
strcat(destname, ".m2v");
|
||||||
|
/* ...then check if it exists already... */
|
||||||
|
if (stat(destname, &st) || (st.st_mtime != st2.st_mtime) || (st.st_size == 0))
|
||||||
|
{
|
||||||
|
struct utimbuf u;
|
||||||
|
u.actime = time(NULL);
|
||||||
|
u.modtime = st2.st_mtime;
|
||||||
|
printf("converting %s -> %s\n", fname, destname);
|
||||||
|
/* it does not exist or has a different date, so call ffmpeg... */
|
||||||
|
sprintf(cmd, "ffmpeg -v 31 -y -f mjpeg -i '%s' -s %s '%s' </dev/null",
|
||||||
|
fname, TARGETRES, destname);
|
||||||
|
system(cmd); /* TODO: use libavcodec to directly convert it */
|
||||||
|
utime(destname, &u);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("cache file %s already current\n", destname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user