summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-01-31 14:06:03 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-01-31 14:06:03 +0000
commit8695f5d8c99952a89f59b314c58a5e0bbd8a6e6e (patch)
tree47af2fb780645208a11b0e3bcea97e709c050330 /src
parent112c134d4636786c1b0e22839bd782d9554b961e (diff)
downloadxine-lib-8695f5d8c99952a89f59b314c58a5e0bbd8a6e6e.tar.gz
xine-lib-8695f5d8c99952a89f59b314c58a5e0bbd8a6e6e.tar.bz2
- MAX_PREVIEW_SIZE = 4096
- new fb driver with zero copy CVS patchset: 4058 CVS date: 2003/01/31 14:06:03
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_asf.c4
-rw-r--r--src/demuxers/demux_elem.c5
-rw-r--r--src/demuxers/demux_mpeg.c4
-rw-r--r--src/demuxers/demux_mpgaudio.c4
-rw-r--r--src/demuxers/demux_ogg.c4
-rw-r--r--src/demuxers/demux_real.c37
-rw-r--r--src/demuxers/demux_ts.c4
-rw-r--r--src/input/input_gnome_vfs.c6
-rw-r--r--src/input/input_http.c5
-rw-r--r--src/input/input_mms.c6
-rw-r--r--src/input/input_net.c7
-rw-r--r--src/input/input_plugin.h5
-rw-r--r--src/input/input_pnm.c2
-rw-r--r--src/input/input_rtsp.c2
-rw-r--r--src/input/input_stdin_fifo.c8
-rw-r--r--src/input/librtsp/rtsp_session.c12
-rw-r--r--src/input/librtsp/rtsp_session.h4
-rw-r--r--src/input/mms.c12
-rw-r--r--src/input/mms.h4
-rw-r--r--src/input/mmsh.c12
-rw-r--r--src/input/mmsh.h4
-rw-r--r--src/input/pnm.c12
-rw-r--r--src/input/pnm.h4
-rw-r--r--src/video_out/video_out_fb.c1144
24 files changed, 783 insertions, 528 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index c476d71a2..39c11def4 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_asf.c,v 1.104 2003/01/30 22:31:21 f1rmb Exp $
+ * $Id: demux_asf.c,v 1.105 2003/01/31 14:06:03 miguelfreitas Exp $
*
* demultiplexer for asf streams
*
@@ -1590,7 +1590,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
input_plugin_t *input) {
demux_asf_t *this;
- uint8_t buf[DEFRAG_BUFSIZE];
+ uint8_t buf[MAX_PREVIEW_SIZE+1];
int len;
switch (stream->content_detection_method) {
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c
index 12e43f44b..71dc918c6 100644
--- a/src/demuxers/demux_elem.c
+++ b/src/demuxers/demux_elem.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_elem.c,v 1.67 2003/01/04 14:48:11 miguelfreitas Exp $
+ * $Id: demux_elem.c,v 1.68 2003/01/31 14:06:06 miguelfreitas Exp $
*
* demultiplexer for elementary mpeg streams
*
@@ -43,6 +43,7 @@
*/
#define NUM_PREVIEW_BUFFERS 50
+#define SCRATCH_SIZE ((MAX_PREVIEW_SIZE>4096)?MAX_PREVIEW_SIZE:4096)
typedef struct {
@@ -60,7 +61,7 @@ typedef struct {
int blocksize;
int status;
- uint8_t scratch[4096];
+ uint8_t scratch[SCRATCH_SIZE];
char last_mrl[1024];
} demux_mpeg_elem_t ;
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index dea0f3eca..61b8d5c01 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_mpeg.c,v 1.105 2003/01/16 22:25:53 miguelfreitas Exp $
+ * $Id: demux_mpeg.c,v 1.106 2003/01/31 14:06:08 miguelfreitas Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -891,7 +891,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
switch (stream->content_detection_method) {
case METHOD_BY_CONTENT: {
- uint8_t buf[4096];
+ uint8_t buf[MAX_PREVIEW_SIZE];
off_t mdat_atom_offset = -1;
int64_t mdat_atom_size = -1;
unsigned int fourcc_tag;
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c
index 6b006b880..e8dc93c72 100644
--- a/src/demuxers/demux_mpgaudio.c
+++ b/src/demuxers/demux_mpgaudio.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_mpgaudio.c,v 1.90 2003/01/26 15:58:36 tmmm Exp $
+ * $Id: demux_mpgaudio.c,v 1.91 2003/01/31 14:06:09 miguelfreitas Exp $
*
* demultiplexer for mpeg audio (i.e. mp3) streams
*
@@ -337,7 +337,7 @@ static int demux_mpgaudio_get_status (demux_plugin_t *this_gen) {
static uint32_t demux_mpgaudio_read_head(input_plugin_t *input) {
- uint8_t buf[4096];
+ uint8_t buf[MAX_PREVIEW_SIZE];
uint32_t head=0;
int bs = 0;
diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c
index 153b73c7c..ca1322ab7 100644
--- a/src/demuxers/demux_ogg.c
+++ b/src/demuxers/demux_ogg.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_ogg.c,v 1.63 2003/01/26 23:48:47 tmattern Exp $
+ * $Id: demux_ogg.c,v 1.64 2003/01/31 14:06:09 miguelfreitas Exp $
*
* demultiplexer for ogg streams
*
@@ -945,7 +945,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
case METHOD_BY_CONTENT:
{
- uint8_t buf[4096];
+ uint8_t buf[MAX_PREVIEW_SIZE];
if ((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) {
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index ecdc4d883..fe9863d87 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -28,7 +28,7 @@
*
* Based on FFmpeg's libav/rm.c.
*
- * $Id: demux_real.c,v 1.39 2003/01/29 18:53:56 miguelfreitas Exp $
+ * $Id: demux_real.c,v 1.40 2003/01/31 14:06:10 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -645,8 +645,7 @@ static int demux_real_parse_references( demux_real_t *this) {
;
j--;
buf[j]='\0';
- printf("demux_real: ref=%s\n", &buf[i]);
-
+
uevent.type = XINE_EVENT_MRL_REFERENCE;
uevent.stream = this->stream;
uevent.data_length = strlen(&buf[i])+sizeof(xine_mrl_reference_data_t);
@@ -1128,13 +1127,13 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
input_plugin_t *input = (input_plugin_t *) input_gen;
demux_real_t *this;
+ uint8_t buf[MAX_PREVIEW_SIZE+1];
+ int len;
switch (stream->content_detection_method) {
case METHOD_BY_CONTENT:
{
- uint8_t buf[4096], len;
-
if ((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) {
input->seek(input, 0, SEEK_SET);
@@ -1214,28 +1213,24 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
/* discover stream type */
- {
- uint8_t buf[4096], len;
-
- this->reference_mode = 0;
- if ((len = input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) {
-
- input->seek(input, 0, SEEK_SET);
+ this->reference_mode = 0;
+ if ((len = input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) {
- if ( (len = input->read(input, buf, 1024)) > 0) {
- if (real_check_stream_type(buf,len) == 2)
- this->reference_mode = 1;
- }
+ input->seek(input, 0, SEEK_SET);
- } else if ((len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW))) {
-
+ if ( (len = input->read(input, buf, 1024)) > 0) {
if (real_check_stream_type(buf,len) == 2)
this->reference_mode = 1;
}
-
- if(this->reference_mode)
- printf("demux_real: reference stream detected\n");
+
+ } else if ((len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW))) {
+
+ if (real_check_stream_type(buf,len) == 2)
+ this->reference_mode = 1;
}
+
+ if(this->reference_mode)
+ printf("demux_real: reference stream detected\n");
this->demux_plugin.send_headers = demux_real_send_headers;
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 4e31e1c2b..a529df41e 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_ts.c,v 1.77 2003/01/26 15:56:21 tmmm Exp $
+ * $Id: demux_ts.c,v 1.78 2003/01/31 14:06:10 miguelfreitas Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -1826,7 +1826,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
switch (stream->content_detection_method) {
case METHOD_BY_CONTENT: {
- uint8_t buf[4096];
+ uint8_t buf[MAX_PREVIEW_SIZE];
int got_sample;
int i, j;
int try_again, ts_detected;
diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c
index ff45b2d4e..c46b86222 100644
--- a/src/input/input_gnome_vfs.c
+++ b/src/input/input_gnome_vfs.c
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_gnome_vfs.c,v 1.2 2003/01/13 20:10:23 hadess Exp $
+ * $Id: input_gnome_vfs.c,v 1.3 2003/01/31 14:06:12 miguelfreitas Exp $
*/
@@ -37,8 +37,6 @@
#define D(x...) g_message (x)
#define LOG
-#define PREVIEW_SIZE 16384
-
typedef struct {
input_class_t input_class;
xine_t *xine;
@@ -56,7 +54,7 @@ typedef struct {
GnomeVFSHandle *sub;
/* Preview */
- char preview[PREVIEW_SIZE];
+ char preview[MAX_PREVIEW_SIZE];
off_t preview_size;
off_t preview_pos;
} gnomevfs_input_t;
diff --git a/src/input/input_http.c b/src/input/input_http.c
index 102dd5e96..9b21dde3d 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -45,7 +45,6 @@
#define LOG
*/
-#define PREVIEW_SIZE 2200
#define BUFSIZE 1024
#define DEFAULT_HTTP_PORT 80
@@ -82,7 +81,7 @@ typedef struct {
char *proxyhost;
int proxyport;
- char preview[PREVIEW_SIZE];
+ char preview[MAX_PREVIEW_SIZE];
off_t preview_size;
off_t preview_pos;
@@ -888,7 +887,7 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea
*/
this->preview_size = http_plugin_read (&this->input_plugin, this->preview,
- PREVIEW_SIZE);
+ MAX_PREVIEW_SIZE);
this->preview_pos = 0;
this->curpos = 0;
diff --git a/src/input/input_mms.c b/src/input/input_mms.c
index d40a564ec..07aa09b2f 100644
--- a/src/input/input_mms.c
+++ b/src/input/input_mms.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_mms.c,v 1.34 2003/01/18 17:19:45 tmattern Exp $
+ * $Id: input_mms.c,v 1.35 2003/01/31 14:06:13 miguelfreitas Exp $
*
* mms input plugin based on work from major mms
*/
@@ -290,10 +290,10 @@ static int mms_plugin_get_optional_data (input_plugin_t *this_gen,
case INPUT_OPTIONAL_DATA_PREVIEW:
switch (this->protocol) {
case PROTOCOL_MMST:
- return mms_peek_header (this->mms, data);
+ return mms_peek_header (this->mms, data, MAX_PREVIEW_SIZE);
break;
case PROTOCOL_MMSH:
- return mmsh_peek_header (this->mmsh, data);
+ return mmsh_peek_header (this->mmsh, data, MAX_PREVIEW_SIZE);
break;
}
break;
diff --git a/src/input/input_net.c b/src/input/input_net.c
index 7e37b625a..a6c72f0dc 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -20,7 +20,7 @@
* Read from a tcp network stream over a lan (put a tweaked mp1e encoder the
* other end and you can watch tv anywhere in the house ..)
*
- * $Id: input_net.c,v 1.41 2002/12/27 16:47:11 miguelfreitas Exp $
+ * $Id: input_net.c,v 1.42 2003/01/31 14:06:13 miguelfreitas Exp $
*
* how to set up mp1e for use with this plugin:
*
@@ -75,7 +75,6 @@
*/
#define NET_BS_LEN 2324
-#define PREVIEW_SIZE 2200
#define BUFSIZE 1024
typedef struct {
@@ -86,7 +85,7 @@ typedef struct {
int fh;
char *mrl;
- char preview[PREVIEW_SIZE];
+ char preview[MAX_PREVIEW_SIZE];
off_t preview_size;
off_t preview_pos;
@@ -361,7 +360,7 @@ static input_plugin_t *net_plugin_open (input_class_t *cls_gen, xine_stream_t *s
this->preview_pos = 0;
this->preview_size = 0;
- this->preview_size = read (this->fh, this->preview, PREVIEW_SIZE);
+ this->preview_size = read (this->fh, this->preview, MAX_PREVIEW_SIZE);
this->preview_pos = 0;
this->curpos = 0;
diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h
index 2bd26461b..d66b97939 100644
--- a/src/input/input_plugin.h
+++ b/src/input/input_plugin.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_plugin.h,v 1.43 2002/12/29 16:48:35 mroi Exp $
+ * $Id: input_plugin.h,v 1.44 2003/01/31 14:06:15 miguelfreitas Exp $
*/
#ifndef HAVE_INPUT_PLUGIN_H
@@ -232,6 +232,8 @@ struct input_plugin_s {
* they can handle the stream or not. the preview data must
* be buffered and delivered again through subsequent
* read() calls.
+ * caller must provide a buffer allocated with at least
+ * MAX_PREVIEW_SIZE bytes.
*/
#define INPUT_CAP_PREVIEW 0x00000040
@@ -256,6 +258,7 @@ struct input_plugin_s {
#define INPUT_OPTIONAL_DATA_PREVIEW 7
#define MAX_MRL_ENTRIES 255
+#define MAX_PREVIEW_SIZE 4096
/* Types of mrls returned by get_dir() */
#define mrl_unknown (0 << 0)
diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c
index 3d75c0ac9..ce62a81d8 100644
--- a/src/input/input_pnm.c
+++ b/src/input/input_pnm.c
@@ -200,7 +200,7 @@ static int pnm_plugin_get_optional_data (input_plugin_t *this_gen,
switch (data_type) {
case INPUT_OPTIONAL_DATA_PREVIEW:
- return pnm_peek_header(this->pnm, data);
+ return pnm_peek_header(this->pnm, data, MAX_PREVIEW_SIZE);
break;
}
diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c
index cf5ecab57..dff1aa851 100644
--- a/src/input/input_rtsp.c
+++ b/src/input/input_rtsp.c
@@ -205,7 +205,7 @@ static int rtsp_plugin_get_optional_data (input_plugin_t *this_gen,
switch (data_type) {
case INPUT_OPTIONAL_DATA_PREVIEW:
- return rtsp_session_peek_header(this->rtsp, data);
+ return rtsp_session_peek_header(this->rtsp, data, MAX_PREVIEW_SIZE);
break;
}
diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c
index d25aba0fe..21dca4bcc 100644
--- a/src/input/input_stdin_fifo.c
+++ b/src/input/input_stdin_fifo.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: input_stdin_fifo.c,v 1.41 2003/01/17 17:50:20 mroi Exp $
+ * $Id: input_stdin_fifo.c,v 1.42 2003/01/31 14:06:16 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -41,8 +41,6 @@
#define LOG
*/
-#define PREVIEW_SIZE 2200
-
#define DEFAULT_LOW_WATER_MARK 1
#define DEFAULT_HIGH_WATER_MARK 5
@@ -55,7 +53,7 @@ typedef struct {
char *mrl;
off_t curpos;
- char preview[PREVIEW_SIZE];
+ char preview[MAX_PREVIEW_SIZE];
off_t preview_size;
off_t preview_pos;
@@ -337,7 +335,7 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea
*/
this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview,
- PREVIEW_SIZE);
+ MAX_PREVIEW_SIZE);
this->preview_pos = 0;
return &this->input_plugin;
diff --git a/src/input/librtsp/rtsp_session.c b/src/input/librtsp/rtsp_session.c
index 145cfe00d..a6d5ab1d6 100644
--- a/src/input/librtsp/rtsp_session.c
+++ b/src/input/librtsp/rtsp_session.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: rtsp_session.c,v 1.7 2002/12/24 01:10:53 holstsn Exp $
+ * $Id: rtsp_session.c,v 1.8 2003/01/31 14:06:17 miguelfreitas Exp $
*
* high level interface to rtsp servers.
*/
@@ -168,10 +168,14 @@ int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
return len;
}
-int rtsp_session_peek_header(rtsp_session_t *this, char *buf) {
+int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize) {
- memcpy(buf, this->header, this->header_len);
- return this->header_len;
+ int len;
+
+ len = (this->header_len < maxsize) ? this->header_len : maxsize;
+
+ memcpy(buf, this->header, len);
+ return len;
}
void rtsp_session_end(rtsp_session_t *session) {
diff --git a/src/input/librtsp/rtsp_session.h b/src/input/librtsp/rtsp_session.h
index d3daa4286..c287118e3 100644
--- a/src/input/librtsp/rtsp_session.h
+++ b/src/input/librtsp/rtsp_session.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: rtsp_session.h,v 1.3 2002/12/24 01:10:53 holstsn Exp $
+ * $Id: rtsp_session.h,v 1.4 2003/01/31 14:06:18 miguelfreitas Exp $
*
* high level interface to rtsp servers.
*/
@@ -31,7 +31,7 @@ rtsp_session_t *rtsp_session_start(char *mrl);
int rtsp_session_read(rtsp_session_t *session, char *data, int len);
-int rtsp_session_peek_header(rtsp_session_t *this, char *buf);
+int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize);
void rtsp_session_end(rtsp_session_t *session);
diff --git a/src/input/mms.c b/src/input/mms.c
index 8afb68ac0..6b5545577 100644
--- a/src/input/mms.c
+++ b/src/input/mms.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: mms.c,v 1.19 2003/01/25 15:00:07 tmattern Exp $
+ * $Id: mms.c,v 1.20 2003/01/31 14:06:17 miguelfreitas Exp $
*
* based on work from major mms
* utility functions to handle communication with an mms server
@@ -1133,10 +1133,14 @@ static int get_media_packet (mms_t *this) {
return 1;
}
-int mms_peek_header (mms_t *this, char *data) {
+int mms_peek_header (mms_t *this, char *data, int maxsize) {
- memcpy (data, this->asf_header, this->asf_header_len);
- return this->asf_header_len;
+ int len;
+
+ len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize;
+
+ memcpy(data, this->asf_header, len);
+ return len;
}
int mms_read (mms_t *this, char *data, int len) {
diff --git a/src/input/mms.h b/src/input/mms.h
index 3bb3b2358..565b89b65 100644
--- a/src/input/mms.h
+++ b/src/input/mms.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: mms.h,v 1.8 2002/12/13 08:56:53 f1rmb Exp $
+ * $Id: mms.h,v 1.9 2003/01/31 14:06:17 miguelfreitas Exp $
*
* libmms public header
*/
@@ -37,7 +37,7 @@ int mms_read (mms_t *this, char *data, int len);
uint32_t mms_get_length (mms_t *this);
void mms_close (mms_t *this);
-int mms_peek_header (mms_t *this, char *data);
+int mms_peek_header (mms_t *this, char *data, int maxsize);
#endif
diff --git a/src/input/mmsh.c b/src/input/mmsh.c
index 1f909fd5c..db3a256c2 100644
--- a/src/input/mmsh.c
+++ b/src/input/mmsh.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: mmsh.c,v 1.9 2003/01/25 15:00:10 tmattern Exp $
+ * $Id: mmsh.c,v 1.10 2003/01/31 14:06:17 miguelfreitas Exp $
*
* based on mms.c and specs from avifile
* (http://avifile.sourceforge.net/asf-1.0.htm)
@@ -1022,10 +1022,14 @@ static int get_media_packet (mmsh_t *this) {
}
}
-int mmsh_peek_header (mmsh_t *this, char *data) {
+int mmsh_peek_header (mmsh_t *this, char *data, int maxsize) {
- memcpy (data, this->asf_header, this->asf_header_len);
- return this->asf_header_len;
+ int len;
+
+ len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize;
+
+ memcpy(data, this->asf_header, len);
+ return len;
}
int mmsh_read (mmsh_t *this, char *data, int len) {
diff --git a/src/input/mmsh.h b/src/input/mmsh.h
index 6005851a5..29ad2bf55 100644
--- a/src/input/mmsh.h
+++ b/src/input/mmsh.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: mmsh.h,v 1.1 2003/01/13 01:11:57 tmattern Exp $
+ * $Id: mmsh.h,v 1.2 2003/01/31 14:06:17 miguelfreitas Exp $
*
* libmmsh public header
*/
@@ -37,6 +37,6 @@ int mmsh_read (mmsh_t *this, char *data, int len);
uint32_t mmsh_get_length (mmsh_t *this);
void mmsh_close (mmsh_t *this);
-int mmsh_peek_header (mmsh_t *this, char *data);
+int mmsh_peek_header (mmsh_t *this, char *data, int maxsize);
#endif
diff --git a/src/input/pnm.c b/src/input/pnm.c
index eb1a1c47a..d0a9b0c9e 100644
--- a/src/input/pnm.c
+++ b/src/input/pnm.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: pnm.c,v 1.10 2003/01/22 16:33:24 holstsn Exp $
+ * $Id: pnm.c,v 1.11 2003/01/31 14:06:17 miguelfreitas Exp $
*
* pnm protocol implementation
* based upon code from joschka
@@ -930,10 +930,14 @@ int pnm_read (pnm_t *this, char *data, int len) {
return len;
}
-int pnm_peek_header (pnm_t *this, char *data) {
+int pnm_peek_header (pnm_t *this, char *data, int maxsize) {
- memcpy (data, this->header, this->header_len);
- return this->header_len;
+ int len;
+
+ len = (this->header_len < maxsize) ? this->header_len : maxsize;
+
+ memcpy(data, this->header, len);
+ return len;
}
void pnm_close(pnm_t *p) {
diff --git a/src/input/pnm.h b/src/input/pnm.h
index a2fb68539..1d4c54698 100644
--- a/src/input/pnm.h
+++ b/src/input/pnm.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: pnm.h,v 1.2 2002/12/12 22:08:15 holstsn Exp $
+ * $Id: pnm.h,v 1.3 2003/01/31 14:06:17 miguelfreitas Exp $
*
* pnm util functions header by joschka
*/
@@ -37,7 +37,7 @@ pnm_t* pnm_connect (const char *url);
int pnm_read (pnm_t *this, char *data, int len);
void pnm_close (pnm_t *this);
-int pnm_peek_header (pnm_t *this, char *data);
+int pnm_peek_header (pnm_t *this, char *data, int maxsize);
#endif
diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c
index d654da14c..8bbb2319e 100644
--- a/src/video_out/video_out_fb.c
+++ b/src/video_out/video_out_fb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2002 the xine project
+ * Copyright (C) 2000-2002 the xine project and Fredrik Noring
*
* This file is part of xine, a free video player.
*
@@ -17,10 +17,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_fb.c,v 1.21 2002/12/21 12:56:49 miguelfreitas Exp $
+ * $Id: video_out_fb.c,v 1.22 2003/01/31 14:06:18 miguelfreitas Exp $
*
* video_out_fb.c, frame buffer xine driver by Miguel Freitas
*
+ * Contributors:
+ *
+ * Fredrik Noring <noring@nocrew.org>: Zero copy buffers and clean up.
+ *
* based on xine's video_out_xshm.c...
* ...based on mpeg2dec code from
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
@@ -28,12 +32,17 @@
* ideas from ppmtofb - Display P?M graphics on framebuffer devices
* by Geert Uytterhoeven and Chris Lawrence
*
- * note: you must use this driver with aaxine. xine-ui won't work because of
- * the visual type (but this can be changed, see below)
+ * Note: Use this with fbxine. It may work with the regular xine too,
+ * provided the visual type is changed (see below).
*
* TODO: VT switching (configurable)
*/
+/* #define USE_X11_VISUAL */
+
+#define RECOMMENDED_NUM_BUFFERS 5
+#define MAXIMUM_NUM_BUFFERS 25
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -73,7 +82,8 @@
#define LOG
-typedef struct fb_frame_s {
+typedef struct fb_frame_s
+{
vo_frame_t vo_frame;
int format;
@@ -83,25 +93,33 @@ typedef struct fb_frame_s {
uint8_t *chunk[3]; /* mem alloc by xmalloc_aligned */
- yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */
+ yuv2rgb_t *yuv2rgb; /* yuv2rgb converter for this frame */
uint8_t *rgb_dst;
int yuv_stride;
int stripe_height, stripe_inc;
int bytes_per_line;
- uint8_t *data;
-} fb_frame_t;
-typedef struct fb_driver_s {
+ uint8_t* video_mem; /* mmapped video memory */
+ uint8_t* data;
+ int yoffset;
+
+ struct fb_driver_s *this;
+} fb_frame_t;
+typedef struct fb_driver_s
+{
vo_driver_t vo_driver;
int fd;
int mem_size;
- uint8_t* video_mem; /* mmapped video memory */
+ uint8_t* video_mem_base; /* mmapped video memory */
int depth, bpp, bytes_per_pixel;
+ int total_num_native_buffers;
+ int used_num_buffers;
+
int yuv2rgb_mode;
int yuv2rgb_swap;
int yuv2rgb_gamma;
@@ -113,470 +131,623 @@ typedef struct fb_driver_s {
/* size / aspect ratio calculations */
vo_scale_t sc;
- int fb_linelength;
+ int fb_bytes_per_line;
+ fb_frame_t *cur_frame, *old_frame;
+
+ struct fb_var_screeninfo fb_var;
+ struct fb_fix_screeninfo fb_fix;
+
+ int use_zero_copy;
} fb_driver_t;
-typedef struct {
+typedef struct
+{
video_driver_class_t driver_class;
-
config_values_t *config;
} fb_class_t;
-
-/*
- * and now, the driver functions
- */
-
-static uint32_t fb_get_capabilities (vo_driver_t *this_gen) {
- return VO_CAP_COPIES_IMAGE | VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS;
+static uint32_t fb_get_capabilities(vo_driver_t *this_gen)
+{
+ return VO_CAP_COPIES_IMAGE |
+ VO_CAP_YV12 |
+ VO_CAP_YUY2 |
+ VO_CAP_BRIGHTNESS;
}
-static void fb_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
- fb_frame_t *frame = (fb_frame_t *) vo_img ;
+static void fb_frame_copy(vo_frame_t *vo_img, uint8_t **src)
+{
+ fb_frame_t *frame = (fb_frame_t *)vo_img ;
vo_img->copy_called = 1;
-
- if (frame->format == XINE_IMGFMT_YV12) {
- frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst,
+ if(frame->format == XINE_IMGFMT_YV12)
+ frame->yuv2rgb->yuv2rgb_fun(frame->yuv2rgb, frame->rgb_dst,
src[0], src[1], src[2]);
- } else {
-
- frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst,
- src[0]);
-
- }
-
+ else
+ frame->yuv2rgb->yuy22rgb_fun(frame->yuv2rgb,
+ frame->rgb_dst, src[0]);
frame->rgb_dst += frame->stripe_inc;
}
-static void fb_frame_field (vo_frame_t *vo_img, int which_field) {
-
- fb_frame_t *frame = (fb_frame_t *) vo_img ;
+static void fb_frame_field(vo_frame_t *vo_img, int which_field)
+{
+ fb_frame_t *frame = (fb_frame_t *)vo_img ;
- switch (which_field) {
+ switch(which_field)
+ {
case VO_TOP_FIELD:
- frame->rgb_dst = (uint8_t *)frame->data;
- frame->stripe_inc = 2*frame->stripe_height * frame->bytes_per_line;
+ frame->rgb_dst = frame->data;
+ frame->stripe_inc = 2*frame->stripe_height *
+ frame->bytes_per_line;
break;
+
case VO_BOTTOM_FIELD:
- frame->rgb_dst = (uint8_t *)frame->data + frame->bytes_per_line ;
- frame->stripe_inc = 2*frame->stripe_height * frame->bytes_per_line;
+ frame->rgb_dst = frame->data +
+ frame->bytes_per_line ;
+ frame->stripe_inc = 2*frame->stripe_height *
+ frame->bytes_per_line;
break;
+
case VO_BOTH_FIELDS:
- frame->rgb_dst = (uint8_t *)frame->data;
+ frame->rgb_dst = frame->data;
break;
}
}
-static void fb_frame_dispose (vo_frame_t *vo_img) {
-
- fb_frame_t *frame = (fb_frame_t *) vo_img ;
+static void fb_frame_dispose(vo_frame_t *vo_img)
+{
+ fb_frame_t *frame = (fb_frame_t *)vo_img;
- if (frame->data) {
+ if(!frame->this->use_zero_copy)
free(frame->data);
- }
-
- free (frame);
+ free(frame);
}
+static vo_frame_t *fb_alloc_frame(vo_driver_t *this_gen)
+{
+ fb_driver_t *this = (fb_driver_t *)this_gen;
+ fb_frame_t *frame;
-static vo_frame_t *fb_alloc_frame (vo_driver_t *this_gen) {
- fb_driver_t *this = (fb_driver_t *) this_gen;
- fb_frame_t *frame ;
+ if(this->use_zero_copy &&
+ this->total_num_native_buffers <= this->used_num_buffers)
+ return 0;
- frame = (fb_frame_t *) malloc (sizeof (fb_frame_t));
- if (frame==NULL) {
- printf ("fb_alloc_frame: out of memory\n");
- return NULL;
+ frame = (fb_frame_t *)malloc(sizeof(fb_frame_t));
+ if(!frame)
+ {
+ fprintf(stderr, "fb_alloc_frame: Out of memory.\n");
+ return 0;
}
- memset (frame, 0, sizeof(fb_frame_t));
- memcpy (&frame->sc, &this->sc, sizeof(vo_scale_t));
+ memset(frame, 0, sizeof(fb_frame_t));
+ memcpy(&frame->sc, &this->sc, sizeof(vo_scale_t));
- pthread_mutex_init (&frame->vo_frame.mutex, NULL);
-
- /*
- * supply required functions
- */
+ pthread_mutex_init(&frame->vo_frame.mutex, NULL);
+ /* supply required functions */
frame->vo_frame.copy = fb_frame_copy;
frame->vo_frame.field = fb_frame_field;
frame->vo_frame.dispose = fb_frame_dispose;
frame->vo_frame.driver = this_gen;
- /*
- * colorspace converter for this frame
- */
-
- frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory);
+ frame->this = this;
- return (vo_frame_t *) frame;
-}
-
+ /* colorspace converter for this frame */
+ frame->yuv2rgb =
+ this->yuv2rgb_factory->create_converter(this->yuv2rgb_factory);
+
+ if(this->use_zero_copy)
+ {
+ frame->yoffset = this->used_num_buffers * this->fb_var.yres;
+ frame->video_mem = this->video_mem_base +
+ this->used_num_buffers * this->fb_var.yres *
+ this->fb_bytes_per_line;
+
+ memset(frame->video_mem, 0,
+ this->fb_var.yres * this->fb_bytes_per_line);
+ }
+ else
+ frame->video_mem = this->video_mem_base;
-static void fb_compute_ideal_size (fb_driver_t *this, fb_frame_t *frame) {
+ this->used_num_buffers++;
- vo_scale_compute_ideal_size( &frame->sc );
+ return (vo_frame_t *)frame;
}
-static void fb_compute_rgb_size (fb_driver_t *this, fb_frame_t *frame) {
+static void fb_compute_ideal_size(fb_driver_t *this, fb_frame_t *frame)
+{
+ vo_scale_compute_ideal_size(&frame->sc);
+}
- vo_scale_compute_output_size( &frame->sc );
+static void fb_compute_rgb_size(fb_driver_t *this, fb_frame_t *frame)
+{
+ vo_scale_compute_output_size(&frame->sc);
/* avoid problems in yuv2rgb */
- if (frame->sc.output_height < ((frame->sc.delivered_height + 15) >> 4))
- frame->sc.output_height = ((frame->sc.delivered_height + 15) >> 4);
+ if(frame->sc.output_height < (frame->sc.delivered_height+15) >> 4)
+ frame->sc.output_height = (frame->sc.delivered_height+15) >> 4;
+
if (frame->sc.output_width < 8)
frame->sc.output_width = 8;
- if (frame->sc.output_width & 1) /* yuv2rgb_mlib needs an even YUV2 width */
- frame->sc.output_width++;
+ /* yuv2rgb_mlib needs an even YUV2 width */
+ if (frame->sc.output_width & 1)
+ frame->sc.output_width++;
#ifdef LOG
printf("video_out_fb: frame source %d x %d => screen output %d x %d%s\n",
frame->sc.delivered_width, frame->sc.delivered_height,
frame->sc.output_width, frame->sc.output_height,
- ( frame->sc.delivered_width != frame->sc.output_width
- || frame->sc.delivered_height != frame->sc.output_height
- ? ", software scaling"
- : "" )
- );
+ (frame->sc.delivered_width != frame->sc.output_width ||
+ frame->sc.delivered_height != frame->sc.output_height ?
+ ", software scaling" : ""));
#endif
}
-static void fb_update_frame_format (vo_driver_t *this_gen,
- vo_frame_t *frame_gen,
- uint32_t width, uint32_t height,
- int ratio_code, int format, int flags) {
-
- fb_driver_t *this = (fb_driver_t *) this_gen;
- fb_frame_t *frame = (fb_frame_t *) frame_gen;
-
- flags &= VO_BOTH_FIELDS;
-
- /* find out if we need to adapt this frame */
-
- if ((width != frame->sc.delivered_width)
- || (height != frame->sc.delivered_height)
- || (ratio_code != frame->sc.delivered_ratio_code)
- || (flags != frame->flags)
- || (format != frame->format)
- || (this->sc.user_ratio != frame->sc.user_ratio)) {
-
-#ifdef LOG
- printf ("video_out_fb: frame format (from decoder) has changed => adapt\n");
-#endif
-
- frame->sc.delivered_width = width;
- frame->sc.delivered_height = height;
- frame->sc.delivered_ratio_code = ratio_code;
- frame->flags = flags;
- frame->format = format;
- frame->sc.user_ratio = this->sc.user_ratio;
+static void setup_colorspace_converter(fb_frame_t *frame, int flags)
+{
+ switch(flags)
+ {
+ case VO_TOP_FIELD:
+ case VO_BOTTOM_FIELD:
+ frame->yuv2rgb->
+ configure(frame->yuv2rgb,
+ frame->sc.delivered_width,
+ 16,
+ 2 * frame->vo_frame.pitches[0],
+ 2 * frame->vo_frame.pitches[1],
+ frame->sc.output_width,
+ frame->stripe_height,
+ frame->bytes_per_line * 2);
+ frame->yuv_stride = frame->bytes_per_line * 2;
+ break;
- fb_compute_ideal_size (this, frame);
- fb_compute_rgb_size (this, frame);
+ case VO_BOTH_FIELDS:
+ frame->yuv2rgb->
+ configure(frame->yuv2rgb,
+ frame->sc.delivered_width,
+ 16,
+ frame->vo_frame.pitches[0],
+ frame->vo_frame.pitches[1],
+ frame->sc.output_width,
+ frame->stripe_height,
+ frame->bytes_per_line);
+ frame->yuv_stride = frame->bytes_per_line;
+ break;
+ }
+}
+static void reset_dest_pointers(fb_frame_t *frame, int flags)
+{
+ switch(flags)
+ {
+ case VO_TOP_FIELD:
+ frame->rgb_dst = frame->data;
+ frame->stripe_inc = 2 * frame->stripe_height *
+ frame->bytes_per_line;
+ break;
- /*
- printf ("video_out_fb: updating frame to %d x %d\n",
- frame->output_width, frame->output_height);
- */
+ case VO_BOTTOM_FIELD:
+ frame->rgb_dst = frame->data +
+ frame->bytes_per_line ;
+ frame->stripe_inc = 2 * frame->stripe_height *
+ frame->bytes_per_line;
+ break;
- /*
- * (re-) allocate
- */
+ case VO_BOTH_FIELDS:
+ frame->rgb_dst = frame->data;
+ frame->stripe_inc = frame->stripe_height *
+ frame->bytes_per_line;
+ break;
+ }
+}
- if (frame->data) {
- if( frame->chunk[0] ) {
- free( frame->chunk[0] );
+static void frame_reallocate(fb_driver_t *this, fb_frame_t *frame,
+ uint32_t width, uint32_t height, int format)
+{
+ if(frame->chunk[0])
+ {
+ free(frame->chunk[0]);
frame->chunk[0] = NULL;
- }
- if( frame->chunk[1] ) {
- free( frame->chunk[1] );
+ }
+ if(frame->chunk[1])
+ {
+ free(frame->chunk[1]);
frame->chunk[1] = NULL;
- }
- if( frame->chunk[2] ) {
- free( frame->chunk[2] );
+ }
+ if(frame->chunk[2])
+ {
+ free(frame->chunk[2]);
frame->chunk[2] = NULL;
- }
+ }
- free (frame->data);
- }
-
+ if(this->use_zero_copy)
+ {
+ frame->data = frame->video_mem +
+ frame->sc.output_yoffset*this->fb_bytes_per_line+
+ frame->sc.output_xoffset*this->bytes_per_pixel;
+ }
+ else
+ {
+ if(frame->data)
+ free(frame->data);
+ frame->data = xine_xmalloc(frame->sc.output_width *
+ frame->sc.output_height *
+ this->bytes_per_pixel);
+ }
- frame->data = xine_xmalloc (frame->sc.output_width * frame->sc.output_height *
- this->bytes_per_pixel );
-
- if (format == XINE_IMGFMT_YV12) {
+ if(format == XINE_IMGFMT_YV12)
+ {
frame->vo_frame.pitches[0] = 8*((width + 7) / 8);
frame->vo_frame.pitches[1] = 8*((width + 15) / 16);
frame->vo_frame.pitches[2] = 8*((width + 15) / 16);
- frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height,
+
+ frame->vo_frame.base[0] =
+ xine_xmalloc_aligned(16,
+ frame->vo_frame.pitches[0] *
+ height,
(void **)&frame->chunk[0]);
- frame->vo_frame.base[1] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[1] * ((height+1)/2),
+
+ frame->vo_frame.base[1] =
+ xine_xmalloc_aligned(16,
+ frame->vo_frame.pitches[1] *
+ ((height+1)/2),
(void **)&frame->chunk[1]);
- frame->vo_frame.base[2] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[2] * ((height+1)/2),
+
+ frame->vo_frame.base[2] =
+ xine_xmalloc_aligned(16,
+ frame->vo_frame.pitches[2] *
+ ((height+1)/2),
(void **)&frame->chunk[2]);
- } else {
- frame->vo_frame.pitches[0] = 8*((width + 3) / 4);
- frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height,
+ }
+ else
+ {
+ frame->vo_frame.pitches[0] = 8 * ((width + 3) / 4);
+
+ frame->vo_frame.base[0] =
+ xine_xmalloc_aligned(16,
+ frame->vo_frame.pitches[0] *
+ height,
(void **)&frame->chunk[0]);
frame->chunk[1] = NULL;
frame->chunk[2] = NULL;
- }
+ }
+}
- frame->stripe_height = 16 * frame->sc.output_height / frame->sc.delivered_height;
- frame->bytes_per_line = frame->sc.output_width * this->bytes_per_pixel;
+static void fb_update_frame_format(vo_driver_t *this_gen,
+ vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height,
+ int ratio_code, int format, int flags)
+{
+ fb_driver_t *this = (fb_driver_t *)this_gen;
+ fb_frame_t *frame = (fb_frame_t *)frame_gen;
- /*
- * set up colorspace converter
- */
+ flags &= VO_BOTH_FIELDS;
- switch (flags) {
- case VO_TOP_FIELD:
- case VO_BOTTOM_FIELD:
- frame->yuv2rgb->configure (frame->yuv2rgb,
- frame->sc.delivered_width,
- 16,
- 2*frame->vo_frame.pitches[0],
- 2*frame->vo_frame.pitches[1],
- frame->sc.output_width,
- frame->stripe_height,
- frame->bytes_per_line*2);
- frame->yuv_stride = frame->bytes_per_line*2;
- break;
- case VO_BOTH_FIELDS:
- frame->yuv2rgb->configure (frame->yuv2rgb,
- frame->sc.delivered_width,
- 16,
- frame->vo_frame.pitches[0],
- frame->vo_frame.pitches[1],
- frame->sc.output_width,
- frame->stripe_height,
- frame->bytes_per_line);
- frame->yuv_stride = frame->bytes_per_line;
- break;
- }
- }
+ /* Find out if we need to adapt this frame. */
+ if (width != frame->sc.delivered_width ||
+ height != frame->sc.delivered_height ||
+ ratio_code != frame->sc.delivered_ratio_code ||
+ flags != frame->flags ||
+ format != frame->format ||
+ this->sc.user_ratio != frame->sc.user_ratio)
+ {
+#ifdef LOG
+ printf("video_out_fb: frame format (from decoder) "
+ "has changed => adapt\n");
+#endif
- /*
- * reset dest pointers
- */
+ frame->sc.delivered_width = width;
+ frame->sc.delivered_height = height;
+ frame->sc.delivered_ratio_code = ratio_code;
+ frame->flags = flags;
+ frame->format = format;
+ frame->sc.user_ratio = this->sc.user_ratio;
- if (frame->data) {
- switch (flags) {
- case VO_TOP_FIELD:
- frame->rgb_dst = (uint8_t *)frame->data;
- frame->stripe_inc = 2 * frame->stripe_height * frame->bytes_per_line;
- break;
- case VO_BOTTOM_FIELD:
- frame->rgb_dst = (uint8_t *)frame->data + frame->bytes_per_line ;
- frame->stripe_inc = 2 * frame->stripe_height * frame->bytes_per_line;
- break;
- case VO_BOTH_FIELDS:
- frame->rgb_dst = (uint8_t *)frame->data;
- frame->stripe_inc = frame->stripe_height * frame->bytes_per_line;
- break;
- }
+ fb_compute_ideal_size(this, frame);
+ fb_compute_rgb_size(this, frame);
+
+ frame_reallocate(this, frame, width, height, format);
+
+ frame->stripe_height = 16 * frame->sc.output_height /
+ frame->sc.delivered_height;
+ if(this->use_zero_copy)
+ frame->bytes_per_line = this->fb_bytes_per_line;
+ else
+ frame->bytes_per_line = frame->sc.output_width *
+ this->bytes_per_pixel;
+
+ setup_colorspace_converter(frame, flags);
}
+
+ reset_dest_pointers(frame, flags);
}
-static void fb_overlay_clut_yuv2rgb(fb_driver_t *this, vo_overlay_t *overlay,
- fb_frame_t *frame) {
+static void fb_overlay_clut_yuv2rgb(fb_driver_t *this,
+ vo_overlay_t *overlay, fb_frame_t *frame)
+{
int i;
- clut_t* clut = (clut_t*) overlay->color;
- if (!overlay->rgb_clut) {
- for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
+ clut_t* clut = (clut_t*)overlay->color;
+
+ if(!overlay->rgb_clut)
+ {
+ for(i = 0;
+ i < sizeof(overlay->color)/sizeof(overlay->color[0]);
+ i++)
+ {
*((uint32_t *)&clut[i]) =
- frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb,
- clut[i].y, clut[i].cb, clut[i].cr);
+ frame->yuv2rgb->
+ yuv2rgb_single_pixel_fun(frame->yuv2rgb,
+ clut[i].y,
+ clut[i].cb,
+ clut[i].cr);
}
overlay->rgb_clut++;
}
- if (!overlay->clip_rgb_clut) {
+
+ if(!overlay->clip_rgb_clut)
+ {
clut = (clut_t*) overlay->clip_color;
- for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
+
+ for(i = 0;
+ i < sizeof(overlay->color)/sizeof(overlay->color[0]);
+ i++)
+ {
*((uint32_t *)&clut[i]) =
- frame->yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb,
- clut[i].y, clut[i].cb, clut[i].cr);
+ frame->yuv2rgb->
+ yuv2rgb_single_pixel_fun(frame->yuv2rgb,
+ clut[i].y,
+ clut[i].cb,
+ clut[i].cr);
}
overlay->clip_rgb_clut++;
}
}
-static void fb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) {
- fb_driver_t *this = (fb_driver_t *) this_gen;
- fb_frame_t *frame = (fb_frame_t *) frame_gen;
+static void fb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ vo_overlay_t *overlay)
+{
+ fb_driver_t *this = (fb_driver_t *)this_gen;
+ fb_frame_t *frame = (fb_frame_t *)frame_gen;
/* Alpha Blend here */
- if (overlay->rle) {
- if( !overlay->rgb_clut || !overlay->clip_rgb_clut)
+ if(overlay->rle)
+ {
+ if(!overlay->rgb_clut || !overlay->clip_rgb_clut)
fb_overlay_clut_yuv2rgb(this,overlay,frame);
- switch(this->bpp) {
+ switch(this->bpp)
+ {
case 16:
- blend_rgb16( (uint8_t *)frame->data, overlay,
- frame->sc.output_width, frame->sc.output_height,
- frame->sc.delivered_width, frame->sc.delivered_height);
+ blend_rgb16(frame->data,
+ overlay,
+ frame->sc.output_width,
+ frame->sc.output_height,
+ frame->sc.delivered_width,
+ frame->sc.delivered_height);
break;
+
case 24:
- blend_rgb24( (uint8_t *)frame->data, overlay,
- frame->sc.output_width, frame->sc.output_height,
- frame->sc.delivered_width, frame->sc.delivered_height);
+ blend_rgb24(frame->data,
+ overlay,
+ frame->sc.output_width,
+ frame->sc.output_height,
+ frame->sc.delivered_width,
+ frame->sc.delivered_height);
break;
+
case 32:
- blend_rgb32( (uint8_t *)frame->data, overlay,
- frame->sc.output_width, frame->sc.output_height,
- frame->sc.delivered_width, frame->sc.delivered_height);
- break;
- default:
- /* It should never get here */
+ blend_rgb32(frame->data,
+ overlay,
+ frame->sc.output_width,
+ frame->sc.output_height,
+ frame->sc.delivered_width,
+ frame->sc.delivered_height);
break;
}
}
}
-static int fb_redraw_needed (vo_driver_t *this_gen) {
+static int fb_redraw_needed(vo_driver_t *this_gen)
+{
return 0;
}
-static void fb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
-
+static void fb_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
+{
fb_driver_t *this = (fb_driver_t *) this_gen;
fb_frame_t *frame = (fb_frame_t *) frame_gen;
- int y;
uint8_t *dst, *src;
+ int y;
- if ( (frame->sc.output_width != this->sc.output_width)
- || (frame->sc.output_height != this->sc.output_height) ) {
-
+ if(frame->sc.output_width != this->sc.output_width ||
+ frame->sc.output_height != this->sc.output_height)
+ {
this->sc.output_width = frame->sc.output_width;
this->sc.output_height = frame->sc.output_height;
- printf ("video_out_fb: gui size %d x %d, frame size %d x %d\n",
+ printf("video_out_fb: gui size %d x %d, frame size %d x %d\n",
this->sc.gui_width, this->sc.gui_height,
frame->sc.output_width, frame->sc.output_height);
- memset(this->video_mem, 0, this->fb_linelength * this->sc.gui_height );
-
+ memset(frame->video_mem, 0,
+ this->fb_bytes_per_line * this->sc.gui_height);
}
- dst = this->video_mem + frame->sc.output_yoffset * this->fb_linelength +
+ if(this->use_zero_copy)
+ {
+ if(this->old_frame)
+ this->old_frame->vo_frame.displayed
+ (&this->old_frame->vo_frame);
+ this->old_frame = this->cur_frame;
+ this->cur_frame = frame;
+
+ this->fb_var.yoffset = frame->yoffset;
+ if(ioctl(this->fd, FBIOPAN_DISPLAY, &this->fb_var) == -1)
+ perror("video_out_fb: ioctl FBIOPAN_DISPLAY failed");
+ }
+ else
+ {
+ dst = frame->video_mem +
+ frame->sc.output_yoffset * this->fb_bytes_per_line +
frame->sc.output_xoffset * this->bytes_per_pixel;
- src = frame->data;
+ src = frame->data;
- for( y = 0; y < frame->sc.output_height; y++ ) {
- xine_fast_memcpy( dst, src, frame->bytes_per_line );
- src += frame->bytes_per_line;
- dst += this->fb_linelength;
- }
+ for(y = 0; y < frame->sc.output_height; y++)
+ {
+ xine_fast_memcpy(dst, src, frame->bytes_per_line);
+ src += frame->bytes_per_line;
+ dst += this->fb_bytes_per_line;
+ }
- frame->vo_frame.displayed (&frame->vo_frame);
+ frame->vo_frame.displayed(&frame->vo_frame);
+ }
}
-static int fb_get_property (vo_driver_t *this_gen, int property) {
+static int fb_get_property(vo_driver_t *this_gen, int property)
+{
+ fb_driver_t *this = (fb_driver_t *)this_gen;
- fb_driver_t *this = (fb_driver_t *) this_gen;
+ switch(property)
+ {
+ case VO_PROP_ASPECT_RATIO:
+ return this->sc.user_ratio;
- if ( property == VO_PROP_ASPECT_RATIO) {
- return this->sc.user_ratio ;
- } else if ( property == VO_PROP_BRIGHTNESS) {
+ case VO_PROP_BRIGHTNESS:
return this->yuv2rgb_gamma;
- } else {
- printf ("video_out_fb: tried to get unsupported property %d\n", property);
+
+ default:
+ printf("video_out_fb: tried to get unsupported "
+ "property %d\n", property);
}
return 0;
}
-static int fb_set_property (vo_driver_t *this_gen,
- int property, int value) {
-
- fb_driver_t *this = (fb_driver_t *) this_gen;
+static int fb_set_property(vo_driver_t *this_gen, int property, int value)
+{
+ fb_driver_t *this = (fb_driver_t *)this_gen;
- if ( property == VO_PROP_ASPECT_RATIO) {
- if (value>=NUM_ASPECT_RATIOS)
+ switch(property)
+ {
+ case VO_PROP_ASPECT_RATIO:
+ if(value>=NUM_ASPECT_RATIOS)
value = ASPECT_AUTO;
this->sc.user_ratio = value;
printf("video_out_fb: aspect ratio changed to %s\n",
vo_scale_aspect_ratio_name(value));
- } else if ( property == VO_PROP_BRIGHTNESS) {
+ break;
+ case VO_PROP_BRIGHTNESS:
this->yuv2rgb_gamma = value;
- this->yuv2rgb_factory->set_gamma (this->yuv2rgb_factory, value);
-
+ this->yuv2rgb_factory->
+ set_gamma(this->yuv2rgb_factory, value);
printf("video_out_fb: gamma changed to %d\n",value);
- } else {
- printf ("video_out_fb: tried to set unsupported property %d\n", property);
+ break;
+
+ default:
+ printf("video_out_fb: tried to set unsupported "
+ "property %d\n", property);
}
return value;
}
-static void fb_get_property_min_max (vo_driver_t *this_gen,
- int property, int *min, int *max) {
-
+static void fb_get_property_min_max(vo_driver_t *this_gen,
+ int property, int *min, int *max)
+{
/* fb_driver_t *this = (fb_driver_t *) this_gen; */
- if ( property == VO_PROP_BRIGHTNESS) {
+
+ if(property == VO_PROP_BRIGHTNESS)
+ {
*min = -100;
*max = +100;
- } else {
+ }
+ else
+ {
*min = 0;
*max = 0;
}
}
-
-static int fb_gui_data_exchange (vo_driver_t *this_gen,
- int data_type, void *data) {
-
+static int fb_gui_data_exchange(vo_driver_t *this_gen,
+ int data_type, void *data)
+{
return 0;
}
-
-static void fb_dispose (vo_driver_t *this_gen) {
-
- fb_driver_t *this = (fb_driver_t *) this_gen;
+static void fb_dispose(vo_driver_t *this_gen)
+{
+ fb_driver_t *this = (fb_driver_t *)this_gen;
munmap(0, this->mem_size);
-
close(this->fd);
}
-static vo_driver_t *fb_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) {
+static int get_fb_var_screeninfo(int fd, struct fb_var_screeninfo *var)
+{
+ int i;
- fb_class_t *class = (fb_class_t *) class_gen;
- config_values_t *config = class->config;
+ if(ioctl(fd, FBIOGET_VSCREENINFO, var))
+ {
+ perror("video_out_fb: ioctl FBIOGET_VSCREENINFO");
+ return 0;
+ }
- fb_driver_t *this;
- int mode;
- char *device_name;
- static char devkey[] = "video.fb_device";
+ var->xres_virtual = var->xres;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->nonstd = 0;
+ var->vmode &= ~FB_VMODE_YWRAP;
+
+ /* Maximize virtual yres to fit as many buffers as possible. */
+ for(i = MAXIMUM_NUM_BUFFERS; i > 0; i--)
+ {
+ var->yres_virtual = i * var->yres;
+ if(ioctl(fd, FBIOPUT_VSCREENINFO, var) == -1)
+ continue;
+ break;
+ }
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
+ /* Get proper value for maximized var->yres_virtual. */
+ if(ioctl(fd, FBIOGET_VSCREENINFO, var) == -1)
+ {
+ perror("video_out_fb: ioctl FBIOGET_VSCREENINFO");
+ return 0;
+ }
- /*
- * allocate plugin struct
- */
+ return 1;
+}
- this = malloc (sizeof (fb_driver_t));
+static int get_fb_fix_screeninfo(int fd, struct fb_fix_screeninfo *fix)
+{
+ if(ioctl(fd, FBIOGET_FSCREENINFO, fix))
+ {
+ perror("video_out_fb: ioctl FBIOGET_FSCREENINFO");
+ return 0;
+ }
- if (!this) {
- printf ("video_out_fb: malloc failed\n");
- return NULL;
+ if((fix->visual != FB_VISUAL_TRUECOLOR &&
+ fix->visual != FB_VISUAL_DIRECTCOLOR) ||
+ fix->type != FB_TYPE_PACKED_PIXELS)
+ {
+ fprintf(stderr, "video_out_fb: only packed truecolor/directcolor is supported (%d).\n"
+ " Check 'fbset -i' or try 'fbset -depth 16'.\n",
+ fix->visual);
+ return 0;
}
- memset (this, 0, sizeof(fb_driver_t));
+ return 1;
+}
+static void register_callbacks(fb_driver_t *this)
+{
this->vo_driver.get_capabilities = fb_get_capabilities;
this->vo_driver.alloc_frame = fb_alloc_frame;
this->vo_driver.update_frame_format = fb_update_frame_format;
- this->vo_driver.overlay_begin = NULL; /* not used */
+ this->vo_driver.overlay_begin = 0; /* not used */
this->vo_driver.overlay_blend = fb_overlay_blend;
- this->vo_driver.overlay_end = NULL; /* not used */
+ this->vo_driver.overlay_end = 0; /* not used */
this->vo_driver.display_frame = fb_display_frame;
this->vo_driver.get_property = fb_get_property;
this->vo_driver.set_property = fb_set_property;
@@ -584,82 +755,116 @@ static vo_driver_t *fb_open_plugin (video_driver_class_t *class_gen, const void
this->vo_driver.gui_data_exchange = fb_gui_data_exchange;
this->vo_driver.dispose = fb_dispose;
this->vo_driver.redraw_needed = fb_redraw_needed;
+}
- device_name = config->register_string (config, devkey, "",
- _("framebuffer device"), NULL, 10, NULL, NULL);
-
- if( strlen(device_name) > 3 ) {
- this->fd = open(device_name, O_RDWR);
- } else {
+static int open_fb_device(config_values_t *config)
+{
+ static char devkey[] = "video.fb_device"; /* Why static? */
+ char *device_name;
+ int fd;
+
+ device_name = config->register_string(config, devkey, "",
+ _("framebuffer device"),
+ NULL, 10, NULL, NULL);
+ if(strlen(device_name) > 3)
+ {
+ fd = open(device_name, O_RDWR);
+ }
+ else
+ {
device_name = "/dev/fb1";
- this->fd = open(device_name, O_RDWR);
+ fd = open(device_name, O_RDWR);
- if( this->fd < 0 ) {
+ if(fd < 0)
+ {
device_name = "/dev/fb0";
- this->fd = open(device_name, O_RDWR);
+ fd = open(device_name, O_RDWR);
}
}
- if( this->fd < 0) {
- printf("video_out_fb: aborting. (unable to open device \"%s\")\n", device_name);
- free(this);
- return NULL;
+ if(fd < 0)
+ {
+ fprintf(stderr, "video_out_fb: Unable to open device \"%s\", aborting: %s\n",
+ device_name, strerror(errno));
+ return -1;
}
- config->update_string (config, devkey, device_name);
+ config->update_string(config, devkey, device_name);
- if (ioctl(this->fd, FBIOGET_VSCREENINFO, &var)) {
- printf("video_out_fb: ioctl FBIOGET_VSCREENINFO: %s\n",
- strerror(errno));
- free(this);
- return NULL;
- }
+ return fd;
+}
- var.xres_virtual = var.xres;
- var.yres_virtual = var.yres;
- var.xoffset = 0;
- var.yoffset = 0;
- var.nonstd = 0;
- var.vmode &= ~FB_VMODE_YWRAP;
+static int mode_visual(fb_driver_t *this, config_values_t *config,
+ struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix)
+{
+ switch(fix->visual)
+ {
+ case FB_VISUAL_TRUECOLOR:
+ case FB_VISUAL_DIRECTCOLOR:
+ switch(this->depth)
+ {
+ case 24:
+ if(this->bpp == 32)
+ {
+ if(!var->blue.offset)
+ return MODE_32_RGB;
+ return MODE_32_BGR;
+ }
+ if(!var->blue.offset)
+ return MODE_24_RGB;
+ return MODE_24_BGR;
+
+ case 16:
+ if(!var->blue.offset)
+ return MODE_16_RGB;
+ return MODE_16_BGR;
- if (ioctl(this->fd, FBIOPUT_VSCREENINFO, &var)) {
- printf("video_out_fb: ioctl FBIOPUT_VSCREENINFO: %s\n",
- strerror(errno));
- free(this);
- return NULL;
- }
+ case 15:
+ if(!var->blue.offset)
+ return MODE_15_RGB;
+ return MODE_15_BGR;
- if (ioctl(this->fd, FBIOGET_FSCREENINFO, &fix)) {
- printf("video_out_fb: ioctl FBIOGET_FSCREENINFO: %s\n",
- strerror(errno));
- free(this);
- return NULL;
- }
-
- if( (fix.visual != FB_VISUAL_TRUECOLOR && fix.visual != FB_VISUAL_DIRECTCOLOR) || fix.type != FB_TYPE_PACKED_PIXELS ) {
- printf("video_out_fb: only packed truecolor/directcolor is supported (%d).\n",fix.visual);
- printf(" check 'fbset -i' or try 'fbset -depth 16'\n");
- free(this);
- return NULL;
+ case 8:
+ if(!var->blue.offset)
+ return MODE_8_RGB;
+ return MODE_8_BGR;
+
+ }
}
- if (fix.line_length)
- this->fb_linelength = fix.line_length;
- else
- this->fb_linelength = (var.xres_virtual * var.bits_per_pixel) / 8;
+ fprintf(stderr, "video_out_fb: Your video mode was not recognized, sorry.\n");
+ return 0;
+}
- vo_scale_init( &this->sc, 0, 0, config );
- this->sc.gui_width = var.xres;
- this->sc.gui_height = var.yres;
- this->sc.user_ratio = ASPECT_AUTO;
-
- this->sc.scaling_disabled = config->register_bool (config, "video.disable_scaling", 0,
- _("disable all video scaling (faster!)"),
- NULL, 10, NULL, NULL);
+static int setup_yuv2rgb(fb_driver_t *this, config_values_t *config,
+ struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix)
+{
+ this->yuv2rgb_mode = mode_visual(this, config, var, fix);
+ if(!this->yuv2rgb_mode)
+ return 0;
+
+ this->yuv2rgb_swap = 0;
+ this->yuv2rgb_gamma =
+ config->register_range(config, "video.fb_gamma", 0,
+ -100, 100,
+ "gamma correction for fb driver",
+ NULL, 0, NULL, NULL);
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init(this->yuv2rgb_mode,
+ this->yuv2rgb_swap,
+ this->yuv2rgb_cmap);
+ this->yuv2rgb_factory->set_gamma(this->yuv2rgb_factory,
+ this->yuv2rgb_gamma);
+ return 1;
+}
+static void setup_buffers(fb_driver_t *this,
+ struct fb_var_screeninfo *var)
+{
/*
- *
* depth in X11 terminology land is the number of bits used to
* actually represent the colour.
*
@@ -668,114 +873,144 @@ static vo_driver_t *fb_open_plugin (video_driver_class_t *class_gen, const void
*
* ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit
* color is 24 bit depth, but can be 24 bpp or 32 bpp.
- */
-
- /* fb assumptions: bpp % 8 = 0 (e.g. 8, 16, 24, 32 bpp)
+ *
+ * fb assumptions: bpp % 8 = 0 (e.g. 8, 16, 24, 32 bpp)
* bpp <= 32
* msb_right = 0
*/
- this->bytes_per_pixel = (var.bits_per_pixel + 7)/8;
+ this->bytes_per_pixel = (this->fb_var.bits_per_pixel + 7)/8;
this->bpp = this->bytes_per_pixel * 8;
- this->depth = var.red.length + var.green.length + var.blue.length;
-
- if (this->depth>16)
- printf ("\n\n"
- "WARNING: current display depth is %d. For better performance\n"
- "a depth of 16 bpp is recommended!\n\n",
- this->depth);
-
- printf ("video_out_fb: video mode depth is %d (%d bpp),\n"
- "\tred: %d/%d, green: %d/%d, blue: %d/%d\n",
- this->depth, this->bpp,
- var.red.length, var.red.offset,
- var.green.length, var.green.offset,
- var.blue.length, var.blue.offset );
-
- mode = 0;
-
- switch (fix.visual) {
- case FB_VISUAL_TRUECOLOR:
- case FB_VISUAL_DIRECTCOLOR:
- switch (this->depth) {
- case 24:
- if (this->bpp == 32) {
- if (!var.blue.offset)
- mode = MODE_32_RGB;
- else
- mode = MODE_32_BGR;
- } else {
- if (!var.blue.offset)
- mode = MODE_24_RGB;
- else
- mode = MODE_24_BGR;
- }
- break;
- case 16:
- if (!var.blue.offset)
- mode = MODE_16_RGB;
- else
- mode = MODE_16_BGR;
- break;
- case 15:
- if (!var.blue.offset)
- mode = MODE_15_RGB;
- else
- mode = MODE_15_BGR;
- break;
- case 8:
- if (!var.blue.offset)
- mode = MODE_8_RGB;
- else
- mode = MODE_8_BGR;
- break;
+ this->depth = this->fb_var.red.length +
+ this->fb_var.green.length +
+ this->fb_var.blue.length;
+
+ this->total_num_native_buffers = var->yres_virtual / var->yres;
+ this->used_num_buffers = 0;
+
+ this->cur_frame = this->old_frame = 0;
+
+ printf("video_out_fb: %d video RAM buffers are available.\n",
+ this->total_num_native_buffers);
+
+ if(this->total_num_native_buffers < RECOMMENDED_NUM_BUFFERS)
+ {
+ this->use_zero_copy = 0;
+ printf("WARNING: video_out_fb: Zero copy buffers are DISABLED because only %d buffers\n"
+ " are available which is less than the recommended %d buffers. Lowering\n"
+ " the frame buffer resolution might help.\n",
+ this->total_num_native_buffers,
+ RECOMMENDED_NUM_BUFFERS);
+ }
+ else
+ {
+ /* test if FBIOPAN_DISPLAY works */
+ this->fb_var.yoffset = this->fb_var.yres;
+ if(ioctl(this->fd, FBIOPAN_DISPLAY, &this->fb_var) == -1) {
+ printf("WARNING: video_out_fb: Zero copy buffers are DISABLED because kernel driver\n"
+ " do not support screen panning (used for frame flips).\n");
+ } else {
+ this->fb_var.yoffset = 0;
+ ioctl(this->fd, FBIOPAN_DISPLAY, &this->fb_var);
+
+ this->use_zero_copy = 1;
+ printf("video_out_fb: Using zero copy buffers.\n");
}
- break;
}
+}
- if (!mode) {
- printf ("video_out_fb: your video mode was not recognized, sorry :-(\n");
- return NULL;
+static vo_driver_t *fb_open_plugin(video_driver_class_t *class_gen,
+ const void *visual_gen)
+{
+ config_values_t *config;
+ fb_driver_t *this;
+ fb_class_t *class;
+
+ class = (fb_class_t *)class_gen;
+ config = class->config;
+
+ /* allocate plugin struct */
+ this = malloc(sizeof(fb_driver_t));
+ if(!this)
+ {
+ fprintf(stderr, "video_out_fb: malloc failed\n");
+ return 0;
}
+ memset(this, 0, sizeof(fb_driver_t));
- /* mmap whole video memory */
- this->mem_size = fix.smem_len;
- this->video_mem = (char *) mmap(0, this->mem_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, this->fd, 0);
-
- this->yuv2rgb_mode = mode;
- this->yuv2rgb_swap = 0;
- this->yuv2rgb_gamma = config->register_range (config, "video.fb_gamma", 0,
- -100, 100,
- "gamma correction for fb driver",
- NULL, 0, NULL, NULL);
-
- this->yuv2rgb_factory = yuv2rgb_factory_init (mode, this->yuv2rgb_swap,
- this->yuv2rgb_cmap);
- this->yuv2rgb_factory->set_gamma (this->yuv2rgb_factory, this->yuv2rgb_gamma);
+ register_callbacks(this);
+
+ this->fd = open_fb_device(config);
+ if(this->fd == -1)
+ goto error;
+ if(!get_fb_var_screeninfo(this->fd, &this->fb_var))
+ goto error;
+ if(!get_fb_fix_screeninfo(this->fd, &this->fb_fix))
+ goto error;
+
+ if(this->fb_fix.line_length)
+ this->fb_bytes_per_line = this->fb_fix.line_length;
+ else
+ this->fb_bytes_per_line =
+ (this->fb_var.xres_virtual *
+ this->fb_var.bits_per_pixel)/8;
+
+ vo_scale_init(&this->sc, 0, 0, config);
+ this->sc.gui_width = this->fb_var.xres;
+ this->sc.gui_height = this->fb_var.yres;
+ this->sc.user_ratio = ASPECT_AUTO;
+
+ this->sc.scaling_disabled =
+ config->register_bool(config, "video.disable_scaling", 0,
+ _("disable all video scaling (faster!)"),
+ NULL, 10, NULL, NULL);
+
+ setup_buffers(this, &this->fb_var);
+
+ if(this->depth > 16)
+ printf("WARNING: video_out_fb: current display depth is %d. For better performance\n"
+ " a depth of 16 bpp is recommended!\n\n",
+ this->depth);
+
+ printf("video_out_fb: video mode depth is %d (%d bpp),\n"
+ " red: %d/%d, green: %d/%d, blue: %d/%d\n",
+ this->depth, this->bpp,
+ this->fb_var.red.length, this->fb_var.red.offset,
+ this->fb_var.green.length, this->fb_var.green.offset,
+ this->fb_var.blue.length, this->fb_var.blue.offset);
- printf ("video_out_fb: warning, xine's framebuffer driver is EXPERIMENTAL\n");
+ if(!setup_yuv2rgb(this, config, &this->fb_var, &this->fb_fix))
+ goto error;
+
+ /* mmap whole video memory */
+ this->mem_size = this->fb_fix.smem_len;
+ this->video_mem_base = mmap(0, this->mem_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, this->fd, 0);
return &this->vo_driver;
+error:
+ free(this);
+ return 0;
}
-static char* fb_get_identifier (video_driver_class_t *this_gen) {
+static char* fb_get_identifier(video_driver_class_t *this_gen)
+{
return "fb";
}
-static char* fb_get_description (video_driver_class_t *this_gen) {
- return _("xine video output plugin using linux framebuffer device");
+static char* fb_get_description(video_driver_class_t *this_gen)
+{
+ return _("Xine video output plugin using the Linux frame buffer device");
}
-static void fb_dispose_class (video_driver_class_t *this_gen) {
-
- fb_class_t *this = (fb_class_t *) this_gen;
-
- free (this);
+static void fb_dispose_class(video_driver_class_t *this_gen)
+{
+ fb_class_t *this = (fb_class_t *)this_gen;
+ free(this);
}
-static void *fb_init_class (xine_t *xine, void *visual_gen) {
-
- fb_class_t *this = (fb_class_t *) malloc (sizeof (fb_class_t));
+static void *fb_init_class(xine_t *xine, void *visual_gen)
+{
+ fb_class_t *this = (fb_class_t *)malloc(sizeof(fb_class_t));
this->driver_class.open_plugin = fb_open_plugin;
this->driver_class.get_identifier = fb_get_identifier;
@@ -787,22 +1022,33 @@ static void *fb_init_class (xine_t *xine, void *visual_gen) {
return this;
}
-
-static vo_info_t vo_info_fb = {
+static vo_info_t vo_info_fb =
+{
1, /* priority */
+#ifdef USE_X11_VISUAL
+ XINE_VISUAL_TYPE_X11 /* visual type */
+#else
XINE_VISUAL_TYPE_FB /* visual type */
-
-/* OBS: to use it from xine-ui set the X11 visual type */
-/* XINE_VISUAL_TYPE_X11 */
+#endif
};
-/*
- * exported plugin catalog entry
- */
-
-plugin_info_t xine_plugin_info[] = {
+/* exported plugin catalog entry */
+plugin_info_t xine_plugin_info[] =
+{
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_OUT, 14, "fb", XINE_VERSION_CODE, &vo_info_fb, fb_init_class },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+ {
+ PLUGIN_VIDEO_OUT,
+ 14,
+ "fb",
+ XINE_VERSION_CODE,
+ &vo_info_fb, fb_init_class
+ },
+ {
+ PLUGIN_NONE,
+ 0,
+ "",
+ 0,
+ NULL,
+ NULL
+ }
};
-