summaryrefslogtreecommitdiffstats
path: root/libvo/vo_dxr3.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/vo_dxr3.c')
-rw-r--r--libvo/vo_dxr3.c403
1 files changed, 173 insertions, 230 deletions
diff --git a/libvo/vo_dxr3.c b/libvo/vo_dxr3.c
index 64665ce5e5..66c640dd02 100644
--- a/libvo/vo_dxr3.c
+++ b/libvo/vo_dxr3.c
@@ -6,6 +6,11 @@
*/
/* ChangeLog added 2002-01-10
+ * 2002-02-03:
+ * Removal of libmp1e, libavcodec has finally become faster (and it's code is helluva lot cleaner)
+ * We will call this one the "gentoo" release in favour of the gentoo linux distribution (www.gentoo.org), which
+ * aims at providing maximum performance
+ *
* 2002-02-02:
* Cleaned out some old code which might have slowed down writes
*
@@ -41,8 +46,19 @@
#include "video_out_internal.h"
#include "../postproc/rgb2rgb.h"
-#ifdef USE_MP1E
-#include "../libmp1e/libmp1e.h"
+#ifdef USE_LIBAVCODEC
+#ifdef USE_LIBAVCODEC_SO
+#include <libffmpeg/avcodec.h>
+#else
+#include "libavcodec/avcodec.h"
+#endif
+/* for video encoder */
+static AVCodec *avc_codec = NULL;
+static AVCodecContext *avc_context = NULL;
+static AVPicture avc_picture;
+char *picture_buf = NULL;
+char *avc_outbuf = NULL;
+int avc_outbuf_size = 100000;
#endif
#ifdef HAVE_MMX
@@ -51,17 +67,6 @@
LIBVO_EXTERN (dxr3)
-#ifdef USE_MP1E
-/* libmp1e specific stuff */
-static rte_context *mp1e_context = NULL;
-static rte_codec *mp1e_codec = NULL;
-static rte_buffer mp1e_buffer;
-
-/* Color buffer data used with libmp1e */
-static unsigned char *picture_data[3];
-static int picture_linesize[3];
-#endif
-
/* Resolutions and positions */
static int v_width, v_height;
static int s_width, s_height;
@@ -87,79 +92,10 @@ static vo_info_t vo_info =
""
};
-#ifdef USE_MP1E
-void write_dxr3(rte_context *context, void *data, size_t size, void *user_data)
-{
- write(fd_video, data, size);
-}
-#endif
-
static uint32_t config(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info)
{
int tmp1, tmp2;
em8300_register_t reg;
- char devname[80];
-
- /* Open the control interface */
- if (vo_subdevice) {
- sprintf(devname, "/dev/em8300-%s", vo_subdevice);
- } else {
- /* Try new naming scheme by default */
- sprintf(devname, "/dev/em8300-0");
- }
- fd_control = open(devname, O_WRONLY);
- if (fd_control < 1) {
- /* Fall back to old naming scheme */
- printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300 instead\n", devname);
- sprintf(devname, "/dev/em8300");
- fd_control = open(devname, O_WRONLY);
- if (fd_control < 1) {
- printf("VO: [dxr3] Error opening /dev/em8300 for writing as well!\nBailing\n");
- return -1;
- }
- }
-
- /* Open the video interface */
- if (vo_subdevice) {
- sprintf(devname, "/dev/em8300_mv-%s", vo_subdevice);
- } else {
- /* Try new naming scheme by default */
- sprintf(devname, "/dev/em8300_mv-0");
- }
- fd_video = open(devname, O_WRONLY);
- if (fd_video < 0) {
- /* Fall back to old naming scheme */
- printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300_mv instead\n", devname);
- sprintf(devname, "/dev/em8300_mv");
- fd_video = open(devname, O_WRONLY);
- if (fd_video < 0) {
- printf("VO: [dxr3] Error opening /dev/em8300_mv for writing as well!\nBailing\n");
- uninit();
- return -1;
- }
- } else {
- printf("VO: [dxr3] Opened %s\n", devname);
- }
-
- /* Open the subpicture interface */
- if (vo_subdevice) {
- sprintf(devname, "/dev/em8300_sp-%s", vo_subdevice);
- } else {
- /* Try new naming scheme by default */
- sprintf(devname, "/dev/em8300_sp-0");
- }
- fd_spu = open(devname, O_WRONLY);
- if (fd_spu < 0) {
- /* Fall back to old naming scheme */
- printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300_sp instead\n", devname);
- sprintf(devname, "/dev/em8300_sp");
- fd_spu = open(devname, O_WRONLY);
- if (fd_spu < 0) {
- printf("VO: [dxr3] Error opening /dev/em8300_sp for writing as well!\nBailing\n");
- uninit();
- return -1;
- }
- }
/* This activates the subpicture processor, you can safely disable this and still send */
/* broken subpics to the em8300, if it's enabled and you send broken subpics you will end */
@@ -182,6 +118,18 @@ static uint32_t config(uint32_t scr_width, uint32_t scr_height, uint32_t width,
reg.reg = 0;
reg.val = MVCOMMAND_SYNC;
ioctl(fd_control, EM8300_IOCTL_WRITEREG, &reg);
+
+ /* Set the default playback speed to 0x900 */
+ ioval = 0x900;
+ ioctl(fd_control, EM8300_IOCTL_SCR_SETSPEED, &ioval);
+
+ /* Flush the buffer and make sure it is clean by syncing it */
+ ioval = EM8300_SUBDEVICE_VIDEO;
+ ioctl(fd_control, EM8300_IOCTL_FLUSH, &ioval);
+ fsync(fd_video);
+ /* We'll be nice and flush the audio buffer as well */
+ ioval = EM8300_SUBDEVICE_AUDIO;
+ ioctl(fd_control, EM8300_IOCTL_FLUSH, &ioval);
/* Store some variables statically that we need later in another scope */
img_format = format;
@@ -207,82 +155,31 @@ static uint32_t config(uint32_t scr_width, uint32_t scr_height, uint32_t width,
}
ioctl(fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &ioval);
- if (format == IMGFMT_YV12 || format == IMGFMT_YUY2 || format == IMGFMT_BGR24) {
-#ifdef USE_MP1E
+ if (format != IMGFMT_MPEGPES) {
+#ifdef USE_LIBAVCODEC
int size;
- enum rte_frame_rate frame_rate;
- enum rte_pixformat pixel_format;
-
- /* Here follows initialization of libmp1e specific stuff */
- if (!rte_init()) {
- printf("VO: [dxr3] Unable to initialize MP1E!\n");
+
+ avc_codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
+ if (!avc_codec) {
+ printf("VO: [dxr3] Unable to find mpeg1video codec\n");
uninit();
return -1;
}
-
- mp1e_context = rte_context_new(s_width, s_height, NULL);
- rte_set_verbosity(mp1e_context, 0);
-
- printf("VO: [dxr3] %dx%d => %dx%d\n", v_width, v_height, s_width, s_height);
-
- if (!mp1e_context) {
- printf( "VO: [dxr3] Unable to create context!\n" );
+ avc_context = malloc(sizeof(AVCodecContext));
+ memset(avc_context, 0, sizeof(avc_context));
+ avc_context->width = v_width;
+ avc_context->height = v_height;
+ avc_context->frame_rate = 30 * FRAME_RATE_BASE;
+ avc_context->gop_size = 0;
+ avc_context->bit_rate = 8e6;
+ avc_context->flags = CODEC_FLAG_HQ;
+ avc_context->pix_fmt = PIX_FMT_YUV420P;
+ if (avcodec_open(avc_context, avc_codec) < 0) {
+ printf("VO: [dxr3] Unable to open codec\n");
uninit();
return -1;
}
- /* I wonder if we could benefit from using mpeg2 em8300-wise (hardware processing) */
- if (!rte_set_format(mp1e_context, "mpeg1")) {
- printf("VO: [dxr3] Unable to set format\n");
- uninit();
- return -1;
- }
-
- rte_set_mode(mp1e_context, RTE_VIDEO);
- mp1e_codec = rte_codec_set(mp1e_context, RTE_STREAM_VIDEO, 0, "mpeg1-video");
-
- if (vo_fps < 24.0) {
- frame_rate = RTE_RATE_1;
- } else if (vo_fps < 25.0) {
- frame_rate = RTE_RATE_2;
- } else if (vo_fps < 29.97) {
- frame_rate = RTE_RATE_3;
- } else if (vo_fps < 30.0) {
- frame_rate = RTE_RATE_4;
- } else if (vo_fps < 50.0) {
- frame_rate = RTE_RATE_5;
- } else if (vo_fps < 59.97) {
- frame_rate = RTE_RATE_6;
- } else if (vo_fps < 60.0) {
- frame_rate = RTE_RATE_7;
- } else if (vo_fps > 60.0) {
- frame_rate = RTE_RATE_8;
- } else {
- frame_rate = RTE_RATE_NORATE;
- }
-
- if (format == IMGFMT_YUY2) {
- pixel_format = RTE_YUYV;
- } else {
- pixel_format = RTE_YUV420;
- }
- if (!rte_set_video_parameters(mp1e_context, pixel_format, mp1e_context->width, mp1e_context->height, frame_rate, 3e6, "I")) {
- printf("VO: [dxr3] Unable to set mp1e context!\n");
- rte_context_destroy(mp1e_context);
- mp1e_context = 0;
- uninit();
- return -1;
- }
-
- rte_set_input(mp1e_context, RTE_VIDEO, RTE_PUSH, TRUE, NULL, NULL, NULL);
- rte_set_output(mp1e_context, (void*) write_dxr3, NULL, NULL);
-
- if (!rte_init_context(mp1e_context)) {
- printf("VO: [dxr3] Unable to init mp1e context!\n");
- uninit();
- return -1;
- }
-
/* This stuff calculations the relative position of video and osd on screen */
/* Old stuff taken from the dvb driver, should be removed when introducing spuenc */
osd_w = s_width;
@@ -303,31 +200,23 @@ static uint32_t config(uint32_t scr_width, uint32_t scr_height, uint32_t width,
} else {
s_pos_y = 0;
}
-
- size = s_width * s_height;
- if (format == IMGFMT_YUY2) {
- /* YUY2 Needs no conversion, so no need for a pixel buffer */
- picture_data[0] = NULL;
- picture_linesize[0] = s_width * 2;
- } else {
- /* Create a pixel buffer and set up pointers for color components */
- picture_data[0] = malloc((size * 3)/2);
- picture_data[1] = picture_data[0] + size;
- picture_data[2] = picture_data[1] + size / 4;
- picture_linesize[0] = s_width;
- picture_linesize[1] = s_width / 2;
- picture_linesize[2] = s_width / 2;
- }
-
- if (!rte_start_encoding(mp1e_context)) {
- printf("VO: [dxr3] Unable to start mp1e encoding!\n");
- uninit();
- return -1;
- }
+ /* Create a pixel buffer and set up pointers for color components */
+ memset(&avc_picture, 0, sizeof(avc_picture));
+ avc_picture.linesize[0] = v_width;
+ avc_picture.linesize[1] = v_width / 2;
+ avc_picture.linesize[2] = v_width / 2;
+ avc_outbuf = malloc(avc_outbuf_size);
+ size = s_width * s_height;
+ picture_buf = malloc((size * 3) / 2);
+ avc_picture.data[0] = picture_buf;
+ avc_picture.data[1] = avc_picture.data[0] + size;
+ avc_picture.data[2] = avc_picture.data[1] + size / 4;
if (format == IMGFMT_BGR24) {
yuv2rgb_init(24, MODE_BGR);
+ } else {
+ yuv2rgb_init(24, MODE_RGB);
}
return 0;
#endif
@@ -349,17 +238,17 @@ static const vo_info_t* get_info(void)
static void draw_alpha(int x0, int y0, int w, int h, unsigned char* src, unsigned char *srca, int srcstride)
{
-#ifdef USE_MP1E
+#ifdef USE_LIBAVCODEC
/* This function draws the osd and subtitles etc. It will change to use spuenc soon */
switch (img_format) {
case IMGFMT_BGR24:
case IMGFMT_YV12:
vo_draw_alpha_yv12(w, h, src, srca, srcstride,
- picture_data[0] + (x0 + d_pos_x) + (y0 + d_pos_y) * picture_linesize[0], picture_linesize[0]);
+ avc_picture.data[0] + (x0 + d_pos_x) + (y0 + d_pos_y) * avc_picture.linesize[0], avc_picture.linesize[0]);
break;
case IMGFMT_YUY2:
vo_draw_alpha_yuy2(w, h, src, srca, srcstride,
- picture_data[0] + (x0 + d_pos_x) * 2 + (y0 + d_pos_y) * picture_linesize[0], picture_linesize[0]);
+ avc_picture.data[0] + (x0 + d_pos_x) * 2 + (y0 + d_pos_y) * avc_picture.linesize[0], avc_picture.linesize[0]);
break;
}
#endif
@@ -376,46 +265,32 @@ static uint32_t draw_frame(uint8_t * src[])
{
if (img_format == IMGFMT_MPEGPES) {
vo_mpegpes_t *p = (vo_mpegpes_t *) src[0];
-
+
if (p->id == 0x20) {
+ ioval = vo_pts / 2;
+ ioctl(fd_spu, EM8300_IOCTL_SPU_SETPTS, &ioval);
write(fd_spu, p->data, p->size);
} else {
+ ioval = vo_pts / 2;
+ ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &ioval);
write(fd_video, p->data, p->size);
}
return 0;
- }
-#ifdef USE_MP1E
- else if (img_format == IMGFMT_YUY2) {
- picture_data[0] = src[0];
- return 0;
- } else if (img_format == IMGFMT_BGR24) {
- /* BGR24 needs to be converted to YUV420 before libmp1e will touch it */
- int x, y, w = v_width, h = v_height;
- unsigned char *s, *dY, *dU, *dV;
-
- if ((d_pos_x + w) > picture_linesize[0]) {
- w = picture_linesize[0] - d_pos_x;
- }
- if ((d_pos_y + h) > s_height) {
- h = s_height - d_pos_y;
+#ifdef USE_LIBAVCODEC
+ } else {
+ int size = s_width * s_height;
+ if (img_format == IMGFMT_YUY2) {
+ yuy2toyv12(src[0], avc_picture.data[0], avc_picture.data[1], avc_picture.data[2],
+ v_width, v_height, avc_picture.linesize[0], avc_picture.linesize[1], v_width*2);
+ } else if (img_format == IMGFMT_BGR24) {
+ rgb24toyv12(src[0], avc_picture.data[0], avc_picture.data[1], avc_picture.data[2],
+ v_width, v_height, avc_picture.linesize[0], avc_picture.linesize[1], v_width*3);
}
-
- s = src[0] + s_pos_y * (w * 3);
-
- dY = picture_data[0] + d_pos_y * picture_linesize[0];
- dU = picture_data[1] + (d_pos_y / 2) * picture_linesize[1];
- dV = picture_data[2] + (d_pos_y / 2) * picture_linesize[2];
-
- rgb24toyv12(s, dY, dU, dV, w, h, picture_linesize[0], picture_linesize[1], v_width * 3);
-
- mp1e_buffer.data = picture_data[0];
- mp1e_buffer.time = vo_pts / 90000.0;
- mp1e_buffer.user_data = NULL;
- vo_draw_text(osd_w, osd_h, draw_alpha);
- rte_push_video_buffer(mp1e_context, &mp1e_buffer);
+ size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture);
+ write(fd_video, avc_outbuf, size);
return 0;
- }
#endif
+ }
return -1;
}
@@ -427,24 +302,17 @@ static void flip_page(void)
ioval = EM8300_SUBDEVICE_VIDEO;
ioctl(fd_control, EM8300_IOCTL_FLUSH, &ioval);
}
-#ifdef USE_MP1E
+#ifdef USE_LIBAVCODEC
if (img_format == IMGFMT_YV12) {
- mp1e_buffer.data = picture_data[0];
- mp1e_buffer.time = vo_pts / 90000.0;
- mp1e_buffer.user_data = NULL;
- rte_push_video_buffer(mp1e_context, &mp1e_buffer);
- } else if (img_format == IMGFMT_YUY2) {
- mp1e_buffer.data = picture_data[0];
- mp1e_buffer.time = vo_pts / 90000.0;
- mp1e_buffer.user_data = NULL;
- rte_push_video_buffer(mp1e_context, &mp1e_buffer);
+ int out_size = avcodec_encode_video(avc_context, avc_outbuf, avc_outbuf_size, &avc_picture);
+ write(fd_video, avc_outbuf, out_size);
}
#endif
}
static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0)
{
-#ifdef USE_MP1E
+#ifdef USE_LIBAVCODEC
if (img_format == IMGFMT_YV12) {
int y;
unsigned char *s, *s1;
@@ -453,19 +321,19 @@ static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0
x0 += d_pos_x;
y0 += d_pos_y;
- if ((x0 + w) > picture_linesize[0]) {
- w = picture_linesize[0] - x0;
+ if ((x0 + w) > avc_picture.linesize[0]) {
+ w = avc_picture.linesize[0] - x0;
}
if ((y0 + h) > s_height) {
h = s_height - y0;
}
s = srcimg[0] + s_pos_x + s_pos_y * stride[0];
- d = picture_data[0] + x0 + y0 * picture_linesize[0];
+ d = avc_picture.data[0] + x0 + y0 * avc_picture.linesize[0];
for(y = 0; y < h; y++) {
memcpy(d, s, w);
s += stride[0];
- d += picture_linesize[0];
+ d += avc_picture.linesize[0];
}
w /= 2;
@@ -474,16 +342,16 @@ static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0
y0 /= 2;
s = srcimg[1] + s_pos_x + (s_pos_y * stride[1]);
- d = picture_data[1] + x0 + (y0 * picture_linesize[1]);
+ d = avc_picture.data[1] + x0 + (y0 * avc_picture.linesize[1]);
s1 = srcimg[2] + s_pos_x + (s_pos_y * stride[2]);
- d1 = picture_data[2] + x0 + (y0 * picture_linesize[2]);
+ d1 = avc_picture.data[2] + x0 + (y0 * avc_picture.linesize[2]);
for(y = 0; y < h; y++) {
memcpy(d, s, w);
memcpy(d1, s1, w);
s += stride[1];
s1 += stride[2];
- d += picture_linesize[1];
- d1 += picture_linesize[2];
+ d += avc_picture.linesize[1];
+ d1 += avc_picture.linesize[2];
}
return 0;
}
@@ -496,15 +364,18 @@ static uint32_t query_format(uint32_t format)
uint32_t flag = 0;
if (format == IMGFMT_MPEGPES) {
- /* Hardware accelerated | Hardware supports subpics | Hardware handles syncing */
+ /* Hardware accelerated | Hardware supports subpics */
flag = 0x2 | 0x8;
-#ifdef USE_MP1E
+#ifdef USE_LIBAVCODEC
} else if (format == IMGFMT_YV12) {
/* Conversion needed | OSD Supported */
flag = 0x1 | 0x4;
} else if (format == IMGFMT_YUY2) {
/* Conversion needed | OSD Supported */
flag = 0x1 | 0x4;
+ } else if (format == IMGFMT_RGB24) {
+ /* Conversion needed | OSD Supported */
+ flag = 0x1 | 0x4;
} else if (format == IMGFMT_BGR24) {
/* Conversion needed | OSD Supported */
flag = 0x1 | 0x4;
@@ -512,7 +383,7 @@ static uint32_t query_format(uint32_t format)
printf("VO: [dxr3] Format unsupported, mail dholm@iname.com\n");
#else
} else {
- printf("VO: [dxr3] You have disabled libmp1e support, you won't be able to play this format!\n");
+ printf("VO: [dxr3] You have enable libavcodec support (Read DOCS/codecs.html)!\n");
#endif
}
return flag;
@@ -521,9 +392,12 @@ static uint32_t query_format(uint32_t format)
static void uninit(void)
{
printf("VO: [dxr3] Uninitializing\n");
-#ifdef USE_MP1E
- if (picture_data[0]) {
- free(picture_data[0]);
+#ifdef USE_LIBAVCODEC
+ if (avc_context) {
+ avcodec_close(avc_context);
+ }
+ if (picture_buf) {
+ free(picture_buf);
}
#endif
if (fd_video) {
@@ -543,6 +417,75 @@ static void check_events(void)
static uint32_t preinit(const char *arg)
{
+ char devname[80];
+ int fdflags = O_WRONLY | O_NONBLOCK;
+
+ /* Open the control interface */
+ if (vo_subdevice) {
+ sprintf(devname, "/dev/em8300-%s", vo_subdevice);
+ } else {
+ /* Try new naming scheme by default */
+ sprintf(devname, "/dev/em8300-0");
+ }
+ fd_control = open(devname, fdflags);
+ if (fd_control < 1) {
+ /* Fall back to old naming scheme */
+ printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300 instead\n", devname);
+ sprintf(devname, "/dev/em8300");
+ fd_control = open(devname, fdflags);
+ if (fd_control < 1) {
+ printf("VO: [dxr3] Error opening /dev/em8300 for writing as well!\nBailing\n");
+ return -1;
+ }
+ }
+
+ /* Open the video interface */
+ if (vo_subdevice) {
+ sprintf(devname, "/dev/em8300_mv-%s", vo_subdevice);
+ } else {
+ /* Try new naming scheme by default */
+ sprintf(devname, "/dev/em8300_mv-0");
+ }
+ fd_video = open(devname, fdflags);
+ if (fd_video < 0) {
+ /* Fall back to old naming scheme */
+ printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300_mv instead\n", devname);
+ sprintf(devname, "/dev/em8300_mv");
+ fd_video = open(devname, fdflags);
+ if (fd_video < 0) {
+ printf("VO: [dxr3] Error opening /dev/em8300_mv for writing as well!\nBailing\n");
+ uninit();
+ return -1;
+ }
+ } else {
+ printf("VO: [dxr3] Opened %s\n", devname);
+ }
+
+ /* Open the subpicture interface */
+ if (vo_subdevice) {
+ sprintf(devname, "/dev/em8300_sp-%s", vo_subdevice);
+ } else {
+ /* Try new naming scheme by default */
+ sprintf(devname, "/dev/em8300_sp-0");
+ }
+ fd_spu = open(devname, fdflags);
+ if (fd_spu < 0) {
+ /* Fall back to old naming scheme */
+ printf("VO: [dxr3] Error opening %s for writing, trying /dev/em8300_sp instead\n", devname);
+ sprintf(devname, "/dev/em8300_sp");
+ fd_spu = open(devname, fdflags);
+ if (fd_spu < 0) {
+ printf("VO: [dxr3] Error opening /dev/em8300_sp for writing as well!\nBailing\n");
+ uninit();
+ return -1;
+ }
+ }
+
+#ifdef USE_LIBAVCODEC
+ avcodec_init();
+ avcodec_register_all();
+#endif
+
return 0;
}