diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /libdvdnav-embedded/src/vm/vmget.c | |
parent | Initial commit. (diff) | |
download | kodi-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.c | 353 |
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); + } +} |