summaryrefslogtreecommitdiff
path: root/src/input/vcd/libvcd/pbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/vcd/libvcd/pbc.c')
-rw-r--r--src/input/vcd/libvcd/pbc.c880
1 files changed, 0 insertions, 880 deletions
diff --git a/src/input/vcd/libvcd/pbc.c b/src/input/vcd/libvcd/pbc.c
deleted file mode 100644
index 1b4f1a6c1..000000000
--- a/src/input/vcd/libvcd/pbc.c
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- $Id: pbc.c,v 1.3 2005/01/01 02:43:59 rockyb Exp $
-
- Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
-
- This program 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.
-
- This program 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
-*/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <string.h>
-#include <stddef.h>
-#include <math.h>
-
-#include <cdio/cdio.h>
-#include <cdio/bytesex.h>
-
-/* Public headers */
-#include <libvcd/logging.h>
-#include <libvcd/files.h>
-#include <libvcd/types.h>
-#include <libvcd/info.h>
-
-/* FIXME! Make this really private. */
-#include <libvcd/files_private.h>
-
-/* Private headers */
-#include "vcd_assert.h"
-#include "obj.h"
-#include "pbc.h"
-#include "util.h"
-
-static const char _rcsid[] = "$Id: pbc.c,v 1.3 2005/01/01 02:43:59 rockyb Exp $";
-
-static uint8_t
-_wtime (int seconds)
-{
- if (seconds < 0)
- return 255;
-
- if (seconds <= 60)
- return seconds;
-
- if (seconds <= 2000)
- {
- double _tmp;
-
- _tmp = seconds;
- _tmp -= 60;
- _tmp /= 10;
- _tmp += 60;
-
- return rint (_tmp);
- }
-
- vcd_warn ("wait time of %ds clipped to 2000s", seconds);
-
- return 254;
-}
-
-static pbc_t *
-_vcd_pbc_byid(const VcdObj *obj, const char item_id[])
-{
- CdioListNode *node;
-
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
-
- if (_pbc->id && !strcmp (item_id, _pbc->id))
- return _pbc;
- }
-
- /* not found */
- return NULL;
-}
-
-unsigned
-_vcd_pbc_lid_lookup (const VcdObj *obj, const char item_id[])
-{
- CdioListNode *node;
- unsigned n = 1;
-
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
-
- vcd_assert (n < 0x8000);
-
- if (_pbc->id && !strcmp (item_id, _pbc->id))
- return n;
-
- n++;
- }
-
- /* not found */
- return 0;
-}
-
-static void
-_set_area_helper (pbc_area_t *dest, const pbc_area_t *src, const char sel_id[])
-{
- memset (dest, 0, sizeof (pbc_area_t));
-
- if (src)
- {
- if (src->x1 || src->x2 || src->y1 || src->y2) /* not disabled */
- {
- if (src->x1 >= src->x2)
- vcd_error ("selection '%s': area x1 >= x2 (%d >= %d)",
- sel_id, src->x1, src->x2);
-
- if (src->y1 >= src->y2)
- vcd_error ("selection '%s': area y1 >= y2 (%d >= %d)",
- sel_id, src->y1, src->y2);
- }
-
- *dest = *src;
- }
-}
-
-enum item_type_t
-_vcd_pbc_lookup (const VcdObj *obj, const char item_id[])
-{
- unsigned id;
-
- vcd_assert (item_id != NULL);
-
- if ((id = _vcd_pbc_pin_lookup (obj, item_id)))
- {
- if (id < 2)
- return ITEM_TYPE_NOTFOUND;
- else if (id < MIN_ENCODED_TRACK_NUM)
- return ITEM_TYPE_TRACK;
- else if (id < 600)
- return ITEM_TYPE_ENTRY;
- else if (id <= MAX_ENCODED_SEGMENT_NUM)
- return ITEM_TYPE_SEGMENT;
- else
- vcd_assert_not_reached ();
- }
- else if (_vcd_pbc_lid_lookup (obj, item_id))
- return ITEM_TYPE_PBC;
-
- return ITEM_TYPE_NOTFOUND;
-}
-
-uint16_t
-_vcd_pbc_pin_lookup (const VcdObj *obj, const char item_id[])
-{
- int n;
- CdioListNode *node;
-
- if (!item_id)
- return 0;
-
- /* check sequence items */
-
- n = 0;
- _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)
- {
- mpeg_sequence_t *_sequence = _cdio_list_node_data (node);
-
- vcd_assert (n < 98);
-
- if (_sequence->id && !strcmp (item_id, _sequence->id))
- return n + 2;
-
- n++;
- }
-
- /* check entry points */
-
- n = 0;
- _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)
- {
- mpeg_sequence_t *_sequence = _cdio_list_node_data (node);
- CdioListNode *node2;
-
- /* default entry point */
-
- if (_sequence->default_entry_id
- && !strcmp (item_id, _sequence->default_entry_id))
- return n + 100;
- n++;
-
- /* additional entry points */
-
- _CDIO_LIST_FOREACH (node2, _sequence->entry_list)
- {
- entry_t *_entry = _cdio_list_node_data (node2);
-
- vcd_assert (n < 500);
-
- if (_entry->id && !strcmp (item_id, _entry->id))
- return n + 100;
-
- n++;
- }
- }
-
- /* check sequence items */
-
- n = 0;
- _CDIO_LIST_FOREACH (node, obj->mpeg_segment_list)
- {
- mpeg_segment_t *_segment = _cdio_list_node_data (node);
-
- vcd_assert (n < 1980);
-
- if (_segment->id && !strcmp (item_id, _segment->id))
- return n + MIN_ENCODED_SEGMENT_NUM;
-
- n += _segment->segment_count;
- }
-
- return 0;
-}
-
-bool
-_vcd_pbc_available (const VcdObj *obj)
-{
- vcd_assert (obj != NULL);
- vcd_assert (obj->pbc_list != NULL);
-
- if (!_cdio_list_length (obj->pbc_list))
- return false;
-
- if (!_vcd_obj_has_cap_p (obj, _CAP_PBC))
- {
- vcd_warn ("PBC list not empty but VCD type not capable of PBC!");
- return false;
- }
-
- return true;
-}
-
-uint16_t
-_vcd_pbc_max_lid (const VcdObj *obj)
-{
- uint16_t retval = 0;
-
- if (_vcd_pbc_available (obj))
- retval = _cdio_list_length (obj->pbc_list);
-
- return retval;
-}
-
-static size_t
-_vcd_pbc_node_length (const VcdObj *obj, const pbc_t *_pbc, bool extended)
-{
- size_t retval = 0;
-
- if (extended)
- vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X));
-
- switch (_pbc->type)
- {
- int n;
-
- case PBC_PLAYLIST:
- n = _cdio_list_length (_pbc->item_id_list);
- retval = __cd_offsetof (_PsdPlayListDescriptor, itemid[n]);
- break;
-
- case PBC_SELECTION:
- n = _cdio_list_length (_pbc->select_id_list);
-
- retval = __cd_offsetof (PsdSelectionListDescriptor_t, ofs[n]);
-
- if (extended || _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD))
- retval += __cd_offsetof (PsdSelectionListDescriptorExtended, area[n]);
- break;
-
- case PBC_END:
- retval = sizeof (PsdEndListDescriptor);
- break;
-
- default:
- vcd_assert_not_reached ();
- break;
- }
-
- return retval;
-}
-
-static uint16_t
-_lookup_psd_offset (const VcdObj *obj, const char item_id[], bool extended)
-{
- CdioListNode *node;
-
- if (extended)
- vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X));
-
- /* disable it */
- if (!item_id)
- return PSD_OFS_DISABLED;
-
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
-
- if (!_pbc->id || strcmp (item_id, _pbc->id))
- continue;
-
- return (extended ? _pbc->offset_ext : _pbc->offset) / INFO_OFFSET_MULT;
- }
-
- vcd_error ("PSD: referenced PSD '%s' not found", item_id);
-
- /* not found */
- return PSD_OFS_DISABLED;
-}
-
-static void
-_vcd_pin_mark_id (const VcdObj *obj, const char _id[])
-{
- mpeg_sequence_t *_seq;
- mpeg_segment_t *_seg;
-
- vcd_assert (obj != NULL);
-
- if (!_id)
- return;
-
- if ((_seq = _vcd_obj_get_sequence_by_id ((VcdObj *) obj, _id)))
- _seq->referenced = true;
-
- if ((_seg = _vcd_obj_get_segment_by_id ((VcdObj *) obj, _id)))
- _seg->referenced = true;
-}
-
-static void
-_vcd_pbc_mark_id (const VcdObj *obj, const char _id[])
-{
- pbc_t *_pbc;
-
- vcd_assert (obj != NULL);
-
- if (!_id)
- return;
-
- _pbc = _vcd_pbc_byid (obj, _id);
-
- if (!_pbc) /* not found */
- return;
-
- if (_pbc->referenced) /* already marked */
- return;
-
- _pbc->referenced = true;
-
- switch (_pbc->type)
- {
- case PBC_PLAYLIST:
- {
- CdioListNode *node;
-
- _vcd_pbc_mark_id (obj, _pbc->prev_id);
- _vcd_pbc_mark_id (obj, _pbc->next_id);
- _vcd_pbc_mark_id (obj, _pbc->retn_id);
-
- _CDIO_LIST_FOREACH (node, _pbc->item_id_list)
- {
- const char *_id = _cdio_list_node_data (node);
-
- _vcd_pin_mark_id (obj, _id);
- }
- }
- break;
-
- case PBC_SELECTION:
- {
- CdioListNode *node;
-
- _vcd_pbc_mark_id (obj, _pbc->prev_id);
- _vcd_pbc_mark_id (obj, _pbc->next_id);
- _vcd_pbc_mark_id (obj, _pbc->retn_id);
-
- if (_pbc->selection_type == _SEL_NORMAL)
- _vcd_pbc_mark_id (obj, _pbc->default_id);
-
- _vcd_pbc_mark_id (obj, _pbc->timeout_id);
-
- _vcd_pin_mark_id (obj, _pbc->item_id);
-
- _CDIO_LIST_FOREACH (node, _pbc->select_id_list)
- {
- const char *_id = _cdio_list_node_data (node);
-
- _vcd_pbc_mark_id (obj, _id);
- }
- }
- break;
-
- case PBC_END:
- _vcd_pin_mark_id (obj, _pbc->image_id);
- break;
-
- default:
- vcd_assert_not_reached ();
- break;
- }
-}
-
-void
-_vcd_pbc_check_unreferenced (const VcdObj *obj)
-{
- CdioListNode *node;
-
- /* clear all flags */
-
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
-
- _pbc->referenced = false;
- }
-
- _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)
- {
- mpeg_sequence_t *_sequence = _cdio_list_node_data (node);
-
- _sequence->referenced = false;
- }
-
- _CDIO_LIST_FOREACH (node, obj->mpeg_segment_list)
- {
- mpeg_segment_t *_segment = _cdio_list_node_data (node);
-
- _segment->referenced = false;
- }
-
- /* start from non-rejected lists */
-
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
-
- vcd_assert (_pbc->id != NULL);
-
- if (_pbc->rejected)
- continue;
-
- _vcd_pbc_mark_id (obj, _pbc->id);
- }
-
- /* collect flags */
-
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
-
- if (!_pbc->referenced)
- vcd_warn ("PSD item '%s' is unreachable", _pbc->id);
- }
-
- _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)
- {
- mpeg_sequence_t *_sequence = _cdio_list_node_data (node);
-
- if (!_sequence->referenced)
- vcd_warn ("sequence '%s' is not reachable by PBC", _sequence->id);
- }
-
- _CDIO_LIST_FOREACH (node, obj->mpeg_segment_list)
- {
- mpeg_segment_t *_segment = _cdio_list_node_data (node);
-
- if (!_segment->referenced)
- vcd_warn ("segment item '%s' is unreachable", _segment->id);
- }
-
-}
-
-void
-_vcd_pbc_node_write (const VcdObj *obj, const pbc_t *_pbc, void *buf,
- bool extended)
-{
- vcd_assert (obj != NULL);
- vcd_assert (_pbc != NULL);
- vcd_assert (buf != NULL);
-
- if (extended)
- vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X));
-
- switch (_pbc->type)
- {
- case PBC_PLAYLIST:
- {
- _PsdPlayListDescriptor *_md = buf;
- CdioListNode *node;
- int n;
-
- _md->type = PSD_TYPE_PLAY_LIST;
- _md->noi = _cdio_list_length (_pbc->item_id_list);
-
- vcd_assert (_pbc->lid < 0x8000);
- _md->lid = uint16_to_be (_pbc->lid | (_pbc->rejected ? 0x8000 : 0));
-
- _md->prev_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->prev_id, extended));
- _md->next_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->next_id, extended));
- _md->return_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->retn_id, extended));
- _md->ptime = uint16_to_be (rint (_pbc->playing_time * 15.0));
- _md->wtime = _wtime (_pbc->wait_time);
- _md->atime = _wtime (_pbc->auto_pause_time);
-
- n = 0;
- _CDIO_LIST_FOREACH (node, _pbc->item_id_list)
- {
- const char *_id = _cdio_list_node_data (node);
- uint16_t _pin;
-
- if (_id)
- {
- _pin = _vcd_pbc_pin_lookup (obj, _id);
-
- if (!_pin)
- vcd_error ("PSD: referenced play item '%s' not found", _id);
-
- _md->itemid[n] = uint16_to_be (_pin);
- }
- else
- _md->itemid[n] = 0; /* play nothing */
-
- n++;
- }
- }
- break;
-
- case PBC_SELECTION:
- {
- PsdSelectionListDescriptor_t *_md = buf;
-
- const unsigned int _nos = _cdio_list_length (_pbc->select_id_list);
-
- if (extended)
- _md->type = PSD_TYPE_EXT_SELECTION_LIST;
- else
- _md->type = PSD_TYPE_SELECTION_LIST;
-
- if (!IN (_pbc->bsn, 1, MAX_PBC_SELECTIONS))
- vcd_error ("selection '%s': BSN (%d) not in range [1..%d]",
- _pbc->id, _pbc->bsn, MAX_PBC_SELECTIONS);
-
- if (!IN (_nos, 0, MAX_PBC_SELECTIONS))
- vcd_error ("selection '%s': too many selections (%d > %d)",
- _pbc->id, _nos, MAX_PBC_SELECTIONS);
-
- if (_nos + _pbc->bsn > 100)
- vcd_error ("selection '%s': BSN + NOS (%d + %d) > 100",
- _pbc->id, _pbc->bsn, _nos);
-
- _md->bsn = _pbc->bsn;
- _md->nos = _nos;
-
- vcd_assert (sizeof (PsdSelectionListFlags) == 1);
-
- /* selection flags */
- if (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD))
- _md->flags.SelectionAreaFlag = true;
- else
- _md->flags.SelectionAreaFlag = false;
-
- _md->flags.CommandListFlag = false;
-
- vcd_assert (_pbc->lid < 0x8000);
- _md->lid = uint16_to_be (_pbc->lid | (_pbc->rejected ? 0x8000 : 0));
-
- _md->prev_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->prev_id, extended));
- _md->next_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->next_id, extended));
- _md->return_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->retn_id, extended));
-
- switch (_pbc->selection_type)
- {
- case _SEL_NORMAL:
- _md->default_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->default_id, extended));
- break;
-
- case _SEL_MULTI_DEF:
- _md->default_ofs = uint16_to_be (PSD_OFS_MULTI_DEF);
- if (_pbc->default_id)
- vcd_warn ("ignoring default target '%s' for multi default selection '%s'",
- _pbc->default_id, _pbc->id);
- break;
-
- case _SEL_MULTI_DEF_NO_NUM:
- _md->default_ofs = uint16_to_be (PSD_OFS_MULTI_DEF_NO_NUM);
- if (_pbc->default_id)
- vcd_warn ("ignoring default target '%s' for multi default (w/o num) selection '%s'",
- _pbc->default_id, _pbc->id);
- break;
-
- default:
- vcd_assert_not_reached ();
- break;
- }
-
- _md->timeout_ofs =
- uint16_to_be (_lookup_psd_offset (obj, _pbc->timeout_id, extended));
- _md->totime = _wtime (_pbc->timeout_time);
-
- if (_pbc->loop_count > 0x7f)
- vcd_warn ("loop count %d > 127", _pbc->loop_count);
-
- _md->loop = (_pbc->loop_count > 0x7f) ? 0x7f : _pbc->loop_count;
-
- if (_pbc->jump_delayed)
- _md->loop |= 0x80;
-
- /* timeout related sanity checks */
- if (_pbc->loop_count > 0
- && _pbc->timeout_time >= 0
- && !_pbc->timeout_id
- && !_nos)
- vcd_warn ("PSD: selection '%s': neither timeout nor select target available, but neither loop count is infinite nor timeout wait time", _pbc->id);
-
- if (_pbc->timeout_id && (_pbc->timeout_time < 0 || _pbc->loop_count <= 0))
- vcd_warn ("PSD: selection '%s': timeout target '%s' is never used due to loop count or timeout wait time given", _pbc->id, _pbc->timeout_id);
-
- if (_pbc->item_id)
- {
- const uint16_t _pin = _vcd_pbc_pin_lookup (obj, _pbc->item_id);
-
- if (!_pin)
- vcd_error ("PSD: referenced play item '%s' not found", _pbc->item_id);
-
- _md->itemid = uint16_to_be (_pin);
- }
- else
- _md->itemid = 0; /* play nothing */
-
- /* sanity checks */
- switch (_pbc->selection_type)
- {
- case _SEL_NORMAL:
- break;
-
- case _SEL_MULTI_DEF:
- case _SEL_MULTI_DEF_NO_NUM:
- if (_pbc->jump_delayed)
- vcd_warn ("selection '%s': jump timing shall be immediate", _pbc->id);
-
- if (_pbc->bsn != 1)
- vcd_error ("selection '%s': BSN != 1 for multi default selection",
- _pbc->id);
-
- /* checking NOS == NOE */
- if (!_pbc->item_id)
- vcd_error ("selection '%s': play nothing play item not allowed for multidefault list",
- _pbc->id);
-
- {
- mpeg_sequence_t *_seq;
-
- if ((_seq = _vcd_obj_get_sequence_by_id ((VcdObj *) obj, _pbc->item_id))
- || (_seq = _vcd_obj_get_sequence_by_entry_id ((VcdObj *) obj, _pbc->item_id)))
- {
- const unsigned _entries =
- _cdio_list_length (_seq->entry_list) + 1;
-
- if (_nos != _entries)
- vcd_error ("selection '%s': number of entrypoints"
- " (%d for sequence '%s') != number of selections (%d)",
- _pbc->id, _entries, _pbc->item_id, _nos);
- }
- else
- vcd_error ("selection '%s': play item '%s'"
- " is requried to be sequence or entry point"
- " item for multi default selecton",
- _pbc->id, _pbc->item_id);
- }
-
- break;
-
- default:
- vcd_assert_not_reached ();
- break;
- }
-
- /* fill selection array */
- {
- CdioListNode *node = NULL;
- int idx = 0;
-
- idx = 0;
- _CDIO_LIST_FOREACH (node, _pbc->select_id_list)
- {
- const char *_id = _cdio_list_node_data (node);
-
- _md->ofs[idx] =
- uint16_to_be (_lookup_psd_offset (obj, _id, extended));
-
- idx++;
- }
- }
-
- if (extended || _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD))
- {
- PsdSelectionListDescriptorExtended *_md2;
- CdioListNode *node;
- int n;
-
- /* append extended selection areas */
-
- _md2 = (void *) &_md->ofs[_nos];
-
- _set_area_helper (&_md2->next_area, _pbc->next_area, _pbc->id);
- _set_area_helper (&_md2->prev_area, _pbc->prev_area, _pbc->id);
- _set_area_helper (&_md2->return_area, _pbc->return_area, _pbc->id);
-
- _set_area_helper (&_md2->default_area, _pbc->default_area, _pbc->id);
-
- n = 0;
- if (_pbc->select_area_list)
- _CDIO_LIST_FOREACH (node, _pbc->select_area_list)
- {
- const pbc_area_t *_area = _cdio_list_node_data (node);
-
- _set_area_helper (&_md2->area[n], _area, _pbc->id);
-
- n++;
- }
-
- vcd_assert (n == _nos);
- }
- }
- break;
-
- case PBC_END:
- {
- PsdEndListDescriptor *_md = buf;
-
- _md->type = PSD_TYPE_END_LIST;
-
- if (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD))
- {
- _md->next_disc = _pbc->next_disc;
-
- if (_pbc->image_id)
- {
- uint16_t _pin = _vcd_pbc_pin_lookup (obj, _pbc->image_id);
- mpeg_segment_t *_segment;
-
- if (!_pbc->next_disc)
- vcd_warn ("PSD: endlist '%s': change disc picture given,"
- " but next volume is 0", _pbc->id);
-
- if (!_pin)
- vcd_error ("PSD: referenced play item '%s' not found",
- _pbc->item_id);
-
- _md->change_pic = uint16_to_be (_pin);
-
- /* sanity checks */
-
- _segment = _vcd_obj_get_segment_by_id ((VcdObj *) obj,
- _pbc->image_id);
-
- if (!_segment)
- vcd_warn ("PSD: endlist '%s': referenced play item '%s'"
- " is not a segment play item",
- _pbc->id, _pbc->image_id);
- else if (_segment->info->shdr[0].seen
- || !(_segment->info->shdr[1].seen || _segment->info->shdr[2].seen))
- vcd_warn ("PSD: endlist '%s': referenced play item '%s'"
- " should be a still picture",
- _pbc->id, _pbc->image_id);
- }
- }
- else if (_pbc->next_disc || _pbc->image_id)
- vcd_warn ("extended end list attributes ignored for non-SVCD");
- }
- break;
-
- default:
- vcd_assert_not_reached ();
- break;
- }
-}
-
-pbc_t *
-vcd_pbc_new (enum pbc_type_t type)
-{
- pbc_t *_pbc;
-
- _pbc = _vcd_malloc (sizeof (pbc_t));
- _pbc->type = type;
-
- switch (type)
- {
- case PBC_PLAYLIST:
- _pbc->item_id_list = _cdio_list_new ();
- break;
-
- case PBC_SELECTION:
- _pbc->select_id_list = _cdio_list_new ();
- _pbc->select_area_list = _cdio_list_new ();
- break;
-
- case PBC_END:
- break;
-
- default:
- vcd_assert_not_reached ();
- break;
- }
-
- return _pbc;
-}
-
-/*
- */
-
-bool
-_vcd_pbc_finalize (VcdObj *obj)
-{
- CdioListNode *node;
- unsigned offset = 0, offset_ext = 0;
- unsigned lid;
-
- lid = 1;
- _CDIO_LIST_FOREACH (node, obj->pbc_list)
- {
- pbc_t *_pbc = _cdio_list_node_data (node);
- unsigned length, length_ext = 0;
-
- length = _vcd_pbc_node_length (obj, _pbc, false);
- if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X))
- length_ext = _vcd_pbc_node_length (obj, _pbc, true);
-
- /* round them up to... */
- length = _vcd_ceil2block (length, INFO_OFFSET_MULT);
- if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X))
- length_ext = _vcd_ceil2block (length_ext, INFO_OFFSET_MULT);
-
- /* node may not cross sector boundary! */
- offset = _vcd_ofs_add (offset, length, ISO_BLOCKSIZE);
- if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X))
- offset_ext = _vcd_ofs_add (offset_ext, length_ext, ISO_BLOCKSIZE);
-
- /* save start offsets */
- _pbc->offset = offset - length;
- if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X))
- _pbc->offset_ext = offset_ext - length_ext;
-
- _pbc->lid = lid;
-
- lid++;
- }
-
- obj->psd_size = offset;
- if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X))
- obj->psdx_size = offset_ext;
-
- vcd_debug ("pbc: psd size %d (extended psd %d)", offset, offset_ext);
-
- return true;
-}