Merge remote-tracking branch 'seife/master'

This commit is contained in:
martii
2013-05-25 12:38:21 +02:00
10 changed files with 215 additions and 28 deletions

View File

@@ -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
])

View File

@@ -8,6 +8,8 @@
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -8,6 +8,8 @@
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,

View File

@@ -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;
}

View File

@@ -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()

View File

@@ -8,6 +8,8 @@
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,

View File

@@ -14,6 +14,8 @@ extern "C" {
#endif
#define DMX_FILTER_SIZE FILTER_LENGTH
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,