summaryrefslogtreecommitdiff
path: root/xine
diff options
context:
space:
mode:
Diffstat (limited to 'xine')
-rw-r--r--xine/BluRay/Makefile33
-rw-r--r--xine/BluRay/decode_spuhdmv.c1027
-rw-r--r--xine/BluRay/demux_ts.c2504
-rw-r--r--xine/adjustable_scr.c309
-rw-r--r--xine/adjustable_scr.h37
-rw-r--r--xine/demux_xvdr.c1234
-rw-r--r--xine/demux_xvdr_tsdata.c91
-rw-r--r--xine/demux_xvdr_tsdata.h34
-rw-r--r--xine/osd_manager.c729
-rw-r--r--xine/osd_manager.h36
-rw-r--r--xine/post.c901
-rw-r--r--xine/post.h99
-rw-r--r--xine/post_util.h144
-rw-r--r--xine/ts2es.c284
-rw-r--r--xine/ts2es.h21
-rw-r--r--xine/vo_hook.c201
-rw-r--r--xine/vo_hook.h42
-rw-r--r--xine/vo_osdreorder.c100
-rw-r--r--xine/vo_osdreorder.h16
-rw-r--r--xine/vo_osdscaler.c439
-rw-r--r--xine/vo_osdscaler.h16
-rw-r--r--xine/vo_post.h25
-rw-r--r--xine/vo_props.h60
-rw-r--r--xine/xvdr_metronom.c164
-rw-r--r--xine/xvdr_metronom.h49
25 files changed, 0 insertions, 8595 deletions
diff --git a/xine/BluRay/Makefile b/xine/BluRay/Makefile
deleted file mode 100644
index 531449c6..00000000
--- a/xine/BluRay/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-
-XINEDMXPLUGIN = xineplug_dmx_mpeg_ts_hdmv.so
-OBJS_XINEDMXPLUGIN = demux_ts.o
-XINESPUPLUGIN = xineplug_decode_spuhdmv.so
-OBJS_XINESPUPLUGIN = decode_spuhdmv.o
-
-LIBS_XINE = $(shell pkg-config libxine --libs)
-CFLAGS += $(shell pkg-config libxine --cflags)
-CFLAGS += -Ixine
-CFLAGS += -O2 -fPIC
-XINEPLUGINDIR = $(shell pkg-config libxine --variable=plugindir)
-DESTDIR = /
-INSTALL = install
-LDFLAGS += -shared -fvisibility=hidden
-
-all: $(XINEDMXPLUGIN) $(XINESPUPLUGIN)
-
-$(XINEDMXPLUGIN): $(OBJS_XINEDMXPLUGIN)
- $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS_XINE) -o $@ $(OBJS_XINEDMXPLUGIN)
-
-$(XINESPUPLUGIN): $(OBJS_XINESPUPLUGIN)
- $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS_XINE) -o $@ $(OBJS_XINESPUPLUGIN)
-
-clean:
- @rm -rf *.o *.so *~
-
-install: all
- @echo Installing $(DESTDIR)/$(XINEPLUGINDIR)/$(XINEDMXPLUGIN)
- @-rm -rf $(DESTDIR)/$(XINEPLUGINDIR)/$(XINEDMXPLUGIN)
- @$(INSTALL) -m 0644 $(XINEDMXPLUGIN) $(DESTDIR)/$(XINEPLUGINDIR)/$(XINEDMXPLUGIN)
- @echo Installing $(DESTDIR)/$(XINEPLUGINDIR)/$(XINESPUPLUGIN)
- @-rm -rf $(DESTDIR)/$(XINEPLUGINDIR)/$(XINESPUPLUGIN)
- @$(INSTALL) -m 0644 $(XINESPUPLUGIN) $(DESTDIR)/$(XINEPLUGINDIR)/$(XINESPUPLUGIN)
diff --git a/xine/BluRay/decode_spuhdmv.c b/xine/BluRay/decode_spuhdmv.c
deleted file mode 100644
index 81ac6778..00000000
--- a/xine/BluRay/decode_spuhdmv.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * Copyright (C) 2000-2009 the xine project
- *
- * Copyright (C) 2009 Petri Hintukainen <phintuka@users.sourceforge.net>
- *
- * 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
- *
- * Decoder for HDMV/BluRay bitmap subtitles
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-# include "xine_internal.h"
-# include "buffer.h"
-# include "xineutils.h"
-# include "video_out.h"
-# include "video_overlay.h"
-#else
-# include <xine/xine_internal.h>
-# include <xine/buffer.h>
-# include <xine/xineutils.h>
-# include <xine/video_out.h>
-# include <xine/video_overlay.h>
-#endif
-
-#define TRACE(x...) printf(x)
-/*#define TRACE(x...) */
-#define ERROR(x...) fprintf(stderr, "spuhdmv: " x)
-/*#define ERROR(x...) lprintf(x) */
-
-#ifndef EXPORTED
-# define EXPORTED __attribute__((visibility("default")))
-#endif
-
-#ifndef BUF_SPU_HDMV
-# define BUF_SPU_HDMV 0x04180000
-#endif
-
-/*
- * cached palette (xine-lib format)
- */
-typedef struct subtitle_clut_s subtitle_clut_t;
-struct subtitle_clut_s {
- uint8_t id;
- uint32_t color[256];
- uint8_t trans[256];
- subtitle_clut_t *next;
-
- int shown;
-};
-
-/*
- * cached RLE image (xine-lib format)
- */
-typedef struct subtitle_object_s subtitle_object_t;
-struct subtitle_object_s {
- uint16_t id;
- uint16_t xpos, ypos;
- uint16_t width, height;
-
- rle_elem_t *rle;
- uint num_rle;
- size_t data_size;
-
-#if 0
- uint8_t *raw_data; /* partial RLE data in HDMV format */
- size_t raw_data_len;
- size_t raw_data_size;
-#endif
-
- subtitle_object_t *next;
-
- int shown;
-};
-
-/*
- * Window definition
- */
-typedef struct window_def_s window_def_t;
-struct window_def_s {
- uint8_t id;
- uint16_t xpos, ypos;
- uint16_t width, height;
-
- window_def_t *next;
-
- int shown;
-};
-
-
-/*
- * decoded SPU
- */
-typedef struct composition_object_s composition_object_t;
-struct composition_object_s {
- uint8_t window_id_ref;
- uint8_t object_id_ref;
-
- uint16_t xpos, ypos;
-
- uint8_t forced_flag;
- uint8_t cropped_flag;
- uint16_t crop_horiz_pos, crop_vert_pos;
- uint16_t crop_width, crop_height;
-
- composition_object_t *next;
-
- int shown;
-};
-
-typedef struct composition_descriptor_s composition_descriptor_t;
-struct composition_descriptor_s {
- uint16_t number;
- uint8_t state;
-};
-
-typedef struct presentation_segment_s presentation_segment_t;
-struct presentation_segment_s {
- composition_descriptor_t comp_descr;
-
- uint8_t palette_update_flag;
- uint8_t palette_id_ref;
- uint8_t object_number;
-
- composition_object_t *comp_objs;
-
- presentation_segment_t *next;
-
- int64_t pts;
- int shown;
-};
-
-/*
- * list handling
- */
-
-#define LIST_REPLACE(list, obj, FREE_FUNC) \
- do { \
- uint id = obj->id; \
- \
- /* insert to list */ \
- obj->next = list; \
- list = obj; \
- \
- /* remove old */ \
- while (obj->next && obj->next->id != id) \
- obj = obj->next; \
- if (obj->next) { \
- void *tmp = (void*)obj->next; \
- obj->next = obj->next->next; \
- FREE_FUNC(tmp); \
- } \
- } while (0);
-
-#define LIST_DESTROY(list, FREE_FUNC) \
- while (list) { \
- void *tmp = (void*)list; \
- list = list->next; \
- FREE_FUNC(tmp); \
- }
-
-static void free_subtitle_object(void *ptr)
-{
- if (ptr) {
- free(((subtitle_object_t*)ptr)->rle);
- free(ptr);
- }
-}
-static void free_presentation_segment(void *ptr)
-{
- if (ptr) {
- presentation_segment_t *seg = (presentation_segment_t*)ptr;
- LIST_DESTROY(seg->comp_objs, free);
- free(ptr);
- }
-}
-
-
-/*
- * segment_buffer_t
- *
- * assemble and decode segments
- */
-
-typedef struct {
- /* current segment */
- int segment_len; /* length of current segment (without 3-byte header) */
- uint8_t segment_type; /* current segment type */
- uint8_t *segment_data; /* pointer to current segment payload */
- uint8_t *segment_end; /* pointer to last byte + 1 of current segment */
- uint8_t error; /* boolean: buffer overflow etc. */
-
- /* accumulated data */
- uint8_t *buf; /* */
- size_t len; /* count of unprocessed bytes */
- size_t data_size; /* allocated buffer size */
-} segment_buffer_t;
-
-/*
- * mgmt
- */
-
-static segment_buffer_t *segbuf_init(void)
-{
- segment_buffer_t *buf = calloc(1, sizeof(segment_buffer_t));
- return buf;
-}
-
-static void segbuf_dispose(segment_buffer_t *buf)
-{
- if (buf->buf)
- free (buf->buf);
- free (buf);
-}
-
-static void segbuf_reset(segment_buffer_t *buf)
-{
- buf->segment_end = buf->segment_data = buf->buf;
- buf->len = 0;
- buf->segment_len = -1;
- buf->segment_type = 0;
- buf->error = 0;
-}
-
-/*
- * assemble, parse
- */
-
-static void segbuf_parse_segment_header(segment_buffer_t *buf)
-{
- if (buf->len > 2) {
- buf->segment_type = buf->buf[0];
- buf->segment_len = (buf->buf[1] << 8) | buf->buf[2];
- buf->segment_data = buf->buf + 3;
- buf->segment_end = buf->segment_data + buf->segment_len;
- buf->error = 0;
-
- if ( buf->segment_type < 0x14 ||
- ( buf->segment_type > 0x18 &&
- buf->segment_type != 0x80)) {
- ERROR("unknown segment type, resetting\n");
- segbuf_reset(buf);
- }
- } else {
- buf->segment_len = -1;
- buf->error = 1;
- }
-}
-
-static void segbuf_fill(segment_buffer_t *buf, uint8_t *data, size_t len)
-{
- if (buf->len + len > buf->data_size) {
- buf->data_size = buf->len + len;
- if (buf->buf)
- buf->buf = realloc(buf->buf, buf->data_size);
- else
- buf->buf = malloc(buf->data_size);
- }
-
- memcpy(buf->buf + buf->len, data, len);
- buf->len += len;
-
- segbuf_parse_segment_header(buf);
-}
-
-static int segbuf_segment_complete(segment_buffer_t *buf)
-{
- return (buf->segment_len >= 0) && (buf->len >= buf->segment_len + 3);
-}
-
-static void segbuf_skip_segment(segment_buffer_t *buf)
-{
- if (segbuf_segment_complete (buf)) {
- buf->len -= buf->segment_len + 3;
- if (buf->len > 0)
- memmove(buf->buf, buf->buf + buf->segment_len + 3, buf->len);
-
- segbuf_parse_segment_header(buf);
-
- TRACE(" skip_segment: %d bytes left\n", (uint)buf->len);
- } else {
- ERROR(" skip_segment: ERROR - %d bytes queued, %d required\n",
- (uint)buf->len, buf->segment_len);
- segbuf_reset (buf);
- }
-}
-
-/*
- * access segment data
- */
-
-uint8_t segbuf_segment_type(segment_buffer_t *buf)
-{
- return buf->segment_type;
-}
-
-static size_t segbuf_data_length(segment_buffer_t *buf)
-{
- ssize_t val = buf->segment_end - buf->segment_data;
- if (val < 0) val = 0;
- return (size_t)val;
-}
-
-static uint8_t segbuf_get_u8(segment_buffer_t *buf)
-{
- if (!(buf->error = ++buf->segment_data > buf->segment_end))
- return buf->segment_data[-1];
- ERROR("segbuf_get_u8: read failed (end of segment reached) !");
- return 0;
-}
-
-static uint16_t segbuf_get_u16(segment_buffer_t *buf)
-{
- return (segbuf_get_u8(buf) << 8) | segbuf_get_u8(buf);
-}
-
-static uint32_t segbuf_get_u24(segment_buffer_t *buf)
-{
- return (segbuf_get_u8(buf) << 16) | (segbuf_get_u8(buf) << 8) | segbuf_get_u8(buf);
-}
-
-uint8_t *segbuf_get_string(segment_buffer_t *buf, size_t len)
-{
- if (len > 0) {
- uint8_t *val = buf->segment_data;
- buf->segment_data += len;
- if (buf->segment_data <= buf->segment_end)
- return val;
- }
- ERROR("segbuf_get_string(%d): read failed (end of segment reached) !", (int)len);
- buf->error = 1;
- return NULL;
-}
-
-/*
- * decode segments
- */
-
-static subtitle_clut_t *segbuf_decode_palette(segment_buffer_t *buf)
-{
- uint8_t palette_id = segbuf_get_u8 (buf);
- uint8_t palette_version_number = segbuf_get_u8 (buf);
-
- size_t len = segbuf_data_length(buf);
- size_t entries = len / 5;
- int i;
-
- if (buf->error)
- return NULL;
-
- if (len % 5) {
- ERROR(" decode_palette: segment size error (%d ; expected %d for %d entries)\n",
- (uint)len, (uint)(5 * entries), (uint)entries);
- return NULL;
- }
- TRACE("decode_palette: %d items (id %d, version %d)\n",
- (uint)entries, palette_id, palette_version_number);
-
- /* convert to xine-lib clut */
- subtitle_clut_t *clut = calloc(1, sizeof(subtitle_clut_t));
- clut->id = palette_id;
-
- for (i = 0; i < entries; i++) {
- uint8_t index = segbuf_get_u8 (buf);
- uint8_t Y = segbuf_get_u8 (buf);
- uint8_t Cr = segbuf_get_u8 (buf);
- uint8_t Cb = segbuf_get_u8 (buf);
- uint8_t alpha = segbuf_get_u8 (buf);
- clut->color[index] = (Y << 16) | (Cr << 8) | Cb;
- clut->trans[index] = alpha >> 4;
- }
-
- return clut;
-}
-
-static int segbuf_decode_rle(segment_buffer_t *buf, subtitle_object_t *obj)
-{
- int x = 0, y = 0;
- int rle_size = sizeof(rle_elem_t) * obj->width / 16 * obj->height + 1;
- rle_elem_t *rlep = malloc(rle_size);
-
- free (obj->rle);
- obj->rle = rlep;
- obj->data_size = rle_size;
- obj->num_rle = 0;
-
- /* convert to xine-lib rle format */
- while (y < obj->height && !buf->error) {
-
- /* decode RLE element */
- uint8_t byte = segbuf_get_u8 (buf);
- if (byte != 0) {
- rlep->color = byte;
- rlep->len = 1;
- } else {
- byte = segbuf_get_u8 (buf);
- if (!(byte & 0x80)) {
- rlep->color = 0;
- if (!(byte & 0x40))
- rlep->len = byte & 0x3f;
- else
- rlep->len = ((byte & 0x3f) << 8) | segbuf_get_u8 (buf);
- } else {
- if (!(byte & 0x40))
- rlep->len = byte & 0x3f;
- else
- rlep->len = ((byte & 0x3f) << 8) | segbuf_get_u8 (buf);
- rlep->color = segbuf_get_u8 (buf);
- }
- }
-
- /* move to next element */
- if (rlep->len > 0) {
- x += rlep->len;
- rlep++;
- obj->num_rle ++;
- } else {
- /* end of line marker (00 00) */
- if (x < obj->width) {
- rlep->len = obj->width - x;
- rlep->color = 0xff;
- rlep++;
- obj->num_rle ++;
- }
- x = 0;
- y++;
- }
-
- /* grow allocated RLE data size ? */
- if (obj->data_size <= (obj->num_rle + 1) * sizeof(rle_elem_t)) {
- obj->data_size *= 2;
- obj->rle = realloc(obj->rle, obj->data_size);
- rlep = obj->rle + obj->num_rle;
- }
- }
-
- return buf->error;
-}
-
-static subtitle_object_t *segbuf_decode_object(segment_buffer_t *buf)
-{
- uint8_t object_id = segbuf_get_u16(buf);
- uint8_t version = segbuf_get_u8 (buf);
- uint8_t seq_desc = segbuf_get_u8 (buf);
-
- TRACE(" decode_object: object_id %d, version %d, seq 0x%x\n",
- object_id, version, seq_desc);
-
- //LIST_FIND();
- subtitle_object_t *obj = calloc(1, sizeof(subtitle_object_t));
- obj->id = object_id;
-
- if (seq_desc & 0x80) {
-
- uint32_t data_len = segbuf_get_u24(buf);
- obj->width = segbuf_get_u16(buf);
- obj->height = segbuf_get_u16(buf);
-
- TRACE(" object length %d bytes, size %dx%d\n", data_len, obj->width, obj->height);
-
- segbuf_decode_rle (buf, obj);
-
- if (buf->error) {
- free_subtitle_object(obj);
- return NULL;
- }
-
- } else {
- ERROR(" TODO: APPEND RLE, length %d bytes\n", buf->segment_len - 4);
- /* TODO */
- free_subtitle_object(obj);
- return NULL;
- }
-
- return obj;
-}
-
-static window_def_t *segbuf_decode_window_definition(segment_buffer_t *buf)
-{
- window_def_t *wnd = calloc(1, sizeof(window_def_t));
-
- uint8_t a = segbuf_get_u8 (buf);
- wnd->id = segbuf_get_u8 (buf);
- wnd->xpos = segbuf_get_u16 (buf);
- wnd->ypos = segbuf_get_u16 (buf);
- wnd->width = segbuf_get_u16 (buf);
- wnd->height = segbuf_get_u16 (buf);
-
- TRACE(" window: [%02x %d] %d,%d %dx%d\n", a,
- wnd->id, wnd->xpos, wnd->ypos, wnd->width, wnd->height);
-
- if (buf->error) {
- free(wnd);
- return NULL;
- }
-
- return wnd;
-}
-
-static int segbuf_decode_video_descriptor(segment_buffer_t *buf)
-{
- uint16_t width = segbuf_get_u16(buf);
- uint16_t height = segbuf_get_u16(buf);
- uint8_t frame_rate = segbuf_get_u8 (buf);
-
- TRACE(" video_descriptor: %dx%d fps %d\n", width, height, frame_rate);
- return buf->error;
-}
-
-static int segbuf_decode_composition_descriptor(segment_buffer_t *buf, composition_descriptor_t *descr)
-{
- descr->number = segbuf_get_u16(buf);
- descr->state = segbuf_get_u8 (buf);
-
- TRACE(" composition_descriptor: number %d, state %d\n", descr->number, descr->state);
- return buf->error;
-}
-
-static composition_object_t *segbuf_decode_composition_object(segment_buffer_t *buf)
-{
- composition_object_t *cobj = calloc(1, sizeof(composition_object_t));
-
- cobj->object_id_ref = segbuf_get_u16 (buf);
- cobj->window_id_ref = segbuf_get_u8 (buf);
- uint8_t tmp = segbuf_get_u8 (buf);
- cobj->cropped_flag = !!(tmp & 0x80);
- cobj->forced_flag = !!(tmp & 0x40);
- cobj->xpos = segbuf_get_u16 (buf);
- cobj->ypos = segbuf_get_u16 (buf);
- if (cobj->cropped_flag) {
- /* x,y where to take the image from */
- cobj->crop_horiz_pos = segbuf_get_u8 (buf);
- cobj->crop_vert_pos = segbuf_get_u8 (buf);
- /* size of the cropped image */
- cobj->crop_width = segbuf_get_u8 (buf);
- cobj->crop_height = segbuf_get_u8 (buf);
- }
-
- if (buf->error) {
- free(cobj);
- return NULL;
- }
-
- TRACE(" composition_object: id: %d, win: %d, position %d,%d crop %d forced %d\n",
- cobj->object_id_ref, cobj->window_id_ref, cobj->xpos, cobj->ypos,
- cobj->cropped_flag, cobj->forced_flag);
-
- return cobj;
-}
-
-static presentation_segment_t *segbuf_decode_presentation_segment(segment_buffer_t *buf)
-{
- presentation_segment_t *seg = calloc(1, sizeof(presentation_segment_t));
- int index;
-
- segbuf_decode_video_descriptor (buf);
- segbuf_decode_composition_descriptor (buf, &seg->comp_descr);
-
- seg->palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80);
- seg->palette_id_ref = segbuf_get_u8 (buf);
- seg->object_number = segbuf_get_u8 (buf);
-
- TRACE(" presentation_segment: object_number %d, palette %d\n",
- seg->object_number, seg->palette_id_ref);
-
- for (index = 0; index < seg->object_number; index++) {
- composition_object_t *cobj = segbuf_decode_composition_object (buf);
- cobj->next = seg->comp_objs;
- seg->comp_objs = cobj;
- }
-
- if (buf->error) {
- free_presentation_segment(seg);
- return NULL;
- }
-
- return seg;
-}
-
-static rle_elem_t *copy_crop_rle(subtitle_object_t *obj, composition_object_t *cobj)
-{
- /* TODO: cropping (w,h sized image from pos x,y) */
-
- rle_elem_t *rle = calloc (obj->num_rle, sizeof(rle_elem_t));
- memcpy (rle, obj->rle, obj->num_rle * sizeof(rle_elem_t));
- return rle;
-}
-
-
-/*
- * xine plugin
- */
-
-typedef struct {
- spu_decoder_class_t decoder_class;
-} spuhdmv_class_t;
-
-typedef struct spuhdmv_decoder_s {
- spu_decoder_t spu_decoder;
-
- spuhdmv_class_t *class;
- xine_stream_t *stream;
-
- segment_buffer_t *buf;
-
- subtitle_clut_t *cluts;
- subtitle_object_t *objects;
- window_def_t *windows;
- presentation_segment_t *segments;
-
- int overlay_handles[MAX_OBJECTS];
-
- int64_t pts;
-
-} spuhdmv_decoder_t;
-
-static int decode_palette(spuhdmv_decoder_t *this)
-{
- /* decode */
- subtitle_clut_t *clut = segbuf_decode_palette(this->buf);
- if (!clut)
- return 1;
-
- LIST_REPLACE (this->cluts, clut, free);
-
- return 0;
-}
-
-static int decode_object(spuhdmv_decoder_t *this)
-{
- /* decode */
- subtitle_object_t *obj = segbuf_decode_object(this->buf);
- if (!obj)
- return 1;
-
- LIST_REPLACE (this->objects, obj, free_subtitle_object);
-
- return 0;
-}
-
-static int decode_window_definition(spuhdmv_decoder_t *this)
-{
- /* decode */
- window_def_t *wnd = segbuf_decode_window_definition (this->buf);
- if (!wnd)
- return 1;
-
- LIST_REPLACE (this->windows, wnd, free);
-
- return 0;
-}
-
-static int decode_presentation_segment(spuhdmv_decoder_t *this)
-{
- /* decode */
- presentation_segment_t *seg = segbuf_decode_presentation_segment(this->buf);
- if (!seg)
- return 1;
-
- seg->pts = this->pts;
-
- /* replace */
- if (this->segments)
- LIST_DESTROY(this->segments, free_presentation_segment);
- this->segments = seg;
-
- return 0;
-}
-
-static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uint palette_id_ref,
- int overlay_index, int64_t pts, int force_update)
-{
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
- metronom_t *metronom = this->stream->metronom;
- video_overlay_event_t event = {0};
- vo_overlay_t overlay = {0};
-
- /* find palette */
- subtitle_clut_t *clut = this->cluts;
- while (clut && clut->id != palette_id_ref)
- clut = clut->next;
- if (!clut) {
- TRACE(" show_overlay: clut %d not found !\n", palette_id_ref);
- return -1;
- }
-
- /* find RLE image */
- subtitle_object_t *obj = this->objects;
- while (obj && obj->id != cobj->object_id_ref)
- obj = obj->next;
- if (!obj) {
- TRACE(" show_overlay: object %d not found !\n", cobj->object_id_ref);
- return -1;
- }
-
- /* find window */
- window_def_t *wnd = this->windows;
- while (wnd && wnd->id != cobj->window_id_ref)
- wnd = wnd->next;
- if (!wnd) {
- TRACE(" show_overlay: window %d not found !\n", cobj->window_id_ref);
- return -1;
- }
-
- /* do not show again if all elements are unchanged */
- if (!force_update && clut->shown && obj->shown && wnd->shown && cobj->shown)
- return 0;
- clut->shown = obj->shown = wnd->shown = cobj->shown = 1;
-
- /* copy palette to xine overlay */
- overlay.rgb_clut = 0;
- memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256);
- memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256);
-
- /* copy and crop RLE image to xine overlay */
- overlay.width = obj->width;
- overlay.height = obj->height;
-
- overlay.rle = copy_crop_rle (obj, cobj);
- overlay.num_rle = obj->num_rle;
- overlay.data_size = obj->num_rle * sizeof(rle_elem_t);
-
- /* */
-
- overlay.x = /*wnd->xpos +*/ cobj->xpos;
- overlay.y = /*wnd->ypos +*/ cobj->ypos;
-
- overlay.unscaled = 0;
- overlay.hili_top = -1;
- overlay.hili_bottom = -1;
- overlay.hili_left = -1;
- overlay.hili_right = -1;
-
- TRACE(" -> overlay: %d,%d %dx%d\n",
- overlay.x, overlay.y, overlay.width, overlay.height);
-
-
- /* set timings */
-
- if (pts > 0)
- event.vpts = metronom->got_spu_packet (metronom, pts);
- else
- event.vpts = 0;
-
-
- /* generate SHOW event */
-
- this->stream->video_out->enable_ovl(this->stream->video_out, 1);
-
- if (this->overlay_handles[overlay_index] < 0)
- this->overlay_handles[overlay_index] = ovl_manager->get_handle(ovl_manager, 0);
-
- event.event_type = OVERLAY_EVENT_SHOW;
- event.object.handle = this->overlay_handles[overlay_index];
- event.object.overlay = &overlay;
- event.object.object_type = 0; /* subtitle */
-
- ovl_manager->add_event (ovl_manager, (void *)&event);
-
- return 0;
-}
-
-static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts)
-{
- video_overlay_event_t event = {0};
- int i = 0;
-
- while (this->overlay_handles[i] >= 0) {
- TRACE(" -> HIDE %d\n", i);
-
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
- metronom_t *metronom = this->stream->metronom;
-
- event.object.handle = this->overlay_handles[i];
- if (this)
- event.vpts = metronom->got_spu_packet (metronom, pts);
- else
- event.vpts = 0;
- event.event_type = OVERLAY_EVENT_HIDE;
- event.object.overlay = NULL;
- ovl_manager->add_event (ovl_manager, (void *)&event);
-
- //this->overlay_handles[i] = -1;
- i++;
- }
-}
-
-static void update_overlays(spuhdmv_decoder_t *this)
-{
- presentation_segment_t *pseg = this->segments;
-
- while (pseg) {
-
- if (!pseg->comp_descr.state) {
-
- /* HIDE */
- if (!pseg->shown)
- hide_overlays (this, pseg->pts);
-
- } else {
-
- /* SHOW */
- composition_object_t *cobj = pseg->comp_objs;
- int i;
-
- for (i = 0; i < pseg->object_number; i++) {
- if (!cobj) {
- ERROR("show_overlays: composition object %d missing !\n", i);
- } else {
- show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown);
- cobj = cobj->next;
- }
- }
- }
-
- pseg->shown = 1;
-
- pseg = pseg->next;
- }
-}
-
-static void free_objs(spuhdmv_decoder_t *this)
-{
- LIST_DESTROY (this->cluts, free);
- LIST_DESTROY (this->objects, free_subtitle_object);
- LIST_DESTROY (this->windows, free);
- LIST_DESTROY (this->segments, free_presentation_segment);
-}
-
-static void decode_segment(spuhdmv_decoder_t *this)
-{
- TRACE("*** new segment, pts %010ld: 0x%02x (%8d bytes)",
- this->pts, (uint)this->buf->segment_type, (uint)this->buf->segment_len);
-
- switch (this->buf->segment_type) {
- case 0x14:
- TRACE(" segment: PALETTE\n");
- decode_palette(this);
- break;
- case 0x15:
- TRACE(" segment: OBJECT\n");
- decode_object(this);
- break;
- case 0x16:
- TRACE(" segment: PRESENTATION SEGMENT\n");
- decode_presentation_segment(this);
- break;
- case 0x17:
- TRACE(" segment: WINDOW DEFINITION\n");
- decode_window_definition(this);
- break;
- case 0x18:
- TRACE(" segment: INTERACTIVE\n");
- break;
- case 0x80:
- TRACE(" segment: END OF DISPLAY\n");
- /* drop all cached objects */
- free_objs(this);
- break;
- default:
- ERROR(" segment type 0x%x unknown, skipping\n", this->buf->segment_type);
- break;
- }
- if (this->buf->error) {
- ERROR("*** DECODE ERROR ***\n");
- }
-
- update_overlays (this);
-}
-
-static void close_osd(spuhdmv_decoder_t *this)
-{
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out);
-
- int i = 0;
- while (this->overlay_handles[i] >= 0) {
- ovl_manager->free_handle(ovl_manager, this->overlay_handles[i]);
- this->overlay_handles[i] = -1;
- i++;
- }
-}
-
-static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- if ((buf->type & 0xffff0000) != BUF_SPU_HDMV)
- return;
-
- if (buf->size < 1)
- return;
-
- if (buf->pts)
- this->pts = buf->pts;
-
-#ifdef DUMP_SPU_DATA
- int i;
- for(i = 0; i < buf->size; i++)
- printf(" %02x", buf->content[i]);
- printf("\n");
-#endif
-
- segbuf_fill(this->buf, buf->content, buf->size);
-
- while (segbuf_segment_complete(this->buf)) {
- decode_segment(this);
- segbuf_skip_segment(this->buf);
- }
-}
-
-static void spudec_reset (spu_decoder_t * this_gen)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- if (this->buf)
- segbuf_reset(this->buf);
-
- free_objs(this);
-
- close_osd(this);
-}
-
-static void spudec_discontinuity (spu_decoder_t *this_gen)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- close_osd(this);
-}
-
-static void spudec_dispose (spu_decoder_t *this_gen)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- close_osd (this);
- segbuf_dispose (this->buf);
-
- free_objs(this);
-
- free (this);
-}
-
-static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream)
-{
- spuhdmv_decoder_t *this;
-
- this = (spuhdmv_decoder_t *) calloc(1, sizeof (spuhdmv_decoder_t));
-
- this->spu_decoder.decode_data = spudec_decode_data;
- this->spu_decoder.reset = spudec_reset;
- this->spu_decoder.discontinuity = spudec_discontinuity;
- this->spu_decoder.dispose = spudec_dispose;
- this->spu_decoder.get_interact_info = NULL;
- this->spu_decoder.set_button = NULL;
- this->stream = stream;
- this->class = (spuhdmv_class_t *) class_gen;
-
- this->buf = segbuf_init();
-
- memset(this->overlay_handles, 0xff, sizeof(this->overlay_handles)); /* --> -1 */
-
- return &this->spu_decoder;
-}
-
-static char *get_identifier (spu_decoder_class_t *this)
-{
- return "spuhdmv";
-}
-
-static char *get_description (spu_decoder_class_t *this)
-{
- return "HDMV/BluRay bitmap SPU decoder plugin";
-}
-
-static void dispose_class (spu_decoder_class_t *this)
-{
- free (this);
-}
-
-static void *init_plugin (xine_t *xine, void *data)
-{
- spuhdmv_class_t *this;
-
- this = calloc(1, sizeof (spuhdmv_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;
-
- return this;
-}
-
-/* plugin catalog information */
-static uint32_t supported_types[] = { BUF_SPU_HDMV, 0 };
-
-static const decoder_info_t dec_info_data = {
- supported_types, /* supported types */
- 5 /* priority */
-};
-
-const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_SPU_DECODER, 16, "spuhdmv", XINE_VERSION_CODE, &dec_info_data, &init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
diff --git a/xine/BluRay/demux_ts.c b/xine/BluRay/demux_ts.c
deleted file mode 100644
index 44d3ee88..00000000
--- a/xine/BluRay/demux_ts.c
+++ /dev/null
@@ -1,2504 +0,0 @@
-/*
- * Copyright (C) 2000-2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * Demultiplexer for MPEG2 Transport Streams.
- *
- * For the purposes of playing video, we make some assumptions about the
- * kinds of TS we have to process. The most important simplification is to
- * assume that the TS contains a single program (SPTS) because this then
- * allows significant simplifications to be made in processing PATs.
- *
- * The next simplification is to assume that the program has a reasonable
- * number of video, audio and other streams. This allows PMT processing to
- * be simplified.
- *
- * MODIFICATION HISTORY
- *
- * Date Author
- * ---- ------
- *
- * 8-Apr-2009 Petri Hintukainen <phi@sdf-eu.org>
- * - support for 192-byte packets (HDMV/BluRay)
- * - support for audio inside PES PID 0xfd (HDMV/BluRay)
- * - demux HDMV/BluRay bitmap subtitles
- *
- * 28-Nov-2004 Mike Lampard <mlampard>
- * - Added support for PMT sections larger than 1 ts packet
- *
- * 28-Aug-2004 James Courtier-Dutton <jcdutton>
- * - Improve PAT and PMT handling. Added some FIXME comments.
- *
- * 9-Aug-2003 James Courtier-Dutton <jcdutton>
- * - Improve readability of code. Added some FIXME comments.
- *
- * 25-Nov-2002 Peter Liljenberg
- * - Added DVBSUB support
- *
- * 07-Nov-2992 Howdy Pierce
- * - various bugfixes
- *
- * 30-May-2002 Mauro Borghi
- * - dynamic allocation leaks fixes
- *
- * 27-May-2002 Giovanni Baronetti and Mauro Borghi <mauro.borghi@tilab.com>
- * - fill buffers before putting them in fifos
- * - force PMT reparsing when PMT PID changes
- * - accept non seekable input plugins -- FIX?
- * - accept dvb as input plugin
- * - optimised read operations
- * - modified resync code
- *
- * 16-May-2002 Thibaut Mattern <tmattern@noos.fr>
- * - fix demux loop
- *
- * 07-Jan-2002 Andr Draszik <andid@gmx.net>
- * - added support for single-section PMTs
- * spanning multiple TS packets
- *
- * 10-Sep-2001 James Courtier-Dutton <jcdutton>
- * - re-wrote sync code so that it now does not loose any data
- *
- * 27-Aug-2001 Hubert Matthews Reviewed by: n/a
- * - added in synchronisation code
- *
- * 1-Aug-2001 James Courtier-Dutton <jcdutton> Reviewed by: n/a
- * - TS Streams with zero PES length should now work
- *
- * 30-Jul-2001 shaheedhaque Reviewed by: n/a
- * - PATs and PMTs seem to work
- *
- * 29-Jul-2001 shaheedhaque Reviewed by: n/a
- * - Compiles!
- *
- *
- * TODO: do without memcpys, preview buffers
- */
-
-
-/** HOW TO IMPLEMENT A DVBSUB DECODER.
- *
- * The DVBSUB protocol is specified in ETSI EN 300 743. It can be
- * downloaded for free (registration required, though) from
- * www.etsi.org.
- *
- * The spu_decoder should handle the packet type BUF_SPU_DVB.
- *
- * BUF_SPU_DVBSUB packets without the flag BUF_FLAG_SPECIAL contain
- * the payload of the PES packets carrying DVBSUB data. Since the
- * payload can be broken up over several buf_element_t and the DVBSUB
- * is PES oriented, the decoder_info[2] field (low 16 bits) is used to convey the
- * packet boundaries to the decoder:
- *
- * + For the first buffer of a packet, buf->content points to the
- * first byte of the PES payload. decoder_info[2] is set to the length of the
- * payload. The decoder can use this value to determine when a
- * complete PES packet has been collected.
- *
- * + For the following buffers of the PES packet, decoder_info[2] is 0.
- *
- * The decoder can either use this information to reconstruct the PES
- * payload, or ignore it and implement a parser that handles the
- * irregularites at the start and end of PES packets.
- *
- * In any case buf->pts is always set to the PTS of the PES packet.
- *
- *
- * BUF_SPU_DVB with BUF_FLAG_SPECIAL set contains no payload, and is
- * used to pass control information to the decoder.
- *
- * If decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR then
- * decoder_info_ptr[2] either points to a spu_dvb_descriptor_t or is NULL.
- *
- * If it is 0, the user has disabled the subtitling, or has selected a
- * channel that is not present in the stream. The decoder should
- * remove any visible subtitling.
- *
- * If it is a pointer, the decoder should reset itself and start
- * extracting the subtitle service identified by comp_page_id and
- * aux_page_id in the spu_dvb_descriptor_t, (the composition and
- * auxilliary page ids, respectively).
- **/
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-
-#define LOG_MODULE "demux_ts"
-#define LOG_VERBOSE
-/*
-#define LOG
-*/
-
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/demux.h>
-
-//#define TS_PMT_LOG
-//#define TS_PAT_LOG
-
-#ifndef EXPORTED
-# define EXPORTED __attribute__((visibility("default")))
-#endif
-
-#ifndef BUF_SPU_HDMV
-# define BUF_SPU_HDMV 0x04180000
-#endif
-
-/*
- #define TS_LOG
- #define TS_PMT_LOG
- #define TS_PAT_LOG
-
- #define TS_READ_STATS // activates read statistics generation
- #define TS_HEADER_LOG // prints out the Transport packet header.
-*/
-
-/*
- * The maximum number of PIDs we are prepared to handle in a single program
- * is the number that fits in a single-packet PMT.
- */
-#define PKT_SIZE 188
-#define BODY_SIZE (188 - 4)
-/* more PIDS are needed due "auto-detection". 40 spare media entries */
-#define MAX_PIDS ((BODY_SIZE - 1 - 13) / 4) + 40
-#define MAX_PMTS ((BODY_SIZE - 1 - 13) / 4) + 10
-#define SYNC_BYTE 0x47
-
-#define MIN_SYNCS 3
-#define NPKT_PER_READ 96 // 96*188 = 94*192
-
-#define BUF_SIZE (NPKT_PER_READ * (PKT_SIZE + 4))
-
-#define MAX_PES_BUF_SIZE 2048
-
-#define CORRUPT_PES_THRESHOLD 10
-
-#define NULL_PID 0x1fff
-#define INVALID_PID ((unsigned int)(-1))
-#define INVALID_PROGRAM ((unsigned int)(-1))
-#define INVALID_CC ((unsigned int)(-1))
-
-#define PROG_STREAM_MAP 0xBC
-#define PRIVATE_STREAM1 0xBD
-#define PADDING_STREAM 0xBE
-#define PRIVATE_STREAM2 0xBF
-#define AUDIO_STREAM_S 0xC0
-#define AUDIO_STREAM_E 0xDF
-#define VIDEO_STREAM_S 0xE0
-#define VIDEO_STREAM_E 0xEF
-#define ECM_STREAM 0xF0
-#define EMM_STREAM 0xF1
-#define DSM_CC_STREAM 0xF2
-#define ISO13522_STREAM 0xF3
-#define PROG_STREAM_DIR 0xFF
-
- typedef enum
- {
- ISO_11172_VIDEO = 0x01, /* ISO/IEC 11172 Video */
- ISO_13818_VIDEO = 0x02, /* ISO/IEC 13818-2 Video */
- ISO_11172_AUDIO = 0x03, /* ISO/IEC 11172 Audio */
- ISO_13818_AUDIO = 0x04, /* ISO/IEC 13818-3 Audi */
- ISO_13818_PRIVATE = 0x05, /* ISO/IEC 13818-1 private sections */
- ISO_13818_PES_PRIVATE = 0x06, /* ISO/IEC 13818-1 PES packets containing private data */
- ISO_13522_MHEG = 0x07, /* ISO/IEC 13512 MHEG */
- ISO_13818_DSMCC = 0x08, /* ISO/IEC 13818-1 Annex A DSM CC */
- ISO_13818_TYPE_A = 0x0a, /* ISO/IEC 13818-6 Multiprotocol encapsulation */
- ISO_13818_TYPE_B = 0x0b, /* ISO/IEC 13818-6 DSM-CC U-N Messages */
- ISO_13818_TYPE_C = 0x0c, /* ISO/IEC 13818-6 Stream Descriptors */
- ISO_13818_TYPE_D = 0x0d, /* ISO/IEC 13818-6 Sections (any type, including private data) */
- ISO_13818_AUX = 0x0e, /* ISO/IEC 13818-1 auxiliary */
- ISO_13818_PART7_AUDIO = 0x0f, /* ISO/IEC 13818-7 Audio with ADTS transport sytax */
- ISO_14496_PART2_VIDEO = 0x10, /* ISO/IEC 14496-2 Visual (MPEG-4) */
- ISO_14496_PART3_AUDIO = 0x11, /* ISO/IEC 14496-3 Audio with LATM transport syntax */
- ISO_14496_PART10_VIDEO = 0x1b, /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
- STREAM_VIDEO_MPEG = 0x80,
- STREAM_AUDIO_AC3 = 0x81,
- STREAM_AUDIO_PRIMARY_DTS_HDMV = 0x86,
- STREAM_SPU_BITMAP_HDMV = 0x90,
-
- STREAM_VIDEO_VC1 = 0xea, /* VC-1 */
- STREAM_VIDEO_SMTPE_VC1 = 0xeb, /* SMTPE VC-1 */
- } streamType;
-
-#define WRAP_THRESHOLD 270000
-
-#define PTS_AUDIO 0
-#define PTS_VIDEO 1
-
-#undef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#undef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-
-/*
-**
-** DATA STRUCTURES
-**
-*/
-
-/*
- * Describe a single elementary stream.
- */
-typedef struct {
- unsigned int pid;
- fifo_buffer_t *fifo;
- uint8_t *content;
- uint32_t size;
- uint32_t type;
- int64_t pts;
- buf_element_t *buf;
- unsigned int counter;
- uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */
- int64_t packet_count;
- int corrupted_pes;
- uint32_t buffered_bytes;
- int autodetected;
-
-} demux_ts_media;
-
-/* DVBSUB */
-#define MAX_SPU_LANGS 16
-
-typedef struct {
- spu_dvb_descriptor_t desc;
- int pid;
- int media_index;
-} demux_ts_spu_lang;
-
-/* Audio Channels */
-#define MAX_AUDIO_TRACKS 16
-
-typedef struct {
- int pid;
- int media_index;
- char lang[4];
-} demux_ts_audio_track;
-
-typedef struct {
- /*
- * The first field must be the "base class" for the plugin!
- */
- demux_plugin_t demux_plugin;
-
- xine_stream_t *stream;
-
- config_values_t *config;
-
- fifo_buffer_t *audio_fifo;
- fifo_buffer_t *video_fifo;
-
- input_plugin_t *input;
-
- int status;
-
- int hdmv; /* -1 = unknown, 0 = mpeg-ts, 1 = hdmv/m2ts */
- int pkt_size; /* TS packet size */
- int pkt_offset; /* TS packet offset */
-
- int blockSize;
- int rate;
- int media_num;
- demux_ts_media media[MAX_PIDS];
- uint32_t program_number[MAX_PMTS];
- uint32_t pmt_pid[MAX_PMTS];
- uint8_t *pmt[MAX_PMTS];
- uint8_t *pmt_write_ptr[MAX_PMTS];
- uint32_t crc32_table[256];
- uint32_t last_pmt_crc;
- /*
- * Stuff to do with the transport header. As well as the video
- * and audio PIDs, we keep the index of the corresponding entry
- * inthe media[] array.
- */
- unsigned int programNumber;
- unsigned int pcrPid;
- unsigned int pid;
- unsigned int pid_count;
- unsigned int videoPid;
- unsigned int videoMedia;
-
- demux_ts_audio_track audio_tracks[MAX_AUDIO_TRACKS];
- int audio_tracks_count;
-
- int send_end_buffers;
- int64_t last_pts[2];
- int send_newpts;
- int buf_flag_seek;
-
- unsigned int scrambled_pids[MAX_PIDS];
- unsigned int scrambled_npids;
-
-#ifdef TS_READ_STATS
- uint32_t rstat[NPKT_PER_READ + 1];
-#endif
-
- /* DVBSUB */
- unsigned int spu_pid;
- unsigned int spu_media;
- demux_ts_spu_lang spu_langs[MAX_SPU_LANGS];
- int spu_langs_count;
- int current_spu_channel;
-
- /* dvb */
- xine_event_queue_t *event_queue;
- /* For syncronisation */
- int32_t packet_number;
- /* NEW: var to keep track of number of last read packets */
- int32_t npkt_read;
-
- uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */
-
- int numPreview;
-
-} demux_ts_t;
-
-typedef struct {
-
- demux_class_t demux_class;
-
- /* class-wide, global variables here */
-
- xine_t *xine;
- config_values_t *config;
-} demux_ts_class_t;
-
-
-static void demux_ts_build_crc32_table(demux_ts_t*this) {
- uint32_t i, j, k;
-
- for( i = 0 ; i < 256 ; i++ ) {
- k = 0;
- for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1) {
- k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
- }
- this->crc32_table[i] = k;
- }
-}
-
-static uint32_t demux_ts_compute_crc32(demux_ts_t*this, uint8_t *data,
- int32_t length, uint32_t crc32) {
- int32_t i;
-
- for(i = 0; i < length; i++) {
- crc32 = (crc32 << 8) ^ this->crc32_table[(crc32 >> 24) ^ data[i]];
- }
- return crc32;
-}
-
-/* redefine abs as macro to handle 64-bit diffs.
- i guess llabs may not be available everywhere */
-#define abs(x) ( ((x)<0) ? -(x) : (x) )
-
-static void check_newpts( demux_ts_t *this, int64_t pts, int video )
-{
- int64_t diff;
-
-#ifdef TS_LOG
- printf ("demux_ts: check_newpts %lld, send_newpts %d, buf_flag_seek %d\n",
- pts, this->send_newpts, this->buf_flag_seek);
-#endif
-
- diff = pts - this->last_pts[video];
-
- if( pts &&
- (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
-
- if (this->buf_flag_seek) {
- _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
- this->buf_flag_seek = 0;
- } else {
- _x_demux_control_newpts(this->stream, pts, 0);
- }
- this->send_newpts = 0;
- this->last_pts[1-video] = 0;
- }
-
- if( pts )
- {
- /* don't detect a discontinuity only for video respectively audio. It's also a discontinuity
- indication when audio and video pts differ to much e. g. when a pts wrap happens.
- The original code worked well when the wrap happend like this:
-
- V7 A7 V8 V9 A9 Dv V0 V1 da A1 V2 V3 A3 V4
-
- Legend:
- Vn = video packet with timestamp n
- An = audio packet with timestamp n
- Dv = discontinuity detected on following video packet
- Da = discontinuity detected on following audio packet
- dv = discontinuity detected on following video packet but ignored
- da = discontinuity detected on following audio packet but ignored
-
- But with a certain delay between audio and video packets (e. g. the way DVB-S broadcasts
- the packets) the code didn't work:
-
- V7 V8 A7 V9 Dv V0 _A9_ V1 V2 Da _A1_ V3 V4 A3
-
- Packet A9 caused audio to jump forward and A1 caused it to jump backward with inserting
- a delay of almoust 26.5 hours!
-
- The new code gives the following sequences for the above examples:
-
- V7 A7 V8 V9 A9 Dv V0 V1 A1 V2 V3 A3 V4
-
- V7 V8 A7 V9 Dv V0 Da A9 Dv V1 V2 A1 V3 V4 A3
-
- After proving this code it should be cleaned up to use just a single variable "last_pts". */
-
-/*
- this->last_pts[video] = pts;
-*/
- this->last_pts[video] = this->last_pts[1-video] = pts;
- }
-}
-
-/* Send a BUF_SPU_DVB to let xine know of that channel. */
-static void demux_send_special_spu_buf( demux_ts_t *this, uint32_t spu_type, int spu_channel )
-{
- buf_element_t *buf;
-
- buf = this->video_fifo->buffer_pool_alloc( this->video_fifo );
- buf->type = spu_type|spu_channel;
- buf->content = buf->mem;
- buf->size = 0;
- this->video_fifo->put( this->video_fifo, buf );
-}
-
-/*
- * demux_ts_update_spu_channel
- *
- * Send a BUF_SPU_DVB with BUF_SPECIAL_SPU_DVB_DESCRIPTOR to tell
- * the decoder to reset itself on the new channel.
- */
-static void demux_ts_update_spu_channel(demux_ts_t *this)
-{
- buf_element_t *buf;
-
- this->current_spu_channel = this->stream->spu_channel;
-
- buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
- buf->type = BUF_SPU_DVB;
- buf->content = buf->mem;
- buf->decoder_flags = BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR;
- buf->size = 0;
-
- if (this->current_spu_channel >= 0
- && this->current_spu_channel < this->spu_langs_count)
- {
- demux_ts_spu_lang *lang = &this->spu_langs[this->current_spu_channel];
-
- buf->decoder_info[2] = sizeof(lang->desc);
- buf->decoder_info_ptr[2] = &(lang->desc);
- buf->type |= this->current_spu_channel;
-
- this->spu_pid = lang->pid;
- this->spu_media = lang->media_index;
-
-#ifdef TS_LOG
- printf("demux_ts: DVBSUB: selecting lang: %s page %ld %ld\n",
- lang->desc.lang, lang->desc.comp_page_id, lang->desc.aux_page_id);
-#endif
- }
- else
- {
- buf->decoder_info_ptr[2] = NULL;
-
- this->spu_pid = INVALID_PID;
-
-#ifdef TS_LOG
- printf("demux_ts: DVBSUB: deselecting lang\n");
-#endif
- }
-
- if ((this->media[this->spu_media].type & BUF_MAJOR_MASK) == BUF_SPU_HDMV) {
- buf->type = BUF_SPU_HDMV;
- }
-
- this->video_fifo->put(this->video_fifo, buf);
-}
-
-/*
- * demux_ts_parse_pat
- *
- * Parse a program association table (PAT).
- * The PAT is expected to be exactly one section long,
- * and that section is expected to be contained in a single TS packet.
- *
- * The PAT is assumed to contain a single program definition, though
- * we can cope with the stupidity of SPTSs which contain NITs.
- */
-static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
- unsigned char *pkt, unsigned int pusi) {
- uint32_t table_id;
- uint32_t section_syntax_indicator;
- int32_t section_length;
- uint32_t transport_stream_id;
- uint32_t version_number;
- uint32_t current_next_indicator;
- uint32_t section_number;
- uint32_t last_section_number;
- uint32_t crc32;
- uint32_t calc_crc32;
-
- unsigned char *program;
- unsigned int program_number;
- unsigned int pmt_pid;
- unsigned int program_count;
-
- /*
- * A PAT in a single section should start with a payload unit start
- * indicator set.
- */
- if (!pusi) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PAT without payload unit start indicator\n");
- return;
- }
-
- /*
- * sections start with a pointer. Skip it!
- */
- pkt += pkt[4];
- if (pkt - original_pkt > PKT_SIZE) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PAT with invalid pointer\n");
- return;
- }
- table_id = (unsigned int)pkt[5] ;
- section_syntax_indicator = (((unsigned int)pkt[6] >> 7) & 1) ;
- section_length = (((unsigned int)pkt[6] & 0x03) << 8) | pkt[7];
- transport_stream_id = ((uint32_t)pkt[8] << 8) | pkt[9];
- version_number = ((uint32_t)pkt[10] >> 1) & 0x1f;
- current_next_indicator = ((uint32_t)pkt[10] & 0x01);
- section_number = (uint32_t)pkt[11];
- last_section_number = (uint32_t)pkt[12];
- crc32 = (uint32_t)pkt[4+section_length] << 24;
- crc32 |= (uint32_t)pkt[5+section_length] << 16;
- crc32 |= (uint32_t)pkt[6+section_length] << 8;
- crc32 |= (uint32_t)pkt[7+section_length] ;
-
-#ifdef TS_PAT_LOG
- printf ("demux_ts: PAT table_id: %.2x\n", table_id);
- printf (" section_syntax: %d\n", section_syntax_indicator);
- printf (" section_length: %d (%#.3x)\n",
- section_length, section_length);
- printf (" transport_stream_id: %#.4x\n", transport_stream_id);
- printf (" version_number: %d\n", version_number);
- printf (" c/n indicator: %d\n", current_next_indicator);
- printf (" section_number: %d\n", section_number);
- printf (" last_section_number: %d\n", last_section_number);
-#endif
-
- if ((section_syntax_indicator != 1) || !(current_next_indicator)) {
- return;
- }
-
- if (pkt - original_pkt > BODY_SIZE - 1 - 3 - section_length) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: FIXME: (unsupported )PAT spans multiple TS packets\n");
- return;
- }
-
- if ((section_number != 0) || (last_section_number != 0)) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: FIXME: (unsupported) PAT consists of multiple (%d) sections\n", last_section_number);
- return;
- }
-
- /* Check CRC. */
- calc_crc32 = demux_ts_compute_crc32 (this, pkt+5, section_length+3-4,
- 0xffffffff);
- if (crc32 != calc_crc32) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PAT with invalid CRC32: packet_crc32: %.8x calc_crc32: %.8x\n",
- crc32,calc_crc32);
- return;
- }
-#ifdef TS_PAT_LOG
- else {
- printf ("demux_ts: PAT CRC32 ok.\n");
- }
-#endif
-
- /*
- * Process all programs in the program loop.
- */
- program_count = 0;
- for (program = pkt + 13;
- program < pkt + 13 + section_length - 9;
- program += 4) {
- program_number = ((unsigned int)program[0] << 8) | program[1];
- pmt_pid = (((unsigned int)program[2] & 0x1f) << 8) | program[3];
-
- /*
- * completely skip NIT pids.
- */
- if (program_number == 0x0000)
- continue;
-
- /*
- * If we have yet to learn our program number, then learn it,
- * use this loop to eventually add support for dynamically changing
- * PATs.
- */
- program_count = 0;
-
- while ((this->program_number[program_count] != INVALID_PROGRAM) &&
- (this->program_number[program_count] != program_number) &&
- (program_count+1 < MAX_PMTS ) ) {
- program_count++;
- }
- this->program_number[program_count] = program_number;
-
- /* force PMT reparsing when pmt_pid changes */
- if (this->pmt_pid[program_count] != pmt_pid) {
- this->pmt_pid[program_count] = pmt_pid;
- this->audio_tracks_count = 0;
- this->last_pmt_crc = 0;
- this->videoPid = INVALID_PID;
- this->spu_pid = INVALID_PID;
-
- this->pmt_pid[program_count] = pmt_pid;
-
- if (this->pmt[program_count] != NULL) {
- free(this->pmt[program_count]);
- this->pmt[program_count] = NULL;
- this->pmt_write_ptr[program_count] = NULL;
- }
- }
-
-#ifdef TS_PAT_LOG
- if (this->program_number[program_count] != INVALID_PROGRAM)
- printf ("demux_ts: PAT acquired count=%d programNumber=0x%04x "
- "pmtPid=0x%04x\n",
- program_count,
- this->program_number[program_count],
- this->pmt_pid[program_count]);
-#endif
- }
-}
-
-static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
- uint8_t *buf, int packet_len,
- xine_stream_t *stream) {
-
- unsigned char *p;
- uint32_t header_len;
- int64_t pts;
- uint32_t stream_id;
- int pkt_len;
-
- p = buf;
- pkt_len = packet_len;
-
- /* we should have a PES packet here */
-
- if (p[0] || p[1] || (p[2] != 1)) {
- xprintf (xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: error %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]);
- return 0 ;
- }
-
- packet_len -= 6;
- /* packet_len = p[4] << 8 | p[5]; */
- stream_id = p[3];
-
- if (packet_len==0)
- {
- xprintf (xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: error pes length 0\n");
- return 0;
- }
-
-#ifdef TS_LOG
- printf ("demux_ts: packet stream id: %.2x len: %d (%x)\n",
- stream_id, packet_len, packet_len);
-#endif
-
- if (p[7] & 0x80) { /* pts avail */
-
- pts = (int64_t)(p[ 9] & 0x0E) << 29 ;
- pts |= p[10] << 22 ;
- pts |= (p[11] & 0xFE) << 14 ;
- pts |= p[12] << 7 ;
- pts |= (p[13] & 0xFE) >> 1 ;
-
- } else
- pts = 0;
-
- /* code works but not used in xine
- if (p[7] & 0x40) {
-
- DTS = (p[14] & 0x0E) << 29 ;
- DTS |= p[15] << 22 ;
- DTS |= (p[16] & 0xFE) << 14 ;
- DTS |= p[17] << 7 ;
- DTS |= (p[18] & 0xFE) >> 1 ;
-
- } else
- DTS = 0;
- */
-
- m->pts = pts;
-
- header_len = p[8];
-
- /* sometimes corruption on header_len causes segfault in memcpy below */
- if (header_len + 9 > pkt_len) {
- xprintf (xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len);
- return 0;
- }
-
- p += header_len + 9;
- packet_len -= header_len + 3;
-
- if (m->descriptor_tag == STREAM_VIDEO_VC1) {
- m->content = p;
- m->size = packet_len;
- m->type = BUF_VIDEO_VC1;
- return 1;
- }
-
- if (m->descriptor_tag == STREAM_SPU_BITMAP_HDMV) {
- long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
-
- m->content = p;
- m->size = packet_len;
- m->type |= BUF_SPU_HDMV;
- m->buf->decoder_info[2] = payload_len;
- return 1;
-
- } else
-
- if (stream_id == 0xbd || stream_id == 0xfd /* HDMV */) {
-
- int spu_id;
-
- lprintf ("audio buf = %02X %02X %02X %02X %02X %02X %02X %02X\n",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-
- /*
- * we check the descriptor tag first because some stations
- * do not include any of the ac3 header info in their audio tracks
- * these "raw" streams may begin with a byte that looks like a stream type.
- * For audio streams, m->type already contains the stream no.
- */
- if((m->descriptor_tag == STREAM_AUDIO_AC3) || /* ac3 - raw */
- (p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */
- m->content = p;
- m->size = packet_len;
- m->type |= BUF_AUDIO_A52;
- return 1;
-
- } else if (m->descriptor_tag == STREAM_AUDIO_PRIMARY_DTS_HDMV) {
- m->content = p;
- m->size = packet_len;
- m->type |= BUF_AUDIO_DTS;
- return 1;
-
- } else if (m->descriptor_tag == ISO_13818_PES_PRIVATE
- && p[0] == 0x20 && p[1] == 0x00) {
- /* DVBSUB */
- long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
-
- m->content = p;
- m->size = packet_len;
- m->type |= BUF_SPU_DVB;
- m->buf->decoder_info[2] = payload_len;
- return 1;
- } else if ((p[0] & 0xE0) == 0x20) {
- spu_id = (p[0] & 0x1f);
-
- m->content = p+1;
- m->size = packet_len-1;
- m->type = BUF_SPU_DVD + spu_id;
- return 1;
- } else if ((p[0] & 0xF0) == 0x80) {
-
- m->content = p+4;
- m->size = packet_len - 4;
- m->type |= BUF_AUDIO_A52;
- return 1;
-
- } else if ((p[0]&0xf0) == 0xa0) {
-
- int pcm_offset;
-
- for (pcm_offset=0; ++pcm_offset < packet_len-1 ; ){
- if (p[pcm_offset] == 0x01 && p[pcm_offset+1] == 0x80 ) { /* START */
- pcm_offset += 2;
- break;
- }
- }
-
- m->content = p+pcm_offset;
- m->size = packet_len-pcm_offset;
- m->type |= BUF_AUDIO_LPCM_BE;
- return 1;
- }
-
- } else if ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) {
-
- m->content = p;
- m->size = packet_len;
- switch (m->descriptor_tag) {
- case ISO_11172_VIDEO:
- case ISO_13818_VIDEO:
- case STREAM_VIDEO_MPEG:
- lprintf ("demux_ts: found MPEG video type.\n");
- m->type = BUF_VIDEO_MPEG;
- break;
- case ISO_14496_PART2_VIDEO:
- lprintf ("demux_ts: found MPEG4 video type.\n");
- m->type = BUF_VIDEO_MPEG4;
- break;
- case ISO_14496_PART10_VIDEO:
- lprintf ("demux_ts: found H264 video type.\n");
- m->type = BUF_VIDEO_H264;
- break;
- default:
- lprintf ("demux_ts: unknown video type: %d, defaulting to MPEG.\n", m->descriptor_tag);
- m->type = BUF_VIDEO_MPEG;
- break;
- }
- return 1;
-
- } else if ((stream_id & 0xe0) == 0xc0) {
-
- m->content = p;
- m->size = packet_len;
- switch (m->descriptor_tag) {
- case ISO_11172_AUDIO:
- case ISO_13818_AUDIO:
- lprintf ("demux_ts: found MPEG audio track.\n");
- m->type |= BUF_AUDIO_MPEG;
- break;
- case ISO_13818_PART7_AUDIO:
- case ISO_14496_PART3_AUDIO:
- lprintf ("demux_ts: found AAC audio track.\n");
- m->type |= BUF_AUDIO_AAC;
- break;
- default:
- lprintf ("demux_ts: unknown audio type: %d, defaulting to MPEG.\n", m->descriptor_tag);
- m->type |= BUF_AUDIO_MPEG;
- break;
- }
- return 1;
-
- } else {
-#ifdef TS_LOG
- printf ("demux_ts: unknown packet, id: %x\n", stream_id);
-#endif
- }
-
- return 0 ;
-}
-
-
-/*
- * buffer arriving pes data
- */
-static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
- unsigned int mediaIndex,
- unsigned int pus,
- unsigned int cc,
- unsigned int len) {
-
- demux_ts_media *m = &this->media[mediaIndex];
-
- if (!m->fifo) {
-#ifdef TS_LOG
- printf ("fifo unavailable (%d)\n", mediaIndex);
-#endif
- return; /* To avoid segfault if video out or audio out plugin not loaded */
- }
-
- /* By checking the CC here, we avoid the need to check for the no-payload
- case (i.e. adaptation field only) when it does not get bumped. */
- if (m->counter != INVALID_CC) {
- if ((m->counter & 0x0f) != cc) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: PID 0x%.4x: unexpected cc %d (expected %d)\n", m->pid, cc, m->counter);
- }
- }
- m->counter = cc;
- m->counter++;
-
- if (pus) { /* new PES packet */
-
- if (m->buffered_bytes) {
- m->buf->content = m->buf->mem;
- m->buf->size = m->buffered_bytes;
- m->buf->type = m->type;
- if( (m->buf->type & 0xffff0000) == BUF_SPU_DVD ) {
- m->buf->decoder_flags |= BUF_FLAG_SPECIAL;
- m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
- m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
- }
- else {
- if (this->numPreview<5)
- ++this->numPreview;
- if ( this->numPreview==1 )
- m->buf->decoder_flags=BUF_FLAG_HEADER | BUF_FLAG_FRAME_END;
- else if ( this->numPreview<5 )
- m->buf->decoder_flags=BUF_FLAG_PREVIEW;
- else
- m->buf->decoder_flags=BUF_FLAG_FRAME_END;
- }
- m->buf->pts = m->pts;
- m->buf->decoder_info[0] = 1;
-
- if( this->input->get_length (this->input) )
- m->buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) *
- 65535 / this->input->get_length (this->input) );
- if (this->rate)
- m->buf->extra_info->input_time = (int)((int64_t)this->input->get_current_pos (this->input)
- * 1000 / (this->rate * 50));
- m->fifo->put(m->fifo, m->buf);
- m->buffered_bytes = 0;
- m->buf = NULL; /* forget about buf -- not our responsibility anymore */
-#ifdef TS_LOG
- printf ("demux_ts: produced buffer, pts=%lld\n", m->pts);
-#endif
- }
- /* allocate the buffer here, as pes_header needs a valid buf for dvbsubs */
- m->buf = m->fifo->buffer_pool_alloc(m->fifo);
-
- if (!demux_ts_parse_pes_header(this->stream->xine, m, ts, len, this->stream)) {
- m->buf->free_buffer(m->buf);
- m->buf = NULL;
-
- if (m->corrupted_pes > CORRUPT_PES_THRESHOLD && m->autodetected) {
- if (this->videoPid == m->pid) {
- this->videoPid = INVALID_PID;
- this->last_pmt_crc = 0;
- }
- } else {
- m->corrupted_pes++;
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: PID 0x%.4x: corrupted pes encountered\n", m->pid);
- }
- } else {
-
- m->corrupted_pes = 0;
- memcpy(m->buf->mem, ts+len-m->size, m->size);
- m->buffered_bytes = m->size;
- }
-
- } else if (!m->corrupted_pes) { /* no pus -- PES packet continuation */
-
- if ((m->buffered_bytes + len) > MAX_PES_BUF_SIZE) {
- m->buf->content = m->buf->mem;
- m->buf->size = m->buffered_bytes;
- m->buf->type = m->type;
- m->buf->pts = m->pts;
- m->buf->decoder_info[0] = 1;
- if( this->input->get_length (this->input) )
- m->buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) *
- 65535 / this->input->get_length (this->input) );
- if (this->rate)
- m->buf->extra_info->input_time = (int)((int64_t)this->input->get_current_pos (this->input)
- * 1000 / (this->rate * 50));
-
- m->fifo->put(m->fifo, m->buf);
- m->buffered_bytes = 0;
- m->buf = m->fifo->buffer_pool_alloc(m->fifo);
-
-#ifdef TS_LOG
- printf ("demux_ts: produced buffer, pts=%lld\n", m->pts);
-#endif
-
- }
- memcpy(m->buf->mem + m->buffered_bytes, ts, len);
- m->buffered_bytes += len;
- }
-}
-
-/*
- * Create a buffer for a PES stream.
- */
-static void demux_ts_pes_new(demux_ts_t*this,
- unsigned int mediaIndex,
- unsigned int pid,
- fifo_buffer_t *fifo,
- uint16_t descriptor) {
-
- demux_ts_media *m = &this->media[mediaIndex];
-
- /* new PID seen - initialise stuff */
- m->pid = pid;
- m->fifo = fifo;
-
- if (m->buf != NULL) m->buf->free_buffer(m->buf);
- m->buf = NULL;
- m->counter = INVALID_CC;
- m->descriptor_tag = descriptor;
- m->corrupted_pes = 1;
- m->buffered_bytes = 0;
-}
-
-
-/* Find the first ISO 639 language descriptor (tag 10) and
- * store the 3-char code in dest, nullterminated. If no
- * code is found, zero out dest.
- **/
-static void demux_ts_get_lang_desc(demux_ts_t *this, char *dest,
- const unsigned char *data, int length)
-{
- const unsigned char *d = data;
-
- while (d < (data + length))
-
- {
- if (d[0] == 10 && d[1] >= 4)
-
- {
- memcpy(dest, d + 2, 3);
- dest[3] = 0;
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found ISO 639 lang: %s\n", dest);
- return;
- }
- d += 2 + d[1];
- }
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found no ISO 639 lang\n");
- memset(dest, 0, 4);
-}
-
-/* Find the registration code (tag=5) and return it as a uint32_t
- * This should return "AC-3" or 0x41432d33 for AC3/A52 audio tracks.
- */
-static void demux_ts_get_reg_desc(demux_ts_t *this, uint32_t *dest,
- const unsigned char *data, int length)
-{
- const unsigned char *d = data;
-
- while (d < (data + length))
-
- {
- if (d[0] == 5 && d[1] >= 4)
-
- {
- *dest = (d[2] << 24) | (d[3] << 16) | (d[4] << 8) | d[5];
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: found registration format identifier: 0x%.4x\n", *dest);
- return;
- }
- d += 2 + d[1];
- }
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found no format id\n");
- *dest = 0;
-}
-
-static inline int ts_payloadsize(unsigned char * tsp)
-{
- if (!(tsp[3] & 0x10))
- return 0;
- if (tsp[3] & 0x20) {
- if (tsp[4] > 183)
- return 0;
- else
- return 183 - tsp[4];
- }
- return 184;
-}
-
-
-/*
- * NAME demux_ts_parse_pmt
- *
- * Parse a PMT. The PMT is expected to be exactly one section long,
- * and that section is expected to be contained in a single TS packet.
- *
- * In other words, the PMT is assumed to describe a reasonable number of
- * video, audio and other streams (with descriptors).
- * FIXME: Implement support for multi section PMT.
- */
-static void demux_ts_parse_pmt (demux_ts_t *this,
- unsigned char *originalPkt,
- unsigned char *pkt,
- unsigned int pusi,
- uint32_t program_count) {
-
- uint32_t table_id;
- uint32_t section_syntax_indicator;
- uint32_t section_length = 0; /* to calm down gcc */
- uint32_t program_number;
- uint32_t version_number;
- uint32_t current_next_indicator;
- uint32_t section_number;
- uint32_t last_section_number;
- uint32_t program_info_length;
- uint32_t crc32;
- uint32_t calc_crc32;
- uint32_t coded_length;
- unsigned int pid;
- unsigned char *stream;
- unsigned int i;
- int count;
- char *ptr = NULL;
- unsigned char len;
- unsigned int offset=0;
-
- /*
- * A new section should start with the payload unit start
- * indicator set. We allocate some mem (max. allowed for a PM section)
- * to copy the complete section into one chunk.
- */
- if (pusi) {
- pkt+=pkt[4]; /* pointer to start of section */
- offset=1;
-
- if (this->pmt[program_count] != NULL) free(this->pmt[program_count]);
- this->pmt[program_count] = (uint8_t *) calloc(4096, sizeof(unsigned char));
- this->pmt_write_ptr[program_count] = this->pmt[program_count];
-
- table_id = pkt[5] ;
- section_syntax_indicator = (pkt[6] >> 7) & 0x01;
- section_length = (((uint32_t) pkt[6] << 8) | pkt[7]) & 0x03ff;
- program_number = ((uint32_t) pkt[8] << 8) | pkt[9];
- version_number = (pkt[10] >> 1) & 0x1f;
- current_next_indicator = pkt[10] & 0x01;
- section_number = pkt[11];
- last_section_number = pkt[12];
-
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT table_id: %2x\n", table_id);
- printf (" section_syntax: %d\n", section_syntax_indicator);
- printf (" section_length: %d (%#.3x)\n",
- section_length, section_length);
- printf (" program_number: %#.4x\n", program_number);
- printf (" version_number: %d\n", version_number);
- printf (" c/n indicator: %d\n", current_next_indicator);
- printf (" section_number: %d\n", section_number);
- printf (" last_section_number: %d\n", last_section_number);
-#endif
-
- if ((section_syntax_indicator != 1) || !current_next_indicator) {
-#ifdef TS_PMT_LOG
- printf ("ts_demux: section_syntax_indicator != 1 "
- "|| !current_next_indicator\n");
-#endif
- return;
- }
-
- if (program_number != this->program_number[program_count]) {
- /* several programs can share the same PMT pid */
-#ifdef TS_PMT_LOG
-printf("Program Number is %i, looking for %i\n",program_number,this->program_number[program_count]);
- printf ("ts_demux: waiting for next PMT on this PID...\n");
-#endif
- return;
- }
-
- if ((section_number != 0) || (last_section_number != 0)) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: FIXME (unsupported) PMT consists of multiple (%d) sections\n", last_section_number);
- return;
- }
-
- }
-
- if (!this->pmt[program_count]) {
- /* not the first TS packet of a PMT, or the calloc didn't work */
-#ifdef TS_PMT_LOG
- printf ("ts_demux: not the first TS packet of a PMT...\n");
-#endif
- return;
- }
-
- if (!pusi){
- section_length = (this->pmt[program_count][1] << 8
- | this->pmt[program_count][2]) & 0x03ff;
- }
-
- count=ts_payloadsize(originalPkt);
-
- ptr = originalPkt+offset+(PKT_SIZE-count);
- len = count-offset;
- memcpy (this->pmt_write_ptr[program_count], ptr, len);
- this->pmt_write_ptr[program_count] +=len;
-
-#ifdef TS_PMT_LOG
- printf ("ts_demux: wr_ptr: %p, will be %p when finished\n",
- this->pmt_write_ptr[program_count],
- this->pmt[program_count] + section_length);
-#endif
- if (this->pmt_write_ptr[program_count] < this->pmt[program_count]
- + section_length) {
- /* didn't get all TS packets for this section yet */
-#ifdef TS_PMT_LOG
- printf ("ts_demux: didn't get all PMT TS packets yet...\n");
-#endif
- return;
- }
-
- if (!section_length) {
- free (this->pmt[program_count]);
- this->pmt[program_count] = NULL;
-#ifdef TS_PMT_LOG
- printf ("ts_demux: eek, zero-length section?\n");
-#endif
- return;
- }
-
-#ifdef TS_PMT_LOG
- printf ("ts_demux: have all TS packets for the PMT section\n");
-#endif
-
- crc32 = (uint32_t) this->pmt[program_count][section_length+3-4] << 24;
- crc32 |= (uint32_t) this->pmt[program_count][section_length+3-3] << 16;
- crc32 |= (uint32_t) this->pmt[program_count][section_length+3-2] << 8;
- crc32 |= (uint32_t) this->pmt[program_count][section_length+3-1] ;
-
- /* Check CRC. */
- calc_crc32 = demux_ts_compute_crc32 (this,
- this->pmt[program_count],
- section_length+3-4, 0xffffffff);
- if (crc32 != calc_crc32) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PMT with invalid CRC32: packet_crc32: %#.8x calc_crc32: %#.8x\n",
- crc32,calc_crc32);
- return;
- }
- else {
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT CRC32 ok.\n");
-#endif
- if ( crc32==this->last_pmt_crc ) {
-#ifdef TS_PMT_LOG
- printf("demux_ts: PMT with CRC32=%d already parsed. Skipping.\n", crc32);
-#endif
- return;
- }
- else {
-#ifdef TS_PMT_LOG
- printf("demux_ts: new PMT, parsing...\n");
-#endif
- this->last_pmt_crc = crc32;
- }
- }
-
- /*
- * Forget the current video, audio and subtitle PIDs; if the PMT has not
- * changed, we'll pick them up again when we parse this PMT, while if the
- * PMT has changed (e.g. an IPTV streamer that's just changed its source),
- * we'll get new PIDs that we should follow.
- */
- this->audio_tracks_count = 0;
- this->videoPid = INVALID_PID;
- this->spu_pid = INVALID_PID;
-
- /*
- * ES definitions start here...we are going to learn upto one video
- * PID and one audio PID.
- */
- program_info_length = ((this->pmt[program_count][10] << 8)
- | this->pmt[program_count][11]) & 0x0fff;
-
-/* Program info descriptor is currently just ignored.
- * printf ("demux_ts: program_info_desc: ");
- * for (i = 0; i < program_info_length; i++)
- * printf ("%.2x ", this->pmt[program_count][12+i]);
- * printf ("\n");
- */
- stream = &this->pmt[program_count][12] + program_info_length;
- coded_length = 13 + program_info_length;
- if (coded_length > section_length) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux error! PMT with inconsistent progInfo length\n");
- return;
- }
- section_length -= coded_length;
-
- /*
- * Extract the elementary streams.
- */
- this->spu_langs_count = 0;
- while (section_length > 0) {
- unsigned int stream_info_length;
-
- pid = ((stream[1] << 8) | stream[2]) & 0x1fff;
- stream_info_length = ((stream[3] << 8) | stream[4]) & 0x0fff;
- coded_length = 5 + stream_info_length;
- if (coded_length > section_length) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux error! PMT with inconsistent streamInfo length\n");
- return;
- }
-
- /*
- * Squirrel away the first audio and the first video stream. TBD: there
- * should really be a way to select the stream of interest.
- */
- switch (stream[0]) {
- case ISO_11172_VIDEO:
- case ISO_13818_VIDEO:
- case ISO_14496_PART2_VIDEO:
- case ISO_14496_PART10_VIDEO:
- case STREAM_VIDEO_VC1:
- if (this->videoPid == INVALID_PID) {
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT video pid 0x%.4x type %2.2x\n", pid, stream[0]);
-#endif
- demux_ts_pes_new(this, this->media_num, pid, this->video_fifo,stream[0]);
- this->videoMedia = this->media_num;
- this->videoPid = pid;
- }
-
- break;
- case ISO_11172_AUDIO:
- case ISO_13818_AUDIO:
- case ISO_13818_PART7_AUDIO:
- case ISO_14496_PART3_AUDIO:
- if (this->audio_tracks_count < MAX_AUDIO_TRACKS) {
- int i, found = 0;
- for(i = 0; i < this->audio_tracks_count; i++) {
- if(this->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if(!found) {
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
-#endif
- demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo,stream[0]);
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
- stream + 5, stream_info_length);
- this->audio_tracks_count++;
- }
- }
- break;
- case ISO_13818_PRIVATE:
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT streamtype 13818_PRIVATE, pid: 0x%.4x type %2.2x\n", pid, stream[0]);
-
- for (i = 5; i < coded_length; i++)
- printf ("%.2x ", stream[i]);
- printf ("\n");
-#endif
- break;
- case ISO_13818_TYPE_C: /* data carousel */
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT streamtype 13818_TYPE_C, pid: 0x%.4x type %2.2x\n", pid, stream[0]);
-#endif
- break;
- case ISO_13818_PES_PRIVATE:
- for (i = 5; i < coded_length; i += stream[i+1] + 2) {
- if ((stream[i] == 0x6a) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) {
- int i, found = 0;
- for(i = 0; i < this->audio_tracks_count; i++) {
- if(this->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if(!found) {
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
-#endif
- demux_ts_pes_new(this, this->media_num, pid,
- this->audio_fifo, STREAM_AUDIO_AC3);
-
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
- stream + 5, stream_info_length);
- this->audio_tracks_count++;
- break;
- }
- }
- /* Teletext */
- else if (stream[i] == 0x56)
- {
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT Teletext, pid: 0x%.4x type %2.2x\n", pid, stream[0]);
-
- for (i = 5; i < coded_length; i++)
- printf ("%.2x ", stream[i]);
- printf ("\n");
-#endif
- break;
- }
-
- /* DVBSUB */
- else if (stream[i] == 0x59)
- {
- int pos;
- for (pos = i + 2;
- pos + 8 <= i + 2 + stream[i + 1]
- && this->spu_langs_count < MAX_SPU_LANGS;
- pos += 8)
- {
- int no = this->spu_langs_count;
- demux_ts_spu_lang *lang = &this->spu_langs[no];
-
- this->spu_langs_count++;
-
- memcpy(lang->desc.lang, &stream[pos], 3);
- lang->desc.lang[3] = 0;
- lang->desc.comp_page_id =
- (stream[pos + 4] << 8) | stream[pos + 5];
- lang->desc.aux_page_id =
- (stream[pos + 6] << 8) | stream[pos + 7];
- lang->pid = pid;
- lang->media_index = this->media_num;
- this->media[this->media_num].type = no;
- demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
- demux_send_special_spu_buf( this, BUF_SPU_DVB, no );
-#ifdef TS_LOG
- printf("demux_ts: DVBSUB: pid 0x%.4x: %s page %ld %ld type %2.2x\n",
- pid, lang->desc.lang,
- lang->desc.comp_page_id,
- lang->desc.aux_page_id,
- stream[0]);
-#endif
- }
- }
- }
- break;
-
- case STREAM_SPU_BITMAP_HDMV:
- if (this->hdmv > 0) {
- if (pid >= 0x1200 && pid < 0x1300) {
- /* HDMV Presentation Graphics / SPU */
- demux_ts_spu_lang *lang = &this->spu_langs[this->spu_langs_count];
-
- memset(lang->desc.lang, 0, sizeof(lang->desc.lang));
- /*memcpy(lang->desc.lang, &stream[pos], 3);*/
- /*lang->desc.lang[3] = 0;*/
- lang->pid = pid;
- lang->media_index = this->media_num;
- this->media[this->media_num].type = this->spu_langs_count;
- demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
- demux_send_special_spu_buf( this, BUF_SPU_HDMV, this->spu_langs_count );
- this->spu_langs_count++;
-#ifdef TS_PMT_LOG
- printf("demux_ts: HDMV subtitle stream_type: 0x%.2x pid: 0x%.4x\n",
- stream[0], pid);
-#endif
- break;
- }
- }
- /* fall thru */
- default:
-
-/* This following section handles all the cases where the audio track info is stored in PMT user info with stream id >= 0x80
- * We first check that the stream id >= 0x80, because all values below that are invalid if not handled above,
- * then we check the registration format identifier to see if it holds "AC-3" (0x41432d33) and
- * if is does, we tag this as an audio stream.
- * FIXME: This will need expanding if we ever see a DTS or other media format here.
- */
- if ((this->audio_tracks_count < MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) {
- int i, found = 0;
- for(i = 0; i < this->audio_tracks_count; i++) {
- if(this->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if(!found) {
- uint32_t format_identifier=0;
- demux_ts_get_reg_desc(this, &format_identifier,
- stream + 5, stream_info_length);
- /* If no format identifier, assume A52 */
- if ((format_identifier == 0x41432d33) || (format_identifier == 0)) {
- demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, stream[0]);
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
- stream + 5, stream_info_length);
- this->audio_tracks_count++;
- break;
- }
- }
- } else {
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT unknown stream_type: 0x%.2x pid: 0x%.4x\n",
- stream[0], pid);
-
- for (i = 5; i < coded_length; i++)
- printf ("%.2x ", stream[i]);
- printf ("\n");
-#endif
- }
- break;
- }
- this->media_num++;
- stream += coded_length;
- section_length -= coded_length;
- }
-
- /*
- * Get the current PCR PID.
- */
- pid = ((this->pmt[program_count][8] << 8)
- | this->pmt[program_count][9]) & 0x1fff;
- if (this->pcrPid != pid) {
-#ifdef TS_PMT_LOG
- if (this->pcrPid == INVALID_PID) {
- printf ("demux_ts: PMT pcr pid 0x%.4x\n", pid);
- } else {
- printf ("demux_ts: PMT pcr pid changed 0x%.4x\n", pid);
- }
-#endif
- this->pcrPid = pid;
- }
-
- if ( this->stream->spu_channel>=0 && this->spu_langs_count>0 )
- demux_ts_update_spu_channel( this );
-
- /* Inform UI of channels changes */
- xine_event_t ui_event;
- ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- ui_event.data_length = 0;
- xine_event_send( this->stream, &ui_event );
-}
-
-static int sync_correct(demux_ts_t*this, uint8_t *buf, int32_t npkt_read) {
-
- int p = 0;
- int n = 0;
- int i = 0;
- int sync_ok = 0;
- int read_length;
-
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: about to resync!\n");
-
- for (p=0; p < npkt_read; p++) {
- for(n=0; n < this->pkt_size; n++) {
- sync_ok = 1;
- for (i=0; i < MIN(MIN_SYNCS, npkt_read - p); i++) {
- if (buf[this->pkt_offset + n + ((i+p) * this->pkt_size)] != SYNC_BYTE) {
- sync_ok = 0;
- break;
- }
- }
- if (sync_ok) break;
- }
- if (sync_ok) break;
- }
-
- if (sync_ok) {
- /* Found sync, fill in */
- memmove(&buf[0], &buf[n + p * this->pkt_size],
- ((this->pkt_size * (npkt_read - p)) - n));
- read_length = this->input->read(this->input,
- &buf[(this->pkt_size * (npkt_read - p)) - n],
- n + p * this->pkt_size);
- /* FIXME: when read_length is not as required... we now stop demuxing */
- if (read_length != (n + p * this->pkt_size)) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts_tsync_correct: sync found, but read failed\n");
- return 0;
- }
- } else {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts_tsync_correct: sync not found! Stop demuxing\n");
- return 0;
- }
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: resync successful!\n");
- return 1;
-}
-
-static int sync_detect(demux_ts_t*this, uint8_t *buf, int32_t npkt_read) {
-
- int i, sync_ok;
-
- sync_ok = 1;
-
- if (this->hdmv) {
- this->pkt_size = PKT_SIZE + 4;
- this->pkt_offset = 4;
- for (i=0; i < MIN(MIN_SYNCS, npkt_read - 3); i++) {
- if (buf[this->pkt_offset + i * this->pkt_size] != SYNC_BYTE) {
- sync_ok = 0;
- break;
- }
- }
- if (sync_ok) {
- if (this->hdmv < 0) {
- /* fix npkt_read (packet size is 192, not 188) */
- this->npkt_read = npkt_read * PKT_SIZE / this->pkt_size;
- }
- this->hdmv = 1;
- return sync_ok;
- }
- if (this->hdmv > 0)
- return sync_correct(this, buf, npkt_read);
-
- /* plain ts */
- this->hdmv = 0;
- this->pkt_size = PKT_SIZE;
- this->pkt_offset = 0;
- }
-
- for (i=0; i < MIN(MIN_SYNCS, npkt_read); i++) {
- if (buf[i * PKT_SIZE] != SYNC_BYTE) {
- sync_ok = 0;
- break;
- }
- }
- if (!sync_ok) return sync_correct(this, buf, npkt_read);
- return sync_ok;
-}
-
-
-/*
- * Main synchronisation routine.
- */
-static unsigned char * demux_synchronise(demux_ts_t* this) {
-
- uint8_t *return_pointer = NULL;
- int32_t read_length;
- if ( (this->packet_number) >= this->npkt_read) {
-
- /* NEW: handle read returning less packets than NPKT_PER_READ... */
- do {
- read_length = this->input->read(this->input, this->buf,
- this->pkt_size * NPKT_PER_READ);
- if (read_length < 0 || read_length % this->pkt_size) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: read returned %d bytes (not a multiple of %d!)\n",
- read_length, this->pkt_size);
- this->status = DEMUX_FINISHED;
- return NULL;
- }
- this->npkt_read = read_length / this->pkt_size;
-
-#ifdef TS_READ_STATS
- this->rstat[this->npkt_read]++;
-#endif
- /*
- * what if this->npkt_read < 5 ? --> ok in sync_detect
- *
- * NEW: stop demuxing if read returns 0 a few times... (200)
- */
-
- if (this->npkt_read == 0) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read 0 packets\n");
- this->status = DEMUX_FINISHED;
- return NULL;
- }
-
- } while (! read_length);
-
- this->packet_number = 0;
-
- if (!sync_detect(this, &(this->buf)[0], this->npkt_read)) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: sync error.\n");
- this->status = DEMUX_FINISHED;
- return NULL;
- }
- }
- return_pointer = &(this->buf)[this->pkt_offset + this->pkt_size * this->packet_number];
- this->packet_number++;
- return return_pointer;
-}
-
-
-static int64_t demux_ts_adaptation_field_parse(uint8_t *data,
- uint32_t adaptation_field_length) {
-
- uint32_t discontinuity_indicator=0;
- uint32_t random_access_indicator=0;
- uint32_t elementary_stream_priority_indicator=0;
- uint32_t PCR_flag=0;
- int64_t PCR=0;
- uint32_t EPCR=0;
- uint32_t OPCR_flag=0;
- uint32_t OPCR=0;
- uint32_t EOPCR=0;
- uint32_t slicing_point_flag=0;
- uint32_t transport_private_data_flag=0;
- uint32_t adaptation_field_extension_flag=0;
- uint32_t offset = 1;
-
- discontinuity_indicator = ((data[0] >> 7) & 0x01);
- random_access_indicator = ((data[0] >> 6) & 0x01);
- elementary_stream_priority_indicator = ((data[0] >> 5) & 0x01);
- PCR_flag = ((data[0] >> 4) & 0x01);
- OPCR_flag = ((data[0] >> 3) & 0x01);
- slicing_point_flag = ((data[0] >> 2) & 0x01);
- transport_private_data_flag = ((data[0] >> 1) & 0x01);
- adaptation_field_extension_flag = (data[0] & 0x01);
-
-#ifdef TS_LOG
- printf ("demux_ts: ADAPTATION FIELD length: %d (%x)\n",
- adaptation_field_length, adaptation_field_length);
- if(discontinuity_indicator) {
- printf (" Discontinuity indicator: %d\n",
- discontinuity_indicator);
- }
- if(random_access_indicator) {
- printf (" Random_access indicator: %d\n",
- random_access_indicator);
- }
- if(elementary_stream_priority_indicator) {
- printf (" Elementary_stream_priority_indicator: %d\n",
- elementary_stream_priority_indicator);
- }
-#endif
- if(PCR_flag) {
- PCR = (((int64_t) data[offset]) & 0xFF) << 25;
- PCR += (int64_t) ((data[offset+1] & 0xFF) << 17);
- PCR += (int64_t) ((data[offset+2] & 0xFF) << 9);
- PCR += (int64_t) ((data[offset+3] & 0xFF) << 1);
- PCR += (int64_t) ((data[offset+4] & 0x80) >> 7);
-
- EPCR = ((data[offset+4] & 0x1) << 8) | data[offset+5];
-#ifdef TS_LOG
- printf ("demux_ts: PCR: %lld, EPCR: %u\n",
- PCR, EPCR);
-#endif
- offset+=6;
- }
- if(OPCR_flag) {
- OPCR = data[offset] << 25;
- OPCR |= data[offset+1] << 17;
- OPCR |= data[offset+2] << 9;
- OPCR |= data[offset+3] << 1;
- OPCR |= (data[offset+4] >> 7) & 0x01;
- EOPCR = ((data[offset+4] & 0x1) << 8) | data[offset+5];
-#ifdef TS_LOG
- printf ("demux_ts: OPCR: %u, EOPCR: %u\n",
- OPCR,EOPCR);
-#endif
- offset+=6;
- }
-#ifdef TS_LOG
- if(slicing_point_flag) {
- printf ("demux_ts: slicing_point_flag: %d\n",
- slicing_point_flag);
- }
- if(transport_private_data_flag) {
- printf ("demux_ts: transport_private_data_flag: %d\n",
- transport_private_data_flag);
- }
- if(adaptation_field_extension_flag) {
- printf ("demux_ts: adaptation_field_extension_flag: %d\n",
- adaptation_field_extension_flag);
- }
-#endif
- return PCR;
-}
-
-/* check if an apid is in the list of known apids */
-static int apid_check(demux_ts_t*this, unsigned int pid) {
- int i;
- for(i=0; i<this->audio_tracks_count; i++) {
- if(this->audio_tracks[i].pid == pid)
- return i;
- }
- return -1;
-}
-
-/* transport stream packet layer */
-static void demux_ts_parse_packet (demux_ts_t*this) {
-
- unsigned char *originalPkt;
- unsigned int sync_byte;
- unsigned int transport_error_indicator;
- unsigned int payload_unit_start_indicator;
- unsigned int transport_priority;
- unsigned int pid;
- unsigned int transport_scrambling_control;
- unsigned int adaptation_field_control;
- unsigned int continuity_counter;
- unsigned int data_offset;
- unsigned int data_len;
- uint32_t program_count;
- int i;
-
- /* get next synchronised packet, or NULL */
- originalPkt = demux_synchronise(this);
- if (originalPkt == NULL)
- return;
-
- sync_byte = originalPkt[0];
- transport_error_indicator = (originalPkt[1] >> 7) & 0x01;
- payload_unit_start_indicator = (originalPkt[1] >> 6) & 0x01;
- transport_priority = (originalPkt[1] >> 5) & 0x01;
- pid = ((originalPkt[1] << 8) |
- originalPkt[2]) & 0x1fff;
- transport_scrambling_control = (originalPkt[3] >> 6) & 0x03;
- adaptation_field_control = (originalPkt[3] >> 4) & 0x03;
- continuity_counter = originalPkt[3] & 0x0f;
-
-
-#ifdef TS_HEADER_LOG
- printf("demux_ts:ts_header:sync_byte=0x%.2x\n",sync_byte);
- printf("demux_ts:ts_header:transport_error_indicator=%d\n", transport_error_indicator);
- printf("demux_ts:ts_header:payload_unit_start_indicator=%d\n", payload_unit_start_indicator);
- printf("demux_ts:ts_header:transport_priority=%d\n", transport_priority);
- printf("demux_ts:ts_header:pid=0x%.4x\n", pid);
- printf("demux_ts:ts_header:transport_scrambling_control=0x%.1x\n", transport_scrambling_control);
- printf("demux_ts:ts_header:adaptation_field_control=0x%.1x\n", adaptation_field_control);
- printf("demux_ts:ts_header:continuity_counter=0x%.1x\n", continuity_counter);
-#endif
- /*
- * Discard packets that are obviously bad.
- */
- if (sync_byte != SYNC_BYTE) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux error! invalid ts sync byte %.2x\n", sync_byte);
- return;
- }
- if (transport_error_indicator) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux error! transport error\n");
- return;
- }
- if (pid == 0x1ffb) {
- /* printf ("demux_ts: PSIP table. Program Guide etc....not supported yet. PID = 0x1ffb\n"); */
- return;
- }
-
- if (transport_scrambling_control) {
- if (this->videoPid == pid) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: selected videoPid is scrambled; skipping...\n");
- }
- for (i=0; i < this->scrambled_npids; i++) {
- if (this->scrambled_pids[i] == pid) return;
- }
- this->scrambled_pids[this->scrambled_npids] = pid;
- this->scrambled_npids++;
-
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID 0x%.4x is scrambled!\n", pid);
- return;
- }
-
- data_offset = 4;
-
- if( adaptation_field_control & 0x2 ){
- uint32_t adaptation_field_length = originalPkt[4];
- if (adaptation_field_length > 0) {
- demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length);
- }
- /*
- * Skip adaptation header.
- */
- data_offset += adaptation_field_length + 1;
- }
-
- if (! (adaptation_field_control & 0x1)) {
- return;
- }
-
- data_len = PKT_SIZE - data_offset;
-
- /*
- * audio/video pid auto-detection, if necessary
- */
- program_count=0;
- if(this->media_num<MAX_PMTS)
- while ((this->program_number[program_count] != INVALID_PROGRAM) &&
- (program_count < MAX_PMTS)) {
- if (pid == this->pmt_pid[program_count]) {
-
-#ifdef TS_LOG
- printf ("demux_ts: PMT prog: 0x%.4x pid: 0x%.4x\n",
- this->program_number[program_count],
- this->pmt_pid[program_count]);
-#endif
- demux_ts_parse_pmt (this, originalPkt, originalPkt+data_offset-4,
- payload_unit_start_indicator,
- program_count);
- return;
- }
- program_count++;
- }
-
- if (payload_unit_start_indicator && this->media_num < MAX_PIDS){
- int pes_stream_id;
- if (pid == 0) {
- demux_ts_parse_pat (this, originalPkt, originalPkt+data_offset-4,
- payload_unit_start_indicator);
- return;
- }
- program_count = 0;
- pes_stream_id = originalPkt[data_offset+3];
-
-#ifdef TS_HEADER_LOG
- printf("demux_ts:ts_pes_header:stream_id=0x%.2x\n",pes_stream_id);
-#endif
-
- if ( (pes_stream_id >= VIDEO_STREAM_S) && (pes_stream_id <= VIDEO_STREAM_E) ) {
- if ( this->videoPid == INVALID_PID) {
- int i, found = 0;
- for(i = 0; i < this->media_num; i++) {
- if (this->media[i].pid == pid) {
- found = 1;
- break;
- }
- }
-
- if (found && (this->media[i].corrupted_pes == 0)) {
- this->videoPid = pid;
- this->videoMedia = i;
- } else if (!found) {
- this->videoPid = pid;
- this->videoMedia = this->media_num;
- this->media[this->videoMedia].autodetected = 1;
- demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, 0x100 + pes_stream_id);
- }
-
- if (this->videoPid != INVALID_PID) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: auto-detected video pid 0x%.4x\n", pid);
- }
- }
- } else if ( (pes_stream_id >= AUDIO_STREAM_S) && (pes_stream_id <= AUDIO_STREAM_E) ) {
- if (this->audio_tracks_count < MAX_AUDIO_TRACKS) {
- int i, found = 0;
- for(i = 0; i < this->audio_tracks_count; i++) {
- if(this->audio_tracks[i].pid == pid) {
- found = 1;
- break;
- }
- }
- if(!found) {
-#ifdef TS_PMT_LOG
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: auto-detected audio pid 0x%.4x\n", pid);
-#endif
- /* store PID, index and stream no. */
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_pes_new(this, this->media_num++, pid,
- this->audio_fifo, 0x100 + pes_stream_id);
- this->audio_tracks_count++;
- }
- }
- }
- }
-
- if (data_len > PKT_SIZE) {
-
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! invalid payload size %d\n", data_len);
-
- } else {
-
- /*
- * Do the demuxing in descending order of packet frequency!
- */
- int index;
- if (pid == this->videoPid) {
-#ifdef TS_LOG
- printf ("demux_ts: Video pid: 0x%.4x\n", pid);
-#endif
- check_newpts(this, this->media[this->videoMedia].pts, PTS_VIDEO);
- demux_ts_buffer_pes (this, originalPkt+data_offset, this->videoMedia,
- payload_unit_start_indicator, continuity_counter,
- data_len);
- return;
- }
- else if ((index = apid_check(this, pid)) > -1) {
-#ifdef TS_LOG
- printf ("demux_ts: Audio pid: 0x%.4x\n", pid);
-#endif
- check_newpts(this, this->media[this->audio_tracks[index].media_index].pts, PTS_AUDIO);
- demux_ts_buffer_pes (this, originalPkt+data_offset,
- this->audio_tracks[index].media_index,
- payload_unit_start_indicator, continuity_counter,
- data_len);
- return;
- }
- else if (pid == NULL_PID) {
-#ifdef TS_LOG
- printf ("demux_ts: Null Packet\n");
-#endif
- return;
- }
- /* DVBSUB */
- else if (pid == this->spu_pid) {
-#ifdef TS_LOG
- printf ("demux_ts: SPU pid: 0x%.4x\n", pid);
-#endif
- demux_ts_buffer_pes (this, originalPkt+data_offset, this->spu_media,
- payload_unit_start_indicator, continuity_counter,
- data_len);
- return;
- }
- }
-}
-
-/*
- * check for pids change events
- */
-
-static void demux_ts_event_handler (demux_ts_t *this) {
-
- xine_event_t *event;
-
- while ((event = xine_event_get (this->event_queue))) {
-
-
- switch (event->type) {
-
- case XINE_EVENT_PIDS_CHANGE:
-
- this->videoPid = INVALID_PID;
- this->audio_tracks_count = 0;
- this->media_num = 0;
- this->send_newpts = 1;
- this->spu_pid = INVALID_PID;
- this->spu_media = 0;
- this->spu_langs_count= 0;
- this->last_pmt_crc = 0;
- _x_demux_control_start (this->stream);
- break;
-
- }
-
- xine_event_free (event);
- }
-}
-
-/*
- * send a piece of data down the fifos
- */
-
-static int demux_ts_send_chunk (demux_plugin_t *this_gen) {
-
- demux_ts_t*this = (demux_ts_t*)this_gen;
-
- demux_ts_event_handler (this);
-
- demux_ts_parse_packet(this);
-
- /* DVBSUB: check if channel has changed. Dunno if I should, or
- * even could, lock the xine object. */
- if (this->stream->spu_channel != this->current_spu_channel) {
- demux_ts_update_spu_channel(this);
- }
-
- return this->status;
-}
-
-static void demux_ts_dispose (demux_plugin_t *this_gen) {
- int i;
- demux_ts_t*this = (demux_ts_t*)this_gen;
-
- for (i=0; i < MAX_PMTS; i++) {
- if (this->pmt[i] != NULL) {
- free(this->pmt[i]);
- this->pmt[i] = NULL;
- }
- }
- for (i=0; i < MAX_PIDS; i++) {
- if (this->media[i].buf != NULL) {
- this->media[i].buf->free_buffer(this->media[i].buf);
- this->media[i].buf = NULL;
- }
- }
-
- xine_event_dispose_queue (this->event_queue);
-
- free(this_gen);
-}
-
-static int demux_ts_get_status(demux_plugin_t *this_gen) {
-
- demux_ts_t*this = (demux_ts_t*)this_gen;
-
- return this->status;
-}
-
-static void demux_ts_send_headers (demux_plugin_t *this_gen) {
-
- demux_ts_t *this = (demux_ts_t *) this_gen;
-
- this->video_fifo = this->stream->video_fifo;
- this->audio_fifo = this->stream->audio_fifo;
-
- this->status = DEMUX_OK;
-
- /*
- * send start buffers
- */
-
- this->videoPid = INVALID_PID;
- this->audio_tracks_count = 0;
- this->media_num= 0;
- this->last_pmt_crc = 0;
-
- _x_demux_control_start (this->stream);
-
- this->input->seek (this->input, 0, SEEK_SET);
-
- this->send_newpts = 1;
-
- demux_ts_build_crc32_table (this);
-
- this->status = DEMUX_OK ;
-
- this->send_end_buffers = 1;
- this->scrambled_npids = 0;
-
- /* DVBSUB */
- this->spu_pid = INVALID_PID;
- this->spu_langs_count = 0;
- this->current_spu_channel = -1;
-
- /* FIXME ? */
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
-}
-
-static int demux_ts_seek (demux_plugin_t *this_gen,
- off_t start_pos, int start_time, int playing) {
-
- demux_ts_t *this = (demux_ts_t *) this_gen;
- int i;
- start_time /= 1000;
- start_pos = (off_t) ( (double) start_pos / 65535 *
- this->input->get_length (this->input) );
-
- if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) {
-
- if ((!start_pos) && (start_time)) {
- start_pos = start_time;
- start_pos *= this->rate;
- start_pos *= 50;
- }
- this->input->seek (this->input, start_pos, SEEK_SET);
-
- }
-
- this->send_newpts = 1;
-
- for (i=0; i<MAX_PIDS; i++) {
- demux_ts_media *m = &this->media[i];
-
- if (m->buf != NULL)
- m->buf->free_buffer(m->buf);
- m->buf = NULL;
- m->counter = INVALID_CC;
- m->corrupted_pes = 1;
- m->buffered_bytes = 0;
- }
-
- if( !playing ) {
-
- this->status = DEMUX_OK;
- this->buf_flag_seek = 0;
-
- } else {
-
- this->buf_flag_seek = 1;
- _x_demux_flush_engine(this->stream);
-
- }
-
- return this->status;
-}
-
-static int demux_ts_get_stream_length (demux_plugin_t *this_gen) {
-
- demux_ts_t*this = (demux_ts_t*)this_gen;
-
- if (this->rate)
- return (int)((int64_t) this->input->get_length (this->input)
- * 1000 / (this->rate * 50));
- else
- return 0;
-}
-
-
-static uint32_t demux_ts_get_capabilities(demux_plugin_t *this_gen)
-{
- return DEMUX_CAP_AUDIOLANG | DEMUX_CAP_SPULANG;
-}
-
-static int demux_ts_get_optional_data(demux_plugin_t *this_gen,
- void *data, int data_type)
-{
- demux_ts_t *this = (demux_ts_t *) this_gen;
- char *str = data;
- int channel = *((int *)data);
-
- /* be a bit paranoid */
- if (this == NULL || this->stream == NULL)
- return DEMUX_OPTIONAL_UNSUPPORTED;
-
- switch (data_type)
- {
- case DEMUX_OPTIONAL_DATA_AUDIOLANG:
- if ((channel >= 0) && (channel < this->audio_tracks_count)) {
- if(this->audio_tracks[channel].lang[0])
- strcpy(str, this->audio_tracks[channel].lang);
- else
- sprintf(str, "%3i", channel);
- }
- else {
- strcpy(str, "none");
- return DEMUX_OPTIONAL_UNSUPPORTED;
- }
- return DEMUX_OPTIONAL_SUCCESS;
-
- case DEMUX_OPTIONAL_DATA_SPULANG:
- if (channel>=0 && channel<this->spu_langs_count) {
- if (this->spu_langs[channel].desc.lang[0]) {
- memcpy(str, this->spu_langs[channel].desc.lang, 3);
- str[3] = 0;
- } else
- sprintf(str, "%3i", channel);
- }
- else {
- strcpy(str, "none");
- return DEMUX_OPTIONAL_UNSUPPORTED;
- }
- return DEMUX_OPTIONAL_SUCCESS;
-
- default:
- return DEMUX_OPTIONAL_UNSUPPORTED;
- }
-}
-
-static int detect_ts(uint8_t *buf, size_t len, int ts_size)
-{
- int i, j;
- int try_again, ts_detected = 0;
- size_t packs = len / ts_size - 2;
-
- for (i = 0; i < ts_size; i++) {
- try_again = 0;
- if (buf[i] == SYNC_BYTE) {
- for (j = 1; j < packs; j++) {
- if (buf[i + j*ts_size] != SYNC_BYTE) {
- try_again = 1;
- break;
- }
- }
- if (try_again == 0) {
-#ifdef TS_LOG
- printf ("demux_ts: found 0x47 pattern at offset %d\n", i);
-#endif
- ts_detected = 1;
- }
- }
- }
-
- return ts_detected;
-}
-
-static demux_plugin_t *open_plugin (demux_class_t *class_gen,
- xine_stream_t *stream,
- input_plugin_t *input) {
-
- demux_ts_t *this;
- int i;
- int hdmv = -1;
-
- switch (stream->content_detection_method) {
-
- case METHOD_BY_CONTENT: {
- uint8_t buf[2069];
-
- if (!_x_demux_read_header(input, buf, sizeof(buf)))
- return NULL;
-
- if (detect_ts(buf, sizeof(buf), PKT_SIZE))
- hdmv = 0;
- else if (detect_ts(buf, sizeof(buf), PKT_SIZE+4))
- hdmv = 1;
- else
- return NULL;
- }
- break;
-
- case METHOD_BY_EXTENSION: {
- const char *const mrl = input->get_mrl (input);
-
- if (_x_demux_check_extension (mrl, "m2ts mts"))
- hdmv = 1;
- else
- hdmv = 0;
-
- /* check extension */
- const char *const extensions = class_gen->get_extensions (class_gen);
-
- if (_x_demux_check_extension (mrl, extensions))
- break;
-
- /* accept dvb streams */
- /*
- * Also handle the special dvbs,dvbt and dvbc mrl formats:
- * the content is exactly the same but the input plugin
- * uses a different tuning algorithm [Pragma]
- */
-
- if (!strncasecmp (mrl, "dvb://", 6))
- break;
- if (!strncasecmp (mrl, "dvbs://", 7))
- break;
- if (!strncasecmp (mrl, "dvbc://", 7))
- break;
- if (!strncasecmp (mrl, "dvbt://", 7))
- break;
-
- return NULL;
- }
-
- case METHOD_EXPLICIT:
- break;
-
- default:
- return NULL;
- }
-
- /*
- * if we reach this point, the input has been accepted.
- */
-
- this = calloc(1, sizeof(*this));
- this->stream = stream;
- this->input = input;
- this->blockSize = PKT_SIZE;
-
- this->demux_plugin.send_headers = demux_ts_send_headers;
- this->demux_plugin.send_chunk = demux_ts_send_chunk;
- this->demux_plugin.seek = demux_ts_seek;
- this->demux_plugin.dispose = demux_ts_dispose;
- this->demux_plugin.get_status = demux_ts_get_status;
- this->demux_plugin.get_stream_length = demux_ts_get_stream_length;
- this->demux_plugin.get_capabilities = demux_ts_get_capabilities;
- this->demux_plugin.get_optional_data = demux_ts_get_optional_data;
- this->demux_plugin.demux_class = class_gen;
-
- /*
- * Initialise our specialised data.
- */
- for (i = 0; i < MAX_PIDS; i++) {
- this->media[i].pid = INVALID_PID;
- this->media[i].buf = NULL;
- this->media[i].autodetected = 0;
- }
-
- for (i = 0; i < MAX_PMTS; i++) {
- this->program_number[i] = INVALID_PROGRAM;
- this->pmt_pid[i] = INVALID_PID;
- this->pmt[i] = NULL;
- this->pmt_write_ptr[i] = NULL;
- }
-
- this->programNumber = INVALID_PROGRAM;
- this->pcrPid = INVALID_PID;
- this->scrambled_npids = 0;
- this->videoPid = INVALID_PID;
- this->audio_tracks_count = 0;
- this->last_pmt_crc = 0;
-
- this->rate = 16000; /* FIXME */
-
- this->status = DEMUX_FINISHED;
-
- /* DVBSUB */
- this->spu_pid = INVALID_PID;
- this->spu_langs_count = 0;
- this->current_spu_channel = -1;
-
- /* dvb */
- this->event_queue = xine_event_new_queue (this->stream);
-
- /* HDMV */
- this->hdmv = hdmv;
- this->pkt_offset = (hdmv > 0) ? 4 : 0;
- this->pkt_size = PKT_SIZE + this->pkt_offset;
-
- this->numPreview=0;
-
- return &this->demux_plugin;
-}
-
-/*
- * ts demuxer class
- */
-
-static const char *get_description (demux_class_t *this_gen) {
- return "MPEG Transport Stream demuxer";
-}
-
-static const char *get_identifier (demux_class_t *this_gen) {
- return "MPEG_TS_HDMV";
-}
-
-static const char *get_extensions (demux_class_t *this_gen) {
- return "m2ts mts";
-}
-
-static const char *get_mimetypes (demux_class_t *this_gen) {
- return NULL;
-}
-
-static void class_dispose (demux_class_t *this_gen) {
-
- demux_ts_class_t *this = (demux_ts_class_t *) this_gen;
-
- free (this);
-}
-
-static void *init_class (xine_t *xine, void *data) {
-
- demux_ts_class_t *this;
-
- this = calloc(1, sizeof(demux_ts_class_t));
- this->config = xine->config;
- this->xine = xine;
-
- this->demux_class.open_plugin = open_plugin;
- this->demux_class.get_description = get_description;
- this->demux_class.get_identifier = get_identifier;
- this->demux_class.get_mimetypes = get_mimetypes;
- this->demux_class.get_extensions = get_extensions;
- this->demux_class.dispose = class_dispose;
-
- return this;
-}
-
-
-/*
- * exported plugin catalog entry
- */
-static const demuxer_info_t demux_info_ts = {
- 5 /* priority */
-};
-
-const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 26, "mpeg-ts-hdmv", XINE_VERSION_CODE, &demux_info_ts, init_class },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};
-
diff --git a/xine/adjustable_scr.c b/xine/adjustable_scr.c
deleted file mode 100644
index 4301e348..00000000
--- a/xine/adjustable_scr.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * adjustable_scr.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: adjustable_scr.c,v 1.2 2008-12-14 01:21:20 phintuka Exp $
- *
- */
-
-
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/metronom.h>
-
-#include "adjustable_scr.h"
-
-/*
- * SCR code is mostly copied from xine-lib (src/input/input_pvr.c)
- *
- *
- * Copyright (C) 2000-2005 the xine project
- * March 2003 - Miguel Freitas
- * This plugin was sponsored by 1Control
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- */
-
-typedef struct scr_impl_s scr_impl_t;
-
-struct scr_impl_s {
- union {
- scr_plugin_t scr;
- adjustable_scr_t ascr;
- };
-
- xine_t *xine;
-
- struct timeval cur_time;
- int64_t cur_pts;
- int xine_speed;
- int scr_speed_base;
- double speed_factor;
- double speed_tuning;
-
- pthread_mutex_t lock;
-
- struct timeval last_time;
-};
-
-/* Only call set_pivot when already mutex locked ! */
-static void set_pivot (scr_impl_t *this)
-{
- struct timeval tv;
- int64_t pts;
- double pts_calc;
-
- xine_monotonic_clock(&tv,NULL);
-
- pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
- pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
- pts = this->cur_pts + pts_calc;
-
- /* This next part introduces a one off inaccuracy
- * to the scr due to rounding tv to pts.
- */
- this->cur_time.tv_sec=tv.tv_sec;
- this->cur_time.tv_usec=tv.tv_usec;
- this->cur_pts=pts;
-
- this->last_time.tv_sec = tv.tv_sec;
- this->last_time.tv_usec = tv.tv_usec;
-
- return ;
-}
-
-/*
- * xine interface (scr_plugin_t)
- */
-
-static int scr_get_priority (scr_plugin_t *scr)
-{
- return 50; /* high priority */
-}
-
-static int scr_set_fine_speed (scr_plugin_t *scr, int speed)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->xine_speed = speed;
- this->speed_factor = (double) speed * (double)this->scr_speed_base /*90000.0*/ /
- (1.0*XINE_FINE_SPEED_NORMAL) *
- this->speed_tuning;
-
- pthread_mutex_unlock (&this->lock);
-
- return speed;
-}
-
-static void scr_adjust (scr_plugin_t *scr, int64_t vpts)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
- struct timeval tv;
-
- pthread_mutex_lock (&this->lock);
-
- xine_monotonic_clock(&tv,NULL);
- this->cur_time.tv_sec=tv.tv_sec;
- this->cur_time.tv_usec=tv.tv_usec;
- this->cur_pts = vpts;
-
- this->last_time.tv_sec = tv.tv_sec;
- this->last_time.tv_usec = tv.tv_usec;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-static void scr_start (scr_plugin_t *scr, int64_t start_vpts)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- xine_monotonic_clock(&this->cur_time, NULL);
- this->cur_pts = start_vpts;
-
- this->last_time.tv_sec = this->cur_time.tv_sec;
- this->last_time.tv_usec = this->cur_time.tv_usec;
-
- pthread_mutex_unlock (&this->lock);
-
- scr_set_fine_speed (&this->scr, XINE_FINE_SPEED_NORMAL);
-}
-
-static int64_t scr_get_current (scr_plugin_t *scr)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- struct timeval tv;
- int64_t pts;
- double pts_calc;
- pthread_mutex_lock (&this->lock);
-
- xine_monotonic_clock(&tv,NULL);
-
- pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
- pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
-
- pts = this->cur_pts + pts_calc;
-
- this->last_time.tv_sec = tv.tv_sec;
- this->last_time.tv_usec = tv.tv_usec;
-
- pthread_mutex_unlock (&this->lock);
-
- return pts;
-}
-
-static void scr_exit (scr_plugin_t *scr)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_destroy (&this->lock);
- free(this);
-}
-
-/*
- * adjusteble_scr_t
- */
-
-/*
- * speed_tuning()
- *
- * - fine-tune SCR speed. Actual speed is base_speed * factor.
- */
-static void adjustable_scr_speed_tuning (adjustable_scr_t *scr, double factor)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->speed_tuning = factor;
- this->speed_factor = (double) this->xine_speed * (double)this->scr_speed_base /*90000.0*/ /
- (1.0*XINE_FINE_SPEED_NORMAL) *
- this->speed_tuning;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-/*
- * speed_base()
- *
- * - set base speed of SCR (default is 90kHz)
- */
-static void adjustable_scr_speed_base (adjustable_scr_t *scr, int hz)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->scr_speed_base = hz;
- this->speed_factor = (double) this->xine_speed * (double)this->scr_speed_base /*90000.0*/ /
- (1.0*XINE_FINE_SPEED_NORMAL) *
- this->speed_tuning;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-/*
- * jump()
- *
- * - Move SCR 'pts' ticks forward
- */
-static void adjustable_scr_jump (adjustable_scr_t *scr, int pts)
-{
- scr_impl_t *this = (scr_impl_t*) scr;
-
- pthread_mutex_lock (&this->lock);
-
- set_pivot( this );
- this->cur_pts += pts;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-/*
- * dispose()
- *
- * - unregister, stop and free resources
- */
-static void adjustable_scr_dispose(adjustable_scr_t *scr)
-{
- scr_impl_t *this = (scr_impl_t*)scr;
-
- /* unregister */
- if (this->xine)
- this->xine->clock->unregister_scr(this->xine->clock, &this->scr);
-
- /* exit and dispose */
- this->scr.exit(&this->scr);
-}
-
-/*
- * adjusteble_scr_start()
- *
- */
-adjustable_scr_t* adjustable_scr_start (xine_t *xine)
-{
- scr_impl_t *this;
-
- this = calloc(1, sizeof(scr_impl_t));
-
- /* xine scr plugin interface */
- this->scr.interface_version = 3;
- this->scr.set_fine_speed = scr_set_fine_speed;
- this->scr.get_priority = scr_get_priority;
- this->scr.adjust = scr_adjust;
- this->scr.start = scr_start;
- this->scr.get_current = scr_get_current;
- this->scr.exit = scr_exit;
-
- /* tuning / management interface */
- this->ascr.set_speed_tuning = adjustable_scr_speed_tuning;
- this->ascr.set_speed_base = adjustable_scr_speed_base;
- this->ascr.jump = adjustable_scr_jump;
- this->ascr.dispose = adjustable_scr_dispose;
-
- /* initialize */
-
- pthread_mutex_init (&this->lock, NULL);
-
- this->xine = xine;
- this->scr_speed_base = 90000;
-
- adjustable_scr_speed_tuning(&this->ascr, 1.0 );
- scr_set_fine_speed (&this->scr, XINE_SPEED_PAUSE);
-
- /* start and register */
-
- uint64_t time = xine->clock->get_current_time(xine->clock);
- this->scr.start(&this->scr, time);
-
- if (xine->clock->register_scr(xine->clock, &this->scr)) {
- scr_exit(&this->scr);
- return NULL;
- }
-
- return &this->ascr;
-}
diff --git a/xine/adjustable_scr.h b/xine/adjustable_scr.h
deleted file mode 100644
index 61707684..00000000
--- a/xine/adjustable_scr.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * adjustable_scr.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: adjustable_scr.h,v 1.1 2008-12-03 22:50:04 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_ADJUSTABLE_SCR_H_
-#define XINELIBOUTPUT_ADJUSTABLE_SCR_H_
-
-/******************************* SCR *************************************
- *
- * unix System Clock Reference + fine tuning
- *
- * fine tuning is used to change playback speed in live mode
- * to keep in sync with mpeg source
- *************************************************************************/
-
-typedef struct adjustable_scr_s adjustable_scr_t;
-
-struct adjustable_scr_s {
- scr_plugin_t scr;
-
- void (*set_speed_tuning)(adjustable_scr_t *this, double factor);
- void (*set_speed_base) (adjustable_scr_t *this, int hz);
- void (*jump) (adjustable_scr_t *this, int pts);
-
- void (*dispose) (adjustable_scr_t *this);
-};
-
-adjustable_scr_t *adjustable_scr_start (xine_t *xine);
-
-
-#endif /* XINELIBOUTPUT_ADJUSTABLE_SCR_H_ */
diff --git a/xine/demux_xvdr.c b/xine/demux_xvdr.c
deleted file mode 100644
index e68dfa5c..00000000
--- a/xine/demux_xvdr.c
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
- * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * demultiplexer for xineliboutput (xvdr)
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/demux.h>
-
-#include "../xine_input_vdr_mrl.h"
-#include "../tools/mpeg.h"
-#include "../tools/h264.h"
-#include "../tools/pes.h"
-#include "../tools/ts.h"
-
-#include "ts2es.h"
-#include "demux_xvdr_tsdata.h"
-
-/*
- * features
- */
-
-#define VDR_SUBTITLES
-#define TEST_DVB_SPU
-
-/*
- * logging
- */
-
-static const char log_module_demux_xvdr[] = "[demux_vdr] ";
-#define LOG_MODULENAME log_module_demux_xvdr
-#define SysLogLevel iSysLogLevel
-
-#include "../logdefs.h"
-
-#define LOGSPU(x...)
-
-/*
- * constants
- */
-
-#define DISC_TRESHOLD 90000
-#define WRAP_THRESHOLD 120000
-#define PTS_AUDIO 0
-#define PTS_VIDEO 1
-
-
-/* redefine abs as macro to handle 64-bit diffs.
- i guess llabs may not be available everywhere */
-#define abs(x) ( ((x)<0) ? -(x) : (x) )
-
-typedef struct demux_xvdr_s {
- demux_plugin_t demux_plugin;
-
- xine_stream_t *stream;
- fifo_buffer_t *audio_fifo;
- fifo_buffer_t *video_fifo;
-
- input_plugin_t *input;
-
- ts_data_t *ts_data; /* MPEG-TS stuff */
-
- int64_t last_pts[2];
- int64_t last_vpts;
- int status;
- uint32_t video_type;
- uint32_t audio_type;
- uint32_t subtitle_type;
-
- /* current buf_element */
- int64_t pts;
- int64_t dts;
- uint32_t packet_len;
- uint8_t stream_id;
-
- uint8_t send_newpts : 1;
- uint8_t buf_flag_seek : 1;
- uint8_t ffmpeg_mpeg2_decoder : 1;
- uint8_t coreavc_h264_decoder : 1;
- uint8_t bih_posted : 1;
-} demux_xvdr_t ;
-
-typedef struct {
-
- demux_class_t demux_class;
-
- /* class-wide, global variables here */
-
- xine_t *xine;
- config_values_t *config;
-} demux_xvdr_class_t;
-
-
-static const char * get_decoder_name(xine_t *xine, int video_type)
-{
- int streamtype = (video_type >> 16) & 0xFF;
- plugin_node_t *node = xine->plugin_catalog->video_decoder_map[streamtype][0];
- if (node) {
- plugin_info_t *info = node->info;
- if (info)
- return info->id;
- }
- return "";
-}
-
-static void detect_video_decoders(demux_xvdr_t *this)
-{
- if (!strcmp(get_decoder_name(this->stream->xine, BUF_VIDEO_MPEG), "ffmpegvideo"))
- this->ffmpeg_mpeg2_decoder = 1;
- LOGMSG("Using decoder \"%s\" for mpeg2 video",
- this->ffmpeg_mpeg2_decoder ? "FFmpeg" : "libmpeg2");
-
- if (!strcmp(get_decoder_name(this->stream->xine, BUF_VIDEO_H264), "dshowserver"))
- this->coreavc_h264_decoder = 1;
- LOGMSG("Using decoder \"%s\" for H.264 video",
- this->coreavc_h264_decoder ? "dshowserver (CoreAVC)" : "FFmpeg");
-}
-
-static void demux_xvdr_parse_ts(demux_xvdr_t *this, buf_element_t *buf);
-static void demux_xvdr_parse_pes(demux_xvdr_t *this, buf_element_t *buf);
-
-static int32_t parse_video_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-static int32_t parse_audio_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-static int32_t parse_private_stream_1(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-static int32_t parse_padding_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf);
-
-static void pts_wrap_workaround(demux_xvdr_t *this, buf_element_t *buf, int video)
-{
-#ifdef LOG_PES_AV_DIFF
- static int64_t vpts = 0, apts = 0;
- if (video) vpts = buf->pts;
- else apts = buf->pts;
- if (vpts > 0 && apts > 0)
- LOGMSG("pts diff [%d] %d", video, (int)(vpts - apts));
-#endif
-
- /* PTS wrap workaround */
- if (buf->pts >= 0) {
- if (video)
- this->last_vpts = buf->pts;
- else if (buf->pts > INT64_C( 0x40400000 ) &&
- this->last_vpts < INT64_C( 0x40000000 ) &&
- this->last_vpts > INT64_C( 0 )) {
- LOGMSG("VIDEO pts wrap before AUDIO, ignoring audio pts %" PRId64, buf->pts);
- buf->pts = INT64_C(0);
- }
- }
-}
-
-static void check_newpts(demux_xvdr_t *this, buf_element_t *buf, int video )
-{
- pts_wrap_workaround(this, buf, video);
-
- if (buf->pts) {
- int64_t diff = buf->pts - this->last_pts[video];
-
- if (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD)) {
-
- if (this->buf_flag_seek) {
- _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK);
- this->buf_flag_seek = 0;
- } else {
- _x_demux_control_newpts(this->stream, buf->pts, 0);
- }
- this->send_newpts = 0;
-
- this->last_pts[1-video] = 0;
- }
-
- this->last_pts[video] = buf->pts;
- }
-}
-
-static void put_control_buf(fifo_buffer_t *buffer, fifo_buffer_t *pool, int cmd)
-{
- buf_element_t *buf = pool->buffer_pool_try_alloc(pool);
- if(buf) {
- buf->type = cmd;
- buffer->put(buffer, buf);
- }
-}
-
-/*
- * post_sequence_end()
- *
- * Add MPEG2 or H.264 sequence end code to fifo buffer
- */
-static void post_sequence_end(fifo_buffer_t *fifo, uint32_t video_type)
-{
- buf_element_t *buf = fifo->buffer_pool_try_alloc(fifo);
- if (buf) {
- buf->type = video_type;
- buf->size = 4;
- buf->decoder_flags = BUF_FLAG_FRAME_END;
- buf->content[0] = 0x00;
- buf->content[1] = 0x00;
- buf->content[2] = 0x01;
- buf->content[3] = (video_type == BUF_VIDEO_H264) ? NAL_END_SEQ : 0xB7;
- fifo->put(fifo, buf);
- }
-}
-
-/*
- * post_frame_end()
- *
- * Signal end of video frame to decoder.
- *
- * This function is used with:
- * - FFmpeg mpeg2 decoder
- * - FFmpeg and CoreAVC H.264 decoders
- * - NOT with libmpeg2 mpeg decoder
- */
-static void post_frame_end(demux_xvdr_t *this, buf_element_t *vid_buf)
-{
- buf_element_t *cbuf = this->video_fifo->buffer_pool_try_alloc (this->video_fifo) ?:
- this->audio_fifo->buffer_pool_try_alloc (this->audio_fifo);
-
- if (!cbuf) {
- LOGMSG("post_frame_end(): buffer_pool_try_alloc() failed, retrying");
- xine_usec_sleep (10*1000);
- cbuf = this->video_fifo->buffer_pool_try_alloc (this->video_fifo);
- if (!cbuf) {
- LOGERR("post_frame_end(): get_buf_element() failed !");
- return;
- }
- }
-
- cbuf->type = this->video_type;
- cbuf->decoder_flags = BUF_FLAG_FRAME_END;
-
- if (!this->bih_posted) {
- video_size_t size = {0};
- if (pes_get_video_size(vid_buf->content, vid_buf->size, &size, this->video_type == BUF_VIDEO_H264)) {
-
- /* reset decoder buffer */
- cbuf->decoder_flags |= BUF_FLAG_FRAME_START;
-
- /* Fill xine_bmiheader for CoreAVC / H.264 */
-
- if (this->video_type == BUF_VIDEO_H264 && this->coreavc_h264_decoder) {
- xine_bmiheader *bmi = (xine_bmiheader*) cbuf->content;
-
- cbuf->decoder_flags |= BUF_FLAG_HEADER;
- cbuf->decoder_flags |= BUF_FLAG_STDHEADER; /* CoreAVC: buffer contains bmiheader */
- cbuf->size = sizeof(xine_bmiheader);
-
- memset (bmi, 0, sizeof(xine_bmiheader));
-
- bmi->biSize = sizeof(xine_bmiheader);
- bmi->biWidth = size.width;
- bmi->biHeight = size.height;
-
- bmi->biPlanes = 1;
- bmi->biBitCount = 24;
- bmi->biCompression = 0x34363248;
- bmi->biSizeImage = 0;
- bmi->biXPelsPerMeter = size.pixel_aspect.num;
- bmi->biYPelsPerMeter = size.pixel_aspect.den;
- bmi->biClrUsed = 0;
- bmi->biClrImportant = 0;
- }
-
- /* Set aspect ratio for ffmpeg mpeg2 / CoreAVC H.264 decoder
- * (not for FFmpeg H.264 or libmpeg2 mpeg2 decoders)
- */
-
- if (size.pixel_aspect.num &&
- (this->video_type != BUF_VIDEO_H264 || this->coreavc_h264_decoder)) {
- cbuf->decoder_flags |= BUF_FLAG_HEADER;
- cbuf->decoder_flags |= BUF_FLAG_ASPECT;
- /* pixel ratio -> frame ratio */
- if (size.pixel_aspect.num > size.height) {
- cbuf->decoder_info[1] = size.pixel_aspect.num / size.height;
- cbuf->decoder_info[2] = size.pixel_aspect.den / size.width;
- } else {
- cbuf->decoder_info[1] = size.pixel_aspect.num * size.width;
- cbuf->decoder_info[2] = size.pixel_aspect.den * size.height;
- }
- }
-
- LOGDBG("post_frame_end: video width %d, height %d, pixel aspect %d:%d",
- size.width, size.height, size.pixel_aspect.num, size.pixel_aspect.den);
-
- this->bih_posted = 1;
- }
- }
-
- this->video_fifo->put (this->video_fifo, cbuf);
-}
-
-static void track_audio_stream_change(demux_xvdr_t *this, buf_element_t *buf)
-{
-#if !defined(BUF_CONTROL_RESET_TRACK_MAP)
-# warning xine-lib is older than 1.1.2. Multiple audio streams are not supported.
-#else
- if (this->audio_type != buf->type) {
- LOGDBG("audio stream changed: %08x -> %08x", this->audio_type, buf->type);
- this->audio_type = buf->type;
- put_control_buf(this->audio_fifo,
- this->audio_fifo,
- BUF_CONTROL_RESET_TRACK_MAP);
- }
-#endif
-}
-
-static void demux_xvdr_fwd_buf(demux_xvdr_t *this, buf_element_t *buf)
-{
- /* demuxed video --> video_fifo */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) {
- this->video_type = buf->type;
- check_newpts (this, buf, PTS_VIDEO);
- this->video_fifo->put (this->video_fifo, buf);
- return;
- }
-
- /* demuxed audio --> audio_fifo */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_AUDIO_BASE) {
- if (this->audio_fifo) {
- check_newpts (this, buf, PTS_AUDIO);
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- } else {
- buf->free_buffer (buf);
- }
- return;
- }
-
- /* decoder flush --> video_fifo */
- if (buf->type == BUF_CONTROL_FLUSH_DECODER) {
- /* append sequence end code */
- post_sequence_end (this->video_fifo, this->video_type);
- this->video_fifo->put (this->video_fifo, buf);
- return;
- }
-
- /* control buffer --> both fifos */
- if ((buf->type & BUF_MAJOR_MASK) == BUF_CONTROL_BASE) {
- if (this->audio_fifo) {
- /* duplicate goes to audio fifo */
- buf_element_t *cbuf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- cbuf->type = buf->type;
- cbuf->decoder_flags = buf->decoder_flags;
- memcpy (cbuf->decoder_info, buf->decoder_info, sizeof(cbuf->decoder_info));
- memcpy (cbuf->decoder_info_ptr, buf->decoder_info_ptr, sizeof(cbuf->decoder_info_ptr));
-
- this->audio_fifo->put (this->audio_fifo, cbuf);
- }
- this->video_fifo->put (this->video_fifo, buf);
- return;
- }
-
- LOGMSG("Unhandled buffer type %08x", buf->type);
- buf->free_buffer (buf);
-}
-
-static void demux_xvdr_parse_pack (demux_xvdr_t *this)
-{
- buf_element_t *buf = NULL;
- uint8_t *p;
-
- buf = this->input->read_block (this->input, this->video_fifo, 8128);
-
- if (!buf) {
- if (errno == EINTR) {
- /* very verbose logging ? */
- if (iSysLogLevel >= SYSLOGLEVEL_VERBOSE)
- LOGDBG("input->read_block() was interrupted");
- } else if (errno != EAGAIN) {
- LOGDBG("DEMUX_FINISHED (input returns NULL with error)");
- this->status = DEMUX_FINISHED;
- ts_data_dispose(&this->ts_data);
- }
- return;
- }
-
- /* If this is not a block for the demuxer, pass it
- * straight through. */
- if (buf->type != BUF_DEMUX_BLOCK) {
- ts_data_flush (this->ts_data);
- demux_xvdr_fwd_buf (this, buf);
- return;
- }
-
- p = buf->content; /* len = this->blocksize; */
- buf->decoder_flags = 0;
-
- if (DATA_IS_TS(p)) {
- demux_xvdr_parse_ts (this, buf);
- return;
- }
- if (DATA_IS_PES(p)) {
- demux_xvdr_parse_pes (this, buf);
- return;
- }
-
- LOGMSG("Header %02x %02x %02x (should be 0x000001 or 0x47)", p[0], p[1], p[2]);
- buf->free_buffer (buf);
- return;
-}
-
-static void demux_xvdr_parse_pes (demux_xvdr_t *this, buf_element_t *buf)
-{
- uint8_t *p = buf->content;
- int32_t result;
-
- this->stream_id = p[3];
-
- if (IS_VIDEO_PACKET(p)) {
- result = parse_video_stream(this, p, buf);
- } else if (IS_MPEG_AUDIO_PACKET(p)) {
- result = parse_audio_stream(this, p, buf);
- } else if (IS_PADDING_PACKET(p)) {
- result = parse_padding_stream(this, p, buf);
- } else if (IS_PS1_PACKET(p)) {
- result = parse_private_stream_1(this, p, buf);
- } else {
- LOGMSG("Unrecognised PES stream 0x%02x", this->stream_id);
- buf->free_buffer (buf);
- return;
- }
-
- if (result < 0) {
- return;
- }
-
- LOGMSG("error! freeing buffer.");
- buf->free_buffer (buf);
-}
-
-/*
- * demux_xvdr_parse_ts()
- *
- * MPEG-TS demuxing
- */
-static void demux_xvdr_parse_ts (demux_xvdr_t *this, buf_element_t *buf)
-{
- if (!this->ts_data)
- this->ts_data = calloc(1, sizeof(ts_data_t));
-
- ts_data_t *ts_data = this->ts_data;
- fifo_buffer_t *src_fifo = buf->source;
-
- while (buf->size >= TS_SIZE) {
-
- unsigned int ts_pid = ts_PID(buf->content);
-
- /* parse PAT */
- if (ts_pid == 0) {
- pat_data_t pat;
-
- ts_data_flush(ts_data);
-
- if (ts_parse_pat(&pat, buf->content)) {
- ts_data->pmt_pid = pat.pmt_pid[0];
- ts_data->program_number = pat.program_number[0];
- if (iSysLogLevel >= SYSLOGLEVEL_VERBOSE)
- LOGDBG("Got PAT, PMT pid = %d, program = %d", ts_data->pmt_pid, ts_data->program_number);
- }
- }
-
- /* parse PMT */
- else if (ts_pid == ts_data->pmt_pid) {
-
- ts_data_flush(ts_data);
-
- if (ts_parse_pmt(&ts_data->pmt, ts_data->program_number, buf->content)) {
-
- /* PMT changed, reset ts->es converters */
- LOGMSG("PMT changed");
- ts_data_ts2es_init(&ts_data, this->stream->video_fifo, this->stream->audio_fifo);
-
- this->video_type = (ts_data->pmt.video_type == ISO_14496_PART10_VIDEO) ?
- BUF_VIDEO_H264 : BUF_VIDEO_MPEG;
-
- /* Inform UI of channels changes */
- xine_event_t event;
- event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
- event.data_length = 0;
- xine_event_send(this->stream, &event);
- }
- }
-
- /* demux video */
- else if (ts_pid == ts_data->pmt.video_pid) {
- if (ts_data->video) {
- buf_element_t *vbuf = ts2es_put(ts_data->video, buf->content, src_fifo);
- if (vbuf) {
- this->pts = vbuf->pts;
- check_newpts( this, vbuf, PTS_VIDEO );
-
- this->stream->video_fifo->put(this->stream->video_fifo, vbuf);
- }
- }
- }
-
- /* demux audio */
- else {
- int i, done = 0;
- for (i=0; i < ts_data->pmt.audio_tracks_count; i++)
- if (ts_pid == ts_data->pmt.audio_tracks[i].pid) {
- if (ts_data->audio[i]) {
- buf_element_t *abuf = ts2es_put(ts_data->audio[i], buf->content, src_fifo);
- if (abuf) {
- this->pts = abuf->pts;
- check_newpts( this, abuf, PTS_AUDIO );
- track_audio_stream_change (this, abuf);
-
- this->stream->audio_fifo->put(this->stream->audio_fifo, abuf);
- }
- }
- done = 1;
- break;
- }
-#if 0
- /* demux subtitles */
- if (!done)
- for (i=0; i < ts_data->pmt.spu_tracks_count; i++)
- if (ts_pid == ts_data->pmt.spu_tracks[i].pid) {
- if (ts_data->spu[i]) {
- buf_element_t *sbuf = ts2es_put(ts_data->spu[i], buf->content, NULL);
- if (sbuf)
- this->stream->video_fifo->put(this->stream->video_fifo, sbuf);
- }
- done = 1;
- break;
- }
-
- if (!done)
- LOGMSG("Got unknown TS packet, pid = %d", ts_pid);
-#endif
- }
-
- buf->content += TS_SIZE;
- buf->size -= TS_SIZE;
- }
-
- buf->free_buffer(buf);
-}
-
-static int32_t parse_padding_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- buf->free_buffer (buf);
- return -1;
-}
-
-/* FIXME: Extension data is not parsed, and is also not skipped. */
-
-static int32_t parse_pes_for_pts(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int32_t header_len;
-
- this->packet_len = p[4] << 8 | p[5];
-
- if ((p[6] & 0xC0) != 0x80 /* mpeg1 */) {
- header_len = 6;
- p += 6; /* packet_len -= 6; */
-
- while ((p[0] & 0x80) == 0x80) {
- p++;
- header_len++;
- this->packet_len--;
- }
-
- if ((p[0] & 0xc0) == 0x40) {
- /* STD_buffer_scale, STD_buffer_size */
- p += 2;
- header_len += 2;
- this->packet_len -= 2;
- }
-
- this->pts = 0;
- this->dts = 0;
-
- if ((p[0] & 0xf0) == 0x20) {
- this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ;
- this->pts |= p[ 1] << 22 ;
- this->pts |= (p[ 2] & 0xFE) << 14 ;
- this->pts |= p[ 3] << 7 ;
- this->pts |= (p[ 4] & 0xFE) >> 1 ;
- p += 5;
- header_len+= 5;
- this->packet_len -=5;
- return header_len;
- } else if ((p[0] & 0xf0) == 0x30) {
- this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ;
- this->pts |= p[ 1] << 22 ;
- this->pts |= (p[ 2] & 0xFE) << 14 ;
- this->pts |= p[ 3] << 7 ;
- this->pts |= (p[ 4] & 0xFE) >> 1 ;
-
- this->dts = (int64_t)(p[ 5] & 0x0E) << 29 ;
- this->dts |= p[ 6] << 22 ;
- this->dts |= (p[ 7] & 0xFE) << 14 ;
- this->dts |= p[ 8] << 7 ;
- this->dts |= (p[ 9] & 0xFE) >> 1 ;
-
- p += 10;
- header_len += 10;
- this->packet_len -= 10;
- return header_len;
- } else {
- p++;
- header_len++;
- this->packet_len--;
- return header_len;
- }
-
- } else { /* mpeg 2 */
-
-
- if ((p[6] & 0xC0) != 0x80) {
- LOGMSG("warning: PES header reserved 10 bits not found");
- buf->free_buffer(buf);
- return -1;
- }
-
-
- /* check PES scrambling_control */
- if ((p[6] & 0x30) != 0) {
- LOGMSG("encrypted PES ?");
- buf->free_buffer(buf);
- return -1;
- }
-
- if (p[7] & 0x80) { /* pts avail */
-
- this->pts = (int64_t)(p[ 9] & 0x0E) << 29 ;
- this->pts |= p[10] << 22 ;
- this->pts |= (p[11] & 0xFE) << 14 ;
- this->pts |= p[12] << 7 ;
- this->pts |= (p[13] & 0xFE) >> 1 ;
-
- } else
- this->pts = 0;
-
- if (p[7] & 0x40) { /* dts avail */
-
- this->dts = (int64_t)(p[14] & 0x0E) << 29 ;
- this->dts |= p[15] << 22 ;
- this->dts |= (p[16] & 0xFE) << 14 ;
- this->dts |= p[17] << 7 ;
- this->dts |= (p[18] & 0xFE) >> 1 ;
-
- } else
- this->dts = 0;
-
-
- header_len = p[8];
-
- this->packet_len -= header_len + 3;
- return header_len + 9;
- }
- return 0;
-}
-
-#if defined(TEST_DVB_SPU)
-/*
- * parse_dvb_spu()
- *
- * DVB subtitle stream demuxing
- */
-static int32_t parse_dvb_spu(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf, int substream_header_len)
-{
- uint spu_id = p[0] & 0x1f;
- _x_select_spu_channel(this->stream, spu_id);
-
-# ifdef VDR_SUBTITLES
- if (substream_header_len == 1) {
- p--;
- this->packet_len++;
- }
-# endif /* VDR_SUBTITLES */
-
- /* Skip substream header */
- p += substream_header_len;
- buf->content = p;
- buf->size = this->packet_len - substream_header_len;
-
- /* Special buffer when payload packet changes */
- if (this->pts > 0) {
- buf_element_t *cbuf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
- int page_id = (*(p+4) << 8) | *(p+5);
-
- spu_dvb_descriptor_t *spu_descriptor = (spu_dvb_descriptor_t *) cbuf->content;
- memset(spu_descriptor, 0, sizeof(spu_dvb_descriptor_t));
- spu_descriptor->comp_page_id = page_id;
-
- cbuf->type = BUF_SPU_DVB + spu_id;
- cbuf->size = 0;
- cbuf->decoder_flags = BUF_FLAG_SPECIAL;
- cbuf->decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR;
- cbuf->decoder_info[2] = sizeof(spu_dvb_descriptor_t);
- cbuf->decoder_info_ptr[2] = spu_descriptor;
-
- this->video_fifo->put (this->video_fifo, cbuf);
- }
-
- buf->type = BUF_SPU_DVB + spu_id;
- buf->pts = this->pts;
- buf->decoder_info[2] = this->pts > 0 ? 0xffff : 0; /* hack - size unknown here (?) */
-
- this->video_fifo->put (this->video_fifo, buf);
-
- return -1;
-}
-
-int detect_dvb_spu(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- LOGSPU("%s%02x %02x %02x %02x %02x %02x %02x %02x",
- this->pts>0?"* ":" ",p[0], p[1], p[2], p[3],
- p[4], p[5], p[6], p[7]);
-
- /* If PES packet has PTS, it starts new subtitle (ES) packet. */
- if (this->pts > 0) {
- /* Reset SPU type */
- this->subtitle_type = 0;
- }
-
-# ifdef VDR_SUBTITLES
- /* Compatibility mode for old subtitles plugin */
- if (this->subtitle_type != BUF_SPU_DVD) {
- if ((buf->content[7] & 0x01) && (p[-3] & 0x81) == 0x01 && p[-2] == 0x81) {
- LOGDBG("DVB SPU: Old vdr-subtitles compability mode");
- return parse_dvb_spu(this, p, buf, 1);
- }
- }
-# endif /* VDR_SUBTITLES */
-
- /* Start of subtitle packet. Guess substream type */
- if (this->pts > 0) {
- if (p[4] == 0x20 && p[5] == 0x00 && (p[6] == 0x0f || p[4] == 0x0f)) {
- this->subtitle_type = BUF_SPU_DVB;
- LOGSPU(" -> DVB SPU");
- } else if (p[2] || (p[3] & 0xfe)) {
- this->subtitle_type = BUF_SPU_DVD;
- LOGSPU(" -> DVD SPU");
- } else {
- this->subtitle_type = BUF_SPU_DVD;
- LOGMSG(" -> DV? SPU -> DVD");
- }
- }
-
- /* DVD SPU ? */
- if (this->subtitle_type == BUF_SPU_DVD)
- return this->packet_len;
-
- /* DVB SPU */
- return parse_dvb_spu(this, p, buf, 4);
-}
-
-#endif /* TEST_DVB_SPU */
-
-static int32_t parse_private_stream_1(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int track, spu_id;
- int32_t result;
-
- result = parse_pes_for_pts(this, p, buf);
- if (result < 0) return -1;
-
- p += result;
-
- /* SPU */
- if ((p[0] & 0xE0) == 0x20) {
- spu_id = (p[0] & 0x1f);
-
- if (this->pts <= 0 && !this->subtitle_type) {
- /* need whole ES packet (after seek etc.) */
- buf->free_buffer(buf);
- return -1;
- }
-
-#ifdef TEST_DVB_SPU
- if (detect_dvb_spu(this, p, buf) < 0)
- return -1;
-#endif /* TEST_DVB_SPU */
- this->subtitle_type = BUF_SPU_DVD;
-
- /* DVD SPU */
- buf->content = p+1;
- buf->size = this->packet_len-1;
-
- buf->type = BUF_SPU_DVD + spu_id;
- buf->decoder_flags |= BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
- buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
- buf->pts = this->pts;
-
- this->video_fifo->put (this->video_fifo, buf);
-
- return -1;
- }
-
- if ((p[0]&0xF0) == 0x80) {
-
- track = p[0] & 0x0F; /* hack : ac3 track */
-
- buf->decoder_info[1] = p[1]; /* Number of frame headers */
- buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */
-
- buf->content = p+4;
- buf->size = this->packet_len-4;
- if (track & 0x8) {
- buf->type = BUF_AUDIO_DTS + (track & 0x07); /* DVDs only have 8 tracks */
- } else {
- buf->type = BUF_AUDIO_A52 + track;
- }
- buf->pts = this->pts;
-
- if (this->audio_fifo) {
- check_newpts( this, buf, PTS_AUDIO );
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- return -1;
- } else {
- buf->free_buffer(buf);
- return -1;
- }
-
- } else if ((p[0]&0xf0) == 0xa0) {
-
- int pcm_offset;
- int number_of_frame_headers;
- int first_access_unit_pointer;
- int audio_frame_number;
- int bits_per_sample;
- int sample_rate;
- int num_channels;
- int dynamic_range;
-
- /*
- * found in http://members.freemail.absa.co.za/ginggs/dvd/mpeg2_lpcm.txt
- * appears to be correct.
- */
-
- track = p[0] & 0x0F;
- number_of_frame_headers = p[1];
- /* unknown = p[2]; */
- first_access_unit_pointer = p[3];
- audio_frame_number = p[4];
-
- /*
- * 000 => mono
- * 001 => stereo
- * 010 => 3 channel
- * ...
- * 111 => 8 channel
- */
- num_channels = (p[5] & 0x7) + 1;
- sample_rate = p[5] & 0x10 ? 96000 : 48000;
- switch ((p[5]>>6) & 3) {
- case 3: /* illegal, use 16-bits? */
- default:
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "illegal lpcm sample format (%d), assume 16-bit samples\n", (p[5]>>6) & 3 );
- case 0: bits_per_sample = 16; break;
- case 1: bits_per_sample = 20; break;
- case 2: bits_per_sample = 24; break;
- }
- dynamic_range = p[6];
-
- /* send lpcm config byte */
- buf->decoder_flags |= BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG;
- buf->decoder_info[2] = p[5];
-
- pcm_offset = 7;
-
- buf->content = p+pcm_offset;
- buf->size = this->packet_len-pcm_offset;
- buf->type = BUF_AUDIO_LPCM_BE + track;
- buf->pts = this->pts;
-
- if (this->audio_fifo) {
- check_newpts( this, buf, PTS_AUDIO );
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- return -1;
- } else {
- buf->free_buffer(buf);
- return -1;
- }
- }
-
- buf->free_buffer(buf);
- return -1;
-}
-
-/*
- * detect_h264()
- *
- * Detect video codec (MPEG2 or H.264)
- */
-static int detect_h264(uint8_t *data)
-{
- /* H.264 detection */
- if (data[0] == 0 && data[1] == 0 && data[2] == 1) {
- if (data[3] == NAL_AUD) {
- LOGMSG("H.264 scanner: Possible H.264 NAL AUD");
- return BUF_VIDEO_H264;
- }
- if (data[3] == 0) {
- LOGDBG("H.264 scanner: Possible MPEG2 start code PICTURE (0x00)");
- return BUF_VIDEO_MPEG;
- }
- if (data[3] >= 0x80) {
- LOGDBG("H.264 scanner: Possible MPEG2 start code (0x%02x)", data[3]);
- return BUF_VIDEO_MPEG;
- }
- LOGMSG("H.264 scanner: Unregonized header 00 00 01 %02x", data[3]);
- }
-
- return 0;
-}
-
-static int32_t parse_video_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int32_t result;
-
- result = parse_pes_for_pts(this, p, buf);
- if (result < 0) return -1;
-
- p += result;
-
- if (this->video_type == 0) {
- this->video_type = detect_h264(p);
- }
-
- buf->type = this->video_type ?: BUF_VIDEO_MPEG;
- buf->pts = this->pts;
- buf->decoder_info[0] = this->pts - this->dts;
-
- /* MPEG2 */
- if (this->video_type == BUF_VIDEO_MPEG) {
- /* Special handling for FFMPEG MPEG2 decoder */
- if (this->ffmpeg_mpeg2_decoder) {
- uint8_t type = pes_get_picture_type(buf->content, buf->size);
- if (type) {
- /* signal FRAME_END to decoder */
- post_frame_end(this, buf);
- /* for some reason ffmpeg mpeg2 decoder does not understand pts'es in B frames ?
- * (B-frame pts's are smaller than in previous P-frame)
- * Anyway, without this block of code B frames with pts are dropped. */
- if (type == B_FRAME)
- buf->pts = 0;
- }
- }
- }
-
- /* H.264 */
- else if (this->video_type == BUF_VIDEO_H264) {
- /* Access Unit Delimiter */
- if (IS_NAL_AUD(p))
- post_frame_end (this, buf);
-
- /* Check for end of still image.
- VDR ensures that H.264 still images end with an end of sequence NAL unit */
- if (buf->size > 4) {
- uint8_t *end = buf->content + buf->size;
- if (IS_NAL_END_SEQ(end-4)) {
- LOGMSG("post_frame_h264: Still frame ? (frame ends with end of sequence NAL unit)");
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
- }
- }
- }
-
- buf->content = p;
- buf->size = this->packet_len;
-
- check_newpts( this, buf, PTS_VIDEO );
-
- this->video_fifo->put (this->video_fifo, buf);
-
- return -1;
-}
-
-static int32_t parse_audio_stream(demux_xvdr_t *this, uint8_t *p, buf_element_t *buf)
-{
- int track;
- int32_t result;
-
- result = parse_pes_for_pts(this, p, buf);
- if (result < 0) return -1;
-
- p += result;
-
- track = this->stream_id & 0x1f;
-
- buf->content = p;
- buf->size = this->packet_len;
- buf->type = BUF_AUDIO_MPEG + track;
- buf->pts = this->pts;
-
- if (this->audio_fifo) {
- check_newpts( this, buf, PTS_AUDIO );
- track_audio_stream_change (this, buf);
- this->audio_fifo->put (this->audio_fifo, buf);
- } else {
- buf->free_buffer(buf);
- }
-
- return -1;
-}
-
-/*
- * interface
- */
-
-static int demux_xvdr_send_chunk (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- demux_xvdr_parse_pack(this);
-
- return this->status;
-}
-
-static void demux_xvdr_dispose (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- LOGDBG("demux_xvdr_dispose()");
-
- ts_data_dispose(&this->ts_data);
-
- free (this);
-}
-
-static int demux_xvdr_get_status (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- if (this->status != DEMUX_OK) {
- if (this->ts_data) {
- LOGMSG("demux_xvdr_get_status(): status != DEMUX_OK. -> freeing ts_data");
- ts_data_dispose(&this->ts_data);
- }
- }
-
- return this->status;
-}
-
-static void demux_xvdr_send_headers (demux_plugin_t *this_gen)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- this->video_fifo = this->stream->video_fifo;
- this->audio_fifo = this->stream->audio_fifo;
-
- /*
- * send start buffer
- */
-
- _x_demux_control_start(this->stream);
-
- this->status = DEMUX_OK;
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, 5000000);
-}
-
-
-static int demux_xvdr_seek (demux_plugin_t *this_gen,
- off_t start_pos, int start_time, int playing)
-{
- demux_xvdr_t *this = (demux_xvdr_t *) this_gen;
-
- /*
- * now start demuxing
- */
- this->send_newpts = 1;
- this->video_type = 0;
- this->audio_type = 0;
- this->subtitle_type = 0;
- this->bih_posted = 0;
- ts_data_dispose(&this->ts_data);
-
- if (!playing) {
-
- this->buf_flag_seek = 0;
- this->status = DEMUX_OK;
- this->last_pts[0] = 0;
- this->last_pts[1] = 0;
- } else {
- this->buf_flag_seek = 1;
- this->last_vpts = INT64_C(-1);
- _x_demux_flush_engine(this->stream);
- }
-
- return this->status;
-}
-
-/*
- * demux class
- */
-
-static int demux_xvdr_get_stream_length (demux_plugin_t *this_gen)
-{
- return 0;
-}
-
-static uint32_t demux_xvdr_get_capabilities(demux_plugin_t *this_gen)
-{
- return DEMUX_CAP_NOCAP;
-}
-
-static int demux_xvdr_get_optional_data(demux_plugin_t *this_gen,
- void *data, int data_type)
-{
- return DEMUX_OPTIONAL_UNSUPPORTED;
-}
-
-static demux_plugin_t *demux_xvdr_open_plugin (demux_class_t *class_gen,
- xine_stream_t *stream,
- input_plugin_t *input_gen)
-{
- input_plugin_t *input = (input_plugin_t *) input_gen;
- demux_xvdr_t *this;
- const char *mrl = input->get_mrl(input);
-
- if (strncmp(mrl, MRL_ID ":/", MRL_ID_LEN + 2 ) &&
- strncmp(mrl, MRL_ID "+pipe://", MRL_ID_LEN + 8) &&
- strncmp(mrl, MRL_ID "+tcp://", MRL_ID_LEN + 7) &&
- strncmp(mrl, MRL_ID "+udp://", MRL_ID_LEN + 7) &&
- strncmp(mrl, MRL_ID "+rtp://", MRL_ID_LEN + 7))
- return NULL;
-
- this = calloc(1, sizeof(demux_xvdr_t));
- this->stream = stream;
- this->input = input;
-
- this->demux_plugin.send_headers = demux_xvdr_send_headers;
- this->demux_plugin.send_chunk = demux_xvdr_send_chunk;
- this->demux_plugin.seek = demux_xvdr_seek;
- this->demux_plugin.dispose = demux_xvdr_dispose;
- this->demux_plugin.get_status = demux_xvdr_get_status;
- this->demux_plugin.get_stream_length = demux_xvdr_get_stream_length;
- this->demux_plugin.get_capabilities = demux_xvdr_get_capabilities;
- this->demux_plugin.get_optional_data = demux_xvdr_get_optional_data;
- this->demux_plugin.demux_class = class_gen;
-
- this->status = DEMUX_FINISHED;
-
- detect_video_decoders(this);
-
- return &this->demux_plugin;
-}
-
-#if DEMUXER_PLUGIN_IFACE_VERSION < 27
-static const char *demux_xvdr_get_description (demux_class_t *this_gen)
-{
- return MRL_ID " demux plugin";
-}
-
-static const char *demux_xvdr_get_identifier (demux_class_t *this_gen)
-{
- return MRL_ID;
-}
-
-static const char *demux_xvdr_get_extensions (demux_class_t *this_gen)
-{
- return NULL;
-}
-
-static const char *demux_xvdr_get_mimetypes (demux_class_t *this_gen)
-{
- return NULL;
-}
-
-static void demux_xvdr_class_dispose (demux_class_t *this_gen)
-{
- demux_xvdr_class_t *this = (demux_xvdr_class_t *) this_gen;
-
- free (this);
-}
-#endif
-
-void *demux_xvdr_init_class (xine_t *xine, void *data)
-{
- demux_xvdr_class_t *this;
-
- this = calloc(1, sizeof(demux_xvdr_class_t));
- this->config = xine->config;
- this->xine = xine;
-
- this->demux_class.open_plugin = demux_xvdr_open_plugin;
-#if DEMUXER_PLUGIN_IFACE_VERSION < 27
- this->demux_class.get_description = demux_xvdr_get_description;
- this->demux_class.get_identifier = demux_xvdr_get_identifier;
- this->demux_class.get_mimetypes = demux_xvdr_get_mimetypes;
- this->demux_class.get_extensions = demux_xvdr_get_extensions;
- this->demux_class.dispose = demux_xvdr_class_dispose;
-#else
- this->demux_class.description = N_("XVDR demux plugin");
- this->demux_class.identifier = MRL_ID;
- this->demux_class.mimetypes = NULL;
- this->demux_class.extensions =
- MRL_ID":/ "
- MRL_ID"+pipe:/ "
- MRL_ID"+tcp:/ "
- MRL_ID"+udp:/ "
- MRL_ID"+rtp:/ "
- MRL_ID"+slave:/";
- this->demux_class.dispose = default_demux_class_dispose;
-#endif
-
- return this;
-}
-
-
diff --git a/xine/demux_xvdr_tsdata.c b/xine/demux_xvdr_tsdata.c
deleted file mode 100644
index 38904a97..00000000
--- a/xine/demux_xvdr_tsdata.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * demux_xvdr_tsdata.h: data for MPEG-TS demuxer
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: demux_xvdr_tsdata.c,v 1.1 2009-02-24 19:50:42 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/buffer.h>
-
-#define LOG_MODULENAME "[demux_vdr] "
-#define SysLogLevel iSysLogLevel
-#include "../logdefs.h"
-
-#include "../tools/ts.h"
-#include "ts2es.h"
-
-#include "demux_xvdr_tsdata.h"
-
-static void ts_data_ts2es_reset(ts_data_t *ts_data)
-{
- int i;
-
- ts2es_dispose(ts_data->video);
- ts_data->video = NULL;
-
- for (i = 0; ts_data->audio[i]; i++) {
- ts2es_dispose(ts_data->audio[i]);
- ts_data->audio[i] = NULL;
- }
-
- for (i = 0; ts_data->spu[i]; i++) {
- ts2es_dispose(ts_data->spu[i]);
- ts_data->spu[i] = NULL;
- }
-}
-
-void ts_data_ts2es_init(ts_data_t **ts_data, fifo_buffer_t *video_fifo, fifo_buffer_t *audio_fifo)
-{
- if (*ts_data)
- ts_data_ts2es_reset(*ts_data);
- else
- *ts_data = calloc (1, sizeof(ts_data_t));
-
- ts_data_t *this = *ts_data;
- int i;
-
- if (video_fifo) {
- if (this->pmt.video_pid != INVALID_PID)
- this->video = ts2es_init(video_fifo, this->pmt.video_type, 0);
-
- for (i=0; i < this->pmt.spu_tracks_count; i++)
- this->spu[i] = ts2es_init(video_fifo, STREAM_DVBSUB, i);
- }
-
- if (audio_fifo) {
- for (i=0; i < this->pmt.audio_tracks_count; i++)
- this->audio[i] = ts2es_init(audio_fifo, this->pmt.audio_tracks[i].type, i);
- }
-}
-
-void ts_data_flush(ts_data_t *ts_data)
-{
- if (ts_data) {
- int i;
-
- if (ts_data->video)
- ts2es_flush(ts_data->video);
-
- for (i = 0; ts_data->audio[i]; i++)
- ts2es_flush(ts_data->audio[i]);
-
- for (i = 0; ts_data->spu[i]; i++)
- ts2es_flush(ts_data->spu[i]);
- }
-}
-
-void ts_data_dispose(ts_data_t **ts_data)
-{
- if (*ts_data) {
-
- ts_data_ts2es_reset(*ts_data);
-
- free(*ts_data);
- *ts_data = NULL;
- }
-}
diff --git a/xine/demux_xvdr_tsdata.h b/xine/demux_xvdr_tsdata.h
deleted file mode 100644
index 96a1b893..00000000
--- a/xine/demux_xvdr_tsdata.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * demux_xvdr_tsdata.h: data for MPEG-TS demuxer
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: demux_xvdr_tsdata.h,v 1.1 2009-02-24 19:50:42 phintuka Exp $
- *
- */
-
-#ifndef _DEMUX_XVDR_TSDATA_H_
-#define _DEMUX_XVDR_TSDATA_H_
-
-struct ts2es_s;
-
-struct ts_data_s {
- uint16_t pmt_pid;
- uint16_t program_number;
-
- pmt_data_t pmt;
-
- struct ts2es_s *video;
- struct ts2es_s *audio[TS_MAX_AUDIO_TRACKS];
- struct ts2es_s *spu[TS_MAX_SPU_TRACKS];
-};
-
-typedef struct ts_data_s ts_data_t;
-
-void ts_data_ts2es_init (ts_data_t **ts_data, fifo_buffer_t *video_fifo, fifo_buffer_t *audio_fifo);
-void ts_data_flush (ts_data_t *ts_data);
-void ts_data_dispose (ts_data_t **ts_data);
-
-
-#endif /* _DEMUX_XVDR_TSDATA_H_ */
diff --git a/xine/osd_manager.c b/xine/osd_manager.c
deleted file mode 100644
index a7d0d6b4..00000000
--- a/xine/osd_manager.c
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * osd_manager.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: osd_manager.c,v 1.13 2009-06-02 14:17:05 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-#include <pthread.h>
-
-#define XINE_ENGINE_INTERNAL
-#include <xine/xine_internal.h>
-#include <xine/video_out.h>
-
-#include "../xine_osd_command.h"
-#include "../xine_input_vdr.h"
-
-#include "../tools/rle.h"
-
-#include "vo_props.h"
-#include "osd_manager.h"
-
-/*#define LOGOSD(x...) LOGMSG(x)*/
-#define LOGOSD(x...)
-
-static const char log_module_input_osd[] = "[input_osd] ";
-#define LOG_MODULENAME log_module_input_osd
-#define SysLogLevel iSysLogLevel
-
-#include "../logdefs.h"
-
-
-typedef struct {
- int handle; /* xine-lib overlay handle */
- osd_command_t cmd; /* Full OSD data: last OSD_Set_RLE event */
-
- uint16_t extent_width; /* output size this OSD was designed for */
- uint16_t extent_height;
-
- int64_t last_changed_vpts;
-} osd_data_t;
-
-typedef struct osd_manager_impl_s {
- osd_manager_t mgr;
-
- pthread_mutex_t lock;
- uint8_t ticket_acquired;
- xine_stream_t *stream;
-
- uint16_t video_width;
- uint16_t video_height;
- uint8_t vo_scaling;
-
- osd_data_t osd[MAX_OSD_OBJECT];
-
-} osd_manager_impl_t;
-
-/************************************* Tools ************************************/
-
-/*
- * acquire_ticket()
- */
-static void acquire_ticket(osd_manager_impl_t *this)
-{
- if (!this->ticket_acquired) {
- this->stream->xine->port_ticket->acquire(this->stream->xine->port_ticket, 1);
- this->ticket_acquired = 1;
- }
-}
-
-static void release_ticket(osd_manager_impl_t *this)
-{
- if (this->ticket_acquired) {
- this->stream->xine->port_ticket->release(this->stream->xine->port_ticket, 1);
- this->ticket_acquired = 0;
- }
-}
-
-/*
- * get_overlay_manager()
- */
-video_overlay_manager_t *get_ovl_manager(osd_manager_impl_t *this)
-{
- /* Get overlay manager. We need ticket ... */
- acquire_ticket(this);
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
- if (!ovl_manager) {
- LOGMSG("Stream has no overlay manager !");
- return NULL;
- }
- return ovl_manager;
-}
-
-/*
- * palette_argb_to_ayuv()
- */
-
-#define saturate(x,min,max) ( (x)<(min) ? (min) : (x)>(max) ? (max) : (x))
-
-static void palette_argb_to_ayuv(xine_clut_t *clut, int colors)
-{
- if (clut && colors>0) {
- int c;
- for (c=0; c<colors; c++) {
- int R = clut[c].r;
- int G = clut[c].g;
- int B = clut[c].b;
- int Y = (( + 66*R + 129*G + 25*B + 0x80) >> 8) + 16;
- int CR = (( + 112*R - 94*G - 18*B + 0x80) >> 8) + 128;
- int CB = (( - 38*R - 74*G + 112*B + 0x80) >> 8) + 128;
- clut[c].y = saturate( Y, 16, 235);
- clut[c].cb = saturate(CB, 16, 240);
- clut[c].cr = saturate(CR, 16, 240);
- }
- }
-}
-
-/*
- * clear_osdcmd()
- *
- * - free allocated memory from osd_command_t
- */
-static void clear_osdcmd(osd_command_t *cmd)
-{
- free(cmd->data);
- cmd->data = NULL;
- free(cmd->palette);
- cmd->palette = NULL;
-}
-
-/*
- * osdcmd_to_overlay()
- *
- * - fill xine-lib vo_overlay_t from osd_command_t
- */
-static void osdcmd_to_overlay(vo_overlay_t *ovl, osd_command_t *cmd)
-{
- int i;
-
- ovl->rle = (rle_elem_t*)cmd->data;
- ovl->data_size = cmd->datalen;
- ovl->num_rle = cmd->datalen / 4;
-
- ovl->x = cmd->x;
- ovl->y = cmd->y;
- ovl->width = cmd->w;
- ovl->height = cmd->h;
-
- /* palette */
- for (i=0; i<cmd->colors; i++) {
- ovl->color[i] = (*(uint32_t*)(cmd->palette + i)) & 0x00ffffff;
- ovl->trans[i] = (cmd->palette[i].alpha + 0x7)/0xf;
- }
- ovl->rgb_clut = cmd->flags & OSDFLAG_YUV_CLUT ? 0 : 1;
-
- ovl->unscaled = cmd->flags & OSDFLAG_UNSCALED ? 1 : 0;
-
- ovl->hili_top = ovl->hili_bottom = ovl->hili_left = ovl->hili_right = -1;
-}
-
-/*
- * osdcmd_scale()
- *
- * Scale OSD_Set_RLE data
- * - modified fields: x, y, w, h, (RLE) data and datalen
- * - old RLE data is stored to osd_data_t *osd
- */
-static void osdcmd_scale(osd_manager_impl_t *this, osd_command_t *cmd,
- osd_data_t *osd, int output_width, int output_height)
-{
- LOGOSD("Size out of margins, rescaling rle image");
-
- /* new position and size */
- int new_x = cmd->x * this->video_width / osd->extent_width;
- int new_y = cmd->y * this->video_height / osd->extent_height;
- int x2 = cmd->x + cmd->w + 1;
- int y2 = cmd->y + cmd->h + 1;
- x2 = ((x2+1) * this->video_width - 1) / osd->extent_width;
- y2 = ((y2+1) * this->video_height - 1) / osd->extent_height;
- int new_w = x2 - new_x - 1;
- int new_h = y2 - new_y - 1;
-
- /* store original RLE data */
- osd->cmd.data = cmd->data;
- osd->cmd.datalen = cmd->datalen;
-
- /* scale */
- int rle_elems = cmd->datalen / sizeof(xine_rle_elem_t);
- cmd->data = rle_scale_nearest(cmd->data, &rle_elems, cmd->w, cmd->h,
- new_w, new_h);
- cmd->datalen = rle_elems * sizeof(xine_rle_elem_t);
-
- cmd->x = new_x;
- cmd->y = new_y;
- cmd->w = new_w;
- cmd->h = new_h;
-}
-
-/*
- * osd_exec_vpts()
- *
- * - calculate execution time (vpts) for OSD update
- */
-static int64_t osd_exec_vpts(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- int64_t vpts = 0; /* now */
-
- /* calculate exec time */
- if (cmd->pts || cmd->delay_ms) {
- int64_t now = xine_get_current_vpts(this->stream);
-
- if (cmd->pts)
- vpts = cmd->pts + this->stream->metronom->get_option(this->stream->metronom, METRONOM_VPTS_OFFSET);
- else
- vpts = this->osd[cmd->wnd].last_changed_vpts + cmd->delay_ms*90;
-
- /* execution time must be in future */
- if (vpts < now)
- vpts = 0;
-
- /* limit delay to 5 seconds */
- if (vpts > now + 5*90000)
- vpts = vpts + 5*90000;
-
- LOGOSD("OSD Command %d scheduled to +%dms", cmd->cmd, (int)(vpts>now ? vpts-now : 0)/90);
- }
-
- return vpts;
-}
-
-/***************************** OSD command handlers *****************************/
-
-/*
- * exec_osd_size()
- *
- * - set the assumed full OSD size
- */
-static int exec_osd_size(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- osd_data_t *osd = &this->osd[cmd->wnd];
- osd->extent_width = cmd->w;
- osd->extent_height = cmd->h;
-
- acquire_ticket(this);
-
- xine_video_port_t *video_out = this->stream->video_out;
- this->vo_scaling = 0;
- if (video_out->get_capabilities(video_out) & VO_CAP_OSDSCALING) {
- this->vo_scaling = 1;
- }
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_nop()
- *
- * - update last changed time of an OSD window
- */
-static int exec_osd_nop(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- this->osd[cmd->wnd].last_changed_vpts = xine_get_current_vpts(this->stream);
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_flush()
- *
- * - commit all pending OSD events immediately
- */
-static int exec_osd_flush(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- video_overlay_manager_t *ovl_manager = get_ovl_manager(this);
- if (!ovl_manager)
- return CONTROL_PARAM_ERROR;
-
- ovl_manager->flush_events(ovl_manager);
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_close()
- *
- */
-static int exec_osd_close(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- video_overlay_manager_t *ovl_manager = get_ovl_manager(this);
- osd_data_t *osd = &this->osd[cmd->wnd];
- int handle = osd->handle;
-
- if (cmd->flags & OSDFLAG_REFRESH) {
- LOGDBG("Ignoring OSD_Close(OSDFLAG_REFRESH)");
- return CONTROL_OK;
- }
-
- if (handle < 0) {
- LOGMSG("OSD_Close(%d): non-existing OSD !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- if (!ovl_manager)
- return CONTROL_PARAM_ERROR;
-
- video_overlay_event_t ov_event = {0};
- ov_event.event_type = OVERLAY_EVENT_FREE_HANDLE;
- ov_event.vpts = osd_exec_vpts(this, cmd);
- ov_event.object.handle = handle;
-
- while (ovl_manager->add_event(ovl_manager, (void *)&ov_event) < 0) {
- LOGMSG("OSD_Close(%d): overlay manager queue full !", cmd->wnd);
- ovl_manager->flush_events(ovl_manager);
- }
-
- clear_osdcmd(&osd->cmd);
- osd->handle = -1;
- osd->extent_width = 720;
- osd->extent_height = 576;
- osd->last_changed_vpts = 0;
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_set_rle()
- *
- */
-static int exec_osd_set_rle(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- video_overlay_manager_t *ovl_manager = get_ovl_manager(this);
- video_overlay_event_t ov_event = {0};
- vo_overlay_t ov_overlay = {0};
- osd_data_t *osd = &this->osd[cmd->wnd];
- int use_unscaled = 0;
- int rle_scaled = 0;
- int unscaled_supported = 1;
- int handle = osd->handle;
-
- if (!ovl_manager)
- return CONTROL_PARAM_ERROR;
-
- this->stream->video_out->enable_ovl(this->stream->video_out, 1);
-
- /* get / allocate OSD handle */
- if (handle < 0) {
- handle = ovl_manager->get_handle(ovl_manager,0);
- osd->handle = handle;
- osd->extent_width = osd->extent_width ?: 720;
- osd->extent_height = osd->extent_height ?: 576;
- osd->last_changed_vpts = 0;
- }
-
- /* fill SHOW event */
- ov_event.event_type = OVERLAY_EVENT_SHOW;
- ov_event.vpts = osd_exec_vpts(this, cmd);
- ov_event.object.handle = handle;
- ov_event.object.overlay = &ov_overlay;
- ov_event.object.object_type = 1; /* menu */
-
- /* check for unscaled OSD capability and request */
- xine_video_port_t *video_out = this->stream->video_out;
- if (! (video_out->get_capabilities(video_out) & VO_CAP_UNSCALED_OVERLAY))
- unscaled_supported = 0;
- else if (cmd->flags & OSDFLAG_UNSCALED)
- use_unscaled = 1;
-
- /* store osd for later rescaling (done if video size changes) */
-
- clear_osdcmd(&osd->cmd);
-
- memcpy(&osd->cmd, cmd, sizeof(osd_command_t));
- osd->cmd.data = NULL;
- if (cmd->palette) {
- /* RGB -> YUV */
- if(!(cmd->flags & OSDFLAG_YUV_CLUT))
- palette_argb_to_ayuv(cmd->palette, cmd->colors);
- cmd->flags |= OSDFLAG_YUV_CLUT;
-
- osd->cmd.palette = malloc(sizeof(xine_clut_t)*cmd->colors);
- memcpy(osd->cmd.palette, cmd->palette, 4*cmd->colors);
- osd->cmd.flags |= OSDFLAG_YUV_CLUT;
- }
-
- /* request OSD scaling from video_out layer */
- this->vo_scaling = 0;
- if (video_out->get_capabilities(video_out) & VO_CAP_OSDSCALING) {
- video_out->set_property(video_out, VO_PROP_OSD_SCALING, cmd->scaling ? 1 : 0);
- this->vo_scaling = 1;
- }
-
- /* if video size differs from expected (VDR osd is designed for 720x576),
- scale osd to video size or use unscaled (display resolution)
- blending */
-
- /* scale OSD ? */
- if (!this->vo_scaling && !use_unscaled) {
- int w_diff = (this->video_width < ((osd->extent_width *242) >> 8) /* 95% */) ? -1 :
- (this->video_width > ((osd->extent_width *280) >> 8) /* 110% */) ? 1 : 0;
- int h_diff = (this->video_height < ((osd->extent_height*242) >> 8) /* 95% */) ? -1 :
- (this->video_height > ((osd->extent_height*280) >> 8) /* 110% */) ? 1 : 0;
-
- if (w_diff || h_diff) {
-
- /* unscaled OSD instead of downscaling ? */
- if (w_diff < 0 || h_diff < 0)
- if (cmd->flags & OSDFLAG_UNSCALED_LOWRES)
- if (0 < (use_unscaled = unscaled_supported))
- LOGOSD("Size out of margins, using unscaled overlay");
-
- if (!use_unscaled && cmd->scaling > 0) {
- osdcmd_scale(this, cmd, osd, this->video_width, this->video_height);
- rle_scaled = 1;
- }
- }
- }
-
- /* Scale unscaled OSD ? */
- if (!this->vo_scaling && use_unscaled && cmd->scaling > 0) {
- int win_width = video_out->get_property(video_out, VO_PROP_WINDOW_WIDTH);
- int win_height = video_out->get_property(video_out, VO_PROP_WINDOW_HEIGHT);
-
- if (win_width >= 360 && win_height >= 288) {
- if (win_width != osd->extent_width || win_height != osd->extent_height) {
- osdcmd_scale(this, cmd, osd, win_width, win_height);
- rle_scaled = 1;
- }
- }
- }
-
- /* fill ov_overlay */
- osdcmd_to_overlay(&ov_overlay, cmd);
- ov_overlay.unscaled = use_unscaled;
-
- /* tag this overlay */
- ov_overlay.hili_rgb_clut = VDR_OSD_MAGIC;
-
- /* fill extra data */
- const vdr_osd_extradata_t extra_data = {
- extent_width: osd->extent_width,
- extent_height: osd->extent_height,
- layer: cmd->layer,
- scaling: cmd->scaling
- };
- memcpy(ov_overlay.hili_color, &extra_data, sizeof(extra_data));
-
-#ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- if (cmd->scaling && !rle_scaled) {
- ov_overlay.extent_width = osd->extent_width;
- ov_overlay.extent_height = osd->extent_height;
- }
-#endif
-
- /* if no scaling was required, we may still need to re-center OSD */
- if (!this->vo_scaling && !rle_scaled) {
- if (this->video_width != osd->extent_width)
- ov_overlay.x += (this->video_width - osd->extent_width)/2;
- if (this->video_height != osd->extent_height)
- ov_overlay.y += (this->video_height - osd->extent_height)/2;
- }
-
- /* store rle for later scaling (done if video size changes) */
- if (!rle_scaled /* if scaled, we already have a copy (original data) */ ) {
- osd->cmd.data = malloc(cmd->datalen);
- memcpy(osd->cmd.data, cmd->data, cmd->datalen);
- }
- cmd->data = NULL; /* we 'consume' data (ownership goes for xine-lib osd manager) */
-
- /* send event to overlay manager */
- while (ovl_manager->add_event(ovl_manager, (void *)&ov_event) < 0) {
- LOGMSG("OSD_Set_RLE(%d): overlay manager queue full !", cmd->wnd);
- ovl_manager->flush_events(ovl_manager);
- }
-
- osd->last_changed_vpts = ov_event.vpts ?: xine_get_current_vpts(this->stream);
-
- return CONTROL_OK;
-}
-
-/*
- * exec_osd_set_palette()
- *
- * - replace palette of an already existing OSD
- */
-static int exec_osd_set_palette(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- osd_data_t *osd = &this->osd[cmd->wnd];
-
- if (!osd->cmd.data) {
- LOGMSG("OSD_SetPalette(%d): old RLE data missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
- if (!cmd->palette) {
- LOGMSG("OSD_SetPalette(%d): new palette missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- /* use cached event to re-create Set_RLE command with modified palette */
- osd_command_t tmp;
- /* steal the original command */
- memcpy(&tmp, &osd->cmd, sizeof(osd_command_t));
- memset(&osd->cmd, 0, sizeof(osd_command_t));
-
- /* replace palette */
- tmp.cmd = OSD_Set_RLE;
- free(tmp.palette);
- tmp.palette = malloc(cmd->colors*sizeof(xine_rle_elem_t));
- memcpy(tmp.palette, cmd->palette, cmd->colors*sizeof(xine_rle_elem_t));
- tmp.colors = cmd->colors;
- tmp.pts = cmd->pts;
- tmp.delay_ms = cmd->delay_ms;
- tmp.flags |= cmd->flags & OSDFLAG_YUV_CLUT;
-
- /* redraw */
- int r = exec_osd_set_rle(this, &tmp);
- clear_osdcmd(&tmp);
- return r;
-}
-
-/*
- * exec_osd_move()
- *
- * - move existing OSD to new position
- */
-static int exec_osd_move(osd_manager_impl_t *this, osd_command_t *cmd)
-{
- osd_data_t *osd = &this->osd[cmd->wnd];
-
- if (!osd->cmd.data) {
- LOGMSG("OSD_Move(%d): old RLE data missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
- if (!osd->cmd.palette) {
- LOGMSG("OSD_Move(%d): old palette missing !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- /* use cached event to re-create Set_RLE command with modified palette */
- osd_command_t tmp;
- /* steal the original command */
- memcpy(&tmp, &osd->cmd, sizeof(osd_command_t));
- memset(&osd->cmd, 0, sizeof(osd_command_t));
-
- /* replace position */
- tmp.cmd = OSD_Set_RLE;
- tmp.x = cmd->x;
- tmp.y = cmd->y;
- tmp.pts = cmd->pts;
- tmp.delay_ms = cmd->delay_ms;
-
- /* redraw */
- int r = exec_osd_set_rle(this, &tmp);
- clear_osdcmd(&tmp);
- return r;
-}
-
-/*
- * exec_osd_command_internal()
- */
-static int exec_osd_command_internal(osd_manager_impl_t *this, struct osd_command_s *cmd)
-{
- LOGOSD("exec_osd_command %d", cmd->cmd);
-
- switch (cmd->cmd) {
- case OSD_Nop: return exec_osd_nop(this, cmd);
- case OSD_Size: return exec_osd_size(this, cmd);
- case OSD_SetPalette: return exec_osd_set_palette(this, cmd);
- case OSD_Move: return exec_osd_move(this, cmd);
- case OSD_Flush: return exec_osd_flush(this, cmd);
- case OSD_Set_RLE: return exec_osd_set_rle(this, cmd);
- case OSD_Close: return exec_osd_close(this, cmd);
- case OSD_Set_YUV:
- /* TODO */
- LOGMSG("OSD_Set_YUV not implemented !");
- return CONTROL_PARAM_ERROR;
- }
-
- LOGMSG("Unknown OSD command %d", cmd->cmd);
- return CONTROL_PARAM_ERROR;
-}
-
-/****************************** Interface handlers ******************************/
-
-/*
- * exec_osd_command()
- *
- * - handler for VDR-based osd_command_t events
- */
-static int exec_osd_command(osd_manager_t *this_gen,
- struct osd_command_s *cmd, xine_stream_t *stream)
-{
- osd_manager_impl_t *this = (osd_manager_impl_t*)this_gen;
- int result;
-
- if (!cmd || !stream) {
- LOGMSG("exec_osd_command: Stream not initialized !");
- return CONTROL_DISCONNECTED;
- }
- if (cmd->wnd >= MAX_OSD_OBJECT) {
- LOGMSG("exec_osd_command: OSD window handle %d out of range !", cmd->wnd);
- return CONTROL_PARAM_ERROR;
- }
-
- if (pthread_mutex_lock(&this->lock)) {
- LOGERR("exec_osd_command: mutex lock failed");
- return CONTROL_DISCONNECTED;
- }
-
- this->stream = stream;
- result = exec_osd_command_internal(this, cmd);
-
- release_ticket(this);
-
- pthread_mutex_unlock(&this->lock);
-
- return result;
-}
-
-/*
- * video_size_changed()
- */
-static void video_size_changed(osd_manager_t *this_gen, xine_stream_t *stream, int width, int height)
-{
- osd_manager_impl_t *this = (osd_manager_impl_t*)this_gen;
- int i;
-
- if (!stream) {
- LOGMSG("video_size_changed: Stream not initialized !");
- return;
- }
-
- if (width < 1 || height < 1) {
- LOGMSG("video_size_changed: Invalid video size %dx%d", width, height);
- return;
- }
-
- if (pthread_mutex_lock(&this->lock)) {
- LOGERR("video_size_changed: mutex lock failed");
- return;
- }
-
- if (this->video_width == width && this->video_height == height) {
- pthread_mutex_unlock(&this->lock);
- return;
- }
-
- LOGOSD("New video size (%dx%d->%dx%d)", this->video_width, this->video_height, width, height);
-
- this->stream = stream;
- this->video_width = width;
- this->video_height = height;
-
- /* just call exec_osd_command for all stored osd's.
- scaling is done automatically if required. */
- if (!this->vo_scaling)
- for (i = 0; i < MAX_OSD_OBJECT; i++)
- if (this->osd[i].handle >= 0 &&
- this->osd[i].cmd.data &&
- this->osd[i].cmd.scaling > 0) {
- osd_command_t tmp;
- memcpy(&tmp, &this->osd[i].cmd, sizeof(osd_command_t));
- memset(&this->osd[i].cmd, 0, sizeof(osd_command_t));
-
- exec_osd_command_internal(this, &tmp);
-
- clear_osdcmd(&tmp);
- }
-
- release_ticket(this);
- pthread_mutex_unlock(&this->lock);
-}
-
-/*
- * osd_manager_dispose()
- */
-static void osd_manager_dispose(osd_manager_t *this_gen, xine_stream_t *stream)
-{
- osd_manager_impl_t *this = (osd_manager_impl_t*)this_gen;
- int i;
-
- while (pthread_mutex_destroy(&this->lock) == EBUSY) {
- LOGMSG("osd_manager_dispose: lock busy ...");
- pthread_mutex_lock(&this->lock);
- pthread_mutex_unlock(&this->lock);
- }
-
- /* close all */
- for (i=0; i<MAX_OSD_OBJECT; i++) {
- if (this->osd[i].handle >= 0) {
- osd_command_t cmd = {
- .cmd = OSD_Close,
- .wnd = i,
- };
- LOGOSD("Closing osd %d", i);
- exec_osd_close(this, &cmd);
- }
- }
-
- release_ticket(this);
-
- free(this);
-}
-
-/*
- * init_osd_manager()
- *
- * - exported
- */
-osd_manager_t *init_osd_manager(void)
-{
- osd_manager_impl_t *this = calloc(1, sizeof(osd_manager_impl_t));
- int i;
-
- this->mgr.command = exec_osd_command;
- this->mgr.dispose = osd_manager_dispose;
- this->mgr.video_size_changed = video_size_changed;
-
- pthread_mutex_init(&this->lock, NULL);
-
- this->video_width = 720;
- this->video_height = 576;
-
- for (i = 0; i < MAX_OSD_OBJECT; i++)
- this->osd[i].handle = -1;
-
- return &this->mgr;
-}
diff --git a/xine/osd_manager.h b/xine/osd_manager.h
deleted file mode 100644
index d71336ed..00000000
--- a/xine/osd_manager.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * osd_manager.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: osd_manager.h,v 1.1 2008-12-06 16:17:18 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_OSD_MANAGER_H_
-#define XINELIBOUTPUT_OSD_MANAGER_H_
-
-/*
- * OSD manager executes OSD control messages from VDR.
- * - cache OSD data
- * - scale OSD when required
- * - re-scale OSD when video size changes
- * - generate xine overlay events
- */
-
-struct osd_command_s;
-
-typedef struct osd_manager_s osd_manager_t;
-
-struct osd_manager_s {
- int (*command)(osd_manager_t *, struct osd_command_s *, xine_stream_t *);
- void (*dispose)(osd_manager_t *, xine_stream_t *);
-
- void (*video_size_changed)(osd_manager_t *, xine_stream_t *, int width, int height);
-};
-
-osd_manager_t *init_osd_manager(void);
-
-
-#endif /* XINELIBOUTPUT_OSD_MANAGER_H_ */
diff --git a/xine/post.c b/xine/post.c
deleted file mode 100644
index 6c637634..00000000
--- a/xine/post.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2003 by Dirk Meyer
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * The code is taken from xine-ui/src/xitk/post.c at changed to work with fbxine
- *
- * Modified for VDR xineliboutput plugin by Petri Hintukainen, 2006
- * - runtime re-configuration (load/unload, enable/disable)
- * - support for multiple streams
- * - support for mosaico post plugin (picture-in-picture)
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "post.h"
-
-#include <sys/types.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <errno.h>
-#include <syslog.h>
-
-#define LOG_MODULENAME "[xine-post] "
-#include "../logdefs.h"
-
-#define fe_t post_plugins_t
-
-typedef struct {
- xine_post_t *post;
- xine_post_api_t *api;
- xine_post_api_descr_t *descr;
- xine_post_api_parameter_t *param;
- char *param_data;
-
- int x;
- int y;
-
- int readonly;
-
- char **properties_names;
-} post_object_t;
-
-
-static int __pplugin_retrieve_parameters(post_object_t *pobj)
-{
- xine_post_in_t *input_api;
-
- if((input_api = (xine_post_in_t *) xine_post_input(pobj->post,
- "parameters"))) {
- xine_post_api_t *post_api;
- xine_post_api_descr_t *api_descr;
- xine_post_api_parameter_t *parm;
- int pnum = 0;
-
- post_api = (xine_post_api_t *) input_api->data;
-
- api_descr = post_api->get_param_descr();
-
- parm = api_descr->parameter;
- pobj->param_data = malloc(api_descr->struct_size);
-
- while(parm->type != POST_PARAM_TYPE_LAST) {
-
- post_api->get_parameters(pobj->post, pobj->param_data);
-
- if(!pnum)
- pobj->properties_names = (char **) calloc(2, sizeof(char *));
- else
- pobj->properties_names = (char **)
- realloc(pobj->properties_names, sizeof(char *) * (pnum + 2));
-
- pobj->properties_names[pnum] = strdup(parm->name);
- pobj->properties_names[pnum + 1] = NULL;
- pnum++;
- parm++;
- }
-
- pobj->api = post_api;
- pobj->descr = api_descr;
- pobj->param = api_descr->parameter;
-
- return 1;
- }
-
- return 0;
-}
-
-static void _pplugin_update_parameter(post_object_t *pobj)
-{
- pobj->api->set_parameters(pobj->post, pobj->param_data);
- pobj->api->get_parameters(pobj->post, pobj->param_data);
-}
-
-static void __pplugin_update_parameters(xine_post_t *post, char *args)
-{
- char *p;
- post_object_t pobj = {
- .post = post,
- };
-
- if(__pplugin_retrieve_parameters(&pobj)) {
- int i;
-
- if(pobj.properties_names && args && *args) {
- char *param;
-
- while((param = xine_strsep(&args, ",")) != NULL) {
-
- p = param;
-
- while((*p != '\0') && (*p != '='))
- p++;
-
- if(p && strlen(p)) {
- int param_num = 0;
-
- *p++ = '\0';
-
- while(pobj.properties_names[param_num]
- && strcasecmp(pobj.properties_names[param_num], param))
- param_num++;
-
- if(pobj.properties_names[param_num]) {
-
- pobj.param = pobj.descr->parameter;
- pobj.param += param_num;
- pobj.readonly = pobj.param->readonly;
-
- switch(pobj.param->type) {
- case POST_PARAM_TYPE_INT:
- if(!pobj.readonly) {
- if(pobj.param->enum_values) {
- char **values = pobj.param->enum_values;
- int i = 0;
-
- while(values[i]) {
- if(!strcasecmp(values[i], p)) {
- *(int *)(pobj.param_data + pobj.param->offset) = i;
- break;
- }
- i++;
- }
-
- if( !values[i] )
- *(int *)(pobj.param_data + pobj.param->offset) = (int) strtol(p, &p, 10);
- } else {
- *(int *)(pobj.param_data + pobj.param->offset) = (int) strtol(p, &p, 10);
- }
- _pplugin_update_parameter(&pobj);
- }
- break;
-
- case POST_PARAM_TYPE_DOUBLE:
- if(!pobj.readonly) {
- *(double *)(pobj.param_data + pobj.param->offset) = strtod(p, &p);
- _pplugin_update_parameter(&pobj);
- }
- break;
-
- case POST_PARAM_TYPE_CHAR:
- case POST_PARAM_TYPE_STRING:
- if(!pobj.readonly) {
- if(pobj.param->type == POST_PARAM_TYPE_CHAR) {
- int maxlen = pobj.param->size / sizeof(char);
-
- snprintf((char *)(pobj.param_data + pobj.param->offset), maxlen, "%s", p);
- _pplugin_update_parameter(&pobj);
- }
- else
- fprintf(stderr, "parameter type POST_PARAM_TYPE_STRING not supported yet.\n");
- }
- break;
-
- case POST_PARAM_TYPE_STRINGLIST: /* unsupported */
- if(!pobj.readonly)
- fprintf(stderr, "parameter type POST_PARAM_TYPE_STRINGLIST not supported yet.\n");
- break;
-
- case POST_PARAM_TYPE_BOOL:
- if(!pobj.readonly) {
- *(int *)(pobj.param_data + pobj.param->offset) = ((int) strtol(p, &p, 10)) ? 1 : 0;
- _pplugin_update_parameter(&pobj);
- }
- break;
- }
- } else {
- LOGMSG("Unknown post plugin parameter %s !", param);
- }
- }
- }
-
- i = 0;
-
- while(pobj.properties_names[i]) {
- free(pobj.properties_names[i]);
- i++;
- }
-
- free(pobj.properties_names);
- }
-
- free(pobj.param_data);
- }
-}
-
-/* -post <name>:option1=value1,option2=value2... */
-static post_element_t **pplugin_parse_and_load(fe_t *fe,
- int plugin_type,
- const char *pchain,
- int *post_elements_num)
-{
- post_element_t **post_elements = NULL;
-
- *post_elements_num = 0;
-
- if(pchain && strlen(pchain)) {
- char *post_chain, *freeme, *p;
-
- freeme = post_chain = strdup(pchain);
-
- while((p = xine_strsep(&post_chain, ";"))) {
-
- if(p && strlen(p)) {
- char *plugin, *args = NULL;
- xine_post_t *post;
-
- while(*p == ' ')
- p++;
-
- plugin = strdup(p);
-
- if((p = strchr(plugin, ':')))
- *p++ = '\0';
-
- if(p && (strlen(p) > 1))
- args = p;
-#if 0
- post = xine_post_init(fe->xine, plugin, 0,
- &fe->audio_port, &fe->video_port);
-#else
- if(plugin_type == XINE_POST_TYPE_VIDEO_COMPOSE) {
- post = xine_post_init(fe->xine, plugin, 2,
- &fe->audio_port, &fe->video_port);
- } else
- post = xine_post_init(fe->xine, plugin, 0,
- &fe->audio_port, &fe->video_port);
-#endif
-
- if (post && plugin_type) {
- if (post->type != plugin_type) {
- xine_post_dispose(fe->xine, post);
- post = NULL;
- }
- }
-
- if(post) {
-
- if(!(*post_elements_num))
- post_elements = (post_element_t **) calloc(2, sizeof(post_element_t *));
- else
- post_elements = (post_element_t **)
- realloc(post_elements, sizeof(post_element_t *) * ((*post_elements_num) + 2));
-
- post_elements[(*post_elements_num)] = calloc(1, sizeof(post_element_t));
- post_elements[(*post_elements_num)]->post = post;
- post_elements[(*post_elements_num)]->name = strdup(plugin);
-#if 1
- post_elements[(*post_elements_num)]->args = args ? strdup(args) : NULL;
- post_elements[(*post_elements_num)]->enable = 0;
-#endif
- (*post_elements_num)++;
- post_elements[(*post_elements_num)] = NULL;
-
- __pplugin_update_parameters(post, args);
- }
-
- free(plugin);
- }
- }
- free(freeme);
- }
-
- return post_elements;
-}
-
-void pplugin_parse_and_store_post(fe_t *fe, int plugin_type,
- const char *post_chain)
-{
- post_element_t ***_post_elements;
- int *_post_elements_num;
- post_element_t **posts = NULL;
- int num;
-
- switch(plugin_type) {
- case XINE_POST_TYPE_VIDEO_FILTER:
- _post_elements = &fe->post_video_elements;
- _post_elements_num = &fe->post_video_elements_num;
- break;
- case XINE_POST_TYPE_VIDEO_COMPOSE:
- _post_elements = &fe->post_pip_elements;
- _post_elements_num = &fe->post_pip_elements_num;
- break;
- case XINE_POST_TYPE_AUDIO_VISUALIZATION:
- _post_elements = &fe->post_vis_elements;
- _post_elements_num = &fe->post_vis_elements_num;
- break;
- default:
- _post_elements = &fe->post_audio_elements;
- _post_elements_num = &fe->post_audio_elements_num;
- break;
- }
-
- if((posts = pplugin_parse_and_load(fe, plugin_type, post_chain, &num))) {
- if(*_post_elements_num) {
- int i;
- int ptot = *_post_elements_num + num;
-
- *_post_elements = (post_element_t **) realloc(*_post_elements,
- sizeof(post_element_t *) * (ptot + 1));
- for(i = *_post_elements_num; i < ptot; i++)
- (*_post_elements)[i] = posts[i - *_post_elements_num];
-
- (*_post_elements)[i] = NULL;
- (*_post_elements_num) += num;
- }
- else {
- *_post_elements = posts;
- *_post_elements_num = num;
- }
-#if 1
- if(SysLogLevel > 2) {
- /* dump list of all loaded plugins */
- int ptot = *_post_elements_num;
- int i;
- char s[4096]="";
- for(i=0; i<ptot; i++)
- if((*_post_elements)[i])
- if(((*_post_elements)[i])->post) {
- if(((*_post_elements)[i])->enable)
- strcat(s, "*");
- if(((*_post_elements)[i])->name)
- strcat(s, ((*_post_elements)[i])->name);
- else
- strcat(s, "<no name!>");
- strcat(s, " ");
- }
- LOGDBG(" loaded plugins (type %d.%d): %s",
- (plugin_type>>16), (plugin_type&0xffff), s);
- }
-#endif
- }
-}
-
-
-void vpplugin_parse_and_store_post(fe_t *fe, const char *post_chain)
-{
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_VIDEO_FILTER, post_chain);
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_VIDEO_COMPOSE, post_chain);
-}
-
-
-void applugin_parse_and_store_post(fe_t *fe, const char *post_chain)
-{
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_AUDIO_FILTER, post_chain);
- pplugin_parse_and_store_post(fe, XINE_POST_TYPE_AUDIO_VISUALIZATION, post_chain);
-}
-
-
-static void _vpplugin_unwire(fe_t *fe)
-{
- xine_post_out_t *vo_source;
- vo_source = xine_get_video_source(fe->video_source);
- (void) xine_post_wire_video_port(vo_source, fe->video_port);
-}
-
-
-static void _applugin_unwire(fe_t *fe)
-{
- xine_post_out_t *ao_source;
- ao_source = xine_get_audio_source(fe->audio_source);
- (void) xine_post_wire_audio_port(ao_source, fe->audio_port);
-}
-
-
-static void _vpplugin_rewire_from_post_elements(fe_t *fe, post_element_t **post_elements, int post_elements_num)
-{
- if(post_elements_num) {
- xine_post_out_t *vo_source;
- int i = 0;
-
- for(i = (post_elements_num - 1); i >= 0; i--) {
- const char *const *outs = xine_post_list_outputs(post_elements[i]->post);
- const xine_post_out_t *vo_out = xine_post_output(post_elements[i]->post, (char *) *outs);
- if(i == (post_elements_num - 1)) {
- LOGDBG(" wiring %10s[out] -> [in]video_out", post_elements[i]->name);
- xine_post_wire_video_port((xine_post_out_t *) vo_out, fe->video_port);
- }
- else {
- const xine_post_in_t *vo_in;
- int err;
-
- /* look for standard input names */
- vo_in = xine_post_input(post_elements[i + 1]->post, "video");
- if( !vo_in )
- vo_in = xine_post_input(post_elements[i + 1]->post, "video in");
-
- LOGDBG(" wiring %10s[out] -> [in]%-10s ",
- post_elements[i]->name, post_elements[i+1]->name);
- err = xine_post_wire((xine_post_out_t *) vo_out,
- (xine_post_in_t *) vo_in);
- }
- }
-
- if(fe->post_pip_enable &&
- !strcmp(post_elements[0]->name, "mosaico") &&
- fe->pip_stream) {
- vo_source = xine_get_video_source(fe->pip_stream);
- LOGDBG(" wiring %10s[out] -> [in1]%-10s ", "pip stream", post_elements[0]->name);
- xine_post_wire_video_port(vo_source,
- post_elements[0]->post->video_input[1]);
- }
-
- vo_source = xine_get_video_source(fe->video_source);
- LOGDBG(" wiring %10s[out] -> [in]%-10s", "stream", post_elements[0]->name);
- xine_post_wire_video_port(vo_source,
- post_elements[0]->post->video_input[0]);
- }
-}
-
-
-static void _applugin_rewire_from_post_elements(fe_t *fe, post_element_t **post_elements, int post_elements_num)
-{
- if(post_elements_num) {
- xine_post_out_t *ao_source;
- int i = 0;
-
- for(i = (post_elements_num - 1); i >= 0; i--) {
- const char *const *outs = xine_post_list_outputs(post_elements[i]->post);
- const xine_post_out_t *ao_out = xine_post_output(post_elements[i]->post, (char *) *outs);
-
- if(i == (post_elements_num - 1)) {
- LOGDBG(" wiring %10s[out] -> [in]audio_out", post_elements[i]->name);
- xine_post_wire_audio_port((xine_post_out_t *) ao_out, fe->audio_port);
- }
- else {
- const xine_post_in_t *ao_in;
- int err;
-
- /* look for standard input names */
- ao_in = xine_post_input(post_elements[i + 1]->post, "audio");
- if( !ao_in )
- ao_in = xine_post_input(post_elements[i + 1]->post, "audio in");
-
- LOGDBG(" wiring %10s[out] -> [in]%-10s ",
- post_elements[i]->name, post_elements[i+1]->name);
- err = xine_post_wire((xine_post_out_t *) ao_out, (xine_post_in_t *) ao_in);
- }
- }
-
- ao_source = xine_get_audio_source(fe->audio_source);
- LOGDBG(" wiring %10s[out] -> [in]%-10s", "stream", post_elements[0]->name);
- xine_post_wire_audio_port(ao_source, post_elements[0]->post->audio_input[0]);
- }
-}
-
-static post_element_t **_pplugin_join_deinterlace_and_post_elements(fe_t *fe, int *post_elements_num)
-{
- post_element_t **post_elements;
- int i = 0, j = 0, n = 0, p = 0;
- static const char *order[] = {"autocrop", "thread", "tvtime", "swscale", NULL};
-
- *post_elements_num = 0;
- if( fe->post_video_enable )
- *post_elements_num += fe->post_video_elements_num;
-
- if( fe->post_pip_enable )
- *post_elements_num += fe->post_pip_elements_num;
-
- if( *post_elements_num == 0 )
- return NULL;
-
- post_elements = calloc( (*post_elements_num), sizeof(post_element_t *));
-
- if(fe->post_pip_enable)
- for( i = 0; i < fe->post_pip_elements_num; i++ ) {
- if(fe->post_pip_elements[i]->enable)
- post_elements[i+j-n] = fe->post_pip_elements[i];
- else
- n++;
- }
-
- if(fe->post_video_enable)
- for( j = 0; j < fe->post_video_elements_num; j++ ) {
- if(fe->post_video_elements[j]->enable) {
- post_elements[i+j-n] = fe->post_video_elements[j];
- } else
- n++;
- }
-
- *post_elements_num -= n;
- if( *post_elements_num == 0 ) {
- free(post_elements);
- return NULL;
- }
-
- /* in some special cases order is important. By default plugin order
- * in post plugin chain is post plugin loading order.
- * But, we want:
- *
- * 1. autocrop - less data to process for other plugins
- * - accepts only YV12
- * 2. deinterlace - blur etc. makes deinterlacing difficult.
- * - upscales chroma (YV12->YUY2) in some modes.
- * 3. anything else
- *
- * So let's move those two to beginning ...
- */
- n = 0;
- while(order[p]) {
- for(i = 0; i<*post_elements_num; i++)
- if(!strcmp(post_elements[i]->name, order[p])) {
- if(i != n) {
- post_element_t *tmp = post_elements[i];
- for(j=i; j>n; j--)
- post_elements[j] = post_elements[j-1];
- post_elements[n] = tmp;
- LOGDBG(" moved %s to post slot %d", order[p], n);
- }
- n++;
- break;
- }
- p++;
- }
-
- return post_elements;
-}
-
-static post_element_t **_pplugin_join_visualization_and_post_elements(fe_t *fe, int *post_elements_num)
-{
- post_element_t **post_elements;
- int i = 0, j = 0, n = 0;
-
- *post_elements_num = 0;
- if( fe->post_audio_enable )
- *post_elements_num += fe->post_audio_elements_num;
-
- if( fe->post_vis_enable )
- *post_elements_num += fe->post_vis_elements_num;
-
- if( *post_elements_num == 0 )
- return NULL;
-
- post_elements = calloc( (*post_elements_num), sizeof(post_element_t *));
-
- if(fe->post_audio_enable)
- for( j = 0; j < fe->post_audio_elements_num; j++ ) {
- if(fe->post_audio_elements[j]->enable)
- post_elements[i+j-n] = fe->post_audio_elements[j];
- else
- n++;
- }
-
- if(fe->post_vis_enable)
- for( i = 0; i < fe->post_vis_elements_num; i++ ) {
- if(fe->post_vis_elements[i]->enable)
- post_elements[i+j-n] = fe->post_vis_elements[i];
- else
- n++;
- }
-
- *post_elements_num -= n;
- if( *post_elements_num == 0 ) {
- free(post_elements);
- return NULL;
- }
-
- return post_elements;
-}
-
-static void _vpplugin_rewire(fe_t *fe)
-{
- static post_element_t **post_elements;
- int post_elements_num;
-
- post_elements = _pplugin_join_deinterlace_and_post_elements(fe, &post_elements_num);
-
- if( post_elements ) {
- _vpplugin_rewire_from_post_elements(fe, post_elements, post_elements_num);
-
- free(post_elements);
- }
-}
-
-static void _applugin_rewire(fe_t *fe)
-{
- static post_element_t **post_elements;
- int post_elements_num;
-
- post_elements = _pplugin_join_visualization_and_post_elements(fe, &post_elements_num);
-
- if( post_elements ) {
- _applugin_rewire_from_post_elements(fe, post_elements, post_elements_num);
-
- free(post_elements);
- }
-}
-
-void vpplugin_rewire_posts(fe_t *fe)
-{
- /*TRACELINE;*/
- _vpplugin_unwire(fe);
- _vpplugin_rewire(fe);
-}
-
-void applugin_rewire_posts(fe_t *fe)
-{
- /*TRACELINE;*/
- _applugin_unwire(fe);
- _applugin_rewire(fe);
-}
-
-static int _pplugin_enable_post(post_plugins_t *fe, const char *name,
- const char *args,
- post_element_t **post_elements,
- int post_elements_num,
- int *found)
-{
- int i, result = 0;
-
- for(i=0; i<post_elements_num; i++)
- if(post_elements[i])
- if(!strcmp(post_elements[i]->name, name)) {
- if(post_elements[i]->enable == 0) {
- post_elements[i]->enable = 1;
- result = 1;
- }
-
- *found = 1;
-
- if(args && *args) {
- if(post_elements[i]->enable != 2) {
- char *tmp = strdup(args);
- __pplugin_update_parameters(post_elements[i]->post, tmp);
- free(tmp);
- if(post_elements[i]->args)
- free(post_elements[i]->args);
- post_elements[i]->args = strdup(args);
- } else {
- LOGDBG(" * enable post %s, parameters fixed in command line.", name);
- LOGDBG(" requested: %s", args ? : "none");
- LOGDBG(" using : %s", post_elements[i]->args ? : "none");
- }
- }
- }
-
- return result;
-}
-
-static int _vpplugin_enable_post(post_plugins_t *fe, const char *name,
- const char *args, int *found)
-{
- int result = 0;
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_video_elements,
- fe->post_video_elements_num, found);
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_pip_elements,
- fe->post_pip_elements_num, found);
- return result;
-}
-
-static int _applugin_enable_post(post_plugins_t *fe, const char *name,
- const char *args, int *found)
-{
- int result = 0;
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_audio_elements,
- fe->post_audio_elements_num, found);
- if(!*found)
- result = _pplugin_enable_post(fe, name, args, fe->post_vis_elements,
- fe->post_vis_elements_num, found);
- return result;
-}
-
-static char * _pp_name_strdup(const char *initstr)
-{
- char *name = strdup(initstr), *pt;
-
- if(NULL != (pt = strchr(name, ':')))
- *pt = 0;
-
- return name;
-}
-
-static const char * _pp_args(const char *initstr)
-{
- char *pt = strchr(initstr, ':');
- if(pt && *(pt+1))
- return pt+1;
- return NULL;
-}
-
-int vpplugin_enable_post(post_plugins_t *fe, const char *initstr,
- int *found)
-{
- char *name = _pp_name_strdup(initstr);
- const char *args = _pp_args(initstr);
-
- int result = _vpplugin_enable_post(fe, name, args, found);
-
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
-
- if(!*found) {
- LOGDBG(" * loading post %s", initstr);
- vpplugin_parse_and_store_post(fe, initstr);
- result = _vpplugin_enable_post(fe, name, NULL, found);
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
- }
-
- if(result)
- _vpplugin_unwire(fe);
-
- free(name);
- return result;
-}
-
-int applugin_enable_post(post_plugins_t *fe, const char *initstr,
- int *found)
-{
- const char * args = _pp_args(initstr);
- char *name = _pp_name_strdup(initstr);
-
- int result = _applugin_enable_post(fe, name, args, found);
-
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
-
- if(!*found) {
- LOGDBG(" * loading post %s", initstr);
- applugin_parse_and_store_post(fe, initstr);
- result = _applugin_enable_post(fe, name, NULL, found);
- LOGDBG(" * enable post %s --> %s, %s", name,
- *found ? "found" : "not found",
- result ? "enabled" : "no action");
- }
-
- if(result)
- _applugin_unwire(fe);
-
- free(name);
- return result;
-}
-
-static int _pplugin_disable_post(post_plugins_t *fe, const char *name,
- post_element_t **post_elements,
- int post_elements_num)
-{
- int i, result = 0;
- /*TRACELINE;*/
- if(post_elements)
- for(i = 0; i < post_elements_num; i++)
- if(post_elements[i])
- if(!name || !strcmp(post_elements[i]->name, name))
- if(post_elements[i]->enable == 1) {
- post_elements[i]->enable = 0;
- result = 1;
- }
- return result;
-}
-
-int vpplugin_disable_post(post_plugins_t *fe, const char *name)
-{
- /*TRACELINE;*/
- if(_pplugin_disable_post(fe, name, fe->post_video_elements,
- fe->post_video_elements_num) ||
- _pplugin_disable_post(fe, name, fe->post_pip_elements,
- fe->post_pip_elements_num)) {
- _vpplugin_unwire(fe);
- return 1;
- }
- return 0;
-}
-
-int applugin_disable_post(post_plugins_t *fe, const char *name)
-{
- /*TRACELINE;*/
- if(_pplugin_disable_post(fe, name, fe->post_audio_elements,
- fe->post_audio_elements_num) ||
- _pplugin_disable_post(fe, name, fe->post_vis_elements,
- fe->post_vis_elements_num)) {
- _applugin_unwire(fe);
- return 1;
- }
- return 0;
-}
-
-static int _pplugin_unload_post(post_plugins_t *fe, const char *name,
- post_element_t ***post_elements,
- int *post_elements_num)
-{
- /* does not unwrire plugins ! */
- int i, j, result = 0;
- /*TRACELINE;*/
-
- if(!*post_elements || !*post_elements_num)
- return 0;
-
- for(i=0; i < *post_elements_num; i++) {
- if((*post_elements)[i]) {
- if(!name || !strcmp((*post_elements)[i]->name, name)) {
-
- if((*post_elements)[i]->enable == 0 || !name) {
- xine_post_dispose(fe->xine, (*post_elements)[i]->post);
-
- free((*post_elements)[i]->name);
-
- if((*post_elements)[i]->args)
- free((*post_elements)[i]->args);
-
- free((*post_elements)[i]);
-
- for(j=i; j < *post_elements_num - 1; j++)
- (*post_elements)[j] = (*post_elements)[j+1];
-
- (*post_elements_num) --;
- (*post_elements)[(*post_elements_num)] = 0;
-
- result = 1;
- i--;
-
- } else {
- LOGDBG("Unload %s failed: plugin enabled and in use",
- (*post_elements)[i]->name);
- }
- }
- }
- }
-
- if(*post_elements_num <= 0) {
- if(*post_elements)
- free(*post_elements);
- *post_elements = NULL;
- }
-
- return result;
-}
-
-int vpplugin_unload_post(post_plugins_t *fe, const char *name)
-{
- int result = vpplugin_disable_post(fe, name);
-
- /* unload already disabled plugins too (result=0) */
- _pplugin_unload_post(fe, name, &fe->post_video_elements,
- &fe->post_video_elements_num);
- _pplugin_unload_post(fe, name, &fe->post_pip_elements,
- &fe->post_pip_elements_num);
-
- /* result indicates only unwiring condition, not unload result */
- return result;
-}
-
-int applugin_unload_post(post_plugins_t *fe, const char *name)
-{
- int result = applugin_disable_post(fe, name);
-
- /* unload already disabled plugins too (result=0) */
- _pplugin_unload_post(fe, name, &fe->post_audio_elements,
- &fe->post_audio_elements_num);
- _pplugin_unload_post(fe, name, &fe->post_vis_elements,
- &fe->post_vis_elements_num);
-
- /* result indicates only unwiring condition, not unload result */
- return result;
-}
-
-
-/* end of post.c */
-
diff --git a/xine/post.h b/xine/post.h
deleted file mode 100644
index 355e8e2c..00000000
--- a/xine/post.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2003 by Dirk Meyer
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * Modified for xineliboutput by Petri Hintukainen, 2006
- *
- */
-
-#ifndef POST_HH
-#define POST_HH
-
-#include <xine.h>
-#include <xine/xine_internal.h>
-#include <xine/xineutils.h>
-#include <xine/plugin_catalog.h>
-
-typedef struct {
- xine_post_t *post;
- char *name;
- char *args;
- int enable; /* 0 - disabled, 1 - enabled, 2 - can't disable */
-} post_element_t;
-
-
-typedef struct post_plugins_s post_plugins_t;
-
-struct post_plugins_s {
-
- /* frontend data */
- char *static_post_plugins; /* post plugins from command line; always on */
- xine_stream_t *video_source; /* stream to take video from */
- xine_stream_t *audio_source; /* stream to take audio from */
- xine_stream_t *pip_stream; /* pip stream */
-
- /* xine */
- xine_t *xine;
- xine_video_port_t *video_port;
- xine_audio_port_t *audio_port;
-
- /* post.c internal use */
- int post_audio_elements_num;
- int post_video_elements_num;
- int post_vis_elements_num;
- int post_pip_elements_num;
-
- post_element_t **post_audio_elements;
- post_element_t **post_video_elements;
- post_element_t **post_vis_elements; /* supports only one */
- post_element_t **post_pip_elements; /* supports only one and two input */
-
- int post_audio_enable;
- int post_video_enable;
- int post_vis_enable;
- int post_pip_enable;
-};
-
-
-void vpplugin_rewire_posts(post_plugins_t *fe);
-void applugin_rewire_posts(post_plugins_t *fe);
-
-/* load and config post plugin(s) */
-/* post == "plugin:arg1=val1,arg2=val2;plugin2..." */
-void vpplugin_parse_and_store_post(post_plugins_t *fe, const char *post);
-void applugin_parse_and_store_post(post_plugins_t *fe, const char *post);
-
-/* enable (and load if not loaded), but don't rewire */
-/* result indicates only unwiring condition, not enable result */
-/* -> if result <> 0, something was enabled and post chain is unwired */
-int vpplugin_enable_post(post_plugins_t *fe, const char *name, int *found);
-int applugin_enable_post(post_plugins_t *fe, const char *name, int *found);
-
-/* disable (and unwire if found), but don't unload */
-/* result indicates only unwiring condition, not disable result */
-int vpplugin_disable_post(post_plugins_t *fe, const char *name);
-int applugin_disable_post(post_plugins_t *fe, const char *name);
-
-/* unload (and unwire) plugin(s) */
-/* result indicates only unwiring condition, not unload result */
-int vpplugin_unload_post(post_plugins_t *fe, const char *name);
-int applugin_unload_post(post_plugins_t *fe, const char *name);
-
-#endif
-
-/* end of post.h */
diff --git a/xine/post_util.h b/xine/post_util.h
deleted file mode 100644
index a539d31d..00000000
--- a/xine/post_util.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * post_util.h: post plugin utility functions
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: post_util.h,v 1.5 2008-12-14 00:52:35 phintuka Exp $
- *
- */
-
-#if POST_PLUGIN_IFACE_VERSION < 9
-# warning POST_PLUGIN_IFACE_VERSION < 9 not supported !
-#endif
-#if POST_PLUGIN_IFACE_VERSION > 10
-# warning POST_PLUGIN_IFACE_VERSION > 10 not supported !
-#endif
-
-/*
- * class util prototypes
- */
-
-static void *init_plugin(xine_t *xine, void *data);
-#if POST_PLUGIN_IFACE_VERSION < 10
-static char *get_identifier(post_class_t *class_gen);
-static char *get_description(post_class_t *class_gen);
-static void class_dispose(post_class_t *class_gen);
-#endif
-
-/* required from plugin: */
-static post_plugin_t *open_plugin(post_class_t *class_gen, int inputs,
- xine_audio_port_t **audio_target,
- xine_video_port_t **video_target);
-
-/*
- * plugin util prototypes
- */
-
-static int dispatch_draw(vo_frame_t *frame, xine_stream_t *stream);
-static int intercept_frame_yuy(post_video_port_t *port, vo_frame_t *frame);
-static int post_draw(vo_frame_t *frame, xine_stream_t *stream);
-#ifdef ENABLE_SLICED
-static void dispatch_slice(vo_frame_t *vo_img, uint8_t **src);
-#endif
-
-/* required from plugin: */
-static vo_frame_t *got_frame(vo_frame_t *frame);
-static void draw_internal(vo_frame_t *frame, vo_frame_t *new_frame);
-
-
-/*
- * class utils
- */
-
-static void *init_plugin(xine_t *xine, void *data)
-{
- post_class_t *class = calloc(1, sizeof(post_class_t));
-
- if (!class)
- return NULL;
-
- class->open_plugin = open_plugin;
-#if POST_PLUGIN_IFACE_VERSION < 10
- class->get_identifier = get_identifier;
- class->get_description = get_description;
- class->dispose = class_dispose;
-#else
- class->identifier = PLUGIN_ID;
- class->description = PLUGIN_DESCR;
- class->dispose = default_post_class_dispose;
-#endif
-
- return class;
-}
-
-#if POST_PLUGIN_IFACE_VERSION < 10
-static char *get_identifier(post_class_t *class_gen)
-{
- return PLUGIN_ID;
-}
-
-static char *get_description(post_class_t *class_gen)
-{
- return PLUGIN_DESCR;
-}
-
-static void class_dispose(post_class_t *class_gen)
-{
- free(class_gen);
-}
-#endif
-
-/*
- * plugin utils
- */
-
-#ifdef ENABLE_SLICED
-static void dispatch_slice(vo_frame_t *vo_img, uint8_t **src)
-{
- if (vo_img->next->proc_slice) {
- _x_post_frame_copy_down(vo_img, vo_img->next);
- vo_img->next->proc_slice(vo_img->next, src);
- _x_post_frame_copy_up(vo_img, vo_img->next);
- }
-}
-#endif
-
-static int dispatch_draw(vo_frame_t *frame, xine_stream_t *stream)
-{
- int skip;
- _x_post_frame_copy_down(frame, frame->next);
- skip = frame->next->draw(frame->next, stream);
- _x_post_frame_copy_up(frame, frame->next);
- return skip;
-}
-
-static int intercept_frame_yuy(post_video_port_t *port, vo_frame_t *frame)
-{
- return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2);
-}
-
-static int post_draw(vo_frame_t *frame, xine_stream_t *stream)
-{
- vo_frame_t *new_frame;
- int skip;
-
- if (frame->bad_frame)
- return dispatch_draw(frame, stream);
-
- new_frame = got_frame(frame);
-
- if (!new_frame)
- return dispatch_draw(frame, stream);
-
- _x_post_frame_copy_down(frame, new_frame);
-
- draw_internal(frame, new_frame);
-
- skip = new_frame->draw(new_frame, stream);
- _x_post_frame_copy_up(frame, new_frame);
- new_frame->free(new_frame);
-
- return skip;
-}
-
diff --git a/xine/ts2es.c b/xine/ts2es.c
deleted file mode 100644
index bb06d3ea..00000000
--- a/xine/ts2es.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * ts2es.c: demux MPEG-TS -> ES
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: ts2es.c,v 1.5 2009-08-25 10:09:20 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/buffer.h>
-
-#include "../tools/ts.h"
-#include "../tools/pes.h"
-
-#include "ts2es.h"
-
-#define LOG_MODULENAME "[demux_vdr] "
-#define SysLogLevel iSysLogLevel
-#include "../logdefs.h"
-
-
-struct ts2es_s {
- fifo_buffer_t *fifo;
- uint32_t stream_type;
- uint32_t xine_buf_type;
-
- buf_element_t *buf;
- int pes_start;
- int first_pusi_seen;
- int video;
- int64_t pts;
-};
-
-
-static void ts2es_parse_pes(ts2es_t *this)
-{
- if (!DATA_IS_PES(this->buf->content)) {
- LOGMSG("ts2es: payload not PES ?");
- return;
- }
-
- /* parse PES header */
- uint hdr_len = PES_HEADER_LEN(this->buf->content);
- uint8_t pes_pid = this->buf->content[3];
- uint pes_len = (this->buf->content[4] << 8) | this->buf->content[5];
-
- /* parse PTS */
- this->buf->pts = pes_get_pts(this->buf->content, this->buf->size);
- if(this->buf->pts >= 0)
- this->pts = this->buf->pts;
- else
- this->pts = 0;
-
- /* strip PES header */
- this->buf->content += hdr_len;
- this->buf->size -= hdr_len;
-
- /* parse substream header */
-
- if (pes_pid != PRIVATE_STREAM1)
- return;
-
- /* RAW AC3 audio ? -> do nothing */
- if (this->stream_type == STREAM_AUDIO_AC3) {
- this->xine_buf_type |= BUF_AUDIO_A52;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- /* AC3 syncword in beginning of PS1 payload ? */
- if (this->buf->content[0] == 0x0B &&
- this->buf->content[1] == 0x77) {
- /* --> RAW AC3 audio - do nothing */
- this->xine_buf_type |= BUF_AUDIO_A52;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- /* audio in PS1 */
- if (this->stream_type == ISO_13818_PES_PRIVATE) {
-
- if ((this->buf->content[0] & 0xf0) == 0x80) {
- /* AC3, strip substream header */
- this->buf->content += 4;
- this->buf->size -= 4;
- this->xine_buf_type |= BUF_AUDIO_A52;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- if ((this->buf->content[0] & 0xf0) == 0xa0) {
- /* PCM, strip substream header */
- int pcm_offset;
- for (pcm_offset=0; ++pcm_offset < this->buf->size-1 ; ) {
- if (this->buf->content[pcm_offset] == 0x01 &&
- this->buf->content[pcm_offset+1] == 0x80 ) { /* START */
- pcm_offset += 2;
- break;
- }
- }
- this->buf->content += pcm_offset;
- this->buf->size -= pcm_offset;
-
- this->xine_buf_type |= BUF_AUDIO_LPCM_BE;
- this->buf->type = this->xine_buf_type;
- return;
- }
-
- LOGMSG("ts2es: unhandled PS1 substream 0x%x", this->buf->content[0]);
- return;
- }
-
- /* DVB SPU */
- if (this->stream_type == STREAM_DVBSUB) {
- if (this->buf->content[0] != 0x20 ||
- this->buf->content[1] != 0x00)
- LOGMSG("ts2es: DVB SPU, invalid PES substream header");
- this->buf->decoder_info[2] = pes_len - hdr_len - 3 + 9;
- return;
- }
-}
-
-buf_element_t *ts2es_put(ts2es_t *this, uint8_t *data, fifo_buffer_t *src_fifo)
-{
- buf_element_t *result = NULL;
- int bytes = ts_PAYLOAD_SIZE(data);
- int pusi = ts_PAYLOAD_START(data);
-
- if (ts_HAS_ERROR(data)) {
- LOGDBG("ts2es: transport error");
- return NULL;
- }
- if (!ts_HAS_PAYLOAD(data)) {
- LOGDBG("ts2es: no payload, size %d", bytes);
- return NULL;
- }
-
- /* handle new payload unit */
- if (pusi) {
- this->first_pusi_seen = 1;
- this->pes_start = 1;
- if (this->buf) {
-
- this->buf->decoder_flags |= BUF_FLAG_FRAME_END;
- this->buf->pts = this->pts;
-
- result = this->buf;
- this->buf = NULL;
- }
- }
-
- /* need new buffer ? */
- if (!this->buf) {
- /* discard data until first payload start indicator */
- if (!this->first_pusi_seen)
- return NULL;
-
- if (src_fifo && src_fifo != this->fifo) {
- if (!this->video)
- this->buf = this->fifo->buffer_pool_try_alloc(this->fifo);
- if (!this->buf)
- this->buf = src_fifo->buffer_pool_try_alloc(src_fifo);
- if (!this->buf)
- this->buf = this->fifo->buffer_pool_alloc(this->fifo);
- } else {
- this->buf = this->fifo->buffer_pool_alloc(this->fifo);
- }
-
- this->buf->type = this->xine_buf_type;
- this->buf->decoder_info[0] = 1;
- }
-
- /* strip ts header */
- data += TS_SIZE - bytes;
-
- /* copy payload */
- memcpy(this->buf->content + this->buf->size, data, bytes);
- this->buf->size += bytes;
-
- /* parse PES header */
- if (this->pes_start) {
- this->pes_start = 0;
-
- ts2es_parse_pes(this);
- }
-
- /* split large packets */
- if ((this->video && this->buf->size >= 2048+64-TS_SIZE) ||
- this->buf->size >= this->buf->max_size-TS_SIZE) {
-
- this->buf->pts = this->pts;
-
- result = this->buf;
- this->buf = NULL;
- }
-
- return result;
-}
-
-void ts2es_flush(ts2es_t *this)
-{
- if (this->buf) {
-
- this->buf->decoder_flags |= BUF_FLAG_FRAME_END;
- this->buf->pts = this->pts;
-
- this->fifo->put (this->fifo, this->buf);
- this->buf = NULL;
- }
-}
-
-void ts2es_dispose(ts2es_t *data)
-{
- if (data) {
- if (data->buf)
- data->buf->free_buffer(data->buf);
- free(data);
- }
-}
-
-ts2es_t *ts2es_init(fifo_buffer_t *dst_fifo, ts_stream_type stream_type, uint stream_index)
-{
- ts2es_t *data = calloc(1, sizeof(ts2es_t));
- data->fifo = dst_fifo;
-
- data->stream_type = stream_type;
-
- switch(stream_type) {
- /* VIDEO (PES streams 0xe0...0xef) */
- case ISO_11172_VIDEO:
- case ISO_13818_VIDEO:
- case STREAM_VIDEO_MPEG:
- data->xine_buf_type = BUF_VIDEO_MPEG;
- break;
- case ISO_14496_PART2_VIDEO:
- data->xine_buf_type = BUF_VIDEO_MPEG4;
- break;
- case ISO_14496_PART10_VIDEO:
- data->xine_buf_type = BUF_VIDEO_H264;
- break;
-
- /* AUDIO (PES streams 0xc0...0xdf) */
- case ISO_11172_AUDIO:
- case ISO_13818_AUDIO:
- data->xine_buf_type = BUF_AUDIO_MPEG;
- break;
- case ISO_13818_PART7_AUDIO:
- case ISO_14496_PART3_AUDIO:
- data->xine_buf_type = BUF_AUDIO_AAC;
- break;
-
- /* AUDIO (PES stream 0xbd) */
- case ISO_13818_PES_PRIVATE:
- data->xine_buf_type = 0;
- /* detect from PES substream header */
- break;
-
- /* DVB SPU (PES stream 0xbd) */
- case STREAM_DVBSUB:
- data->xine_buf_type = BUF_SPU_DVB;
- break;
-
- /* RAW AC3 */
- case STREAM_AUDIO_AC3:
- data->xine_buf_type = BUF_AUDIO_A52;
- break;
-
- default:
- LOGMSG("ts2es: unknown stream type 0x%x", stream_type);
- break;
- }
-
- /* substream ID (audio/SPU) */
- data->xine_buf_type |= stream_index;
-
- if ((data->xine_buf_type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE)
- data->video = 1;
-
- return data;
-}
-
diff --git a/xine/ts2es.h b/xine/ts2es.h
deleted file mode 100644
index e009fc1c..00000000
--- a/xine/ts2es.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * ts2es.h: demux MPEG-TS -> ES
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: ts2es.h,v 1.2 2009-08-18 10:04:32 phintuka Exp $
- *
- */
-
-#ifndef _DEMUX_XVDR_TS2ES_H_
-#define _DEMUX_XVDR_TS2ES_H_
-
-typedef struct ts2es_s ts2es_t;
-
-ts2es_t *ts2es_init (fifo_buffer_t *dst_fifo, ts_stream_type stream_type, uint stream_index);
-buf_element_t *ts2es_put (ts2es_t *ts2es, uint8_t *ts_packet, fifo_buffer_t *src_fifo);
-void ts2es_flush (ts2es_t *ts2es);
-void ts2es_dispose (ts2es_t *ts2es);
-
-#endif /* _DEMUX_XVDR_TS2ES_H_ */
diff --git a/xine/vo_hook.c b/xine/vo_hook.c
deleted file mode 100644
index 89190b9c..00000000
--- a/xine/vo_hook.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * vo_hook.c: Intercept video driver
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_hook.c,v 1.5 2009-05-09 16:05:06 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-
-#define LOG_MODULENAME "[xine-vo ] "
-#include "../logdefs.h"
-
-#include "vo_hook.h"
-#include "vo_post.h"
-
-/* This module supports only video driver interface version 21 */
-#if (VIDEO_OUT_DRIVER_IFACE_VERSION < 21)
-# error xine-lib VIDEO_OUT_DRIVER_IFACE_VERSION < 21
-#endif
-
-
-/*
- * default handlers
- *
- * - Forward function call to original driver
- */
-
-#define DEF_HANDLER3(RET, NAME, ARG1, ARG2, ARG3) \
-RET vo_def_##NAME (vo_driver_t *self, ARG1 a1, ARG2 a2, ARG3 a3) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver, a1, a2, a3); \
-}
-
-#define DEF_HANDLER2(RET, NAME, ARG1, ARG2) \
-RET vo_def_##NAME (vo_driver_t *self, ARG1 a1, ARG2 a2) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver, a1, a2); \
-}
-
-#define DEF_HANDLER1(RET, NAME, ARG1) \
-RET vo_def_##NAME (vo_driver_t *self, ARG1 a1) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver, a1); \
-}
-
-#define DEF_HANDLER0(RET, NAME) \
-RET vo_def_##NAME (vo_driver_t *self) { \
- vo_driver_hook_t *this = (vo_driver_hook_t *) self; \
- return this->orig_driver-> NAME (this->orig_driver); \
-}
-
-/*
- *
- */
-
-DEF_HANDLER0(uint32_t, get_capabilities);
-DEF_HANDLER0(vo_frame_t*, alloc_frame);
-
-void vo_def_update_frame_format (vo_driver_t *self, vo_frame_t *img,
- uint32_t width, uint32_t height,
- double ratio, int format, int flags)
-{
- vo_driver_hook_t *this = (vo_driver_hook_t *) self;
- return this->orig_driver-> update_frame_format (this->orig_driver, img, width, height, ratio, format, flags);
-}
-
-DEF_HANDLER1(void, display_frame, vo_frame_t * );
-DEF_HANDLER2(void, overlay_begin, vo_frame_t *, int );
-DEF_HANDLER2(void, overlay_blend, vo_frame_t *, vo_overlay_t * );
-DEF_HANDLER1(void, overlay_end, vo_frame_t *);
-DEF_HANDLER1(int, get_property, int);
-DEF_HANDLER2(int, set_property, int, int);
-DEF_HANDLER3(void, get_property_min_max, int, int*, int*);
-DEF_HANDLER2(int, gui_data_exchange, int, void * );
-DEF_HANDLER0(int, redraw_needed );
-
-void vo_def_dispose(vo_driver_t *self)
-{
- vo_driver_hook_t *this = (vo_driver_hook_t *) self;
- if (this->orig_driver)
- this->orig_driver->dispose(this->orig_driver);
- free(self);
-}
-
-/*
- * vo_def_hooks_init()
- *
- * initialize driver_hook_t with default handlers
- *
- */
-static void vo_proxy_hooks_init(vo_driver_t *drv, vo_driver_t *next_driver)
-{
- drv->get_capabilities = drv->get_capabilities ?: vo_def_get_capabilities;
- drv->alloc_frame = drv->alloc_frame ?: vo_def_alloc_frame;
- drv->update_frame_format = drv->update_frame_format ?: vo_def_update_frame_format;
- drv->display_frame = drv->display_frame ?: vo_def_display_frame;
-
- drv->get_property = drv->get_property ?: vo_def_get_property;
- drv->set_property = drv->set_property ?: vo_def_set_property;
- drv->get_property_min_max = drv->get_property_min_max ?: vo_def_get_property_min_max;
- drv->gui_data_exchange = drv->gui_data_exchange ?: vo_def_gui_data_exchange;
- drv->redraw_needed = drv->redraw_needed ?: vo_def_redraw_needed;
- drv->dispose = drv->dispose ?: vo_def_dispose;
-
- /* drop old default handlers for OSD (OSD handlers are optional) */
- if (drv->overlay_begin == vo_def_overlay_begin)
- drv->overlay_begin = NULL;
- if (drv->overlay_blend == vo_def_overlay_blend)
- drv->overlay_blend = NULL;
- if (drv->overlay_end == vo_def_overlay_end)
- drv->overlay_end = NULL;
-
- /* Set proxy handlers for OSD only if next driver has OSD handlers */
- if (!drv->overlay_begin && next_driver->overlay_begin)
- drv->overlay_begin = vo_def_overlay_begin;
- if (!drv->overlay_blend && next_driver->overlay_blend)
- drv->overlay_blend = vo_def_overlay_blend;
- if (!drv->overlay_end && next_driver->overlay_end)
- drv->overlay_end = vo_def_overlay_end;
-
- drv->node = next_driver->node; /* ??? used only by plugin_loader ? */
-}
-
-/*
- *
- */
-
-/* from xine-lib video_out.c */
-typedef struct {
- xine_video_port_t vo; /* public part */
- vo_driver_t *driver;
- /* ... */
-} vos_t;
-
-/*
- * wire_video_driver()
- *
- */
-int wire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook)
-{
- vo_driver_t *vos_driver = ((vos_t*)video_port)->driver;
-
- if (video_port->driver != vos_driver) {
- LOGMSG("wire_video_driver() FAILED (vo_driver != vos_driver)");
- return 0;
- }
-
- /*LOGMSG("wire_video_driver: vo_driver == vos_driver");*/
-
- /* wire */
-
- /* set proxy handlers for undefined methods */
- vo_proxy_hooks_init(hook, video_port->driver);
-
- /* append original driver chain to new driver */
- ((vo_driver_hook_t *)hook)->orig_driver = video_port->driver;
-
- /* push new driver to start of driver chain */
- video_port->driver = hook;
- ((vos_t*)video_port)->driver = hook;
-
- return 1;
-}
-
-/*
- * unwire_video_driver()
- *
- */
-int unwire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook_gen, vo_driver_t *video_out)
-{
- vo_driver_hook_t *hook = (vo_driver_hook_t*)hook_gen;
- vo_driver_hook_t *next = (vo_driver_hook_t*)video_port->driver;
-
- if (next == hook) {
- /* special handling for first entry */
- video_port->driver = next->orig_driver;
- /* need to patch video_port private driver pointer too ... */
- ((vos_t*)video_port)->driver = next->orig_driver;
- next->orig_driver = NULL;
- return 1;
- }
-
- vo_driver_hook_t *prev = next;
- while (next && next != hook && (vo_driver_t*)next != video_out) {
- prev = next;
- next = (vo_driver_hook_t*)next->orig_driver;
- }
-
- if (prev && next == hook) {
- prev->orig_driver = next->orig_driver;
- next->orig_driver = NULL;
- return 1;
- }
-
- return 0;
-}
diff --git a/xine/vo_hook.h b/xine/vo_hook.h
deleted file mode 100644
index 0de93fd0..00000000
--- a/xine/vo_hook.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * vo_hook.h: Intercept video driver
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_hook.h,v 1.3 2008-12-14 01:14:54 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_HOOK_H
-#define _XINELIBOUTPUT_VO_HOOK_H
-
-#include <xine/video_out.h>
-
-/*
- * synchronous video post plugins
- * internal API
- */
-
-
-/*
- * vo_driver_hook_t
- *
- * Used as base for video driver hooks
- */
-
-typedef struct driver_hook_s {
- vo_driver_t vo; /* public part */
- vo_driver_t *orig_driver;
-} vo_driver_hook_t;
-
-/* proxy handlers: forward call to original driver */
-
-uint32_t vo_def_get_capabilities(vo_driver_t *self);
-int vo_def_get_property(vo_driver_t *self, int prop);
-int vo_def_set_property(vo_driver_t *self, int prop, int val);
-
-void vo_def_dispose(vo_driver_t *self);
-
-
-#endif /* _XINELIBOUTPUT_VO_HOOK_H */
diff --git a/xine/vo_osdreorder.c b/xine/vo_osdreorder.c
deleted file mode 100644
index 6fed9e3c..00000000
--- a/xine/vo_osdreorder.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * vo_osdreorder.c: OSD re-ordering video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdreorder.c,v 1.1 2009-03-17 12:14:41 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-
-#include "vo_props.h"
-#include "vo_hook.h"
-
-/*
- * osdreorder_hook_t
- */
-typedef struct {
- vo_driver_hook_t h;
-
- /* currently showing OSDs in new drawing order */
- vo_overlay_t *overlay[50];
-
-} osdreorder_hook_t;
-
-/*
- *
- */
-
-static int osd_level(vo_overlay_t *overlay)
-{
- if (overlay->hili_rgb_clut != VDR_OSD_MAGIC /* not from vdr */) {
- return 9999;
- }
-
- /* VDR input plugin stores some control data in hili clut area */
- vdr_osd_extradata_t *data = (vdr_osd_extradata_t *)overlay->hili_color;
- return data->layer;
-}
-
-/*
- * interface
- */
-
-/*
- * override overlay_blend()
- */
-static void osdreorder_overlay_blend (vo_driver_t *self, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- osdreorder_hook_t *this = (osdreorder_hook_t*)self;
- int my_level = osd_level(overlay);
- int i;
-
- /* search position */
- for (i = 0; this->overlay[i] && osd_level(this->overlay[i]) >= my_level; i++)
- ;
-
- /* make room */
- if (this->overlay[i])
- memmove(&this->overlay[i+1], &this->overlay[i], (49-i)*sizeof(vo_overlay_t*));
-
- this->overlay[i] = overlay;
- return;
-}
-
-/*
- * override overlay_end()
- */
-static void osdreorder_overlay_end (vo_driver_t *self, vo_frame_t *vo_img)
-{
- osdreorder_hook_t *this = (osdreorder_hook_t*)self;
- int i;
-
- for (i = 0; this->overlay[i]; i++) {
- this->h.orig_driver->overlay_blend(this->h.orig_driver, vo_img, this->overlay[i]);
- this->overlay[i] = NULL;
- }
-
- /* redirect */
- if (this->h.orig_driver->overlay_end)
- this->h.orig_driver->overlay_end(this->h.orig_driver, vo_img);
-}
-
-/*
- * init()
- */
-vo_driver_t *osd_reorder_init(void)
-{
- osdreorder_hook_t *this = calloc(1, sizeof(osdreorder_hook_t));
-
- /* OSD interface */
- this->h.vo.overlay_blend = osdreorder_overlay_blend;
- this->h.vo.overlay_end = osdreorder_overlay_end;
-
- return &this->h.vo;
-}
-
diff --git a/xine/vo_osdreorder.h b/xine/vo_osdreorder.h
deleted file mode 100644
index 15ec7a6b..00000000
--- a/xine/vo_osdreorder.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * vo_osdreorder.h: OSD re-ordering video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdreorder.h,v 1.1 2009-03-17 12:14:41 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_OSDREORDER_H
-#define _XINELIBOUTPUT_VO_OSDREORDER_H
-
-vo_driver_t *osd_reorder_init(void);
-
-#endif /* _XINELIBOUTPUT_VO_OSDREORDER_H */
diff --git a/xine/vo_osdscaler.c b/xine/vo_osdscaler.c
deleted file mode 100644
index d9562d9e..00000000
--- a/xine/vo_osdscaler.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * vo_osdscaler.c: OSD scaling video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdscaler.c,v 1.4 2009-05-27 08:37:06 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/video_out.h>
-#ifdef SWBLEND
-# include <xine/alphablend.h>
-#endif
-
-#define LOG_MODULENAME "[osdscaler] "
-#include "../logdefs.h"
-
-#include "vo_props.h"
-#include "vo_hook.h"
-
-/*#define LOGOSD(x...) LOGMSG(x)*/
-#define LOGOSD(x...)
-
-typedef rle_elem_t xine_rle_elem_t;
-
-#include "../tools/rle.h"
-
-
-/* Make sure our properties won't overlap with xine's properties */
-#if VO_NUM_PROPERTIES > VO_PROP_OSD_SCALING
-# error VO_NUM_PROPERTIES > VO_PROP_OSD_SCALING
-#endif
-
-#undef ABS
-#define ABS(x) ((x)<0?-(x):(x))
-
-
-/*
- * osd_data_t
- *
- * - cache scaled OSD data
- */
-
-typedef struct osd_data_s osd_data_t;
-
-struct osd_data_s {
- /* original source */
- vo_overlay_t *source;
-
- /* scaled overlay */
- uint8_t scaled : 1;
- vo_overlay_t ovl;
-
- /* for what output resolution overlay was scaled */
- uint16_t output_width;
- uint16_t output_height;
-
- /* linked list */
- osd_data_t *next;
-};
-
-/*
- * osd_data_dispose()
- *
- * - free() osd_data_t and all allocated memory
- */
-static void osd_data_dispose(osd_data_t *data)
-{
- if (data->scaled)
- free(data->ovl.rle);
- free(data);
-}
-
-/*
- * osd_data_clear()
- *
- * - free() whole linked list
- */
-static void osd_data_clear(osd_data_t *data)
-{
- if (data) {
- if (data->next)
- osd_data_clear(data->next);
- osd_data_dispose(data);
- }
-}
-
-/*
- * osd_data_remove()
- *
- * - remove (and free) specific osd_data_t item from linked list
- */
-static void osd_data_remove(osd_data_t **list, osd_data_t *data)
-{
- if (!list || !*list)
- return;
-
- /* special handling for list head */
- if (data == *list) {
- *list = data->next;
- free(data);
- return;
- }
-
- osd_data_t *it = *list;
- while (it) {
- if (data == it->next) {
- it->next = data->next;
- free(data);
- return;
- }
- it = it->next;
- }
-}
-
-/*
- * osd_data_init()
- *
- * - allocate and fill new osd_data_t
- *
- */
-static osd_data_t *osd_data_init(vo_overlay_t *ovl, osd_data_t *next,
- uint32_t factor_x, uint32_t factor_y)
-{
- osd_data_t *data = calloc(1, sizeof(osd_data_t));
-
- data->source = ovl;
- data->next = next;
-
- memcpy(&data->ovl, ovl, sizeof(vo_overlay_t));
-
- int num_rle = data->ovl.num_rle;
-
- /* new position and size */
- int x2 = ovl->x + ovl->width + 1;
- int y2 = ovl->y + ovl->height + 1;
- x2 = ((x2+1) * factor_x) >> 16;
- y2 = ((y2+1) * factor_y) >> 16;
- data->ovl.x = (ovl->x * factor_x) >> 16;
- data->ovl.y = (ovl->y * factor_y) >> 16;
- data->ovl.width = x2 - data->ovl.x - 1;
- data->ovl.height = y2 - data->ovl.y - 1;
-
- data->ovl.rle = (rle_elem_t*)
- rle_scale_nearest((struct xine_rle_elem_s*)ovl->rle, &num_rle,
- ovl->width, ovl->height,
- data->ovl.width, data->ovl.height);
- data->ovl.num_rle = num_rle;
- data->scaled = 1;
-
- LOGOSD("I: %d,%d %dx%d", ovl->x, ovl->y, ovl->width, ovl->height);
- LOGOSD("O: %d,%d %dx%d", data->ovl.x, data->ovl.y, data->ovl.width, data->ovl.height);
-
- return data;
-}
-
-/*
- * osdscaler_hook_t
- */
-typedef struct {
- vo_driver_hook_t h;
-
- /* configuration */
- uint8_t enable;
- uint8_t unscaled_supported;
- uint8_t custom_extent_supported;
- uint8_t argb_supported;
-
- /* current output */
- uint16_t output_width;
- uint16_t output_height;
- uint32_t factor_x; /* scaling factor << 16 */
- uint32_t factor_y;
- uint16_t x_move; /* OSD displacement */
- uint16_t y_move;
-
- /* currently showing OSDs - pre-scaled data */
- osd_data_t *active_osds;
-
-} osdscaler_hook_t;
-
-/*
- *
- */
-
-/*
- * override overlay_begin()
- */
-static void osdscaler_overlay_begin (vo_driver_t *self, vo_frame_t *frame, int changed)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- /* assume we're wired when called */
- if (!this->h.orig_driver) {
- LOGMSG("osdscaler_overlay_begin: assertion this->h.orig_driver failed !");
- abort();
- }
-
- /* re-scale all if OSD changed */
- if (changed) {
- LOGOSD("osdscaler_overlay_begin: changed = 1");
- osd_data_clear(this->active_osds);
- this->active_osds = NULL;
- this->unscaled_supported = (vo_def_get_capabilities(self) & VO_CAP_UNSCALED_OVERLAY);
- /* VO_CAP_OSDSCALING == VO_CAP_CUSTOM_EXTENT_OVERLAY */
- this->custom_extent_supported = (vo_def_get_capabilities(self) & VO_CAP_OSDSCALING);
- /* VO_CAP_ARGB == VO_CAP_ARGB_LAYER_OVERLAY */
- this->argb_supported = (vo_def_get_capabilities(self) & VO_CAP_ARGB);
- }
-
- /* redirect */
- if (this->h.orig_driver->overlay_begin)
- this->h.orig_driver->overlay_begin(this->h.orig_driver, frame, changed);
-}
-
-static int check_for_scaling(osdscaler_hook_t *this, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- this->x_move = this->y_move = 0;
-
- if (!this->enable)
- return 0;
-
- /* check for VDR OSD */
- if (overlay->hili_rgb_clut != VDR_OSD_MAGIC /* not from vdr */) {
- LOGOSD("overlay: source not VDR");
- return 0;
- }
-
- /* VDR input plugin stores some control data in hili clut area */
- vdr_osd_extradata_t *data = (vdr_osd_extradata_t *)overlay->hili_color;
- int extent_width = data->extent_width;
- int extent_height = data->extent_height;
-
- if (!data->scaling)
- return 0;
-
-#if 0
- if (this->custom_extent_supported) {
- /* let the "real" video driver do scaling */
- return 0;
- }
-#else
-# ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- /* disable VDPAU HW scaler */
- overlay->extent_width = 0;
- overlay->extent_height = 0;
-# endif
-#endif
-
- /* detect output size */
- if (overlay->unscaled && this->unscaled_supported) {
- this->output_width = vo_def_get_property((vo_driver_t*)this, VO_PROP_WINDOW_WIDTH);
- this->output_height = vo_def_get_property((vo_driver_t*)this, VO_PROP_WINDOW_HEIGHT);
- } else {
- this->output_width = frame->width;
- this->output_height = frame->height;
- /* check cropping */
- if (frame->crop_top > 0) this->output_height -= frame->crop_top;
- if (frame->crop_bottom > 0) this->output_height -= frame->crop_bottom;
- if (frame->crop_left > 0) this->output_width -= frame->crop_left;
- if (frame->crop_right > 0) this->output_width -= frame->crop_right;
- }
-
- /* check if scaling should be done */
- if (ABS(this->output_width - extent_width) > extent_width /20 ||
- ABS(this->output_height - extent_height) > extent_height/20 ) {
- LOGOSD("scaling required");
- this->factor_x = 0x10000 * this->output_width / extent_width;
- this->factor_y = 0x10000 * this->output_height / extent_height;
- return 1;
- }
-
- /* if no scaling was required, we may still need to re-center OSD */
- if(this->output_width != extent_width)
- this->x_move = (this->output_width - extent_width)/2;
- if(this->output_height != extent_height)
- this->y_move = (this->output_height - extent_height)/2;
-
- return 0;
-}
-
-static vo_overlay_t *scale_overlay(osdscaler_hook_t *this, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- if (check_for_scaling(this, frame, overlay)) {
-
- /* find old scaled OSD */
- osd_data_t *scaled = this->active_osds;
- while (scaled && scaled->source != overlay)
- scaled = scaled->next;
-
- /* output size changed since last scaling (need to re-scale) ? */
- if (scaled &&
- (scaled->output_width != this->output_width ||
- scaled->output_height != this->output_height)) {
-
- LOGOSD("re-scaling required: output size changed %dx%d -> %dx%d",
- scaled->output_width, scaled->output_height, this->output_width, this->output_height);
-
- osd_data_remove(&this->active_osds, scaled);
- scaled = NULL;
- }
-
- /* not scaled found ? */
- if (!scaled) {
- LOGOSD("scaling OSD");
- scaled = this->active_osds = osd_data_init(overlay, this->active_osds,
- this->factor_x, this->factor_y);
- scaled->output_width = this->output_width;
- scaled->output_height = this->output_height;
- }
-
- /* override */
- overlay = &scaled->ovl;
- }
-
- return overlay;
-}
-
-
-/*
- * interface
- */
-
-/*
- * override overlay_blend()
- */
-static void osdscaler_overlay_blend (vo_driver_t *self, vo_frame_t *frame, vo_overlay_t *overlay)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- overlay = scale_overlay(this, frame, overlay);
-
- /* redirect */
- if (this->h.orig_driver->overlay_blend)
- this->h.orig_driver->overlay_blend(this->h.orig_driver, frame, overlay);
-}
-
-/*
- * override overlay_end()
- */
-static void osdscaler_overlay_end (vo_driver_t *self, vo_frame_t *vo_img)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- /* redirect */
- if (this->h.orig_driver->overlay_end)
- this->h.orig_driver->overlay_end(this->h.orig_driver, vo_img);
-}
-
-
-/*
- * Management interface
- */
-
-/*
- * override get_capabilities()
- */
-static uint32_t osdscaler_get_capabilities(vo_driver_t *self)
-{
- return vo_def_get_capabilities(self) |
- VO_CAP_OSDSCALING;
-}
-
-/*
- * override get_property()
- */
-static int osdscaler_get_property(vo_driver_t *self, int prop)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- switch (prop) {
- case VO_PROP_OSD_SCALING: return this->enable;
- default:;
- }
-
- return vo_def_get_property(self, prop);
-}
-
-/*
- * override set_property()
- */
-static int osdscaler_set_property(vo_driver_t *self, int prop, int val)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t*)self;
-
- switch (prop) {
- case VO_PROP_OSD_SCALING:
- if (this->enable != val) {
- LOGOSD("osdscaler_set_property: enable %d->%d", this->enable, val);
- this->enable = val?1:0;
- }
- return this->enable;
- }
-
- return vo_def_set_property(self, prop, val);
-}
-
-
-/*
- * dispose()
- */
-static void osdscaler_dispose(vo_driver_t *self)
-{
- osdscaler_hook_t *this = (osdscaler_hook_t *) self;
-
- osd_data_clear(this->active_osds);
-
- vo_def_dispose(self);
-}
-
-
-/*
- * init()
- */
-vo_driver_t *osdscaler_init(void)
-{
- osdscaler_hook_t *this = calloc(1, sizeof(osdscaler_hook_t));
-
- /* OSD interface */
- this->h.vo.overlay_begin = osdscaler_overlay_begin;
- this->h.vo.overlay_blend = osdscaler_overlay_blend;
- this->h.vo.overlay_end = osdscaler_overlay_end;
-
- /* management interface */
- this->h.vo.get_capabilities = osdscaler_get_capabilities;
- this->h.vo.get_property = osdscaler_get_property;
- this->h.vo.set_property = osdscaler_set_property;
-
- this->h.vo.dispose = osdscaler_dispose;
-
- /* initialize data */
- this->enable = 0;
-
- return &this->h.vo;
-}
-
diff --git a/xine/vo_osdscaler.h b/xine/vo_osdscaler.h
deleted file mode 100644
index fe7d21d0..00000000
--- a/xine/vo_osdscaler.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * vo_osdscaler.h: OSD scaling video-out post plugin
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_osdscaler.h,v 1.1 2008-11-20 09:24:27 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_OSDSCALER_H
-#define _XINELIBOUTPUT_VO_OSDSCALER_H
-
-vo_driver_t *osdscaler_init(void);
-
-#endif /* _XINELIBOUTPUT_VO_OSDSCALER_H */
diff --git a/xine/vo_post.h b/xine/vo_post.h
deleted file mode 100644
index 8ed7b076..00000000
--- a/xine/vo_post.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * vo_post.h: Intercept video driver
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_post.h,v 1.3 2008-12-14 01:19:21 phintuka Exp $
- *
- */
-
-#ifndef _XINELIBOUTPUT_VO_POST_H
-#define _XINELIBOUTPUT_VO_POST_H
-
-#include <xine/video_out.h>
-
-/*
- * synchronous video post plugins
- * public API
- */
-
-/* Wire / unwire hook chain to video port */
-int wire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook);
-int unwire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook, vo_driver_t *video_out);
-
-#endif /* _XINELIBOUTPUT_VO_POST_H */
diff --git a/xine/vo_props.h b/xine/vo_props.h
deleted file mode 100644
index dc377dfc..00000000
--- a/xine/vo_props.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * vo_props.h: Extended video-out capabilities and properties
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: vo_props.h,v 1.4 2009-03-17 12:20:33 phintuka Exp $
- *
- */
-
-#ifndef XINELIBOUTPUT_VO_PROPS_H_
-#define XINELIBOUTPUT_VO_PROPS_H_
-
-/*
- * Extended vo capabilities
- */
-
-/* output can scale OSD */
-#ifdef VO_CAP_CUSTOM_EXTENT_OVERLAY
- /* xine-lib 1.2 */
-# define VO_CAP_OSDSCALING VO_CAP_CUSTOM_EXTENT_OVERLAY
-#else
-# define VO_CAP_OSDSCALING 0x01000000
-#endif
-
-/* Output can blend ARGB surfaces */
-#ifdef VO_CAP_ARGB_LAYER_OVERLAY
-# define VO_CAP_ARGB VO_CAP_ARGB_LAYER_OVERLAY
-#else
-# define VO_CAP_ARGB 0x02000000
-#endif
-
-
-/*
- * Extended vo properties
- */
-
-/* enable/disable OSD scaling */
-#define VO_PROP_OSD_SCALING 0x1001
-
-
-/*
- * VDR OSD tagging and extra data
- */
-
-/* VDR OSD , stored in overlay hili_rgb_clut member */
-#define VDR_OSD_MAGIC -9999
-
-/* VDR OSD extra data, stored in overlay hili clut data */
-typedef struct {
- /* extent of reference coordinate system */
- uint16_t extent_width;
- uint16_t extent_height;
- /* overlay layer */
- uint32_t layer;
- /* scaling: 0 - disable , 1...N - quality */
- uint8_t scaling;
-} vdr_osd_extradata_t;
-
-#endif /* XINELIBOUTPUT_VO_PROPS_H_ */
diff --git a/xine/xvdr_metronom.c b/xine/xvdr_metronom.c
deleted file mode 100644
index 1a2316ab..00000000
--- a/xine/xvdr_metronom.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * xvdr_metronom.c:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xvdr_metronom.c,v 1.1 2009-05-22 21:02:30 phintuka Exp $
- *
- */
-
-#include <stdlib.h>
-
-#include <xine/xine_internal.h>
-#include <xine/metronom.h>
-
-#define LOG_MODULENAME "[metronom ] "
-#define SysLogLevel iSysLogLevel
-#include "../logdefs.h"
-
-#define XVDR_METRONOM_COMPILE
-#include "xvdr_metronom.h"
-
-
-static void got_video_frame(metronom_t *metronom, vo_frame_t *frame)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
-
- this->video_frames++;
-
- if (this->frame_decoded)
- this->frame_decoded(this->handle, this->video_frames, this->audio_frames);
-
- return this->orig_metronom->got_video_frame (this->orig_metronom, frame);
-}
-
-static int64_t got_audio_samples(metronom_t *metronom, int64_t pts, int nsamples)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
-
- this->audio_frames++;
-
- if (this->frame_decoded)
- this->frame_decoded(this->handle, this->video_frames, this->audio_frames);
-
- return this->orig_metronom->got_audio_samples (this->orig_metronom, pts, nsamples);
-}
-
-/*
- * dummy hooks
- */
-
-static int64_t got_spu_packet(metronom_t *metronom, int64_t pts)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- return this->orig_metronom->got_spu_packet(this->orig_metronom, pts);
-}
-
-static void handle_audio_discontinuity(metronom_t *metronom, int type, int64_t disc_off)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->handle_audio_discontinuity(this->orig_metronom, type, disc_off);
-}
-
-static void handle_video_discontinuity(metronom_t *metronom, int type, int64_t disc_off)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->handle_video_discontinuity(this->orig_metronom, type, disc_off);
-}
-
-static void set_audio_rate(metronom_t *metronom, int64_t pts_per_smpls)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->set_audio_rate(this->orig_metronom, pts_per_smpls);
-}
-
-static void set_option(metronom_t *metronom, int option, int64_t value)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->set_option(this->orig_metronom, option, value);
-}
-
-static int64_t get_option(metronom_t *metronom, int option)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- return this->orig_metronom->get_option(this->orig_metronom, option);
-}
-
-static void set_master(metronom_t *metronom, metronom_t *master)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
- this->orig_metronom->set_master(this->orig_metronom, master);
-}
-
-static void metronom_exit(metronom_t *metronom)
-{
- xvdr_metronom_t *this = (xvdr_metronom_t *)metronom;
-
- LOGERR("xvdr_metronom: metronom_exit() called !");
-
- /* un-hook */
- this->stream->metronom = this->orig_metronom;
- this->orig_metronom = NULL;
- this->stream = NULL;
-
- this->orig_metronom->exit(this->orig_metronom);
-}
-
-/*
- * xvdr_metronom_t
- */
-
-static void xvdr_metronom_set_cb(xvdr_metronom_t *this,
- void (*cb)(void*, uint, uint),
- void *handle)
-{
- this->handle = handle;
- this->frame_decoded = cb;
-}
-
-static void xvdr_metronom_dispose(xvdr_metronom_t *this)
-{
- if (this->stream && this->orig_metronom)
- this->stream->metronom = this->orig_metronom;
-
- free(this);
-}
-
-static void xvdr_metronom_reset_frames(xvdr_metronom_t *this)
-{
- this->video_frames = this->audio_frames = 0;
-}
-
-/*
- * init
- */
-
-xvdr_metronom_t *xvdr_metronom_init(xine_stream_t *stream)
-{
- xvdr_metronom_t *this = calloc(1, sizeof(xvdr_metronom_t));
-
- this->stream = stream;
- this->orig_metronom = stream->metronom;
-
- this->set_cb = xvdr_metronom_set_cb;
- this->reset_frames = xvdr_metronom_reset_frames;
- this->dispose = xvdr_metronom_dispose;
-
- this->metronom.set_audio_rate = set_audio_rate;
- this->metronom.got_video_frame = got_video_frame;
- this->metronom.got_audio_samples = got_audio_samples;
- this->metronom.got_spu_packet = got_spu_packet;
- this->metronom.handle_audio_discontinuity = handle_audio_discontinuity;
- this->metronom.handle_video_discontinuity = handle_video_discontinuity;
- this->metronom.set_option = set_option;
- this->metronom.get_option = get_option;
- this->metronom.set_master = set_master;
-
- this->metronom.exit = metronom_exit;
-
- /* hook up to stream */
- this->stream->metronom = &this->metronom;
-
- return this;
-}
diff --git a/xine/xvdr_metronom.h b/xine/xvdr_metronom.h
deleted file mode 100644
index 21188f28..00000000
--- a/xine/xvdr_metronom.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * xvdr_metronom.h:
- *
- * See the main source file 'xineliboutput.c' for copyright information and
- * how to reach the author.
- *
- * $Id: xvdr_metronom.h,v 1.1 2009-05-22 21:02:30 phintuka Exp $
- *
- */
-
-#ifndef XVDR_METRONOM_H
-#define XVDR_METRONOM_H
-
-typedef struct xvdr_metronom_s xvdr_metronom_t;
-
-struct xvdr_metronom_s {
- /* xine-lib metronom interface */
- metronom_t metronom;
-
- /* management interface */
- void (*set_cb) (xvdr_metronom_t *,
- void (*cb) (void *, uint, uint),
- void *);
- void (*reset_frames)(xvdr_metronom_t *);
- void (*dispose) (xvdr_metronom_t *);
-
- /* accumulated frame data */
- volatile uint video_frames;
- volatile uint audio_frames;
-
- /* private data */
-
-#ifdef XVDR_METRONOM_COMPILE
-
- /* original metronom */
- metronom_t *orig_metronom;
- xine_stream_t *stream;
-
- /* callback */
- void *handle;
- void (*frame_decoded)(void *handle, uint video_count, uint audio_count);
-
-#endif
-};
-
-xvdr_metronom_t *xvdr_metronom_init(xine_stream_t *);
-
-
-#endif /* XVDR_METRONOM_H */