📄 files.c
字号:
memcpy (buf, &tracks_svd_buf, sizeof(tracks_svd_buf));}voidset_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;}voidset_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;}voidset_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_tvcd_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: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -