diff options
Diffstat (limited to 'src/input/vcd/libvcd/files.c')
-rw-r--r-- | src/input/vcd/libvcd/files.c | 1020 |
1 files changed, 0 insertions, 1020 deletions
diff --git a/src/input/vcd/libvcd/files.c b/src/input/vcd/libvcd/files.c deleted file mode 100644 index 38780edf0..000000000 --- a/src/input/vcd/libvcd/files.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - $Id: files.c,v 1.4 2006/09/26 21:18:18 dgp85 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 <stdlib.h> -#include <stddef.h> -#include <math.h> - -#include <cdio/cdio.h> -#include <cdio/bytesex.h> -#include <cdio/util.h> - -/* Public headers */ -#include <libvcd/files.h> -#include <libvcd/types.h> -#include <libvcd/logging.h> - -/* FIXME! Make this local */ -#include <libvcd/files_private.h> - -/* Private headers */ -#include "vcd_assert.h" -#include "mpeg_stream.h" -#include "obj.h" -#include "pbc.h" -#include "util.h" - -static const char _rcsid[] = "$Id: files.c,v 1.4 2006/09/26 21:18:18 dgp85 Exp $"; - -inline static bool -_pal_p (const struct vcd_mpeg_stream_vid_info *_info) -{ - return (_info->vsize == 288 || _info->vsize == 576); -} - -static int -_derive_vid_type (const struct vcd_mpeg_stream_info *_info, bool svcd) -{ - if (_info->shdr[0].seen) - return _pal_p (&_info->shdr[0]) ? 0x7 : 0x3; - - if (_info->shdr[2].seen) - { - if (svcd) - vcd_warn ("stream with 0xE2 still stream id not allowed for IEC62107 compliant SVCDs"); - return _pal_p (&_info->shdr[2]) ? 0x6 : 0x2; - } - - if (_info->shdr[1].seen) - return _pal_p (&_info->shdr[1]) ? 0x5 : 0x1; - - return 0; -} - -static int -_derive_ogt_type (const struct vcd_mpeg_stream_info *_info, bool svcd) -{ - - if (!svcd) - return 0; - - if ((_info->ogt[3] || _info->ogt[2]) - && _info->ogt[1] && _info->ogt[0]) - return 0x3; - - if (_info->ogt[1] && _info->ogt[0]) - return 0x2; - - if (_info->ogt[0]) - return 0x1; - - vcd_debug ("OGT streams available: %d %d %d %d", - _info->ogt[0], _info->ogt[1], - _info->ogt[2], _info->ogt[3]); - - return 0x0; -} - -static int -_derive_aud_type (const struct vcd_mpeg_stream_info *_info, bool svcd) -{ - if (!_info->ahdr[0].seen) - return 0; /* no MPEG audio */ - - if (svcd) - { - if (_info->ahdr[2].seen) - return 3; /* MC */ - - if (_info->ahdr[1].seen) - return 2; /* 2 streams */ - - return 1; /* just one stream */ - } - else - switch (_info->ahdr[0].mode) - { - case MPEG_SINGLE_CHANNEL: - return 1; - break; - - case MPEG_STEREO: - case MPEG_JOINT_STEREO: - return 2; - break; - - case MPEG_DUAL_CHANNEL: - return 3; - break; - } - - return 0; -} - -void -set_entries_vcd (VcdObj *obj, void *buf) -{ - CdioListNode *node = NULL; - int idx = 0; - int track_idx = 0; - EntriesVcd_t entries_vcd; - - vcd_assert (sizeof(EntriesVcd_t) == 2048); - - vcd_assert (_cdio_list_length (obj->mpeg_track_list) <= MAX_ENTRIES); - vcd_assert (_cdio_list_length (obj->mpeg_track_list) > 0); - - memset(&entries_vcd, 0, sizeof(entries_vcd)); /* paranoia / fixme */ - - switch (obj->type) - { - case VCD_TYPE_VCD: - strncpy(entries_vcd.ID, ENTRIES_ID_VCD, 8); - entries_vcd.version = ENTRIES_VERSION_VCD; - entries_vcd.sys_prof_tag = ENTRIES_SPTAG_VCD; - break; - - case VCD_TYPE_VCD11: - strncpy(entries_vcd.ID, ENTRIES_ID_VCD, 8); - entries_vcd.version = ENTRIES_VERSION_VCD11; - entries_vcd.sys_prof_tag = ENTRIES_SPTAG_VCD11; - break; - - case VCD_TYPE_VCD2: - strncpy(entries_vcd.ID, ENTRIES_ID_VCD, 8); - entries_vcd.version = ENTRIES_VERSION_VCD2; - entries_vcd.sys_prof_tag = ENTRIES_SPTAG_VCD2; - break; - - case VCD_TYPE_SVCD: - if (!obj->svcd_vcd3_entrysvd) - strncpy(entries_vcd.ID, ENTRIES_ID_SVCD, 8); - else - { - vcd_warn ("setting ENTRYSVD signature for *DEPRECATED* VCD 3.0 type SVCD"); - strncpy(entries_vcd.ID, ENTRIES_ID_VCD3, 8); - } - entries_vcd.version = ENTRIES_VERSION_SVCD; - entries_vcd.sys_prof_tag = ENTRIES_SPTAG_SVCD; - break; - - case VCD_TYPE_HQVCD: - strncpy(entries_vcd.ID, ENTRIES_ID_SVCD, 8); - entries_vcd.version = ENTRIES_VERSION_HQVCD; - entries_vcd.sys_prof_tag = ENTRIES_SPTAG_HQVCD; - break; - - default: - vcd_assert_not_reached (); - break; - } - - idx = 0; - track_idx = 2; - _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list) - { - mpeg_sequence_t *track = _cdio_list_node_data (node); - uint32_t lsect = track->relative_start_extent; - CdioListNode *node2; - - lsect += obj->iso_size; - - entries_vcd.entry[idx].n = cdio_to_bcd8(track_idx); - cdio_lba_to_msf(cdio_lsn_to_lba(lsect), - &(entries_vcd.entry[idx].msf)); - - idx++; - lsect += obj->track_front_margin; - - _CDIO_LIST_FOREACH (node2, track->entry_list) - { - entry_t *_entry = _cdio_list_node_data (node2); - /* additional entries */ - - vcd_assert (idx < MAX_ENTRIES); - - entries_vcd.entry[idx].n = cdio_to_bcd8(track_idx); - cdio_lba_to_msf(lsect + cdio_lsn_to_lba(_entry->aps.packet_no), - &(entries_vcd.entry[idx].msf)); - - idx++; - } - - track_idx++; - } - - entries_vcd.entry_count = uint16_to_be (idx); - - memcpy(buf, &entries_vcd, sizeof(entries_vcd)); -} - -static void -_set_bit (uint8_t bitset[], unsigned bitnum) -{ - unsigned _byte = bitnum / 8; - unsigned _bit = bitnum % 8; - - bitset[_byte] |= (1 << _bit); -} - -uint32_t -get_psd_size (VcdObj *obj, bool extended) -{ - if (extended) - vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X)); - - if (!_vcd_pbc_available (obj)) - return 0; - - if (extended) - return obj->psdx_size; - - return obj->psd_size; -} - -void -set_psd_vcd (VcdObj *obj, void *buf, bool extended) -{ - CdioListNode *node; - - if (extended) - vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X)); - - vcd_assert (_vcd_pbc_available (obj)); - - _CDIO_LIST_FOREACH (node, obj->pbc_list) - { - pbc_t *_pbc = _cdio_list_node_data (node); - char *_buf = buf; - unsigned offset = (extended ? _pbc->offset_ext : _pbc->offset); - - vcd_assert (offset % INFO_OFFSET_MULT == 0); - - _vcd_pbc_node_write (obj, _pbc, _buf + offset, extended); - } -} - -void -set_lot_vcd(VcdObj *obj, void *buf, bool extended) -{ - LotVcd_t *lot_vcd = NULL; - CdioListNode *node; - - if (extended) - vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X)); - - vcd_assert (_vcd_pbc_available (obj)); - - lot_vcd = _vcd_malloc (sizeof (LotVcd_t)); - memset(lot_vcd, 0xff, sizeof(LotVcd_t)); - - lot_vcd->reserved = 0x0000; - - _CDIO_LIST_FOREACH (node, obj->pbc_list) - { - pbc_t *_pbc = _cdio_list_node_data (node); - unsigned int offset = extended ? _pbc->offset_ext : _pbc->offset; - - vcd_assert (offset % INFO_OFFSET_MULT == 0); - - if (_pbc->rejected) - continue; - - offset /= INFO_OFFSET_MULT; - - lot_vcd->offset[_pbc->lid - 1] = uint16_to_be (offset); - } - - memcpy(buf, lot_vcd, sizeof(LotVcd_t)); - free(lot_vcd); -} - -void -set_info_vcd(VcdObj *obj, void *buf) -{ - InfoVcd_t info_vcd; - CdioListNode *node = NULL; - int n = 0; - - vcd_assert (sizeof (InfoVcd_t) == 2048); - vcd_assert (_cdio_list_length (obj->mpeg_track_list) <= 98); - - memset (&info_vcd, 0, sizeof (info_vcd)); - - switch (obj->type) - { - case VCD_TYPE_VCD: - strncpy (info_vcd.ID, INFO_ID_VCD, sizeof (info_vcd.ID)); - info_vcd.version = INFO_VERSION_VCD; - info_vcd.sys_prof_tag = INFO_SPTAG_VCD; - break; - - case VCD_TYPE_VCD11: - strncpy (info_vcd.ID, INFO_ID_VCD, sizeof (info_vcd.ID)); - info_vcd.version = INFO_VERSION_VCD11; - info_vcd.sys_prof_tag = INFO_SPTAG_VCD11; - break; - - case VCD_TYPE_VCD2: - strncpy (info_vcd.ID, INFO_ID_VCD, sizeof (info_vcd.ID)); - info_vcd.version = INFO_VERSION_VCD2; - info_vcd.sys_prof_tag = INFO_SPTAG_VCD2; - break; - - case VCD_TYPE_SVCD: - strncpy (info_vcd.ID, INFO_ID_SVCD, sizeof (info_vcd.ID)); - info_vcd.version = INFO_VERSION_SVCD; - info_vcd.sys_prof_tag = INFO_SPTAG_SVCD; - break; - - case VCD_TYPE_HQVCD: - strncpy (info_vcd.ID, INFO_ID_HQVCD, sizeof (info_vcd.ID)); - info_vcd.version = INFO_VERSION_HQVCD; - info_vcd.sys_prof_tag = INFO_SPTAG_HQVCD; - break; - - default: - vcd_assert_not_reached (); - break; - } - - iso9660_strncpy_pad (info_vcd.album_desc, - obj->info_album_id, - sizeof(info_vcd.album_desc), ISO9660_DCHARS); - /* fixme, maybe it's VCD_ACHARS? */ - - info_vcd.vol_count = uint16_to_be (obj->info_volume_count); - info_vcd.vol_id = uint16_to_be (obj->info_volume_number); - - if (_vcd_obj_has_cap_p (obj, _CAP_PAL_BITS)) - { - /* NTSC/PAL bitset */ - - n = 0; - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - mpeg_track_t *track = _cdio_list_node_data (node); - - const struct vcd_mpeg_stream_vid_info *_info = &track->info->shdr[0]; - - if (vcd_mpeg_get_norm (_info) == MPEG_NORM_PAL - || vcd_mpeg_get_norm (_info) == MPEG_NORM_PAL_S) - _set_bit(info_vcd.pal_flags, n); - else if (_pal_p (_info)) - { - vcd_warn ("INFO.{VCD,SVD}: assuming PAL-type resolution for track #%d" - " -- are we creating a X(S)VCD?", n); - _set_bit(info_vcd.pal_flags, n); - } - - n++; - } - } - - if (_vcd_obj_has_cap_p (obj, _CAP_PBC)) - { - info_vcd.flags.restriction = obj->info_restriction; - info_vcd.flags.use_lid2 = obj->info_use_lid2; - info_vcd.flags.use_track3 = obj->info_use_seq2; - - if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X) - &&_vcd_pbc_available (obj)) - info_vcd.flags.pbc_x = true; - - info_vcd.psd_size = uint32_to_be (get_psd_size (obj, false)); - info_vcd.offset_mult = _vcd_pbc_available (obj) ? INFO_OFFSET_MULT : 0; - info_vcd.lot_entries = uint16_to_be (_vcd_pbc_max_lid (obj)); - - if (_cdio_list_length (obj->mpeg_segment_list)) - { - unsigned segments = 0; - - if (!_vcd_pbc_available (obj)) - vcd_warn ("segment items available, but no PBC items set!" - " SPIs will be unreachable"); - - _CDIO_LIST_FOREACH (node, obj->mpeg_segment_list) - { - mpeg_segment_t *segment = _cdio_list_node_data (node); - unsigned idx; - InfoSpiContents contents = { 0, }; - - contents.video_type = - _derive_vid_type (segment->info, - _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)); - - contents.audio_type = - _derive_aud_type (segment->info, - _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)); - - contents.ogt = - _derive_ogt_type (segment->info, - _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)); - - if (!contents.video_type && !contents.audio_type) - vcd_warn ("segment item '%s' seems contains neither video nor audio", - segment->id); - - for (idx = 0; idx < segment->segment_count; idx++) - { - vcd_assert (segments + idx < MAX_SEGMENTS); - - info_vcd.spi_contents[segments + idx] = contents; - - if (!contents.item_cont) - contents.item_cont = true; - } - - segments += idx; - } - - info_vcd.item_count = uint16_to_be (segments); - - cdio_lba_to_msf (cdio_lsn_to_lba(obj->mpeg_segment_start_extent), - &info_vcd.first_seg_addr); - } - } - - memcpy(buf, &info_vcd, sizeof(info_vcd)); -} - -static void -set_tracks_svd_v30 (VcdObj *obj, void *buf) -{ - char tracks_svd_buf[ISO_BLOCKSIZE] = { 0, }; - TracksSVD_v30 *tracks_svd = (void *) tracks_svd_buf; - CdioListNode *node; - double playtime; - int n; - - strncpy (tracks_svd->file_id, TRACKS_SVD_FILE_ID, - sizeof (TRACKS_SVD_FILE_ID)-1); - tracks_svd->version = TRACKS_SVD_VERSION; - tracks_svd->tracks = _cdio_list_length (obj->mpeg_track_list); - - n = 0; - playtime = 0; - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - mpeg_track_t *track = _cdio_list_node_data (node); - int i; - - playtime += track->info->playing_time; - - tracks_svd->track[n].audio_info = track->info->ahdr[0].seen ? 0x2 : 0x0; /* fixme */ - tracks_svd->track[n].audio_info |= track->info->ahdr[1].seen ? 0x20 : 0x0; /* fixme */ - - tracks_svd->track[n].ogt_info = 0x0; - for (i = 0; i < 4; i++) - if (track->info->ogt[i]) - tracks_svd->track[n].ogt_info |= 1 << (i * 2); /* fixme */ - - /* setting playtime */ - - { - double i, f; - - while (playtime >= 6000.0) - playtime -= 6000.0; - - f = modf(playtime, &i); - - cdio_lba_to_msf (i * 75, &tracks_svd->track[n].cum_playing_time); - tracks_svd->track[n].cum_playing_time.f = - cdio_to_bcd8 (floor (f * 75.0)); - } - - n++; - } - - memcpy (buf, &tracks_svd_buf, sizeof(tracks_svd_buf)); -} - -void -set_tracks_svd (VcdObj *obj, void *buf) -{ - char tracks_svd[ISO_BLOCKSIZE] = { 0, }; - TracksSVD *tracks_svd1 = (void *) tracks_svd; - TracksSVD2 *tracks_svd2; - CdioListNode *node; - int n; - - vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)); - - if (obj->svcd_vcd3_tracksvd) - { - set_tracks_svd_v30 (obj, buf); - return; - } - - vcd_assert (sizeof (SVDTrackContent) == 1); - - strncpy (tracks_svd1->file_id, TRACKS_SVD_FILE_ID, sizeof (TRACKS_SVD_FILE_ID)-1); - tracks_svd1->version = TRACKS_SVD_VERSION; - - tracks_svd1->tracks = _cdio_list_length (obj->mpeg_track_list); - - tracks_svd2 = (void *) &(tracks_svd1->playing_time[tracks_svd1->tracks]); - - n = 0; - - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - mpeg_track_t *track = _cdio_list_node_data (node); - const double playtime = track->info->playing_time; - - int _video; - - _video = tracks_svd2->contents[n].video = - _derive_vid_type (track->info, true); - - tracks_svd2->contents[n].audio = - _derive_aud_type (track->info, true); - - tracks_svd2->contents[n].ogt = - _derive_ogt_type (track->info, true); - - if (_video != 0x3 && _video != 0x7) - vcd_warn("SVCD/TRACKS.SVCD: No MPEG motion video for track #%d?", n); - - /* setting playtime */ - - { - double i, f; - - f = modf(playtime, &i); - - if (playtime >= 6000.0) - { - vcd_warn ("SVCD/TRACKS.SVD: playing time value (%d seconds) to great," - " clipping to 100 minutes", (int) i); - i = 5999.0; - f = 74.0 / 75.0; - } - - cdio_lba_to_msf (i * 75, &(tracks_svd1->playing_time[n])); - tracks_svd1->playing_time[n].f = cdio_to_bcd8 (floor (f * 75.0)); - } - - n++; - } - - memcpy (buf, &tracks_svd, sizeof(tracks_svd)); -} - -static double -_get_cumulative_playing_time (const VcdObj *obj, unsigned up_to_track_no) -{ - double result = 0; - CdioListNode *node; - - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - mpeg_track_t *track = _cdio_list_node_data (node); - - if (!up_to_track_no) - break; - - result += track->info->playing_time; - up_to_track_no--; - } - - if (up_to_track_no) - vcd_warn ("internal error..."); - - return result; -} - -static unsigned -_get_scanpoint_count (const VcdObj *obj) -{ - double total_playing_time; - - total_playing_time = _get_cumulative_playing_time (obj, _cdio_list_length (obj->mpeg_track_list)); - - return ceil (total_playing_time * 2.0); -} - -uint32_t -get_search_dat_size (const VcdObj *obj) -{ - return sizeof (SearchDat) - + (_get_scanpoint_count (obj) * sizeof (msf_t)); -} - -static CdioList * -_make_track_scantable (const VcdObj *obj) -{ - CdioList *all_aps = _cdio_list_new (); - CdioList *scantable = _cdio_list_new (); - unsigned scanpoints = _get_scanpoint_count (obj); - unsigned track_no; - CdioListNode *node; - - track_no = 0; - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - mpeg_track_t *track = _cdio_list_node_data (node); - CdioListNode *node2; - - _CDIO_LIST_FOREACH (node2, track->info->shdr[0].aps_list) - { - struct aps_data *_data = _vcd_malloc (sizeof (struct aps_data)); - - *_data = *(struct aps_data *)_cdio_list_node_data (node2); - - _data->timestamp += _get_cumulative_playing_time (obj, track_no); - _data->packet_no += obj->iso_size + track->relative_start_extent; - _data->packet_no += obj->track_front_margin; - - _cdio_list_append (all_aps, _data); - } - track_no++; - } - - { - CdioListNode *aps_node = _cdio_list_begin (all_aps); - CdioListNode *n; - struct aps_data *_data; - double aps_time; - double playing_time; - int aps_packet; - double t; - - playing_time = scanpoints; - playing_time /= 2; - - vcd_assert (aps_node != NULL); - - _data = _cdio_list_node_data (aps_node); - aps_time = _data->timestamp; - aps_packet = _data->packet_no; - - for (t = 0; t < playing_time; t += 0.5) - { - for(n = _cdio_list_node_next (aps_node); n; - n = _cdio_list_node_next (n)) - { - _data = _cdio_list_node_data (n); - - if (fabs (_data->timestamp - t) < fabs (aps_time - t)) - { - aps_node = n; - aps_time = _data->timestamp; - aps_packet = _data->packet_no; - } - else - break; - } - - { - uint32_t *lsect = _vcd_malloc (sizeof (uint32_t)); - - *lsect = aps_packet; - _cdio_list_append (scantable, lsect); - } - - } - - } - - _cdio_list_free (all_aps, true); - - vcd_assert (scanpoints == _cdio_list_length (scantable)); - - return scantable; -} - -void -set_search_dat (VcdObj *obj, void *buf) -{ - CdioList *scantable; - CdioListNode *node; - SearchDat search_dat; - unsigned n; - - vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)); - /* vcd_assert (sizeof (SearchDat) == ?) */ - - memset (&search_dat, 0, sizeof (search_dat)); - - strncpy (search_dat.file_id, SEARCH_FILE_ID, sizeof (SEARCH_FILE_ID)-1); - - search_dat.version = SEARCH_VERSION; - search_dat.scan_points = uint16_to_be (_get_scanpoint_count (obj)); - search_dat.time_interval = SEARCH_TIME_INTERVAL; - - memcpy (buf, &search_dat, sizeof (search_dat)); - - scantable = _make_track_scantable (obj); - - n = 0; - _CDIO_LIST_FOREACH (node, scantable) - { - SearchDat *search_dat2 = buf; - uint32_t sect = *(uint32_t *) _cdio_list_node_data (node); - - cdio_lba_to_msf(cdio_lsn_to_lba(sect), &(search_dat2->points[n])); - n++; - } - - vcd_assert (n = _get_scanpoint_count (obj)); - - _cdio_list_free (scantable, true); -} - -static uint32_t -_get_scandata_count (const struct vcd_mpeg_stream_info *info) -{ - return ceil (info->playing_time * 2.0); -} - -static uint32_t * -_get_scandata_table (const struct vcd_mpeg_stream_info *info) -{ - CdioListNode *n, *aps_node = _cdio_list_begin (info->shdr[0].aps_list); - struct aps_data *_data; - double aps_time, t; - int aps_packet; - uint32_t *retval; - unsigned i; - - retval = _vcd_malloc (_get_scandata_count (info) * sizeof (uint32_t)); - - _data = _cdio_list_node_data (aps_node); - aps_time = _data->timestamp; - aps_packet = _data->packet_no; - - for (t = 0, i = 0; t < info->playing_time; t += 0.5, i++) - { - for(n = _cdio_list_node_next (aps_node); n; n = _cdio_list_node_next (n)) - { - _data = _cdio_list_node_data (n); - - if (fabs (_data->timestamp - t) < fabs (aps_time - t)) - { - aps_node = n; - aps_time = _data->timestamp; - aps_packet = _data->packet_no; - } - else - break; - } - - /* vcd_debug ("%f %f %d", t, aps_time, aps_packet); */ - - vcd_assert (i < _get_scandata_count (info)); - - retval[i] = aps_packet; - } - - vcd_assert (i = _get_scandata_count (info)); - - return retval; -} - -uint32_t -get_scandata_dat_size (const VcdObj *obj) -{ - uint32_t retval = 0; - - /* struct 1 */ - retval += sizeof (ScandataDat1); - retval += sizeof (msf_t) * _cdio_list_length (obj->mpeg_track_list); - - /* struct 2 */ - /* vcd_assert (sizeof (ScandataDat2) == 0); - retval += sizeof (ScandataDat2); */ - retval += sizeof (uint16_t) * 0; - - /* struct 3 */ - retval += sizeof (ScandataDat3); - retval += (sizeof (uint8_t) + sizeof (uint16_t)) * _cdio_list_length (obj->mpeg_track_list); - - /* struct 4 */ - /* vcd_assert (sizeof (ScandataDat4) == 0); - retval += sizeof (ScandataDat4); */ - { - CdioListNode *node; - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - const mpeg_track_t *track = _cdio_list_node_data (node); - - retval += sizeof (msf_t) * _get_scandata_count (track->info); - } - } - - return retval; -} - -void -set_scandata_dat (VcdObj *obj, void *buf) -{ - const unsigned tracks = _cdio_list_length (obj->mpeg_track_list); - - ScandataDat1 *scandata_dat1 = (ScandataDat1 *) buf; - ScandataDat2 *scandata_dat2 = - (ScandataDat2 *) &(scandata_dat1->cum_playtimes[tracks]); - ScandataDat3 *scandata_dat3 = - (ScandataDat3 *) &(scandata_dat2->spi_indexes[0]); - ScandataDat4 *scandata_dat4 = - (ScandataDat4 *) &(scandata_dat3->mpeg_track_offsets[tracks]); - - const uint16_t _begin_offset = - __cd_offsetof (ScandataDat3, mpeg_track_offsets[tracks]) - - __cd_offsetof (ScandataDat3, mpeg_track_offsets); - - CdioListNode *node; - unsigned n; - uint16_t _tmp_offset; - - vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)); - - /* memset (buf, 0, get_scandata_dat_size (obj)); */ - - /* struct 1 */ - strncpy (scandata_dat1->file_id, SCANDATA_FILE_ID, sizeof (SCANDATA_FILE_ID)-1); - - scandata_dat1->version = SCANDATA_VERSION_SVCD; - scandata_dat1->reserved = 0x00; - scandata_dat1->scandata_count = uint16_to_be (_get_scanpoint_count (obj)); - - scandata_dat1->track_count = uint16_to_be (tracks); - scandata_dat1->spi_count = uint16_to_be (0); - - for (n = 0; n < tracks; n++) - { - double playtime = _get_cumulative_playing_time (obj, n + 1); - double i = 0, f = 0; - - f = modf(playtime, &i); - - while (i >= (60 * 100)) - i -= (60 * 100); - - vcd_assert (i >= 0); - - cdio_lba_to_msf (i * 75, &(scandata_dat1->cum_playtimes[n])); - scandata_dat1->cum_playtimes[n].f = cdio_to_bcd8 (floor (f * 75.0)); - } - - /* struct 2 -- nothing yet */ - - /* struct 3/4 */ - - vcd_assert ((_begin_offset % sizeof (msf_t) == 0) - && _begin_offset > 0); - - _tmp_offset = 0; - - scandata_dat3->mpegtrack_start_index = uint16_to_be (_begin_offset); - - n = 0; - _CDIO_LIST_FOREACH (node, obj->mpeg_track_list) - { - const mpeg_track_t *track = _cdio_list_node_data (node); - uint32_t *_table; - const unsigned scanpoints = _get_scandata_count (track->info); - const unsigned _table_ofs = - (_tmp_offset * sizeof (msf_t)) + _begin_offset; - unsigned point; - - scandata_dat3->mpeg_track_offsets[n].track_num = n + 2; - scandata_dat3->mpeg_track_offsets[n].table_offset = uint16_to_be (_table_ofs); - - _table = _get_scandata_table (track->info); - - for (point = 0; point < scanpoints; point++) - { - uint32_t lsect = _table[point]; - - lsect += obj->iso_size; - lsect += track->relative_start_extent; - lsect += obj->track_front_margin; - - /* vcd_debug ("lsect %d %d", point, lsect); */ - - cdio_lba_to_msf(cdio_lsn_to_lba(lsect), - &(scandata_dat4->scandata_table[_tmp_offset + point])); - } - - free (_table); - - _tmp_offset += scanpoints; - n++; - } - - /* struct 4 */ - - -} - -vcd_type_t -vcd_files_info_detect_type (const void *info_buf) -{ - const InfoVcd_t *_info = info_buf; - vcd_type_t _type = VCD_TYPE_INVALID; - - vcd_assert (info_buf != NULL); - - if (!strncmp (_info->ID, INFO_ID_VCD, sizeof (_info->ID))) - switch (_info->version) - { - case INFO_VERSION_VCD2: - if (_info->sys_prof_tag != INFO_SPTAG_VCD2) - vcd_warn ("INFO.VCD: unexpected system profile tag %d encountered", - _info->version); - _type = VCD_TYPE_VCD2; - break; - - case INFO_VERSION_VCD: - /* case INFO_VERSION_VCD11: */ - switch (_info->sys_prof_tag) - { - case INFO_SPTAG_VCD: - _type = VCD_TYPE_VCD; - break; - case INFO_SPTAG_VCD11: - _type = VCD_TYPE_VCD11; - break; - default: - vcd_warn ("INFO.VCD: unexpected system profile tag %d " - "encountered, assuming VCD 1.1", _info->sys_prof_tag); - break; - } - break; - - default: - vcd_warn ("unexpected VCD version %d encountered -- assuming VCD 2.0", - _info->version); - break; - } - else if (!strncmp (_info->ID, INFO_ID_SVCD, sizeof (_info->ID))) - switch (_info->version) - { - case INFO_VERSION_SVCD: - if (_info->sys_prof_tag != INFO_SPTAG_SVCD) - vcd_warn ("INFO.SVD: unexpected system profile tag value %d " - "-- assuming SVCD", _info->sys_prof_tag); - _type = VCD_TYPE_SVCD; - break; - - default: - vcd_warn ("INFO.SVD: unexpected version value %d seen " - " -- still assuming SVCD", _info->version); - _type = VCD_TYPE_SVCD; - break; - } - else if (!strncmp (_info->ID, INFO_ID_HQVCD, sizeof (_info->ID))) - switch (_info->version) - { - case INFO_VERSION_HQVCD: - if (_info->sys_prof_tag != INFO_SPTAG_HQVCD) - vcd_warn ("INFO.SVD: unexpected system profile tag value -- assuming hqvcd"); - _type = VCD_TYPE_HQVCD; - break; - - default: - vcd_warn ("INFO.SVD: unexpected version value %d seen " - "-- still assuming HQVCD", _info->version); - _type = VCD_TYPE_HQVCD; - break; - } - else - vcd_warn ("INFO.SVD: signature not found"); - - return _type; -} - -/* eof */ - - -/* - * Local variables: - * c-file-style: "gnu" - * tab-width: 8 - * indent-tabs-mode: nil - * End: - */ |