summaryrefslogtreecommitdiffstats
path: root/libdvdnav-embedded/src/vm/vmget.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /libdvdnav-embedded/src/vm/vmget.c
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libdvdnav-embedded/src/vm/vmget.c')
-rw-r--r--libdvdnav-embedded/src/vm/vmget.c353
1 files changed, 353 insertions, 0 deletions
diff --git a/libdvdnav-embedded/src/vm/vmget.c b/libdvdnav-embedded/src/vm/vmget.c
new file mode 100644
index 0000000..5816f2c
--- /dev/null
+++ b/libdvdnav-embedded/src/vm/vmget.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2000, 2001 HÃ¥kan Hjort
+ * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
+ * 2002-2004 the dvdnav project
+ *
+ * This file is part of libdvdnav, a DVD navigation library. It is modified
+ * from a file originally part of the Ogle DVD player.
+ *
+ * libdvdnav 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.
+ *
+ * libdvdnav 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 libdvdnav; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <dvdread/nav_types.h>
+#include <dvdread/ifo_read.h>
+#include "dvdnav/dvdnav.h"
+
+#include "decoder.h"
+#include "vm.h"
+#include "getset.h"
+#include "dvdnav_internal.h"
+#include "logger.h"
+
+/* getting information */
+
+int vm_get_current_menu(vm_t *vm, int *menuid) {
+ const pgcit_t* pgcit;
+ int pgcn;
+ pgcn = (vm->state).pgcN;
+ pgcit = get_PGCIT(vm);
+ if(pgcit==NULL) return 0;
+ *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ;
+ return 1;
+}
+
+int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) {
+ vts_ptt_srpt_t *vts_ptt_srpt;
+ int title, part = 0, vts_ttn;
+ int found;
+ int16_t pgcN, pgN;
+
+ vts_ptt_srpt = vm->vtsi->vts_ptt_srpt;
+ pgcN = get_PGCN(vm);
+ pgN = vm->state.pgN;
+
+ found = 0;
+ for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) {
+ for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) {
+ if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) {
+ if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN) {
+ found = 1;
+ break;
+ }
+ if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN &&
+ vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) {
+ part--;
+ found = 1;
+ break;
+ }
+ }
+ }
+ if (found) break;
+ }
+ vts_ttn++;
+ part++;
+
+ if (!found) {
+ Log1(vm, "chapter NOT FOUND!");
+ return 0;
+ }
+
+ title = get_TT(vm, vm->state.vtsN, vts_ttn);
+
+#ifdef TRACE
+ if (title) {
+ Log3(vm, "************ this chapter FOUND!");
+ Log3(vm, "VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i",
+ title, part,
+ vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn ,
+ vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn );
+ }
+#endif
+ *title_result = title;
+ *part_result = part;
+ return 1;
+}
+
+/* Return the substream id for 'logical' audio stream audioN.
+ * 0 <= audioN < 8
+ */
+int vm_get_audio_stream(vm_t *vm, int audioN) {
+ int streamN = -1;
+
+ if((vm->state).domain != DVD_DOMAIN_VTSTitle)
+ audioN = 0;
+
+ if(audioN < 8) {
+ /* Is there any control info for this logical stream */
+ if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
+ streamN = ((vm->state).pgc->audio_control[audioN] >> 8) & 0x07;
+ }
+ }
+
+ if((vm->state).domain != DVD_DOMAIN_VTSTitle && streamN == -1)
+ streamN = 0;
+
+ /* FIXME: Should also check in vtsi/vmgi status what kind of stream
+ * it is (ac3/lpcm/dts/sdds...) to find the right (sub)stream id */
+ return streamN;
+}
+
+/* Return the substream id for 'logical' subpicture stream subpN and given mode.
+ * 0 <= subpN < 32
+ * mode == 0 - widescreen
+ * mode == 1 - letterbox
+ * mode == 2 - pan&scan
+ */
+int vm_get_subp_stream(vm_t *vm, int subpN, int mode) {
+ int streamN = -1;
+ int source_aspect = vm_get_video_aspect(vm);
+
+ if((vm->state).domain != DVD_DOMAIN_VTSTitle)
+ subpN = 0;
+
+ if(subpN < 32) { /* a valid logical stream */
+ /* Is this logical stream present */
+ if((vm->state).pgc->subp_control[subpN] & (1u<<31)) {
+ if(source_aspect == 0) /* 4:3 */
+ streamN = ((vm->state).pgc->subp_control[subpN] >> 24) & 0x1f;
+ if(source_aspect == 3) /* 16:9 */
+ switch (mode) {
+ case 0:
+ streamN = ((vm->state).pgc->subp_control[subpN] >> 16) & 0x1f;
+ break;
+ case 1:
+ streamN = ((vm->state).pgc->subp_control[subpN] >> 8) & 0x1f;
+ break;
+ case 2:
+ streamN = (vm->state).pgc->subp_control[subpN] & 0x1f;
+ }
+ }
+ }
+
+ if((vm->state).domain != DVD_DOMAIN_VTSTitle && streamN == -1)
+ streamN = 0;
+
+ /* FIXME: Should also check in vtsi/vmgi status what kind of stream it is. */
+ return streamN;
+}
+
+int vm_get_audio_active_stream(vm_t *vm) {
+ int audioN;
+ int streamN;
+ audioN = (vm->state).AST_REG ;
+ streamN = vm_get_audio_stream(vm, audioN);
+
+ /* If no such stream, then select the first one that exists. */
+ if(streamN == -1) {
+ for(audioN = 0; audioN < 8; audioN++) {
+ if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
+ if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0)
+ break;
+ }
+ }
+ }
+
+ return streamN;
+}
+
+int vm_get_subp_active_stream(vm_t *vm, int mode) {
+ int subpN;
+ int streamN;
+ subpN = (vm->state).SPST_REG & ~0x40;
+ streamN = vm_get_subp_stream(vm, subpN, mode);
+
+ /* If no such stream, then select the first one that exists. */
+ if(streamN == -1) {
+ for(subpN = 0; subpN < 32; subpN++) {
+ if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
+ if ((streamN = vm_get_subp_stream(vm, subpN, mode)) >= 0)
+ break;
+ }
+ }
+ }
+
+ if((vm->state).domain == DVD_DOMAIN_VTSTitle && !((vm->state).SPST_REG & 0x40))
+ /* Bit 7 set means hide, and only let Forced display show */
+ return (streamN | 0x80);
+ else
+ return streamN;
+}
+
+void vm_get_angle_info(vm_t *vm, int *current, int *num_avail) {
+ *num_avail = 1;
+ *current = 1;
+
+ if((vm->state).domain == DVD_DOMAIN_VTSTitle) {
+ const title_info_t *title;
+ /* TTN_REG does not always point to the correct title.. */
+ if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
+ return;
+ title = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1];
+ if(title->title_set_nr != (vm->state).vtsN ||
+ title->vts_ttn != (vm->state).VTS_TTN_REG)
+ return;
+ *num_avail = title->nr_of_angles;
+ *current = (vm->state).AGL_REG;
+ }
+}
+
+#if 0
+/* currently unused */
+void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+ case DVD_DOMAIN_VTSTitle:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_audio_streams;
+ *current = (vm->state).AST_REG;
+ break;
+ case DVD_DOMAIN_VTSMenu:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /* 1 */
+ *current = 1;
+ break;
+ case DVD_DOMAIN_VMGM:
+ case DVD_DOMAIN_FirstPlay:
+ *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /* 1 */
+ *current = 1;
+ break;
+ }
+}
+
+/* currently unused */
+void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+ case DVD_DOMAIN_VTSTitle:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_subp_streams;
+ *current = (vm->state).SPST_REG;
+ break;
+ case DVD_DOMAIN_VTSMenu:
+ *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /* 1 */
+ *current = 0x41;
+ break;
+ case DVD_DOMAIN_VMGM:
+ case DVD_DOMAIN_FirstPlay:
+ *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /* 1 */
+ *current = 0x41;
+ break;
+ }
+}
+#endif
+
+void vm_get_video_res(vm_t *vm, int *width, int *height) {
+ video_attr_t attr = vm_get_video_attr(vm);
+
+ if(attr.video_format != 0)
+ *height = 576;
+ else
+ *height = 480;
+ switch(attr.picture_size) {
+ case 0:
+ *width = 720;
+ break;
+ case 1:
+ *width = 704;
+ break;
+ case 2:
+ *width = 352;
+ break;
+ case 3:
+ *width = 352;
+ *height /= 2;
+ break;
+ }
+}
+
+int vm_get_video_aspect(vm_t *vm) {
+ int aspect = vm_get_video_attr(vm).display_aspect_ratio;
+
+ if(aspect != 0 && aspect != 3) {
+ Log1(vm, "display aspect ratio is unexpected: %d!", aspect);
+ return -1;
+ }
+
+ (vm->state).registers.SPRM[14] &= ~(0x3 << 10);
+ (vm->state).registers.SPRM[14] |= aspect << 10;
+
+ return aspect;
+}
+
+int vm_get_video_scale_permission(vm_t *vm) {
+ return vm_get_video_attr(vm).permitted_df;
+}
+
+video_attr_t vm_get_video_attr(vm_t *vm) {
+ switch ((vm->state).domain) {
+ case DVD_DOMAIN_VTSTitle:
+ return vm->vtsi->vtsi_mat->vts_video_attr;
+ case DVD_DOMAIN_VTSMenu:
+ return vm->vtsi->vtsi_mat->vtsm_video_attr;
+ case DVD_DOMAIN_VMGM:
+ case DVD_DOMAIN_FirstPlay:
+ return vm->vmgi->vmgi_mat->vmgm_video_attr;
+ default:
+ assert(0);
+ }
+}
+
+audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN) {
+ switch ((vm->state).domain) {
+ case DVD_DOMAIN_VTSTitle:
+ return vm->vtsi->vtsi_mat->vts_audio_attr[streamN];
+ case DVD_DOMAIN_VTSMenu:
+ return vm->vtsi->vtsi_mat->vtsm_audio_attr;
+ case DVD_DOMAIN_VMGM:
+ case DVD_DOMAIN_FirstPlay:
+ return vm->vmgi->vmgi_mat->vmgm_audio_attr;
+ default:
+ assert(0);
+ }
+}
+
+subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN) {
+ switch ((vm->state).domain) {
+ case DVD_DOMAIN_VTSTitle:
+ return vm->vtsi->vtsi_mat->vts_subp_attr[streamN];
+ case DVD_DOMAIN_VTSMenu:
+ return vm->vtsi->vtsi_mat->vtsm_subp_attr;
+ case DVD_DOMAIN_VMGM:
+ case DVD_DOMAIN_FirstPlay:
+ return vm->vmgi->vmgi_mat->vmgm_subp_attr;
+ default:
+ assert(0);
+ }
+}