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 open_s(stream_t *stream,int mode, void* opts, int* file_format) { struct stream_priv_s* p = (struct stream_priv_s*)opts; char *filename; int event,len,tmplen=0; uint32_t pos, l2; dvdnav_priv_t *priv; dvdnav_status_t status; if(p->device) filename = p->device; else if(dvd_device) filename= dvd_device; else filename = DEFAULT_DVD_DEVICE; if(!(priv=new_dvdnav_stream(filename))) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_CantOpenDVD,filename); return STREAM_UNSUPORTED; } if(p->track > 0) { if(dvd_chapter > 0 && dvd_last_chapter > 0 && dvd_chapter > dvd_last_chapter) { mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, invalid chapter range: %d > %d\n", dvd_chapter, dvd_last_chapter); return STREAM_UNSUPORTED; } priv->title = p->track; if(dvdnav_title_play(priv->dvdnav, p->track) != DVDNAV_STATUS_OK) { mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, couldn't select title %d, error '%s'\n", p->track, dvdnav_err_to_string(priv->dvdnav)); return STREAM_UNSUPORTED; } if(dvd_chapter > 0) dvdnav_part_play(priv->dvdnav, p->track, dvd_chapter); } else if(p->track == -1) dvdnav_menu_call(priv->dvdnav, DVD_MENU_Root); else { mp_msg(MSGT_OPEN,MSGL_INFO,"dvdnav_stream, you didn't specify a track number (as in dvdnav://1), playing whole disc\n"); dvdnav_menu_call(priv->dvdnav, DVD_MENU_Title); } if(dvd_angle > 1) dvdnav_angle_change(priv->dvdnav, dvd_angle); stream->sector_size = 2048; stream->flags = STREAM_READ | STREAM_SEEK; stream->fill_buffer = fill_buffer; stream->seek = seek; stream->control = control; stream->close = stream_dvdnav_close; stream->type = STREAMTYPE_DVDNAV; stream->priv=(void*)priv; *file_format = DEMUXER_TYPE_MPEG_PS; update_title_len(stream); if(!stream->pos) mp_msg(MSGT_OPEN,MSGL_ERR, "INIT ERROR: %d, couldn't get init pos %s\r\n", status, dvdnav_err_to_string(priv->dvdnav)); mp_msg(MSGT_OPEN,MSGL_INFO, "Remember to disable MPlayer's cache when playing dvdnav:// streams (adding -nocache to your command line)\r\n"); return STREAM_OK; }
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; }