c0760c8d2a
ok sthen@
160 lines
5.8 KiB
Plaintext
160 lines
5.8 KiB
Plaintext
$OpenBSD: patch-src_dvdnav_c,v 1.1 2012/09/26 00:04:09 brad Exp $
|
|
|
|
- Check that a VOB is open in case we need to open one
|
|
- Add a function to create a dpu of a dvdnav handle
|
|
- Prevent overflow by pre-casting to int64_t
|
|
- Remove unneeded address-of of CLUT
|
|
- Make sure we get nav packets for all cells in multi angle features
|
|
- Test still like a boolean value and not an integer value
|
|
- Always check whether a still is being handled
|
|
|
|
--- src/dvdnav.c.orig Wed Sep 5 14:23:55 2012
|
|
+++ src/dvdnav.c Wed Sep 5 14:24:07 2012
|
|
@@ -71,6 +71,67 @@ static dvdnav_status_t dvdnav_clear(dvdnav_t * this) {
|
|
return DVDNAV_STATUS_OK;
|
|
}
|
|
|
|
+dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src) {
|
|
+ dvdnav_t *this;
|
|
+
|
|
+ (*dest) = NULL;
|
|
+ this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
|
|
+ if(!this)
|
|
+ return DVDNAV_STATUS_ERR;
|
|
+
|
|
+ memcpy(this, src, sizeof(dvdnav_t));
|
|
+ this->file = NULL;
|
|
+
|
|
+ pthread_mutex_init(&this->vm_lock, NULL);
|
|
+
|
|
+ this->vm = vm_new_copy(src->vm);
|
|
+ if(!this->vm) {
|
|
+ printerr("Error initialising the DVD VM.");
|
|
+ pthread_mutex_destroy(&this->vm_lock);
|
|
+ free(this);
|
|
+ return DVDNAV_STATUS_ERR;
|
|
+ }
|
|
+
|
|
+ /* Start the read-ahead cache. */
|
|
+ this->cache = dvdnav_read_cache_new(this);
|
|
+
|
|
+ (*dest) = this;
|
|
+ return DVDNAV_STATUS_OK;
|
|
+}
|
|
+
|
|
+dvdnav_status_t dvdnav_free_dup(dvdnav_t *this) {
|
|
+
|
|
+#ifdef LOG_DEBUG
|
|
+ fprintf(MSG_OUT, "libdvdnav: free_dup:called\n");
|
|
+#endif
|
|
+
|
|
+ if (this->file) {
|
|
+ pthread_mutex_lock(&this->vm_lock);
|
|
+ DVDCloseFile(this->file);
|
|
+#ifdef LOG_DEBUG
|
|
+ fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
|
|
+#endif
|
|
+ this->file = NULL;
|
|
+ pthread_mutex_unlock(&this->vm_lock);
|
|
+ }
|
|
+
|
|
+ /* Free the VM */
|
|
+ if(this->vm)
|
|
+ vm_free_copy(this->vm);
|
|
+
|
|
+ pthread_mutex_destroy(&this->vm_lock);
|
|
+
|
|
+ /* We leave the final freeing of the entire structure to the cache,
|
|
+ * because we don't know, if there are still buffers out in the wild,
|
|
+ * that must return first. */
|
|
+ if(this->cache)
|
|
+ dvdnav_read_cache_free(this->cache);
|
|
+ else
|
|
+ free(this);
|
|
+
|
|
+ return DVDNAV_STATUS_OK;
|
|
+}
|
|
+
|
|
dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
|
|
dvdnav_t *this;
|
|
struct timeval time;
|
|
@@ -203,12 +264,12 @@ int64_t dvdnav_convert_time(dvd_time_t *time) {
|
|
int64_t result;
|
|
int64_t frames;
|
|
|
|
- result = (time->hour >> 4 ) * 10 * 60 * 60 * 90000;
|
|
- result += (time->hour & 0x0f) * 60 * 60 * 90000;
|
|
- result += (time->minute >> 4 ) * 10 * 60 * 90000;
|
|
- result += (time->minute & 0x0f) * 60 * 90000;
|
|
- result += (time->second >> 4 ) * 10 * 90000;
|
|
- result += (time->second & 0x0f) * 90000;
|
|
+ result = ((int64_t)(time->hour >> 4 )) * 10 * 60 * 60 * 90000;
|
|
+ result += ((int64_t)(time->hour & 0x0f)) * 60 * 60 * 90000;
|
|
+ result += ((int64_t)(time->minute >> 4 )) * 10 * 60 * 90000;
|
|
+ result += ((int64_t)(time->minute & 0x0f)) * 60 * 90000;
|
|
+ result += ((int64_t)(time->second >> 4 )) * 10 * 90000;
|
|
+ result += ((int64_t)(time->second & 0x0f)) * 90000;
|
|
|
|
frames = ((time->frame_u & 0x30) >> 4) * 10;
|
|
frames += ((time->frame_u & 0x0f) ) ;
|
|
@@ -336,9 +397,10 @@ static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *
|
|
dvdnav_angle_change(this, 1);
|
|
}
|
|
#endif
|
|
+ /* only use ILVU information if we are at the last vobunit in ILVU */
|
|
+ /* otherwise we will miss nav packets from vobunits inbetween */
|
|
+ if(num_angle != 0 && (nav_dsi->sml_pbi.category & DSI_ILVU_MASK) == (DSI_ILVU_BLOCK | DSI_ILVU_LAST)) {
|
|
|
|
- if(num_angle != 0) {
|
|
-
|
|
if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) {
|
|
if((next & 0x3fffffff) != 0) {
|
|
if(next & 0x80000000)
|
|
@@ -518,8 +580,10 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *
|
|
return DVDNAV_STATUS_OK;
|
|
}
|
|
|
|
- /* Check to see if we need to change the currently opened VOB */
|
|
- if((this->position_current.vts != this->position_next.vts) ||
|
|
+ /* Check to see if we need to change the currently opened VOB or open
|
|
+ * a new one because we don't currently have an opened VOB. */
|
|
+ if((this->file == NULL) ||
|
|
+ (this->position_current.vts != this->position_next.vts) ||
|
|
(this->position_current.domain != this->position_next.domain)) {
|
|
dvd_read_domain_t domain;
|
|
int32_t vtsN;
|
|
@@ -655,7 +719,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *
|
|
fprintf(MSG_OUT, "libdvdnav: SPU_CLUT_CHANGE\n");
|
|
#endif
|
|
(*len) = 16 * sizeof(uint32_t);
|
|
- memcpy(*buf, &(state->pgc->palette), 16 * sizeof(uint32_t));
|
|
+ memcpy(*buf, state->pgc->palette, sizeof(state->pgc->palette));
|
|
this->spu_clut_changed = 0;
|
|
pthread_mutex_unlock(&this->vm_lock);
|
|
return DVDNAV_STATUS_OK;
|
|
@@ -731,16 +795,15 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *
|
|
/* we are about to leave a cell, so a lot of state changes could occur;
|
|
* under certain conditions, the application should get in sync with us before this,
|
|
* otherwise it might show stills or menus too shortly */
|
|
- if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) {
|
|
+ if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip)
|
|
this->sync_wait = 1;
|
|
- } else {
|
|
- if( this->position_current.still == 0 || this->skip_still ) {
|
|
- /* 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;
|
|
- }
|
|
+
|
|
+ if(!this->position_current.still || this->skip_still ) {
|
|
+ /* 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;
|