mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
Merge remote-tracking branch 'seife/master'
This commit is contained in:
21
acinclude.m4
21
acinclude.m4
@@ -2,7 +2,6 @@ AC_DEFUN([TUXBOX_APPS],[
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_GNU_SOURCE
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
AC_ARG_WITH(target,
|
||||
@@ -58,21 +57,33 @@ check_path () {
|
||||
|
||||
])
|
||||
|
||||
dnl expand nested ${foo}/bar
|
||||
AC_DEFUN([TUXBOX_EXPAND_VARIABLE],[__$1="$2"
|
||||
for __CNT in false false false false true; do dnl max 5 levels of indirection
|
||||
|
||||
$1=`eval echo "$__$1"`
|
||||
echo ${$1} | grep -q '\$' || break # 'grep -q' is POSIX, exit if no $ in variable
|
||||
__$1="${$1}"
|
||||
done
|
||||
$__CNT && AC_MSG_ERROR([can't expand variable $1=$2]) dnl bail out if we did not expand
|
||||
])
|
||||
|
||||
AC_DEFUN([TUXBOX_APPS_DIRECTORY_ONE],[
|
||||
AC_ARG_WITH($1,[ $6$7 [[PREFIX$4$5]]],[
|
||||
_$2=$withval
|
||||
if test "$TARGET" = "cdk"; then
|
||||
$2=`eval echo "${targetprefix}$withval"`
|
||||
$2=`eval echo "${targetprefix}$withval"` # no indirection possible IMNSHO
|
||||
else
|
||||
$2=$withval
|
||||
fi
|
||||
TARGET_$2=${$2}
|
||||
],[
|
||||
$2="\${$3}$5"
|
||||
# RFC 1925: "you can always add another level of indirection..."
|
||||
TUXBOX_EXPAND_VARIABLE($2,"${$3}$5")
|
||||
if test "$TARGET" = "cdk"; then
|
||||
_$2=`eval echo "${target$3}$5"`
|
||||
TUXBOX_EXPAND_VARIABLE(_$2,"${target$3}$5")
|
||||
else
|
||||
_$2=`eval echo "${$3}$5"`
|
||||
_$2=${$2}
|
||||
fi
|
||||
TARGET_$2=$_$2
|
||||
])
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include "../common/cs_types.h"
|
||||
|
||||
#define MAX_DMX_UNITS 4
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMX_INVALID = 0,
|
||||
|
@@ -2,6 +2,7 @@ AC_INIT(libstb-hal,0.1.1)
|
||||
AM_INIT_AUTOMAKE(libstb-hal,0.1.1)
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_GNU_SOURCE
|
||||
LT_INIT
|
||||
|
||||
## ugly, disables shared library build (not wanted yet)
|
||||
|
@@ -45,12 +45,18 @@ extern cDemux *audioDemux;
|
||||
static uint8_t *dmxbuf = NULL;
|
||||
static int bufpos;
|
||||
|
||||
extern bool HAL_nodec;
|
||||
|
||||
static cAudio *gThiz = NULL;
|
||||
|
||||
static ao_device *adevice = NULL;
|
||||
static ao_sample_format sformat;
|
||||
|
||||
cAudio::cAudio(void *, void *, void *)
|
||||
{
|
||||
thread_started = false;
|
||||
dmxbuf = (uint8_t *)malloc(DMX_BUF_SZ);
|
||||
if (!HAL_nodec)
|
||||
dmxbuf = (uint8_t *)malloc(DMX_BUF_SZ);
|
||||
bufpos = 0;
|
||||
curr_pts = 0;
|
||||
gThiz = this;
|
||||
@@ -61,6 +67,9 @@ cAudio::~cAudio(void)
|
||||
{
|
||||
closeDevice();
|
||||
free(dmxbuf);
|
||||
if (adevice)
|
||||
ao_close(adevice);
|
||||
adevice = NULL;
|
||||
ao_shutdown();
|
||||
}
|
||||
|
||||
@@ -89,7 +98,8 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
|
||||
int cAudio::Start(void)
|
||||
{
|
||||
lt_info("%s >\n", __func__);
|
||||
OpenThreads::Thread::start();
|
||||
if (! HAL_nodec)
|
||||
OpenThreads::Thread::start();
|
||||
lt_info("%s <\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
@@ -126,21 +136,56 @@ int cAudio::setChannel(int /*channel*/)
|
||||
return 0;
|
||||
};
|
||||
|
||||
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
|
||||
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int le)
|
||||
{
|
||||
lt_debug("%s ch %d srate %d bits %d le %d\n", __func__, ch, srate, bits, little_endian);
|
||||
lt_debug("%s ch %d srate %d bits %d le %d adevice %p\n", __func__, ch, srate, bits, le, adevice);;
|
||||
int driver;
|
||||
int byte_format = le ? AO_FMT_LITTLE : AO_FMT_BIG;
|
||||
if (sformat.bits != bits || sformat.channels != ch || sformat.rate != srate ||
|
||||
sformat.byte_format != byte_format || adevice == NULL)
|
||||
{
|
||||
driver = ao_default_driver_id();
|
||||
sformat.bits = bits;
|
||||
sformat.channels = ch;
|
||||
sformat.rate = srate;
|
||||
sformat.byte_format = byte_format;
|
||||
sformat.matrix = 0;
|
||||
if (adevice)
|
||||
ao_close(adevice);
|
||||
adevice = ao_open_live(driver, &sformat, NULL);
|
||||
ao_info *ai = ao_driver_info(driver);
|
||||
lt_info("%s: changed params ch %d srate %d bits %d le %d adevice %p\n",
|
||||
__func__, ch, srate, bits, le, adevice);;
|
||||
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
|
||||
driver, ai->name, ai->short_name, ai->author);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int cAudio::WriteClip(unsigned char * /*buffer*/, int /*size*/)
|
||||
int cAudio::WriteClip(unsigned char *buffer, int size)
|
||||
{
|
||||
lt_debug("cAudio::%s\n", __func__);
|
||||
return 0;
|
||||
lt_debug("cAudio::%s buf 0x%p size %d\n", __func__, buffer, size);
|
||||
if (!adevice) {
|
||||
lt_info("%s: adevice not opened?\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
ao_play(adevice, (char *)buffer, size);
|
||||
return size;
|
||||
};
|
||||
|
||||
int cAudio::StopClip()
|
||||
{
|
||||
lt_debug("%s\n", __func__);
|
||||
#if 0
|
||||
/* don't do anything - closing / reopening ao all the time makes for long delays
|
||||
* reinit on-demand (e.g. for changed parameters) instead */
|
||||
if (!adevice) {
|
||||
lt_info("%s: adevice not opened?\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
ao_close(adevice);
|
||||
adevice = NULL;
|
||||
#endif
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -232,8 +277,8 @@ void cAudio::run()
|
||||
int ret, driver;
|
||||
/* libao */
|
||||
ao_info *ai;
|
||||
ao_device *adevice;
|
||||
ao_sample_format sformat;
|
||||
// ao_device *adevice;
|
||||
// ao_sample_format sformat;
|
||||
|
||||
curr_pts = 0;
|
||||
av_init_packet(&avpkt);
|
||||
@@ -279,16 +324,24 @@ void cAudio::run()
|
||||
lt_info("%s: avcodec_alloc_frame failed\n", __func__);
|
||||
goto out2;
|
||||
}
|
||||
driver = ao_default_driver_id();
|
||||
sformat.bits = 16;
|
||||
sformat.channels = c->channels;
|
||||
sformat.rate = c->sample_rate;
|
||||
sformat.byte_format = AO_FMT_NATIVE;
|
||||
sformat.matrix = 0;
|
||||
adevice = ao_open_live(driver, &sformat, NULL);
|
||||
ai = ao_driver_info(driver);
|
||||
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
|
||||
driver, ai->name, ai->short_name, ai->author);
|
||||
if (sformat.channels != c->channels || sformat.rate != c->sample_rate ||
|
||||
sformat.byte_format != AO_FMT_NATIVE || sformat.bits != 16 || adevice == NULL)
|
||||
{
|
||||
driver = ao_default_driver_id();
|
||||
sformat.bits = 16;
|
||||
sformat.channels = c->channels;
|
||||
sformat.rate = c->sample_rate;
|
||||
sformat.byte_format = AO_FMT_NATIVE;
|
||||
sformat.matrix = 0;
|
||||
if (adevice)
|
||||
ao_close(adevice);
|
||||
adevice = ao_open_live(driver, &sformat, NULL);
|
||||
ai = ao_driver_info(driver);
|
||||
lt_info("%s: changed params ch %d srate %d bits %d adevice %p\n",
|
||||
__func__, c->channels, c->sample_rate, 16, adevice);;
|
||||
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
|
||||
driver, ai->name, ai->short_name, ai->author);
|
||||
}
|
||||
#if 0
|
||||
lt_info(" driver options:");
|
||||
for (int i = 0; i < ai->option_count; ++i)
|
||||
@@ -309,7 +362,7 @@ void cAudio::run()
|
||||
}
|
||||
av_free_packet(&avpkt);
|
||||
}
|
||||
ao_close(adevice); /* can take long :-( */
|
||||
// ao_close(adevice); /* can take long :-( */
|
||||
avcodec_free_frame(&frame);
|
||||
out2:
|
||||
avcodec_close(c);
|
||||
|
@@ -76,6 +76,8 @@ static const char *devname[] = {
|
||||
static int dmx_tp_count = 0;
|
||||
#define MAX_TS_COUNT 8
|
||||
|
||||
extern bool HAL_nodec;
|
||||
|
||||
cDemux::cDemux(int n)
|
||||
{
|
||||
if (n < 0 || n > 2)
|
||||
@@ -379,14 +381,20 @@ bool cDemux::pesFilter(const unsigned short pid)
|
||||
switch (dmx_type) {
|
||||
case DMX_PCR_ONLY_CHANNEL:
|
||||
p_flt.pes_type = DMX_PES_PCR;
|
||||
if (HAL_nodec)
|
||||
return true;
|
||||
break;
|
||||
case DMX_AUDIO_CHANNEL:
|
||||
p_flt.pes_type = DMX_PES_OTHER;
|
||||
p_flt.output = DMX_OUT_TSDEMUX_TAP;
|
||||
if (HAL_nodec) /* no need to demux if we don't decode... */
|
||||
return true;
|
||||
break;
|
||||
case DMX_VIDEO_CHANNEL:
|
||||
p_flt.pes_type = DMX_PES_OTHER;
|
||||
p_flt.output = DMX_OUT_TSDEMUX_TAP;
|
||||
if (HAL_nodec)
|
||||
return true;
|
||||
break;
|
||||
case DMX_PES_CHANNEL:
|
||||
p_flt.pes_type = DMX_PES_OTHER;
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include "../common/cs_types.h"
|
||||
|
||||
#define MAX_DMX_UNITS 4
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMX_INVALID = 0,
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
static bool initialized = false;
|
||||
GLFramebuffer *glfb = NULL;
|
||||
bool HAL_nodec = false;
|
||||
|
||||
void init_td_api()
|
||||
{
|
||||
@@ -35,6 +36,10 @@ void init_td_api()
|
||||
|
||||
glfb = new GLFramebuffer(x, y); /* hard coded to PAL resolution for now */
|
||||
}
|
||||
/* allow disabling of Audio/video decoders in case we just want to
|
||||
* valgrind-check other parts... export HAL_NOAVDEC=1 */
|
||||
if (getenv("HAL_NOAVDEC"))
|
||||
HAL_nodec = true;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
@@ -50,6 +50,8 @@ extern cDemux *videoDemux;
|
||||
extern GLFramebuffer *glfb;
|
||||
int system_rev = 0;
|
||||
|
||||
extern bool HAL_nodec;
|
||||
|
||||
static uint8_t *dmxbuf;
|
||||
static int bufpos;
|
||||
|
||||
@@ -66,7 +68,8 @@ cVideo::cVideo(int, void *, void *)
|
||||
{
|
||||
lt_debug("%s\n", __func__);
|
||||
av_register_all();
|
||||
dmxbuf = (uint8_t *)malloc(DMX_BUF_SZ);
|
||||
if (!HAL_nodec)
|
||||
dmxbuf = (uint8_t *)malloc(DMX_BUF_SZ);
|
||||
bufpos = 0;
|
||||
thread_running = false;
|
||||
w_h_changed = false;
|
||||
@@ -135,7 +138,7 @@ int cVideo::setCroppingMode(int)
|
||||
int cVideo::Start(void *, unsigned short, unsigned short, void *)
|
||||
{
|
||||
lt_info("%s running %d >\n", __func__, thread_running);
|
||||
if (!thread_running)
|
||||
if (!thread_running && !HAL_nodec)
|
||||
OpenThreads::Thread::start();
|
||||
lt_info("%s running %d <\n", __func__, thread_running);
|
||||
return 0;
|
||||
@@ -206,8 +209,106 @@ void cVideo::SetVideoMode(analog_mode_t)
|
||||
{
|
||||
}
|
||||
|
||||
void cVideo::ShowPicture(const char *)
|
||||
void cVideo::ShowPicture(const char *fname)
|
||||
{
|
||||
lt_info("%s(%s)\n", __func__, fname);
|
||||
if (access(fname, R_OK))
|
||||
return;
|
||||
|
||||
unsigned int i;
|
||||
int stream_id = -1;
|
||||
int got_frame = 0;
|
||||
int len;
|
||||
AVFormatContext *avfc = NULL;
|
||||
AVCodecContext *c = NULL;
|
||||
AVCodec *codec;
|
||||
AVFrame *frame, *rgbframe;
|
||||
AVPacket avpkt;
|
||||
|
||||
if (avformat_open_input(&avfc, fname, NULL, NULL) < 0) {
|
||||
lt_info("%s: Could not open file %s\n", __func__, fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
||||
lt_info("%s: Could not find file info %s\n", __func__, fname);
|
||||
goto out_close;
|
||||
}
|
||||
for (i = 0; i < avfc->nb_streams; i++) {
|
||||
if (avfc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
stream_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stream_id < 0)
|
||||
goto out_close;
|
||||
c = avfc->streams[stream_id]->codec;
|
||||
codec = avcodec_find_decoder(c->codec_id);
|
||||
if (!avcodec_open2(c, codec, NULL) < 0) {
|
||||
lt_info("%s: Could not find/open the codec, id 0x%x\n", __func__, c->codec_id);
|
||||
goto out_close;
|
||||
}
|
||||
frame = avcodec_alloc_frame();
|
||||
rgbframe = avcodec_alloc_frame();
|
||||
if (!frame || !rgbframe) {
|
||||
lt_info("%s: Could not allocate video frame\n", __func__);
|
||||
goto out_free;
|
||||
}
|
||||
av_init_packet(&avpkt);
|
||||
if (av_read_frame(avfc, &avpkt) < 0) {
|
||||
lt_info("%s: av_read_frame < 0\n", __func__);
|
||||
goto out_free;
|
||||
}
|
||||
len = avcodec_decode_video2(c, frame, &got_frame, &avpkt);
|
||||
if (len < 0) {
|
||||
lt_info("%s: avcodec_decode_video2 %d\n", __func__, len);
|
||||
av_free_packet(&avpkt);
|
||||
goto out_free;
|
||||
}
|
||||
if (avpkt.size > len)
|
||||
lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len);
|
||||
if (got_frame) {
|
||||
unsigned int need = avpicture_get_size(PIX_FMT_RGB32, c->width, c->height);
|
||||
struct SwsContext *convert = sws_getContext(c->width, c->height, c->pix_fmt,
|
||||
c->width, c->height, PIX_FMT_RGB32,
|
||||
SWS_BICUBIC, 0, 0, 0);
|
||||
if (!convert)
|
||||
lt_info("%s: ERROR setting up SWS context\n", __func__);
|
||||
else {
|
||||
buf_m.lock();
|
||||
SWFramebuffer *f = &buffers[buf_in];
|
||||
if (f->size() < need)
|
||||
f->resize(need);
|
||||
avpicture_fill((AVPicture *)rgbframe, &(*f)[0], PIX_FMT_RGB32,
|
||||
c->width, c->height);
|
||||
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
|
||||
rgbframe->data, rgbframe->linesize);
|
||||
sws_freeContext(convert);
|
||||
f->width(c->width);
|
||||
f->height(c->height);
|
||||
f->pts(AV_NOPTS_VALUE);
|
||||
AVRational a = av_guess_sample_aspect_ratio(avfc, avfc->streams[stream_id], frame);
|
||||
f->AR(a);
|
||||
buf_in++;
|
||||
buf_in %= VDEC_MAXBUFS;
|
||||
buf_num++;
|
||||
if (buf_num > (VDEC_MAXBUFS - 1)) {
|
||||
lt_info("%s: buf_num overflow\n", __func__);
|
||||
buf_out++;
|
||||
buf_out %= VDEC_MAXBUFS;
|
||||
buf_num--;
|
||||
}
|
||||
buf_m.unlock();
|
||||
}
|
||||
}
|
||||
av_free_packet(&avpkt);
|
||||
out_free:
|
||||
avcodec_close(c);
|
||||
avcodec_free_frame(&frame);
|
||||
avcodec_free_frame(&rgbframe);
|
||||
out_close:
|
||||
avformat_close_input(&avfc);
|
||||
lt_debug("%s(%s) end\n", __func__, fname);
|
||||
}
|
||||
|
||||
void cVideo::StopPicture()
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include "../common/cs_types.h"
|
||||
|
||||
#define MAX_DMX_UNITS 4
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMX_INVALID = 0,
|
||||
|
@@ -14,6 +14,8 @@ extern "C" {
|
||||
#endif
|
||||
#define DMX_FILTER_SIZE FILTER_LENGTH
|
||||
|
||||
#define MAX_DMX_UNITS 4
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMX_INVALID = 0,
|
||||
|
Reference in New Issue
Block a user