📄 dvdnav.c
字号:
/* no active cell still -> get us to the next cell */ vm_get_next_cell(this->vm); this->position_current.still = 0; /* still gets activated at end of cell */ this->skip_still = 0; this->sync_wait_skip = 0; } } /* handle related state changes in next iteration */ (*event) = DVDNAV_NOP; (*len) = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Perform remapping jump if necessary (this is always a * VOBU boundary). */ if (this->vm->map) { this->vobu.vobu_next = remap_block( this->vm->map, this->vm->state.domain, this->vm->state.TTN_REG, this->vm->state.pgN, this->vobu.vobu_start, this->vobu.vobu_next); } /* at the start of the next VOBU -> expecting NAV packet */ result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf); if(result <= 0) { printerr("Error reading NAV packet."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* Decode nav into pci and dsi. Then get next VOBU info. */ if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) { printerr("Expected NAV packet but none found."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* We need to update the vm state->blockN with which VOBU we are in. * This is so RSM resumes to the VOBU level and not just the CELL level. */ this->vm->state.blockN = this->vobu.vobu_start - this->position_current.cell_start; dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu); this->vobu.blockN = 0; /* Give the cache a hint about the size of next VOBU. * This improves pre-caching, because the VOBU will almost certainly be read entirely. */ dvdnav_pre_cache_blocks(this->cache, this->vobu.vobu_start+1, this->vobu.vobu_length+1); /* release NAV menu filter, when we reach the same NAV packet again */ if (this->last_cmd_nav_lbn == this->pci.pci_gi.nv_pck_lbn) this->last_cmd_nav_lbn = SRI_END_OF_CELL; /* Successfully got a NAV packet */ (*event) = DVDNAV_NAV_PACKET;#ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: NAV_PACKET\n");#endif (*len) = 2048; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* If we've got here, it must just be a normal block. */ if(!this->file) { printerr("Attempting to read without opening file."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } this->vobu.blockN++; result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.blockN, 1, buf); if(result <= 0) { printerr("Error reading from DVD."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } (*event) = DVDNAV_BLOCK_OK; (*len) = 2048; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK;}dvdnav_status_t dvdnav_get_title_string(dvdnav_t *this, const char **title_str) { if(!this || !title_str) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } (*title_str) = this->vm->dvd_name; return DVDNAV_STATUS_OK;}uint8_t dvdnav_get_video_aspect(dvdnav_t *this) { uint8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); retval = (uint8_t)vm_get_video_aspect(this->vm); pthread_mutex_unlock(&this->vm_lock); return retval;}uint8_t dvdnav_get_video_scale_permission(dvdnav_t *this) { uint8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); retval = (uint8_t)vm_get_video_scale_permission(this->vm); pthread_mutex_unlock(&this->vm_lock); return retval;}uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *this, uint8_t stream) { audio_attr_t attr; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); attr = vm_get_audio_attr(this->vm, stream); pthread_mutex_unlock(&this->vm_lock); if(attr.lang_type != 1) return 0xffff; return attr.lang_code;}uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) { subp_attr_t attr; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); attr = vm_get_subp_attr(this->vm, stream); pthread_mutex_unlock(&this->vm_lock); if(attr.type != 1) return 0xffff; return attr.lang_code;}int8_t dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_audio_stream(this->vm, audio_num); pthread_mutex_unlock(&this->vm_lock); return retval;}int8_t dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_subp_stream(this->vm, subp_num, 0); pthread_mutex_unlock(&this->vm_lock); return retval;}int8_t dvdnav_get_active_audio_stream(dvdnav_t *this) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_audio_active_stream(this->vm); pthread_mutex_unlock(&this->vm_lock); return retval;}int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_subp_active_stream(this->vm, 0); pthread_mutex_unlock(&this->vm_lock); return retval;}static int8_t dvdnav_is_domain(dvdnav_t *this, domain_t domain) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); retval = (this->vm->state.domain == domain); pthread_mutex_unlock(&this->vm_lock); return retval;}/* First Play domain. (Menu) */int8_t dvdnav_is_domain_fp(dvdnav_t *this) { return dvdnav_is_domain(this, FP_DOMAIN);}/* Video management Menu domain. (Menu) */int8_t dvdnav_is_domain_vmgm(dvdnav_t *this) { return dvdnav_is_domain(this, VMGM_DOMAIN);}/* Video Title Menu domain (Menu) */int8_t dvdnav_is_domain_vtsm(dvdnav_t *this) { return dvdnav_is_domain(this, VTSM_DOMAIN);}/* Video Title domain (playing movie). */int8_t dvdnav_is_domain_vts(dvdnav_t *this) { return dvdnav_is_domain(this, VTS_DOMAIN);}/* Generally delegate angle information handling to VM */dvdnav_status_t dvdnav_angle_change(dvdnav_t *this, int32_t angle) { int32_t num, current; if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); vm_get_angle_info(this->vm, ¤t, &num); /* Set angle SPRM if valid */ if((angle > 0) && (angle <= num)) { this->vm->state.AGL_REG = angle; } else { printerr("Passed an invalid angle number."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK;}dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *this, int32_t *current_angle, int32_t *number_of_angles) { if(!this || !current_angle || !number_of_angles) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); vm_get_angle_info(this->vm, current_angle, number_of_angles); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK;}pci_t* dvdnav_get_current_nav_pci(dvdnav_t *this) { if(!this) return 0; return &this->pci;}dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *this) { if(!this) return 0; return &this->dsi;}uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) { if(!this) return -1; return this->position_next.still;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -