diff options
author | Diego 'Flameeyes' Pettenò <flameeyes@gmail.com> | 2007-04-04 22:32:38 +0200 |
---|---|---|
committer | Diego 'Flameeyes' Pettenò <flameeyes@gmail.com> | 2007-04-04 22:32:38 +0200 |
commit | 97a947ebad397381309c1c41badecc31999defb6 (patch) | |
tree | 059815e312703fbc85e906e4a3e28ecd3399e1eb /src/libreal/xine_decoder.c | |
parent | 63707aa6026241c7040b8cee59032aed10559e15 (diff) | |
download | xine-lib-97a947ebad397381309c1c41badecc31999defb6.tar.gz xine-lib-97a947ebad397381309c1c41badecc31999defb6.tar.bz2 |
Rename audio_decoder.c and xine_decoder.c
--HG--
rename : src/libreal/audio_decoder.c => src/libreal/xine_real_audio_decoder.c
rename : src/libreal/xine_decoder.c => src/libreal/xine_real_video_decoder.c
Diffstat (limited to 'src/libreal/xine_decoder.c')
-rw-r--r-- | src/libreal/xine_decoder.c | 557 |
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 */ -}; |