static int dvdnav_stream_read(dvdnav_priv_t * priv, unsigned char *buf, int *len) { int event = DVDNAV_NOP; if (!len) return -1; *len=-1; if (!priv) return -1; if (!buf) return -1; if (dvd_nav_still) { mp_msg(MSGT_OPEN,MSGL_V, "%s: got a stream_read while I should be asleep!\n",__FUNCTION__); *len=0; return -1; } if (dvdnav_get_next_block(priv->dvdnav,buf,&event,len)!=DVDNAV_STATUS_OK) { mp_msg(MSGT_OPEN,MSGL_V, "Error getting next block from DVD %d (%s)\n",event, dvdnav_err_to_string(priv->dvdnav) ); *len=-1; } else if (event!=DVDNAV_BLOCK_OK) { // need to handle certain events internally (like skipping stills) switch (event) { case DVDNAV_NAV_PACKET: return event; case DVDNAV_STILL_FRAME: { dvdnav_still_event_t *still_event = (dvdnav_still_event_t*)(buf); //if (priv->started) dvd_nav_still=1; //else dvdnav_still_skip(priv->dvdnav); // don't let dvdnav stall on this image break; } case DVDNAV_HIGHLIGHT: { dvdnav_get_highlight (priv, 1); break; } case DVDNAV_CELL_CHANGE: { dvdnav_cell_change_event_t *ev = (dvdnav_cell_change_event_t*)buf; if(ev->pgc_length) priv->duration = ev->pgc_length/90; break; } case DVDNAV_SPU_CLUT_CHANGE: { memcpy(priv->spu_clut, buf, 16*sizeof(unsigned int)); priv->spu_set = 1; break; } case DVDNAV_WAIT: dvdnav_wait_skip(priv->dvdnav); break; } *len=0; } return event; }
static int fill_buffer(stream_t *s, char *but, int len) { int event; dvdnav_priv_t* priv=s->priv; len=0; if(!s->end_pos) update_title_len(s); while(!len) /* grab all event until DVDNAV_BLOCK_OK (len=2048), DVDNAV_STOP or DVDNAV_STILL_FRAME */ { event=dvdnav_stream_read(priv, s->buffer, &len); if(event==-1 || len==-1) { mp_msg(MSGT_CPLAYER,MSGL_ERR, "DVDNAV stream read error!\n"); return 0; } switch (event) { case DVDNAV_STOP: case DVDNAV_BLOCK_OK: case DVDNAV_NAV_PACKET: return len; case DVDNAV_VTS_CHANGE: { int tit = 0, part = 0; dvdnav_vts_change_event_t *vts_event = (dvdnav_vts_change_event_t *)s->buffer; mp_msg(MSGT_CPLAYER,MSGL_INFO, "DVDNAV, switched to title: %d\r\n", vts_event->new_vtsN); s->end_pos = 0; update_title_len(s); if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) == DVDNAV_STATUS_OK) { mp_msg(MSGT_CPLAYER,MSGL_V, "\r\nDVDNAV, NEW TITLE %d\r\n", tit); dvdnav_get_highlight (priv, 0); if(priv->title > 0 && tit != priv->title) return 0; } break; } case DVDNAV_CELL_CHANGE: { if(priv->title > 0 && dvd_last_chapter > 0) { int tit=0, part=0; if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) == DVDNAV_STATUS_OK && part > dvd_last_chapter) return 0; } } break; } } mp_msg(MSGT_STREAM,MSGL_DBG2,"DVDNAV fill_buffer len: %d\n",len); return len; }
static int fill_buffer(stream_t *s, char *but, int len) { int event; dvdnav_priv_t* priv=s->priv; if (priv->state & NAV_FLAG_WAIT_READ) /* read is suspended */ return -1; len=0; if(!s->end_pos) update_title_len(s); while(!len) /* grab all event until DVDNAV_BLOCK_OK (len=2048), DVDNAV_STOP or DVDNAV_STILL_FRAME */ { event=dvdnav_stream_read(priv, s->buffer, &len); if(event==-1 || len==-1) { mp_msg(MSGT_CPLAYER,MSGL_ERR, "DVDNAV stream read error!\n"); return 0; } if (event != DVDNAV_BLOCK_OK) dvdnav_get_highlight (priv, 1); switch (event) { case DVDNAV_STOP: { priv->state |= NAV_FLAG_EOF; return len; } case DVDNAV_BLOCK_OK: case DVDNAV_NAV_PACKET: case DVDNAV_STILL_FRAME: return len; case DVDNAV_WAIT: { if (priv->state & NAV_FLAG_WAIT) return len; break; } case DVDNAV_VTS_CHANGE: { int tit = 0, part = 0; dvdnav_vts_change_event_t *vts_event = (dvdnav_vts_change_event_t *)s->buffer; mp_msg(MSGT_CPLAYER,MSGL_INFO, "DVDNAV, switched to title: %d\r\n", vts_event->new_vtsN); priv->state |= NAV_FLAG_CELL_CHANGE; priv->state |= NAV_FLAG_AUDIO_CHANGE; priv->state |= NAV_FLAG_SPU_CHANGE; priv->state &= ~NAV_FLAG_WAIT_SKIP; priv->state &= ~NAV_FLAG_WAIT; s->end_pos = 0; update_title_len(s); show_audio_subs_languages(priv->dvdnav); if (priv->state & NAV_FLAG_WAIT_READ_AUTO) priv->state |= NAV_FLAG_WAIT_READ; if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) == DVDNAV_STATUS_OK) { mp_msg(MSGT_CPLAYER,MSGL_V, "\r\nDVDNAV, NEW TITLE %d\r\n", tit); dvdnav_get_highlight (priv, 0); if(priv->title > 0 && tit != priv->title) { priv->state |= NAV_FLAG_EOF; return 0; } } break; } case DVDNAV_CELL_CHANGE: { priv->state |= NAV_FLAG_CELL_CHANGE; priv->state |= NAV_FLAG_AUDIO_CHANGE; priv->state |= NAV_FLAG_SPU_CHANGE; priv->state &= ~NAV_FLAG_WAIT_SKIP; priv->state &= ~NAV_FLAG_WAIT; if (priv->state & NAV_FLAG_WAIT_READ_AUTO) priv->state |= NAV_FLAG_WAIT_READ; if(priv->title > 0 && dvd_last_chapter > 0) { int tit=0, part=0; if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) == DVDNAV_STATUS_OK && part > dvd_last_chapter) { priv->state |= NAV_FLAG_EOF; return 0; } } dvdnav_get_highlight (priv, 1); } break; case DVDNAV_AUDIO_STREAM_CHANGE: priv->state |= NAV_FLAG_AUDIO_CHANGE; break; case DVDNAV_SPU_STREAM_CHANGE: priv->state |= NAV_FLAG_SPU_CHANGE; break; } } mp_msg(MSGT_STREAM,MSGL_DBG2,"DVDNAV fill_buffer len: %d\n",len); return len; }
static int dvdnav_stream_read(dvdnav_priv_t * priv, unsigned char *buf, int *len) { int event = DVDNAV_NOP; *len=-1; if (dvdnav_get_next_block(priv->dvdnav,buf,&event,len)!=DVDNAV_STATUS_OK) { mp_msg(MSGT_OPEN,MSGL_V, "Error getting next block from DVD %d (%s)\n",event, dvdnav_err_to_string(priv->dvdnav) ); *len=-1; } else if (event!=DVDNAV_BLOCK_OK) { // need to handle certain events internally (like skipping stills) switch (event) { case DVDNAV_NAV_PACKET: return event; case DVDNAV_STILL_FRAME: { dvdnav_still_event_t *still_event = (dvdnav_still_event_t *) buf; priv->still_length = still_event->length; /* set still frame duration */ priv->duration = dvdnav_get_duration (priv->still_length); if (priv->still_length <= 1) { pci_t *pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav); priv->duration = mp_dvdtimetomsec (&pnavpci->pci_gi.e_eltm); } break; } case DVDNAV_HIGHLIGHT: { dvdnav_get_highlight (priv, 1); break; } case DVDNAV_CELL_CHANGE: { dvdnav_cell_change_event_t *ev = (dvdnav_cell_change_event_t*)buf; uint32_t nextstill; priv->state &= ~NAV_FLAG_WAIT_SKIP; priv->state |= NAV_FLAG_STREAM_CHANGE; if(ev->pgc_length) priv->duration = ev->pgc_length/90; if (dvdnav_is_domain_vts(priv->dvdnav)) { mp_msg(MSGT_IDENTIFY, MSGL_INFO, "DVDNAV_TITLE_IS_MOVIE\n"); priv->state &= ~NAV_FLAG_VTS_DOMAIN; } else { mp_msg(MSGT_IDENTIFY, MSGL_INFO, "DVDNAV_TITLE_IS_MENU\n"); priv->state |= NAV_FLAG_VTS_DOMAIN; } nextstill = dvdnav_get_next_still_flag (priv->dvdnav); if (nextstill) { priv->duration = dvdnav_get_duration (nextstill); priv->still_length = nextstill; if (priv->still_length <= 1) { pci_t *pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav); priv->duration = mp_dvdtimetomsec (&pnavpci->pci_gi.e_eltm); } } break; } case DVDNAV_SPU_CLUT_CHANGE: { memcpy(priv->spu_clut, buf, 16*sizeof(unsigned int)); priv->state |= NAV_FLAG_SPU_SET; break; } case DVDNAV_WAIT: { if ((priv->state & NAV_FLAG_WAIT_SKIP) && !(priv->state & NAV_FLAG_WAIT)) dvdnav_wait_skip (priv->dvdnav); else priv->state |= NAV_FLAG_WAIT; break; } case DVDNAV_VTS_CHANGE: { priv->state &= ~NAV_FLAG_WAIT_SKIP; priv->state |= NAV_FLAG_STREAM_CHANGE; break; } case DVDNAV_SPU_STREAM_CHANGE: { priv->state |= NAV_FLAG_STREAM_CHANGE; break; } } *len=0; } return event; }