static event_t * dvd_media_enqueue(dvd_player_t *dp, media_queue_t *mq, media_codec_t *cw, int data_type, void *data, int datalen, int rate, int64_t dts, int64_t pts) { media_buf_t *mb = media_buf_alloc_unlocked(dp->dp_mp, datalen); event_t *e; AVCodecContext *ctx = cw->codec_ctx; mb->mb_cw = media_codec_ref(cw); mb->mb_data_type = data_type; mb->mb_duration = cw->codec_ctx->ticks_per_frame * 1000000LL * av_q2d(ctx->time_base); mb->mb_aspect_override = dp->dp_aspect_override; mb->mb_disable_deinterlacer = 1; mb->mb_dts = dts; mb->mb_pts = pts; if(pts != AV_NOPTS_VALUE && data_type == MB_VIDEO) { if(dp->dp_time_pts_delta == AV_NOPTS_VALUE) { int64_t t = av_rescale_q(dvdnav_get_current_time(dp->dp_dvdnav), mpeg_tc, AV_TIME_BASE_Q); dp->dp_time_pts_delta = pts - t; } mb->mb_time = pts - dp->dp_time_pts_delta; } else { mb->mb_time = AV_NOPTS_VALUE; } memcpy(mb->mb_data, data, datalen); do { if((e = mb_enqueue_with_events(dp->dp_mp, mq, mb)) == NULL) { mb = NULL; break; } e = dvd_process_event(dp, e); } while(e == NULL); if(mb != NULL) media_buf_free_unlocked(dp->dp_mp, mb); return e; }
static int control(stream_t *stream, int cmd, void* arg) { dvdnav_priv_t* priv=stream->priv; int tit, part; switch(cmd) { case STREAM_CTRL_SEEK_TO_CHAPTER: { int chap = *(unsigned int *)arg+1; if(chap < 1 || dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK) break; if(dvdnav_part_play(priv->dvdnav, tit, chap) != DVDNAV_STATUS_OK) break; return 1; } case STREAM_CTRL_GET_NUM_CHAPTERS: { if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK) break; if(dvdnav_get_number_of_parts(priv->dvdnav, tit, &part) != DVDNAV_STATUS_OK) break; if(!part) break; *(unsigned int *)arg = part; return 1; } case STREAM_CTRL_GET_CURRENT_CHAPTER: { if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK) break; *(unsigned int *)arg = part - 1; return 1; } case STREAM_CTRL_GET_TIME_LENGTH: { if(priv->duration || priv->still_length) { *(double *)arg = (double)priv->duration / 1000.0; return 1; } break; } case STREAM_CTRL_GET_ASPECT_RATIO: { uint8_t ar = dvdnav_get_video_aspect(priv->dvdnav); *(double *)arg = !ar ? 4.0/3.0 : 16.0/9.0; return 1; } case STREAM_CTRL_GET_CURRENT_TIME: { double tm; tm = dvdnav_get_current_time(priv->dvdnav)/90000.0f; if(tm != -1) { *(double *)arg = tm; return 1; } break; } case STREAM_CTRL_SEEK_TO_TIME: { uint64_t tm = *(double *)arg * 90000; if(dvdnav_time_search(priv->dvdnav, tm) == DVDNAV_STATUS_OK) return 1; break; } case STREAM_CTRL_GET_NUM_ANGLES: { uint32_t curr, angles; if(dvdnav_get_angle_info(priv->dvdnav, &curr, &angles) != DVDNAV_STATUS_OK) break; *(int *)arg = angles; return 1; } case STREAM_CTRL_GET_ANGLE: { uint32_t curr, angles; if(dvdnav_get_angle_info(priv->dvdnav, &curr, &angles) != DVDNAV_STATUS_OK) break; *(int *)arg = curr; return 1; } case STREAM_CTRL_SET_ANGLE: { uint32_t curr, angles; int new_angle = *(int *)arg; if(dvdnav_get_angle_info(priv->dvdnav, &curr, &angles) != DVDNAV_STATUS_OK) break; if(new_angle>angles || new_angle<1) break; if(dvdnav_angle_change(priv->dvdnav, new_angle) != DVDNAV_STATUS_OK) return 1; } case STREAM_CTRL_GET_LANG: { struct stream_lang_req *req = arg; int lang = 0; switch(req->type) { case stream_ctrl_audio: lang = mp_dvdnav_lang_from_aid(stream, req->id); break; case stream_ctrl_sub: lang = mp_dvdnav_lang_from_sid(stream, req->id); break; } if (!lang) break; req->buf[0] = lang >> 8; req->buf[1] = lang; req->buf[2] = 0; return STREAM_OK; } } return STREAM_UNSUPPORTED; }
static int control(stream_t *stream, int cmd, void* arg) { dvdnav_priv_t* priv=stream->priv; int tit, part; switch(cmd) { case STREAM_CTRL_SEEK_TO_CHAPTER: { int chap = *((unsigned int *)arg)+1; if(chap < 1 || dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK) break; if(dvdnav_part_play(priv->dvdnav, tit, chap) != DVDNAV_STATUS_OK) break; return 1; } case STREAM_CTRL_GET_NUM_CHAPTERS: { if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK) break; if(dvdnav_get_number_of_parts(priv->dvdnav, tit, &part) != DVDNAV_STATUS_OK) break; if(!part) break; *((unsigned int *)arg) = part; return 1; } case STREAM_CTRL_GET_CURRENT_CHAPTER: { if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK) break; *((unsigned int *)arg) = part - 1; return 1; } case STREAM_CTRL_GET_TIME_LENGTH: { if(priv->duration) { *((double *)arg) = (double)priv->duration / 1000.0; return 1; } break; } case STREAM_CTRL_GET_ASPECT_RATIO: { uint8_t ar = dvdnav_get_video_aspect(priv->dvdnav); *((double *)arg) = !ar ? 4.0/3.0 : 16.0/9.0; return 1; } case STREAM_CTRL_GET_CURRENT_TIME: { double tm; tm = dvdnav_get_current_time(priv->dvdnav)/90000.0f; if(tm != -1) { *((double *)arg) = tm; return 1; } break; } case STREAM_CTRL_SEEK_TO_TIME: { uint64_t tm = (uint64_t) (*((double*)arg) * 90000); if(dvdnav_time_search(priv->dvdnav, tm) == DVDNAV_STATUS_OK) return 1; break; } } return STREAM_UNSUPPORTED; }