summaryrefslogtreecommitdiff
path: root/src/libreal/xine_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libreal/xine_decoder.c')
-rw-r--r--src/libreal/xine_decoder.c557
1 files changed, 0 insertions, 557 deletions
diff --git a/src/libreal/xine_decoder.c b/src/libreal/xine_decoder.c
deleted file mode 100644
index ea1fc8c54..000000000
--- a/src/libreal/xine_decoder.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright (C) 2000-2004 the xine project
- *
- * This file is part of xine, a free 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * $Id: xine_decoder.c,v 1.93 2007/03/17 15:45:41 dgp85 Exp $
- *
- * thin layer to use real binary-only codecs in xine
- *
- * code inspired by work from Florian Schneider for the MPlayer Project
- */
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-#define LOG_MODULE "real_decoder"
-#define LOG_VERBOSE
-/*
-#define LOG
-*/
-#include "bswap.h"
-#include "xine_internal.h"
-#include "video_out.h"
-#include "buffer.h"
-#include "xineutils.h"
-
-#include "real_common.h"
-
-typedef struct {
- video_decoder_class_t decoder_class;
-
- /* empty so far */
-} real_class_t;
-
-#define BUF_SIZE 65536
-
-typedef struct realdec_decoder_s {
- video_decoder_t video_decoder;
-
- real_class_t *cls;
-
- xine_stream_t *stream;
-
- void *rv_handle;
-
- uint32_t (*rvyuv_custom_message)(void*, void*);
- uint32_t (*rvyuv_free)(void*);
- uint32_t (*rvyuv_hive_message)(uint32_t, uint32_t);
- uint32_t (*rvyuv_init)(void*, void*); /* initdata,context */
- uint32_t (*rvyuv_transform)(char*, char*, void*, uint32_t*,void*);
-
- void *context;
-
- uint32_t width, height;
- double ratio;
- double fps;
-
- uint8_t *chunk_buffer;
- int chunk_buffer_size;
- int chunk_buffer_max;
-
- int64_t pts;
- int duration;
-
- uint8_t *frame_buffer;
- int frame_size;
- int decoder_ok;
-
-} realdec_decoder_t;
-
-/* we need exact positions */
-typedef struct {
- int16_t unk1;
- int16_t w;
- int16_t h;
- int16_t unk3;
- int32_t unk2;
- int32_t subformat;
- int32_t unk5;
- int32_t format;
-} rv_init_t;
-
-/*
- * Structures for data packets. These used to be tables of unsigned ints, but
- * that does not work on 64 bit platforms (e.g. Alpha). The entries that are
- * pointers get truncated. Pointers on 64 bit platforms are 8 byte longs.
- * So we have to use structures so the compiler will assign the proper space
- * for the pointer.
- */
-typedef struct cmsg_data_s {
- uint32_t data1;
- uint32_t data2;
- uint32_t* dimensions;
-} cmsg_data_t;
-
-typedef struct transform_in_s {
- uint32_t len;
- uint32_t unknown1;
- uint32_t chunks;
- uint32_t* extra;
- uint32_t unknown2;
- uint32_t timestamp;
-} transform_in_t;
-
-/*
- * real codec loader
- */
-
-static int load_syms_linux (realdec_decoder_t *this, const char *codec_name, const char *const codec_alternate) {
- cfg_entry_t* entry =
- this->stream->xine->config->lookup_entry(this->stream->xine->config,
- "decoder.external.real_codecs_path");
-
- if ( (this->rv_handle = _x_real_codec_open(this->stream, entry->str_value, codec_name, codec_alternate)) == NULL )
- return 0;
-
- this->rvyuv_custom_message = dlsym (this->rv_handle, "RV20toYUV420CustomMessage");
- this->rvyuv_free = dlsym (this->rv_handle, "RV20toYUV420Free");
- this->rvyuv_hive_message = dlsym (this->rv_handle, "RV20toYUV420HiveMessage");
- this->rvyuv_init = dlsym (this->rv_handle, "RV20toYUV420Init");
- this->rvyuv_transform = dlsym (this->rv_handle, "RV20toYUV420Transform");
-
- if (this->rvyuv_custom_message &&
- this->rvyuv_free &&
- this->rvyuv_hive_message &&
- this->rvyuv_init &&
- this->rvyuv_transform)
- return 1;
-
- this->rvyuv_custom_message = dlsym (this->rv_handle, "RV40toYUV420CustomMessage");
- this->rvyuv_free = dlsym (this->rv_handle, "RV40toYUV420Free");
- this->rvyuv_hive_message = dlsym (this->rv_handle, "RV40toYUV420HiveMessage");
- this->rvyuv_init = dlsym (this->rv_handle, "RV40toYUV420Init");
- this->rvyuv_transform = dlsym (this->rv_handle, "RV40toYUV420Transform");
-
- if (this->rvyuv_custom_message &&
- this->rvyuv_free &&
- this->rvyuv_hive_message &&
- this->rvyuv_init &&
- this->rvyuv_transform)
- return 1;
-
- xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
- _("libreal: Error resolving symbols! (version incompatibility?)\n"));
- return 0;
-}
-
-static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
-
- /* unsigned int* extrahdr = (unsigned int*) (buf->content+28); */
- int result;
- rv_init_t init_data = {11, 0, 0, 0, 0, 0, 1, 0}; /* rv30 */
-
-
- switch (buf->type) {
- case BUF_VIDEO_RV20:
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 2.0");
- if (!load_syms_linux (this, "drv2.so", "drv2.so.6.0"))
- return 0;
- break;
- case BUF_VIDEO_RV30:
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 3.0");
- if (!load_syms_linux (this, "drvc.so", "drv3.so.6.0"))
- return 0;
- break;
- case BUF_VIDEO_RV40:
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 4.0");
- if (!load_syms_linux(this, "drvc.so", "drv3.so.6.0"))
- return 0;
- break;
- default:
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "libreal: error, i don't handle buf type 0x%08x\n", buf->type);
- _x_abort();
- }
-
- init_data.w = BE_16(&buf->content[12]);
- init_data.h = BE_16(&buf->content[14]);
-
- this->width = (init_data.w + 1) & (~1);
- this->height = (init_data.h + 1) & (~1);
-
- if(buf->decoder_flags & BUF_FLAG_ASPECT)
- this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2];
- else
- this->ratio = (double)this->width / (double)this->height;
-
- /* While the framerate is stored in the header it sometimes doesn't bear
- * much resemblence to the actual frequency of frames in the file. Hence
- * it's better to just let the engine estimate the frame duration for us */
-#if 0
- this->fps = (double) BE_16(&buf->content[22]) +
- ((double) BE_16(&buf->content[24]) / 65536.0);
- this->duration = 90000.0 / this->fps;
-#endif
-
- lprintf("this->ratio=%f\n", this->ratio);
-
- lprintf ("init_data.w=%d(0x%x), init_data.h=%d(0x%x),"
- "this->width=%d(0x%x), this->height=%d(0x%x)\n",
- init_data.w, init_data.w,
- init_data.h, init_data.h,
- this->width, this->width, this->height, this->height);
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration);
-
- init_data.subformat = BE_32(&buf->content[26]);
- init_data.format = BE_32(&buf->content[30]);
-
-#ifdef LOG
- printf ("libreal: init_data for rvyuv_init:\n");
- xine_hexdump ((char *) &init_data, sizeof (init_data));
-
- printf ("libreal: buf->content\n");
- xine_hexdump (buf->content, buf->size);
-#endif
- lprintf ("init codec %dx%d... %x %x\n",
- init_data.w, init_data.h,
- init_data.subformat, init_data.format );
-
- this->context = NULL;
-
- result = this->rvyuv_init (&init_data, &this->context);
-
- lprintf ("init result: %d\n", result);
-
- /* setup rv30 codec (codec sub-type and image dimensions): */
- if ((init_data.format>=0x20200002) && (buf->type != BUF_VIDEO_RV40)) {
- int i, j;
- uint32_t cmsg24[(buf->size - 34 + 2) * sizeof(uint32_t)];
- cmsg_data_t cmsg_data = { 0x24, 1 + ((init_data.subformat >> 16) & 7), &cmsg24[0] };
-
- cmsg24[0] = this->width;
- cmsg24[1] = this->height;
- for(i = 2, j = 34; j < buf->size; i++, j++)
- cmsg24[i] = 4 * buf->content[j];
-
-#ifdef LOG
- printf ("libreal: CustomMessage cmsg_data:\n");
- xine_hexdump ((uint8_t *) cmsg_data, sizeof (cmsg_data));
- printf ("libreal: cmsg24:\n");
- xine_hexdump ((uint8_t *) cmsg24, (buf->size - 34 + 2) * sizeof(uint32_t));
-#endif
-
- this->rvyuv_custom_message (&cmsg_data, this->context);
- }
-
- this->stream->video_out->open(this->stream->video_out, this->stream);
-
- this->frame_size = this->width * this->height;
- this->frame_buffer = xine_xmalloc (this->width * this->height * 3 / 2);
-
- this->chunk_buffer = xine_xmalloc (BUF_SIZE);
- this->chunk_buffer_max = BUF_SIZE;
-
- return 1;
-}
-
-static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
- realdec_decoder_t *this = (realdec_decoder_t *) this_gen;
-
- lprintf ("decode_data, flags=0x%08x, len=%d, pts=%"PRId64" ...\n",
- buf->decoder_flags, buf->size, buf->pts);
-
- if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
- /* real_find_sequence_header (&this->real, buf->content, buf->content + buf->size);*/
- return;
- }
-
- if (buf->decoder_flags & BUF_FLAG_FRAMERATE) {
- this->duration = buf->decoder_info[0];
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION,
- this->duration);
- }
-
- if (buf->decoder_flags & BUF_FLAG_HEADER) {
-
- this->decoder_ok = init_codec (this, buf);
- if( !this->decoder_ok )
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
-
- } else if (this->decoder_ok && this->context) {
-
- /* Each frame starts with BUF_FLAG_FRAME_START and ends with
- * BUF_FLAG_FRAME_END.
- * The last buffer contains the chunk offset table.
- */
-
- if (!(buf->decoder_flags & BUF_FLAG_SPECIAL)) {
-
- lprintf ("buffer (%d bytes)\n", buf->size);
-
- if (buf->decoder_flags & BUF_FLAG_FRAME_START) {
- /* new frame starting */
-
- this->chunk_buffer_size = 0;
- this->pts = buf->pts;
- lprintf ("new frame starting, pts=%"PRId64"\n", this->pts);
- }
-
- if ((this->chunk_buffer_size + buf->size) > this->chunk_buffer_max) {
- lprintf("increasing chunk buffer size\n");
-
- this->chunk_buffer_max *= 2;
- this->chunk_buffer = realloc(this->chunk_buffer, this->chunk_buffer_max);
- }
-
- xine_fast_memcpy (this->chunk_buffer + this->chunk_buffer_size,
- buf->content,
- buf->size);
-
- this->chunk_buffer_size += buf->size;
-
- } else {
- /* end of frame, chunk table */
-
- lprintf ("special buffer (%d bytes)\n", buf->size);
-
- if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) {
-
- int result;
- vo_frame_t *img;
-
- uint32_t transform_out[5];
- transform_in_t transform_in = {
- this->chunk_buffer_size,
- /* length of the packet (sub-packets appended) */
- 0,
- /* unknown, seems to be unused */
- buf->decoder_info[2],
- /* number of sub-packets - 1 */
- buf->decoder_info_ptr[2],
- /* table of sub-packet offsets */
- 0,
- /* unknown, seems to be unused */
- this->pts / 90
- /* timestamp (the integer value from the stream) */
- };
-
- lprintf ("chunk table\n");
-
-
-#ifdef LOG
- printf ("libreal: got %d chunks\n",
- buf->decoder_info[2] + 1);
-
- printf ("libreal: decoding %d bytes:\n", this->chunk_buffer_size);
- xine_hexdump (this->chunk_buffer, this->chunk_buffer_size);
-
- printf ("libreal: transform_in:\n");
- xine_hexdump ((uint8_t *) transform_in, 6 * 4);
-
- printf ("libreal: chunk_table:\n");
- xine_hexdump ((uint8_t *) buf->decoder_info_ptr[2],
- 2*(buf->decoder_info[2]+1)*sizeof(uint32_t));
-#endif
-
- result = this->rvyuv_transform (this->chunk_buffer,
- this->frame_buffer,
- &transform_in,
- transform_out,
- this->context);
-
- lprintf ("transform result: %08x\n", result);
- lprintf ("transform_out:\n");
- #ifdef LOG
- xine_hexdump ((uint8_t *) transform_out, 5 * 4);
- #endif
-
- /* Sometimes the stream contains video of a different size
- * to that specified in the realmedia header */
- if(transform_out[0] && ((transform_out[3] != this->width) ||
- (transform_out[4] != this->height))) {
- this->width = transform_out[3];
- this->height = transform_out[4];
-
- this->frame_size = this->width * this->height;
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height);
- }
-
- img = this->stream->video_out->get_frame (this->stream->video_out,
- /* this->av_picture.linesize[0], */
- this->width,
- this->height,
- this->ratio,
- XINE_IMGFMT_YV12,
- VO_BOTH_FIELDS);
-
- img->pts = this->pts;
- img->duration = this->duration;
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration);
- img->bad_frame = 0;
-
- yv12_to_yv12(
- /* Y */
- this->frame_buffer, this->width,
- img->base[0], img->pitches[0],
- /* U */
- this->frame_buffer + this->frame_size, this->width/2,
- img->base[1], img->pitches[1],
- /* V */
- this->frame_buffer + this->frame_size * 5/4, this->width/2,
- img->base[2], img->pitches[2],
- /* width x height */
- this->width, this->height);
-
- img->draw(img, this->stream);
- img->free(img);
-
- } else {
- /* unsupported special buf */
- }
- }
- }
-
- lprintf ("decode_data...done\n");
-}
-
-static void realdec_flush (video_decoder_t *this_gen) {
- /* realdec_decoder_t *this = (realdec_decoder_t *) this_gen; */
-
- lprintf ("flush\n");
-}
-
-static void realdec_reset (video_decoder_t *this_gen) {
- realdec_decoder_t *this = (realdec_decoder_t *) this_gen;
-
- this->chunk_buffer_size = 0;
-}
-
-static void realdec_discontinuity (video_decoder_t *this_gen) {
- realdec_decoder_t *this = (realdec_decoder_t *) this_gen;
-
- this->pts = 0;
-}
-
-static void realdec_dispose (video_decoder_t *this_gen) {
-
- realdec_decoder_t *this = (realdec_decoder_t *) this_gen;
-
- lprintf ("dispose\n");
-
- if (this->context)
- this->stream->video_out->close(this->stream->video_out, this->stream);
-
- if (this->rvyuv_free && this->context)
- this->rvyuv_free (this->context);
-
- if (this->rv_handle)
- dlclose (this->rv_handle);
-
- if (this->frame_buffer)
- free (this->frame_buffer);
-
- if (this->chunk_buffer)
- free (this->chunk_buffer);
-
- free (this);
-
- lprintf ("dispose done\n");
-}
-
-static video_decoder_t *open_plugin (video_decoder_class_t *class_gen,
- xine_stream_t *stream) {
-
- real_class_t *cls = (real_class_t *) class_gen;
- realdec_decoder_t *this ;
-
- this = (realdec_decoder_t *) xine_xmalloc (sizeof (realdec_decoder_t));
-
- this->video_decoder.decode_data = realdec_decode_data;
- this->video_decoder.flush = realdec_flush;
- this->video_decoder.reset = realdec_reset;
- this->video_decoder.discontinuity = realdec_discontinuity;
- this->video_decoder.dispose = realdec_dispose;
- this->stream = stream;
- this->cls = cls;
-
- this->context = 0;
- this->pts = 0;
-
- this->duration = 0;
-
- return &this->video_decoder;
-}
-
-/*
- * real plugin class
- */
-
-static char *get_identifier (video_decoder_class_t *this) {
- return "realvdec";
-}
-
-static char *get_description (video_decoder_class_t *this) {
- return "real binary-only codec based video decoder plugin";
-}
-
-static void dispose_class (video_decoder_class_t *this) {
- free (this);
-}
-
-void *init_realvdec (xine_t *xine, void *data) {
-
- real_class_t *this;
- config_values_t *config = xine->config;
-
- this = (real_class_t *) xine_xmalloc (sizeof (real_class_t));
-
- this->decoder_class.open_plugin = open_plugin;
- this->decoder_class.get_identifier = get_identifier;
- this->decoder_class.get_description = get_description;
- this->decoder_class.dispose = dispose_class;
-
- _x_real_codecs_init(xine);
-
- return this;
-}
-
-/*
- * exported plugin catalog entry
- */
-
-static uint32_t supported_types[] = { BUF_VIDEO_RV20,
- BUF_VIDEO_RV30,
- BUF_VIDEO_RV40,
- 0 };
-
-const decoder_info_t dec_info_realvideo = {
- supported_types, /* supported types */
- 7 /* priority */
-};