summaryrefslogtreecommitdiff
path: root/src/dxr3
diff options
context:
space:
mode:
Diffstat (limited to 'src/dxr3')
-rw-r--r--src/dxr3/Makefile.am44
-rw-r--r--src/dxr3/dxr3.h22
-rw-r--r--src/dxr3/dxr3_decode_spu.c55
-rw-r--r--src/dxr3/dxr3_decode_video.c56
-rw-r--r--src/dxr3/dxr3_mpeg_encoders.c53
-rw-r--r--src/dxr3/dxr3_scr.h2
-rw-r--r--src/dxr3/ffmpeg_encoder.c339
-rw-r--r--src/dxr3/video_out_dxr3.c83
-rw-r--r--src/dxr3/video_out_dxr3.h4
9 files changed, 439 insertions, 219 deletions
diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am
index fadb8b736..b904c899a 100644
--- a/src/dxr3/Makefile.am
+++ b/src/dxr3/Makefile.am
@@ -1,18 +1,18 @@
+include $(top_srcdir)/misc/Makefile.quiet
include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
-AM_CFLAGS = $(X_CFLAGS) $(LIBFAME_CFLAGS)
+AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG)
+AM_CPPFLAGS =
+AM_LDFLAGS = $(xineplug_ldflags)
-if HAVE_DXR3
-dxr3_modules = xineplug_decode_dxr3_video.la \
- xineplug_decode_dxr3_spu.la \
- xineplug_vo_out_dxr3.la
-endif
if HAVE_X11
+AM_CFLAGS += $(X_CFLAGS)
link_x_libs = $(X_LIBS) -lXext
endif
if HAVE_LIBFAME
-link_fame = $(LIBFAME_LIBS)
+AM_CFLAGS += $(LIBFAME_CFLAGS)
+link_fame = $(LIBFAME_LIBS)
endif
if HAVE_LIBRTE
link_rte = -lrte
@@ -20,37 +20,33 @@ endif
EXTRA_DIST = compat.c
-xineplug_LTLIBRARIES = $(dxr3_modules)
+noinst_HEADERS = em8300.h dxr3.h dxr3_scr.h video_out_dxr3.h
+
+if ENABLE_DXR3
+xineplug_LTLIBRARIES = xineplug_decode_dxr3_video.la \
+ xineplug_decode_dxr3_spu.la \
+ xineplug_vo_out_dxr3.la
+endif
xineplug_decode_dxr3_video_la_SOURCES = dxr3_decode_video.c
xineplug_decode_dxr3_video_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
-xineplug_decode_dxr3_video_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
-xineplug_decode_dxr3_video_la_LDFLAGS = $(xineplug_ldflags)
-if HAVE_DVDNAV
-AM_CPPFLAGS = $(DVDNAV_CFLAGS)
+if WITH_EXTERNAL_DVDNAV
xineplug_decode_dxr3_spu_la_SOURCES = dxr3_decode_spu.c
xineplug_decode_dxr3_spu_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(DVDNAV_LIBS)
+xineplug_decode_dxr3_spu_la_CFLAGS = $(AM_CFLAGS) $(DVDNAV_CFLAGS)
else
-AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav
xineplug_decode_dxr3_spu_la_SOURCES = dxr3_decode_spu.c nav_read.c
xineplug_decode_dxr3_spu_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
+xineplug_decode_dxr3_spu_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/input/libdvdnav
endif
-xineplug_decode_dxr3_spu_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
-xineplug_decode_dxr3_spu_la_LDFLAGS = $(xineplug_ldflags)
xineplug_vo_out_dxr3_la_SOURCES = \
dxr3_mpeg_encoders.c \
+ ffmpeg_encoder.c \
dxr3_spu_encoder.c \
dxr3_scr.c \
video_out_dxr3.c
-xineplug_vo_out_dxr3_la_LIBADD = $(XINE_LIB) $(link_fame) $(link_rte) $(link_x_libs) $(LTLIBINTL) $(DYNAMIC_LD_LIBS) -lm
-xineplug_vo_out_dxr3_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
-xineplug_vo_out_dxr3_la_LDFLAGS = $(xineplug_ldflags)
-
-noinst_HEADERS = \
- em8300.h \
- dxr3.h \
- dxr3_scr.h \
- video_out_dxr3.h
+xineplug_vo_out_dxr3_la_CFLAGS = $(AM_CFLAGS) $(AVUTIL_CFLAGS) $(FFMPEG_CFLAGS)
+xineplug_vo_out_dxr3_la_LIBADD = $(XINE_LIB) $(link_fame) $(link_rte) $(link_x_libs) $(LTLIBINTL) $(AVUTIL_LIBS) $(FFMPEG_LIBS) -lm
diff --git a/src/dxr3/dxr3.h b/src/dxr3/dxr3.h
index 78e74a7b4..be151d055 100644
--- a/src/dxr3/dxr3.h
+++ b/src/dxr3/dxr3.h
@@ -23,7 +23,11 @@
#include "em8300.h"
-#include "xine_internal.h"
+#include <xine/xine_internal.h>
+
+#ifndef LOG_VID
+#define LOG_VID 0
+#endif
/* data for the device name config entry */
#define CONF_KEY "dxr3.device_number"
@@ -37,5 +41,19 @@
* (used by decoders to check for dxr3 presence) */
#define DXR3_VO_ID "dxr3"
-#endif
+/* inline helper implementations */
+static inline int dxr3_present(xine_stream_t *stream)
+{
+ int present = 0;
+
+ if (stream->video_driver && stream->video_driver->node &&
+ stream->video_driver->node->plugin_class ) {
+ const video_driver_class_t *const vo_class = (video_driver_class_t *)stream->video_driver->node->plugin_class;
+ if (vo_class->identifier)
+ present = (strcmp(vo_class->identifier, DXR3_VO_ID) == 0);
+ }
+ llprintf(LOG_VID, "dxr3 %s\n", present ? "present" : "not present");
+ return present;
+}
+#endif
diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c
index 100ba7674..0dc024253 100644
--- a/src/dxr3/dxr3_decode_spu.c
+++ b/src/dxr3/dxr3_decode_spu.c
@@ -46,9 +46,9 @@
#define LOG_SPU 0
#define LOG_BTN 0
-#include "xine_internal.h"
-#include "xineutils.h"
-#include "buffer.h"
+#include <xine/xine_internal.h>
+#include <xine/xineutils.h>
+#include <xine/buffer.h>
#include "xine-engine/bswap.h"
#ifdef HAVE_DVDNAV
# ifdef HAVE_DVDNAV_NAVTYPES_H
@@ -75,7 +75,7 @@ static void *dxr3_spudec_init_plugin(xine_t *xine, void *);
/* plugin catalog information */
-static uint32_t supported_types[] = { BUF_SPU_DVD, 0 };
+static const uint32_t supported_types[] = { BUF_SPU_DVD, 0 };
static const decoder_info_t dxr3_spudec_info = {
supported_types, /* supported types */
@@ -84,16 +84,13 @@ static const decoder_info_t dxr3_spudec_info = {
const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_SPU_DECODER, 16, "dxr3-spudec", XINE_VERSION_CODE, &dxr3_spudec_info, &dxr3_spudec_init_plugin },
+ { PLUGIN_SPU_DECODER, 17, "dxr3-spudec", XINE_VERSION_CODE, &dxr3_spudec_info, &dxr3_spudec_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
/* plugin class functions */
static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xine_stream_t *stream);
-static char *dxr3_spudec_get_identifier(spu_decoder_class_t *class_gen);
-static char *dxr3_spudec_get_description(spu_decoder_class_t *class_gen);
-static void dxr3_spudec_class_dispose(spu_decoder_class_t *class_gen);
/* plugin instance functions */
static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf);
@@ -156,24 +153,6 @@ static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode
static inline void dxr3_swab_clut(int* clut);
/* inline helper implementations */
-static inline int dxr3_present(xine_stream_t *stream)
-{
- plugin_node_t *node;
- video_driver_class_t *vo_class;
- int present = 0;
-
- if (stream->video_driver && stream->video_driver->node) {
- node = (plugin_node_t *)stream->video_driver->node;
- if (node->plugin_class) {
- vo_class = (video_driver_class_t *)node->plugin_class;
- if (vo_class->get_identifier)
- present = (strcmp(vo_class->get_identifier(vo_class), DXR3_VO_ID) == 0);
- }
- }
- llprintf(LOG_SPU, "dxr3 %s\n", present ? "present" : "not present");
- return present;
-}
-
static inline void dxr3_spudec_clear_nav_list(dxr3_spudec_t *this)
{
while (this->pci_cur.next) {
@@ -213,9 +192,9 @@ static void *dxr3_spudec_init_plugin(xine_t *xine, void* data)
if (!this) return NULL;
this->spu_decoder_class.open_plugin = dxr3_spudec_open_plugin;
- this->spu_decoder_class.get_identifier = dxr3_spudec_get_identifier;
- this->spu_decoder_class.get_description = dxr3_spudec_get_description;
- this->spu_decoder_class.dispose = dxr3_spudec_class_dispose;
+ this->spu_decoder_class.identifier = "dxr3-spudec";
+ this->spu_decoder_class.description = N_("subtitle decoder plugin using the hardware decoding capabilities of a DXR3 decoder card");
+ this->spu_decoder_class.dispose = default_spu_decoder_class_dispose;
this->instance = 0;
@@ -286,22 +265,6 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi
return &this->spu_decoder;
}
-static char *dxr3_spudec_get_identifier(spu_decoder_class_t *class_gen)
-{
- return "dxr3-spudec";
-}
-
-static char *dxr3_spudec_get_description(spu_decoder_class_t *class_gen)
-{
- return "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 decoder card";
-}
-
-static void dxr3_spudec_class_dispose(spu_decoder_class_t *class_gen)
-{
- free(class_gen);
-}
-
-
static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
{
dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen;
@@ -582,7 +545,7 @@ static void dxr3_spudec_discontinuity(spu_decoder_t *this_gen)
static void dxr3_spudec_dispose(spu_decoder_t *this_gen)
{
- uint8_t empty_spu[] = {
+ static const uint8_t empty_spu[] = {
0x00, 0x26, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x20, 0x01, 0x03, 0x00, 0x00,
0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00,
diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c
index 71c6b4d1b..ec28b4648 100644
--- a/src/dxr3/dxr3_decode_video.c
+++ b/src/dxr3/dxr3_decode_video.c
@@ -44,8 +44,8 @@
#define LOG_VID 0
#define LOG_PTS 0
-#include "xine_internal.h"
-#include "buffer.h"
+#include <xine/xine_internal.h>
+#include <xine/buffer.h>
#include "video_out_dxr3.h"
#include "dxr3.h"
@@ -71,7 +71,7 @@ static void *dxr3_init_plugin(xine_t *xine, void *);
/* plugin catalog information */
-static uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 };
+static const uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 };
static const decoder_info_t dxr3_video_decoder_info = {
supported_types, /* supported types */
@@ -80,16 +80,13 @@ static const decoder_info_t dxr3_video_decoder_info = {
const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_DECODER, 18, "dxr3-mpeg2", XINE_VERSION_CODE, &dxr3_video_decoder_info, &dxr3_init_plugin },
+ { PLUGIN_VIDEO_DECODER, 19, "dxr3-mpeg2", XINE_VERSION_CODE, &dxr3_video_decoder_info, &dxr3_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
/* plugin class functions */
static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream);
-static char *dxr3_get_identifier(video_decoder_class_t *class_gen);
-static char *dxr3_get_description(video_decoder_class_t *class_gen);
-static void dxr3_class_dispose(video_decoder_class_t *class_gen);
/* plugin instance functions */
static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf);
@@ -152,7 +149,6 @@ typedef struct dxr3_decoder_s {
} dxr3_decoder_t;
/* helper functions */
-static inline int dxr3_present(xine_stream_t *stream);
static inline int dxr3_mvcommand(int fd_control, int command);
static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t *buffer);
static int get_duration(dxr3_decoder_t *this);
@@ -165,24 +161,6 @@ static void dxr3_update_enhanced_mode(void *this_gen, xine_cfg_entry_t *ent
static void dxr3_update_correct_durations(void *this_gen, xine_cfg_entry_t *entry);
/* inline helper implementations */
-static inline int dxr3_present(xine_stream_t *stream)
-{
- plugin_node_t *node;
- video_driver_class_t *vo_class;
- int present = 0;
-
- if (stream->video_driver && stream->video_driver->node) {
- node = (plugin_node_t *)stream->video_driver->node;
- if (node->plugin_class) {
- vo_class = (video_driver_class_t *)node->plugin_class;
- if (vo_class->get_identifier)
- present = (strcmp(vo_class->get_identifier(vo_class), DXR3_VO_ID) == 0);
- }
- }
- llprintf(LOG_VID, "dxr3 %s\n", present ? "present" : "not present");
- return present;
-}
-
static inline int dxr3_mvcommand(int fd_control, int command)
{
em8300_register_t reg;
@@ -203,9 +181,9 @@ static void *dxr3_init_plugin(xine_t *xine, void *data)
if (!this) return NULL;
this->video_decoder_class.open_plugin = dxr3_open_plugin;
- this->video_decoder_class.get_identifier = dxr3_get_identifier;
- this->video_decoder_class.get_description = dxr3_get_description;
- this->video_decoder_class.dispose = dxr3_class_dispose;
+ this->video_decoder_class.identifier = "dxr3-mpeg2";
+ this->video_decoder_class.description = N_("MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 decoder card.");
+ this->video_decoder_class.dispose = default_video_decoder_class_dispose;
this->instance = 0;
@@ -217,7 +195,7 @@ static void *dxr3_init_plugin(xine_t *xine, void *data)
static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream)
{
- static char *panscan_types[] = { "only when forced", "use MPEG hint", "use DVB hint", NULL };
+ static const char *const panscan_types[] = { "only when forced", "use MPEG hint", "use DVB hint", NULL };
dxr3_decoder_t *this;
dxr3_decoder_class_t *class = (dxr3_decoder_class_t *)class_gen;
config_values_t *cfg;
@@ -305,22 +283,6 @@ static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_
return &this->video_decoder;
}
-static char *dxr3_get_identifier(video_decoder_class_t *class_gen)
-{
- return "dxr3-mpeg2";
-}
-
-static char *dxr3_get_description(video_decoder_class_t *class_gen)
-{
- return "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 decoder card.";
-}
-
-static void dxr3_class_dispose(video_decoder_class_t *class_gen)
-{
- free(class_gen);
-}
-
-
static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
{
dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen;
@@ -650,7 +612,7 @@ static void dxr3_flush(video_decoder_t *this_gen)
* (the highlights won't move without), but some dvds have stills
* with no sequence end code. Since it is very likely that flush() is called
* in still situations, we send one here. */
- static uint8_t end_buffer[4] = { 0x00, 0x00, 0x01, 0xb7 };
+ static const uint8_t end_buffer[4] = { 0x00, 0x00, 0x01, 0xb7 };
write(this->fd_video, &end_buffer, 4);
this->sequence_open = 0;
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: WARNING: added missing end sequence\n");
diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c
index 8ca48c6ae..7e9a0e523 100644
--- a/src/dxr3/dxr3_mpeg_encoders.c
+++ b/src/dxr3/dxr3_mpeg_encoders.c
@@ -44,11 +44,17 @@
#include <math.h>
#include <unistd.h>
+#ifdef HAVE_FFMPEG_AVUTIL_H
+# include <mem.h>
+#else
+# include <libavutil/mem.h>
+#endif
+
#define LOG_MODULE "dxr3_mpeg_encoder"
/* #define LOG_VERBOSE */
/* #define LOG */
-#include "xineutils.h"
+#include <xine/xineutils.h>
#include "video_out_dxr3.h"
/* buffer size for encoded mpeg1 stream; will hold one intra frame
@@ -99,7 +105,7 @@ typedef struct {
char *buffer; /* temporary buffer for mpeg data */
/* temporary buffer for YUY2->YV12 conversion */
uint8_t *out[3]; /* aligned buffer for YV12 data */
- uint8_t *buf; /* unaligned YV12 buffer */
+ uint8_t *buf; /* base address of YV12 buffer */
} fame_data_t;
/* helper function */
@@ -107,13 +113,6 @@ static int fame_prepare_frame(fame_data_t *this, dxr3_driver_t *drv,
dxr3_frame_t *frame);
#endif
-/* initialization function */
-int dxr3_lavc_init(dxr3_driver_t *drv, plugin_node_t *node);
-
-/* close function from encoder api */
-static int lavc_on_close(dxr3_driver_t *drv);
-
-
#ifdef HAVE_LIBRTE
int dxr3_rte_init(dxr3_driver_t *drv)
{
@@ -337,8 +336,7 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
fame_parameters_t init_fp = FAME_PARAMETERS_INITIALIZER;
double fps;
- if (this->buf) free(this->buf);
- this->buf = 0;
+ av_freep(&this->buf);
this->out[0] = this->out[1] = this->out[2] = 0;
/* if YUY2 and dimensions changed, we need to re-allocate the
@@ -346,8 +344,7 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
if (frame->vo_frame.format == XINE_IMGFMT_YUY2) {
int image_size = frame->vo_frame.width * frame->oheight;
- this->out[0] = xine_xmalloc_aligned(16, image_size * 3/2,
- (void *)&this->buf);
+ this->out[0] = this->buf = av_mallocz(image_size * 3/2);
this->out[1] = this->out[0] + image_size;
this->out[2] = this->out[1] + image_size/4;
@@ -537,33 +534,3 @@ static int fame_prepare_frame(fame_data_t *this, dxr3_driver_t *drv, dxr3_frame_
return 1;
}
#endif
-
-
-int dxr3_lavc_init(dxr3_driver_t *drv, plugin_node_t *node)
-{
- void *ffmpeg;
- int (*init)(dxr3_driver_t *);
- int result;
-
- ffmpeg = dlopen(node->file->filename, RTLD_LAZY);
- if (!ffmpeg) return 0;
-
- init = dlsym(ffmpeg, "dxr3_encoder_init");
- if (!init) return 0;
-
- result = init(drv);
- /* the close function is implemented here, because it will call dlclose()
- * and that should not be done be the library we are closing... */
- drv->enc->on_close = lavc_on_close;
- drv->enc->handle = ffmpeg;
- return result;
-}
-
-static int lavc_on_close(dxr3_driver_t *drv)
-{
- drv->enc->on_unneeded(drv);
- dlclose(drv->enc->handle);
- free(drv->enc);
- drv->enc = NULL;
- return 1;
-}
diff --git a/src/dxr3/dxr3_scr.h b/src/dxr3/dxr3_scr.h
index 612f16ccb..28e2e0f1b 100644
--- a/src/dxr3/dxr3_scr.h
+++ b/src/dxr3/dxr3_scr.h
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
-#include "xine_internal.h"
+#include <xine/xine_internal.h>
/* plugin structure */
diff --git a/src/dxr3/ffmpeg_encoder.c b/src/dxr3/ffmpeg_encoder.c
new file mode 100644
index 000000000..4b444a3bc
--- /dev/null
+++ b/src/dxr3/ffmpeg_encoder.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2000-2004 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine 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.
+ *
+ * xine 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ */
+
+/* mpeg encoders for the dxr3 video out plugin. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+
+#define LOG_MODULE "dxr3_mpeg_encoder"
+/* #define LOG_VERBOSE */
+/* #define LOG */
+
+#include "video_out_dxr3.h"
+
+#ifdef HAVE_FFMPEG_AVUTIL_H
+# include <avcodec.h>
+#else
+# include <libavcodec/avcodec.h>
+#endif
+
+#include "../combined/ffmpeg/ffmpeg_compat.h"
+
+/* buffer size for encoded mpeg1 stream; will hold one intra frame
+ * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */
+#define DEFAULT_BUFFER_SIZE 512*1024
+
+
+/* functions required by encoder api */
+static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame);
+static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame);
+static int lavc_on_unneeded(dxr3_driver_t *drv);
+
+/*encoder structure*/
+typedef struct lavc_data_s {
+ encoder_data_t encoder_data;
+ AVCodecContext *context; /* handle for encoding */
+ int width, height; /* width and height of the video frame */
+ uint8_t *ffmpeg_buffer; /* lavc buffer */
+ AVFrame *picture; /* picture to be encoded */
+ uint8_t *out[3]; /* aligned buffer for YV12 data */
+ uint8_t *buf; /* base address of YV12 buffer */
+} lavc_data_t;
+
+
+static int dxr3_lavc_close(dxr3_driver_t *drv) {
+ drv->enc->on_unneeded(drv);
+ free(drv->enc);
+ drv->enc = NULL;
+
+ return 1;
+}
+
+int dxr3_lavc_init(dxr3_driver_t *drv, plugin_node_t *plugin)
+{
+ lavc_data_t* this;
+ avcodec_init();
+
+ avcodec_register_all();
+ lprintf("lavc init , version %x\n", avcodec_version());
+ this = calloc(1, sizeof(lavc_data_t));
+ if (!this) return 0;
+
+ this->encoder_data.type = ENC_LAVC;
+ this->encoder_data.on_update_format = lavc_on_update_format;
+ this->encoder_data.on_frame_copy = NULL;
+ this->encoder_data.on_display_frame = lavc_on_display_frame;
+ this->encoder_data.on_unneeded = lavc_on_unneeded;
+ this->context = 0;
+
+ drv->enc = &this->encoder_data;
+ drv->enc->on_close = dxr3_lavc_close;
+ return 1;
+}
+
+/* helper function */
+static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame);
+
+static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ lavc_data_t *this = (lavc_data_t *)drv->enc;
+ AVCodec *codec;
+ unsigned char use_quantizer;
+
+ if (this->context) {
+ avcodec_close(this->context);
+ free(this->context);
+ free(this->picture);
+ this->context = NULL;
+ this->picture = NULL;
+ }
+
+ /* if YUY2 and dimensions changed, we need to re-allocate the
+ * internal YV12 buffer */
+ if (frame->vo_frame.format == XINE_IMGFMT_YUY2) {
+ int image_size = frame->vo_frame.pitches[0] * frame->oheight;
+
+ this->out[0] = this->buf = av_mallocz(image_size * 3/2);
+ this->out[1] = this->out[0] + image_size;
+ this->out[2] = this->out[1] + image_size/4;
+
+ /* fill with black (yuv 16,128,128) */
+ memset(this->out[0], 16, image_size);
+ memset(this->out[1], 128, image_size/4);
+ memset(this->out[2], 128, image_size/4);
+ lprintf("Using YUY2->YV12 conversion\n");
+ }
+
+ /* resolution must be a multiple of two */
+ if ((frame->vo_frame.pitches[0] % 2 != 0) || (frame->oheight % 2 != 0)) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: lavc only handles video dimensions which are multiples of 2\n");
+ return 0;
+ }
+
+ /* get mpeg codec handle */
+ codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
+ if (!codec) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: lavc MPEG1 codec not found\n");
+ return 0;
+ }
+ lprintf("lavc MPEG1 encoder found.\n");
+
+ this->width = frame->vo_frame.pitches[0];
+ this->height = frame->oheight;
+
+ this->context = avcodec_alloc_context();
+ if (!this->context) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: Couldn't start the ffmpeg library\n");
+ return 0;
+ }
+ this->picture = avcodec_alloc_frame();
+ if (!this->picture) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: Couldn't allocate ffmpeg frame\n");
+ return 0;
+ }
+
+ /* mpeg1 encoder only support YUV420P */
+ this->context->pix_fmt = PIX_FMT_YUVJ420P;
+
+ /* put sample parameters */
+ this->context->bit_rate = drv->class->xine->config->register_range(drv->class->xine->config,
+ "dxr3.encoding.lavc_bitrate", 10000, 1000, 20000,
+ _("libavcodec mpeg output bitrate (kbit/s)"),
+ _("The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. "
+ "Higher values will increase quality and CPU usage.\n"
+ "This setting is only considered, when constant quality mode is disabled."), 10, NULL, NULL);
+ this->context->bit_rate *= 1000; /* config in kbit/s, libavcodec wants bit/s */
+
+ use_quantizer = drv->class->xine->config->register_bool(drv->class->xine->config,
+ "dxr3.encoding.lavc_quantizer", 1,
+ _("constant quality mode"),
+ _("When enabled, libavcodec will use a constant quality mode by dynamically "
+ "compressing the images based on their complexity. When disabled, libavcodec "
+ "will use constant bitrate mode."), 10, NULL, NULL);
+
+ if (use_quantizer) {
+ this->context->qmin = drv->class->xine->config->register_range(drv->class->xine->config,
+ "dxr3.encoding.lavc_qmin", 1, 1, 10,
+ _("minimum compression"),
+ _("The minimum compression to apply to an image in constant quality mode."),
+ 10, NULL, NULL);
+
+ this->context->qmax = drv->class->xine->config->register_range(drv->class->xine->config,
+ "dxr3.encoding.lavc_qmax", 2, 1, 20,
+ _("maximum quantizer"),
+ _("The maximum compression to apply to an image in constant quality mode."),
+ 10, NULL, NULL);
+ }
+
+ lprintf("lavc -> bitrate %d \n", this->context->bit_rate);
+
+ this->context->width = frame->vo_frame.pitches[0];
+ this->context->height = frame->oheight;
+
+ this->context->gop_size = 0; /*intra frames only */
+ this->context->me_method = ME_ZERO; /*motion estimation type*/
+
+ this->context->time_base.den = 90000;
+ if (frame->vo_frame.duration > 90000 / 24)
+ this->context->time_base.num = 90000 / 24;
+ else if (frame->vo_frame.duration < 90000 / 60)
+ this->context->time_base.num = 90000 / 60;
+ else
+ this->context->time_base.num = frame->vo_frame.duration;
+ /* ffmpeg can complain about illegal framerates, but since this seems no
+ * problem for the DXR3, we just tell ffmpeg to be more lax with */
+ this->context->strict_std_compliance = -1;
+
+ /* open avcodec */
+ if (avcodec_open(this->context, codec) < 0) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: could not open codec\n");
+ return 0;
+ }
+ lprintf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n");
+
+ if (!this->ffmpeg_buffer)
+ this->ffmpeg_buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); /* why allocate more than needed ?! */
+ if (!this->ffmpeg_buffer) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ int size;
+ lavc_data_t* this = (lavc_data_t *)drv->enc;
+ ssize_t written;
+
+ if (frame->vo_frame.bad_frame) return 1;
+ /* ignore old frames */
+ if ((frame->vo_frame.pitches[0] != this->context->width) || (frame->oheight != this->context->height)) {
+ frame->vo_frame.free(&frame->vo_frame);
+ lprintf("LAVC ignoring frame !!!\n");
+ return 1;
+ }
+
+ /* prepare frame for conversion, handles YUY2 -> YV12 conversion when necessary */
+ lavc_prepare_frame(this, drv, frame);
+
+ /* do the encoding */
+ size = avcodec_encode_video(this->context, this->ffmpeg_buffer, DEFAULT_BUFFER_SIZE, this->picture);
+
+ frame->vo_frame.free(&frame->vo_frame);
+
+ if (size < 0) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: encoding failed\n");
+ return 0;
+ }
+
+ written = write(drv->fd_video, this->ffmpeg_buffer, size);
+ if (written < 0) {
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno));
+ return 0;
+ }
+ if (written != size)
+ xprintf(drv->class->xine, XINE_VERBOSITY_LOG,
+ "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, size);
+ return 1;
+}
+
+static int lavc_on_unneeded(dxr3_driver_t *drv)
+{
+ lavc_data_t *this = (lavc_data_t *)drv->enc;
+ lprintf("flushing buffers\n");
+ if (this->context) {
+ avcodec_close(this->context);
+ free(this->context);
+ free(this->picture);
+ this->context = NULL;
+ this->picture = NULL;
+ }
+ return 1;
+}
+
+static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ int i, j, w2;
+ uint8_t *yuy2;
+
+ if (frame->vo_frame.bad_frame) return 1;
+
+ if (frame->vo_frame.format == XINE_IMGFMT_YUY2) {
+ /* need YUY2->YV12 conversion */
+ if (!(this->out[0] && this->out[1] && this->out[2]) ) {
+ lprintf("Internal YV12 buffer not created.\n");
+ return 0;
+ }
+ this->picture->data[0] = this->out[0] + frame->vo_frame.pitches[0] * drv->top_bar; /* y */
+ this->picture->data[1] = this->out[1] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* u */
+ this->picture->data[2] = this->out[2] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* v */
+ yuy2 = frame->vo_frame.base[0];
+ w2 = frame->vo_frame.pitches[0] / 2;
+ for (i = 0; i < frame->vo_frame.height; i += 2) {
+ for (j = 0; j < w2; j++) {
+ /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */
+ *(this->picture->data[0]++) = *(yuy2++);
+ *(this->picture->data[1]++) = *(yuy2++);
+ *(this->picture->data[0]++) = *(yuy2++);
+ *(this->picture->data[2]++) = *(yuy2++);
+ }
+ /* down sampling */
+ for (j = 0; j < w2; j++) {
+ /* skip every second line for U and V */
+ *(this->picture->data[0]++) = *(yuy2++);
+ yuy2++;
+ *(this->picture->data[0]++) = *(yuy2++);
+ yuy2++;
+ }
+ }
+ /* reset for encoder */
+ this->picture->data[0] = this->out[0];
+ this->picture->data[1] = this->out[1];
+ this->picture->data[2] = this->out[2];
+ }
+ else { /* YV12 **/
+ this->picture->data[0] = frame->real_base[0];
+ this->picture->data[1] = frame->real_base[1];
+ this->picture->data[2] = frame->real_base[2];
+ }
+ this->picture->linesize[0] = this->context->width;
+ this->picture->linesize[1] = this->context->width / 2;
+ this->picture->linesize[2] = this->context->width / 2;
+ return 1;
+}
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
index ed5ae4b58..1fd1028a8 100644
--- a/src/dxr3/video_out_dxr3.c
+++ b/src/dxr3/video_out_dxr3.c
@@ -60,12 +60,18 @@
#define LOG_VID 0
#define LOG_OVR 0
-#include "xine_internal.h"
-#include "xineutils.h"
-#include "video_out.h"
+#include <xine/xine_internal.h>
+#include <xine/xineutils.h>
+#include <xine/video_out.h>
#include "dxr3.h"
#include "video_out_dxr3.h"
+#ifdef HAVE_FFMPEG_AVUTIL_H
+# include <mem.h>
+#else
+# include <libavutil/mem.h>
+#endif
+
#include "compat.c"
/* the amount of extra time we give the card for decoding */
@@ -94,17 +100,15 @@ static const vo_info_t vo_info_dxr3_aa = {
const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
#ifdef HAVE_X11
- { PLUGIN_VIDEO_OUT, 21, "dxr3", XINE_VERSION_CODE, &vo_info_dxr3_x11, &dxr3_x11_init_plugin },
+ { PLUGIN_VIDEO_OUT, 22, "dxr3", XINE_VERSION_CODE, &vo_info_dxr3_x11, &dxr3_x11_init_plugin },
#endif
- { PLUGIN_VIDEO_OUT, 21, "aadxr3", XINE_VERSION_CODE, &vo_info_dxr3_aa, &dxr3_aa_init_plugin },
+ { PLUGIN_VIDEO_OUT, 22, "aadxr3", XINE_VERSION_CODE, &vo_info_dxr3_aa, &dxr3_aa_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
/* plugin class functions */
static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const void *visual);
-static char *dxr3_vo_get_identifier(video_driver_class_t *class_gen);
-static char *dxr3_vo_get_description(video_driver_class_t *class_gen);
static void dxr3_vo_class_dispose(video_driver_class_t *class_gen);
/* plugin instance functions */
@@ -178,8 +182,8 @@ static dxr3_driver_class_t *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL);
this->video_driver_class.open_plugin = dxr3_vo_open_plugin;
- this->video_driver_class.get_identifier = dxr3_vo_get_identifier;
- this->video_driver_class.get_description = dxr3_vo_get_description;
+ this->video_driver_class.identifier = DXR3_VO_ID;
+ this->video_driver_class.description = N_("video output plugin displaying images through your DXR3 decoder card");
this->video_driver_class.dispose = dxr3_vo_class_dispose;
this->xine = xine;
@@ -191,16 +195,6 @@ static dxr3_driver_class_t *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
return this;
}
-static char *dxr3_vo_get_identifier(video_driver_class_t *class_gen)
-{
- return DXR3_VO_ID;
-}
-
-static char *dxr3_vo_get_description(video_driver_class_t *class_gen)
-{
- return "video output plugin displaying images through your DXR3 decoder card";
-}
-
static void dxr3_vo_class_dispose(video_driver_class_t *class_gen)
{
dxr3_driver_class_t *class = (dxr3_driver_class_t *)class_gen;
@@ -222,13 +216,14 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v
static char *available_encoders[SUPPORTED_ENCODER_COUNT + 2];
plugin_node_t *node;
+ static const char *const videoout_modes[] = {
+ "letterboxed tv", "widescreen tv",
#ifdef HAVE_X11
- static const char const *videoout_modes[] = { "letterboxed tv", "widescreen tv",
- "letterboxed overlay", "widescreen overlay", NULL };
-#else
- static const char const *videoout_modes[] = { "letterboxed tv", "widescreen tv", NULL };
+ "letterboxed overlay", "widescreen overlay",
#endif
- static const char const *tv_modes[] = { "ntsc", "pal", "pal60" , "default", NULL };
+ NULL
+ };
+ static const char *const tv_modes[] = { "ntsc", "pal", "pal60" , "default", NULL };
int list_id, list_size;
xine_sarray_t *plugin_list;
@@ -299,21 +294,8 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v
#if LOG_VID
printf("video_out_dxr3: Supported mpeg encoders: ");
#endif
- /* check, if ffmpeg plugin is available by looking through plugin
- * catalog; catalog mutex is already locked here, since this is open_plugin() */
- node = NULL;
- plugin_list = class->xine->plugin_catalog->plugin_lists[PLUGIN_VIDEO_DECODER - 1];
- list_size = xine_sarray_size(plugin_list);
- for (list_id = 0; list_id < list_size; list_id++) {
- node = xine_sarray_get (plugin_list, list_id);
- if (strcasecmp(node->info->id, "ffmpegvideo") == 0) {
- available_encoders[encoder++] = "libavcodec";
-#if LOG_VID
- printf("libavcodec, ");
-#endif
- break;
- }
- }
+ available_encoders[encoder++] = "libavcodec";
+ printf("libavcodec, ");
#ifdef HAVE_LIBFAME
available_encoders[encoder++] = "fame";
#if LOG_VID
@@ -589,7 +571,7 @@ static void dxr3_frame_dispose(vo_frame_t *frame_gen)
{
dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
- if (frame->mem) free(frame->mem);
+ av_free(frame->mem);
pthread_mutex_destroy(&frame_gen->mutex);
free(frame);
}
@@ -629,12 +611,9 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge
frame->aspect = XINE_VO_ASPECT_ANAMORPHIC;
frame->pan_scan = flags & VO_PAN_SCAN_FLAG;
- if (frame->mem) {
- free(frame->mem);
- frame->mem = NULL;
- frame->real_base[0] = frame->real_base[1] = frame->real_base[2] = NULL;
- frame_gen->base[0] = frame_gen->base[1] = frame_gen->base[2] = NULL;
- }
+ av_freep(&frame->mem);
+ frame->real_base[0] = frame->real_base[1] = frame->real_base[2] = NULL;
+ frame_gen->base[0] = frame_gen->base[1] = frame_gen->base[2] = NULL;
return;
}
@@ -719,10 +698,7 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge
/* if dimensions changed, we need to re-allocate frame memory */
if ((frame->vo_frame.width != width) || (frame->vo_frame.height != height) ||
(frame->oheight != oheight) || (frame->vo_frame.format != format)) {
- if (frame->mem) {
- free (frame->mem);
- frame->mem = NULL;
- }
+ av_freep(&frame->mem);
if (format == XINE_IMGFMT_YUY2) {
int i, image_size;
@@ -733,8 +709,7 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge
/* planar format, only base[0] */
/* add one extra line for field swap stuff */
- frame->real_base[0] = xine_xmalloc_aligned(16, image_size + frame->vo_frame.pitches[0],
- &frame->mem);
+ frame->real_base[0] = frame->mem = av_mallocz(image_size + frame->vo_frame.pitches[0]);
/* don't use first line */
frame->real_base[0] += frame->vo_frame.pitches[0];
@@ -761,8 +736,8 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge
image_size_v = frame->vo_frame.pitches[2] * ((oheight + 1) / 2);
/* add one extra line for field swap stuff */
- frame->real_base[0] = xine_xmalloc_aligned(16, image_size_y + frame->vo_frame.pitches[0] +
- image_size_u + image_size_v, &frame->mem);
+ frame->real_base[0] = frame->mem = av_mallocz(image_size_y + frame->vo_frame.pitches[0] +
+ image_size_u + image_size_v);
/* don't use first line */
frame->real_base[0] += frame->vo_frame.pitches[0];
diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h
index 7e24781bf..8158bba8e 100644
--- a/src/dxr3/video_out_dxr3.h
+++ b/src/dxr3/video_out_dxr3.h
@@ -26,8 +26,8 @@
# include <X11/Xlib.h>
#endif
-#include "xine_internal.h"
-#include "vo_scale.h"
+#include <xine/xine_internal.h>
+#include <xine/vo_scale.h>
#include "dxr3_scr.h"
#include "dxr3.h"