35#include <dvdnav/dvdnav.h>
36#include <dvdread/dvd_reader.h>
37#include <dvdread/ifo_read.h>
38#include <dvdread/ifo_types.h>
39#include <dvdread/nav_read.h>
57#define DVDVIDEO_MAX_PS_SEARCH_BLOCKS 128
58#define DVDVIDEO_BLOCK_SIZE 2048
59#define DVDVIDEO_TIME_BASE_Q (AVRational) { 1, 90000 }
60#define DVDVIDEO_PTS_WRAP_BITS 32
61#define DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE 1024
63#define PCI_START_BYTE 45
73 "Fullscreen",
"Widescreen",
"Letterbox",
"Pan and Scan"
178 const char *msg, va_list msg_va)
184 vsnprintf(msg_buf,
sizeof(msg_buf), msg, msg_va);
186 if (
level == DVD_LOGGER_LEVEL_ERROR)
188 else if (
level == DVD_LOGGER_LEVEL_WARN)
191 av_log(
s, lavu_level,
"libdvdread: %s\n", msg_buf);
195 const char *msg, va_list msg_va)
201 vsnprintf(msg_buf,
sizeof(msg_buf), msg, msg_va);
203 if (
level == DVDNAV_LOGGER_LEVEL_ERROR)
209 av_log(
s, lavu_level,
"libdvdnav: %s\n", msg_buf);
217 ifoClose(
c->vts_ifo);
220 ifoClose(
c->vmg_ifo);
223 DVDClose(
c->dvdread);
230 dvd_logger_cb dvdread_log_cb;
231 title_info_t title_info;
234 c->dvdread = DVDOpen2(
s, &dvdread_log_cb,
s->url);
242 if (!(
c->vmg_ifo = ifoOpen(
c->dvdread, 0))) {
249 if (
c->opt_menu_vts > 0 && !(
c->vts_ifo = ifoOpen(
c->dvdread,
c->opt_menu_vts))) {
255 if ((!
c->opt_menu_vts &&
c->vmg_ifo->vmgi_mat->nr_of_vmgm_audio_streams > 8) ||
256 (
c->opt_menu_vts &&
c->vts_ifo->vtsi_mat->nr_of_vtsm_audio_streams > 8)) {
265 if (
c->opt_title >
c->vmg_ifo->tt_srpt->nr_of_srpts) {
271 title_info =
c->vmg_ifo->tt_srpt->title[
c->opt_title - 1];
272 if (
c->opt_angle > title_info.nr_of_angles) {
278 if (title_info.nr_of_ptts < 1) {
284 if (
c->opt_chapter_start > title_info.nr_of_ptts ||
285 (
c->opt_chapter_end > 0 &&
c->opt_chapter_end > title_info.nr_of_ptts)) {
287 c->opt_chapter_start,
c->opt_chapter_end);
292 if (!(
c->vts_ifo = ifoOpen(
c->dvdread, title_info.title_set_nr))) {
294 title_info.title_set_nr);
299 if (title_info.vts_ttn < 1 ||
300 title_info.vts_ttn > 99 ||
301 title_info.vts_ttn >
c->vts_ifo->vts_ptt_srpt->nr_of_srpts ||
302 c->vts_ifo->vtsi_mat->nr_of_vts_audio_streams > 8 ||
303 c->vts_ifo->vtsi_mat->nr_of_vts_subp_streams > 32) {
309 c->nb_angles = title_info.nr_of_angles;
316 dvd_time_t cell_duration = pgc->cell_playback[celln - 1].playback_time;
318 return cell_duration.second >= 1 || cell_duration.minute >= 1 || cell_duration.hour >= 1;
323 for (
int i = 1;
i <= pgc->nr_of_cells;
i++)
333 DVDCloseFile(
state->vob_file);
341 pgci_ut =
c->opt_menu_vts ?
c->vts_ifo->pgci_ut :
c->vmg_ifo->pgci_ut;
344 c->opt_menu_lu,
c->opt_pgc);
349 if (
c->opt_pgc < 1 ||
350 c->opt_menu_lu < 1 ||
351 c->opt_menu_lu > pgci_ut->nr_of_lus ||
352 c->opt_pgc > pgci_ut->lu[
c->opt_menu_lu - 1].pgcit->nr_of_pgci_srp) {
361 state->pgc = pgci_ut->lu[
c->opt_menu_lu - 1].pgcit->pgci_srp[
c->opt_pgc - 1].pgc;
362 if (!
state->pgc || !
state->pgc->program_map || !
state->pgc->cell_playback) {
364 c->opt_menu_lu,
c->opt_pgc);
370 state->entry_pgn =
c->opt_pg;
371 if (
state->entry_pgn < 1 ||
state->entry_pgn >
state->pgc->nr_of_programs) {
381 if (
state->celln_start < 1 ||
state->celln_start >
state->pgc->nr_of_cells) {
387 state->sector_end =
state->pgc->cell_playback[
state->celln - 1].last_sector;
388 state->vobu_next =
state->pgc->cell_playback[
state->celln - 1].first_sector;
391 if (
c->opt_menu_vts > 0)
394 if (!(
state->vob_file = DVDOpenFile(
c->dvdread,
c->opt_menu_vts, DVD_READ_MENU_VOBS))) {
396 "Unable to open main menu VOB (VIDEO_TS.VOB)\n" :
397 "Unable to open menu VOBs for VTS %d\n",
c->opt_menu_vts);
406 uint8_t *buf,
int buf_size,
int *p_is_nav_packet)
410 pci_t pci = (pci_t) {0};
411 dsi_t dsi = (dsi_t) {0};
413 (*p_is_nav_packet) = 0;
414 state->ptm_discont = 0;
424 if (!
state->vobu_remaining &&
state->in_pgc) {
425 if (
state->vobu_next == SRI_END_OF_CELL) {
430 state->sector_offset =
state->pgc->cell_playback[
state->celln - 1].first_sector;
431 state->sector_end =
state->pgc->cell_playback[
state->celln - 1].last_sector;
440 blocks_read = DVDReadBlocks(
state->vob_file,
state->sector_offset, 1, read_buf);
441 if (blocks_read != 1) {
443 state->sector_offset, blocks_read);
449 if (!
state->vobu_remaining) {
453 read_buf[DSI_START_BYTE - 1] != 0x01) {
456 state->sector_offset);
462 navRead_DSI(&dsi, &read_buf[DSI_START_BYTE]);
464 if (!pci.pci_gi.vobu_s_ptm ||
465 !pci.pci_gi.vobu_e_ptm ||
466 pci.pci_gi.vobu_s_ptm > pci.pci_gi.vobu_e_ptm) {
469 state->sector_offset);
474 state->vobu_remaining = dsi.dsi_gi.vobu_ea;
475 state->vobu_next = dsi.vobu_sri.next_vobu == SRI_END_OF_CELL ? SRI_END_OF_CELL :
476 dsi.dsi_gi.nv_pck_lbn + (dsi.vobu_sri.next_vobu & 0x7FFFFFFF);
477 state->sector_offset++;
480 if (
state->vobu_e_ptm != pci.pci_gi.vobu_s_ptm) {
481 state->ptm_discont = 1;
482 state->ptm_offset +=
state->vobu_e_ptm - pci.pci_gi.vobu_s_ptm;
489 state->vobu_e_ptm = pci.pci_gi.vobu_e_ptm;
490 state->vobu_duration = pci.pci_gi.vobu_e_ptm - pci.pci_gi.vobu_s_ptm;
493 "vobu_s_ptm=%d vobu_e_ptm=%d ptm_offset=%" PRId64
"\n",
494 dsi.dsi_gi.nv_pck_lbn,
495 pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm,
state->ptm_offset);
498 (*p_is_nav_packet) = 1;
505 state->sector_offset++;
506 state->vobu_remaining--;
517 if (
state->pgc_pg_times_est)
518 free(
state->pgc_pg_times_est);
520 if (dvdnav_close(
state->dvdnav) != DVDNAV_STATUS_OK)
522 dvdnav_err_to_string(
state->dvdnav));
529 dvdnav_logger_cb dvdnav_log_cb;
530 dvdnav_status_t dvdnav_open_status;
533 int cur_title, cur_pgcn, cur_pgn;
537 dvdnav_open_status = dvdnav_open2(&
state->dvdnav,
s, &dvdnav_log_cb,
s->url);
539 if (!
state->dvdnav ||
540 dvdnav_open_status != DVDNAV_STATUS_OK ||
541 dvdnav_set_readahead_flag(
state->dvdnav, 0) != DVDNAV_STATUS_OK ||
542 dvdnav_set_PGC_positioning_flag(
state->dvdnav, 1) != DVDNAV_STATUS_OK ||
543 dvdnav_get_region_mask(
state->dvdnav, &disc_region_mask) != DVDNAV_STATUS_OK) {
546 goto end_dvdnav_error;
549 player_region_mask =
c->opt_region > 0 ? (1 << (
c->opt_region - 1)) : disc_region_mask;
550 if (dvdnav_set_region_mask(
state->dvdnav, player_region_mask) != DVDNAV_STATUS_OK) {
553 goto end_dvdnav_error;
556 if (
c->opt_pgc > 0) {
557 if (dvdnav_program_play(
state->dvdnav,
c->opt_title,
c->opt_pgc,
c->opt_pg) != DVDNAV_STATUS_OK) {
559 c->opt_title,
c->opt_pgc,
c->opt_pg);
561 goto end_dvdnav_error;
565 state->entry_pgn =
c->opt_pg;
567 if (dvdnav_part_play(
state->dvdnav,
c->opt_title,
c->opt_chapter_start) != DVDNAV_STATUS_OK ||
568 dvdnav_current_title_program(
state->dvdnav, &cur_title, &cur_pgcn, &cur_pgn) != DVDNAV_STATUS_OK) {
571 c->opt_title,
c->opt_chapter_start);
572 goto end_dvdnav_error;
575 state->pgcn = cur_pgcn;
576 state->entry_pgn = cur_pgn;
579 pgc =
c->vts_ifo->vts_pgcit->pgci_srp[
state->pgcn - 1].pgc;
581 if (pgc->pg_playback_mode != 0) {
589 "if you want to try anyway, disable the -trim option\n",
590 c->opt_title,
state->pgcn);
595 if (dvdnav_angle_change(
state->dvdnav,
c->opt_angle) != DVDNAV_STATUS_OK) {
598 goto end_dvdnav_error;
603 state->pgc_nb_pg_est = dvdnav_describe_title_chapters(
state->dvdnav,
c->opt_title,
604 &
state->pgc_pg_times_est,
605 &
state->pgc_duration_est);
608 if (!
state->pgc_nb_pg_est) {
611 goto end_dvdnav_error;
614 state->nav_pts = dvdnav_get_current_time(
state->dvdnav);
615 state->vtsn =
c->vmg_ifo->tt_srpt->title[
c->opt_title - 1].title_set_nr;
630 uint8_t *buf,
int buf_size,
int *p_is_nav_packet)
638 dvdnav_vts_change_event_t *e_vts;
639 dvdnav_cell_change_event_t *e_cell;
640 int cur_title, cur_pgcn, cur_pgn, cur_angle, cur_title_unused, cur_ptt, cur_nb_angles;
644 (*p_is_nav_packet) = 0;
645 state->ptm_discont = 0;
658 if (dvdnav_get_next_block(
state->dvdnav, nav_buf, &nav_event, &nav_len) != DVDNAV_STATUS_OK) {
661 goto end_dvdnav_error;
665 if (nav_event == DVDNAV_STOP)
675 if (dvdnav_current_title_info(
state->dvdnav, &cur_title, &cur_ptt) != DVDNAV_STATUS_OK) {
678 goto end_dvdnav_error;
682 if (cur_title == 0 || !dvdnav_is_domain_vts(
state->dvdnav))
685 if (dvdnav_current_title_program(
state->dvdnav, &cur_title_unused, &cur_pgcn, &cur_pgn) != DVDNAV_STATUS_OK) {
688 goto end_dvdnav_error;
695 if (dvdnav_get_angle_info(
state->dvdnav, &cur_angle, &cur_nb_angles) != DVDNAV_STATUS_OK) {
698 goto end_dvdnav_error;
702 "new block: i=%d nav_event=%d nav_len=%d cur_title=%d "
703 "cur_ptt=%d cur_angle=%d cur_celln=%d cur_pgcn=%d cur_pgn=%d "
704 "play_in_vts=%d play_in_pgc=%d play_in_ps=%d\n",
705 i, nav_event, nav_len, cur_title,
706 cur_ptt, cur_angle,
state->celln, cur_pgcn, cur_pgn,
710 case DVDNAV_VTS_CHANGE:
714 e_vts = (dvdnav_vts_change_event_t *) nav_buf;
716 if (e_vts->new_vtsN ==
state->vtsn && e_vts->new_domain == DVD_DOMAIN_VTSTitle)
720 case DVDNAV_CELL_CHANGE:
724 e_cell = (dvdnav_cell_change_event_t *) nav_buf;
729 if (cur_title ==
c->opt_title &&
730 (
c->opt_pgc || cur_ptt ==
c->opt_chapter_start) &&
731 cur_pgcn ==
state->pgcn &&
732 cur_pgn ==
state->entry_pgn) {
736 }
else if (!
state->is_seeking &&
737 (
state->celln >= e_cell->cellN ||
state->pgn > cur_pgn)) {
741 state->celln = e_cell->cellN;
742 state->ptt = cur_ptt;
743 state->pgn = cur_pgn;
746 case DVDNAV_NAV_PACKET:
751 (
c->opt_chapter_end > 0 && cur_ptt >
c->opt_chapter_end)) {
762 e_pci = dvdnav_get_current_nav_pci(
state->dvdnav);
763 e_dsi = dvdnav_get_current_nav_dsi(
state->dvdnav);
765 if (e_pci ==
NULL || e_dsi ==
NULL ||
766 e_pci->pci_gi.vobu_s_ptm > e_pci->pci_gi.vobu_e_ptm) {
772 if (
state->nb_vobu_skip > 0) {
774 e_dsi->dsi_gi.nv_pck_scr);
775 state->nb_vobu_skip -= 1;
779 state->vobu_duration = e_pci->pci_gi.vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
781 state->nav_pts = dvdnav_get_current_time(
state->dvdnav);
782 state->ptt = cur_ptt;
783 state->pgn = cur_pgn;
786 "NAV packet: s_ptm=%d e_ptm=%d "
787 "scr=%d lbn=%d vobu_duration=%d nav_pts=%" PRId64
"\n",
788 e_pci->pci_gi.vobu_s_ptm, e_pci->pci_gi.vobu_e_ptm,
789 e_dsi->dsi_gi.nv_pck_scr,
790 e_pci->pci_gi.nv_pck_lbn,
state->vobu_duration,
state->nav_pts);
804 if (
state->vobu_e_ptm != e_pci->pci_gi.vobu_s_ptm) {
805 state->ptm_discont = 1;
806 state->ptm_offset +=
state->vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
810 state->vobu_e_ptm = e_pci->pci_gi.vobu_e_ptm;
812 (*p_is_nav_packet) = 1;
815 case DVDNAV_BLOCK_OK:
829 if (cur_angle !=
c->opt_angle) {
831 c->opt_angle, cur_angle);
836 if (
state->pgn != cur_pgn)
838 "this could be due to a missed NAV packet\n",
839 state->pgn, cur_pgn);
841 memcpy(buf, &nav_buf, nav_len);
843 state->is_seeking = 0;
847 if (dvdnav_wait_skip(
state->dvdnav) != DVDNAV_STATUS_OK) {
850 goto end_dvdnav_error;
854 case DVDNAV_STILL_FRAME:
855 case DVDNAV_HOP_CHANNEL:
856 case DVDNAV_HIGHLIGHT:
860 if (nav_event == DVDNAV_STILL_FRAME) {
861 if (dvdnav_still_skip(
state->dvdnav) != DVDNAV_STATUS_OK) {
864 goto end_dvdnav_error;
880 cur_title, cur_pgcn, cur_pgn,
state->celln,
881 dvdnav_err_to_string(
state->dvdnav));
890 uint64_t time_prev = 0;
893 int chapter_start =
c->opt_chapter_start;
894 int chapter_end =
c->opt_chapter_end > 0 ?
c->opt_chapter_end :
c->play_state.pgc_nb_pg_est;
897 if (
c->play_state.pgc_nb_pg_est == 1 ||
898 chapter_start >
c->play_state.pgc_nb_pg_est ||
899 chapter_end >
c->play_state.pgc_nb_pg_est) {
906 for (
int i = chapter_start - 1;
i < chapter_end;
i++) {
907 uint64_t time_effective =
c->play_state.pgc_pg_times_est[
i] -
c->play_state.nav_pts;
909 if (time_effective - time_prev == 0)
912 if (chapter_start != chapter_end &&
918 time_prev = time_effective;
919 total_duration = time_effective;
922 if (
c->opt_chapter_start == 1 &&
c->opt_chapter_end == 0)
936 int ret, partn, last_partn;
937 int interrupt = 0, nb_chapters = 0;
938 uint64_t cur_chapter_offset = 0, cur_chapter_duration = 0;
944 if (
c->opt_chapter_start ==
c->opt_chapter_end)
950 last_partn =
state.celln;
954 last_partn =
c->opt_chapter_start;
957 if (
state.pgc->nr_of_programs == 1)
961 "Indexing chapter markers, this will take a long time. Please wait...\n");
977 if (partn == last_partn) {
978 cur_chapter_duration +=
state.vobu_duration;
984 if (cur_chapter_duration > 0) {
986 cur_chapter_offset + cur_chapter_duration,
NULL)) {
994 cur_chapter_offset += cur_chapter_duration;
995 cur_chapter_duration =
state.vobu_duration;
1030 int is_pal = video_attr.video_format == 1;
1033 height = is_pal ? 576 : 480;
1036 switch (video_attr.picture_size) {
1055 "this could be an authoring error or empty title "
1056 "(video_format=%d picture_size=%d)\n",
1057 video_attr.video_format, video_attr.picture_size);
1062 entry->startcode = 0x1E0;
1089#if FF_API_R_FRAME_RATE
1111 video_attr_t video_attr;
1114 video_attr = !
c->opt_menu_vts ?
c->vmg_ifo->vmgi_mat->vmgm_video_attr :
1115 c->vts_ifo->vtsi_mat->vtsm_video_attr;
1117 video_attr =
c->vts_ifo->vtsi_mat->vts_video_attr;
1135 int sample_rate = 0;
1137 int nb_channels = 0;
1139 char lang_dvd[3] = {0};
1141 int position = (audio_control & 0x7F00) >> 8;
1144 switch (audio_attr.audio_format) {
1148 sample_rate = 48000;
1149 startcode = 0x80 + position;
1154 sample_rate = 48000;
1155 bit_depth = audio_attr.quantization ? 20 : 16;
1156 startcode = 0x1C0 + position;
1161 sample_rate = 48000;
1162 bit_depth = audio_attr.quantization ? 20 : 16;
1163 startcode = 0x1C0 + position;
1168 sample_rate = audio_attr.sample_frequency ? 96000 : 48000;
1169 bit_depth = audio_attr.quantization == 2 ? 24 : (audio_attr.quantization ? 20 : 16);
1170 startcode = 0xA0 + position;
1175 sample_rate = 48000;
1176 bit_depth = audio_attr.quantization == 2 ? 24 : (audio_attr.quantization ? 20 : 16);
1177 startcode = 0x88 + position;
1181 nb_channels = audio_attr.channels + 1;
1190 "this could be an authoring error or dummy title "
1191 "(stream position %d in IFO)\n", position);
1195 if (nb_channels == 1)
1197 else if (nb_channels == 2)
1199 else if (nb_channels == 6)
1201 else if (nb_channels == 7)
1203 else if (nb_channels == 8)
1207 if (audio_attr.application_mode == 1) {
1211 "(stream id=%d)\n", startcode);
1214 if (audio_attr.code_extension == 2)
1216 if (audio_attr.code_extension == 3 || audio_attr.code_extension == 4)
1219 AV_WB16(lang_dvd, audio_attr.lang_code);
1221 entry->startcode = startcode;
1223 entry->sample_rate = sample_rate;
1225 entry->nb_channels = nb_channels;
1226 entry->ch_layout = ch_layout;
1252 if (
entry->lang_iso)
1273 nb_streams = !
c->opt_menu_vts ?
c->vmg_ifo->vmgi_mat->nr_of_vmgm_audio_streams :
1274 c->vts_ifo->vtsi_mat->nr_of_vtsm_audio_streams;
1276 nb_streams =
c->vts_ifo->vtsi_mat->nr_of_vts_audio_streams;
1280 audio_attr_t audio_attr;
1283 audio_attr = !
c->opt_menu_vts ?
c->vmg_ifo->vmgi_mat->vmgm_audio_attr :
1284 c->vts_ifo->vtsi_mat->vtsm_audio_attr;
1286 audio_attr =
c->vts_ifo->vtsi_mat->vts_audio_attr[
i];
1288 if (!(
c->play_state.pgc->audio_control[
i] & 0x8000))
1296 for (
int j = 0; j <
s->nb_streams; j++)
1297 if (
s->streams[j]->id ==
entry.startcode)
1319 char lang_dvd[3] = {0};
1323 if (subp_attr.lang_extension == 9)
1334 AV_WB16(lang_dvd, subp_attr.lang_code);
1357 if (
entry->lang_iso)
1375 subp_attr_t subp_attr,
1381 entry.viewport = viewport;
1387 for (
int i = 0;
i <
s->nb_streams;
i++)
1388 if (
s->streams[
i]->id ==
entry.startcode)
1408 nb_streams = !
c->opt_menu_vts ?
c->vmg_ifo->vmgi_mat->nr_of_vmgm_subp_streams :
1409 c->vts_ifo->vtsi_mat->nr_of_vtsm_subp_streams;
1411 nb_streams =
c->vts_ifo->vtsi_mat->nr_of_vts_subp_streams;
1416 uint32_t subp_control;
1417 subp_attr_t subp_attr;
1418 video_attr_t video_attr;
1420 subp_control =
c->play_state.pgc->subp_control[
i];
1421 if (!(subp_control & 0x80000000))
1427 video_attr = !
c->opt_menu_vts ?
c->vmg_ifo->vmgi_mat->vmgm_video_attr :
1428 c->vts_ifo->vtsi_mat->vtsm_video_attr;
1430 subp_attr = !
c->opt_menu_vts ?
c->vmg_ifo->vmgi_mat->vmgm_subp_attr :
1431 c->vts_ifo->vtsi_mat->vtsm_subp_attr;
1433 video_attr =
c->vts_ifo->vtsi_mat->vts_video_attr;
1434 subp_attr =
c->vts_ifo->vtsi_mat->vts_subp_attr[
i];
1438 if (!video_attr.display_aspect_ratio) {
1452 if (video_attr.permitted_df == 2 || video_attr.permitted_df == 0)
1458 if (video_attr.permitted_df == 1 || video_attr.permitted_df == 0)
1483 if (is_nav_packet) {
1484 if (
c->play_state.ptm_discont) {
1485 c->subdemux_reset = 1;
1497 c->mpeg_pb.pub.eof_reached = 1;
1498 c->mpeg_pb.pub.error = ret;
1499 c->mpeg_pb.pub.read_packet =
NULL;
1500 c->mpeg_pb.pub.buf_end =
c->mpeg_pb.pub.buf_ptr =
c->mpeg_pb.pub.buffer;
1524 c->mpeg_pb.pub.seekable = 0;
1538 c->mpeg_ctx->probesize = 0;
1539 c->mpeg_ctx->max_analyze_duration = 0;
1540 c->mpeg_ctx->interrupt_callback =
s->interrupt_callback;
1541 c->mpeg_ctx->pb = &
c->mpeg_pb.pub;
1542 c->mpeg_ctx->io_open =
NULL;
1567 if (
c->opt_region ||
1569 c->opt_chapter_start > 1 ||
1570 c->opt_chapter_end > 0) {
1572 "or -chapter_start/-chapter_end options\n");
1593 if (
c->opt_pgc && (
c->opt_chapter_start > 1 ||
c->opt_chapter_end > 0 ||
c->opt_preindex)) {
1594 av_log(
s,
AV_LOG_ERROR,
"PGC extraction not compatible with chapter or preindex options\n");
1599 if (!
c->opt_pgc && (
c->opt_chapter_end != 0 &&
c->opt_chapter_start >
c->opt_chapter_end)) {
1601 c->opt_chapter_start,
c->opt_chapter_end);
1606 if (
c->opt_title == 0) {
1608 "This is not always the main feature, validation suggested.\n");
1632 for (
int i = 0;
i <
s->nb_streams;
i++)
1646 uint8_t ac3_bitstream_id;
1647 uint16_t ac3_frame_size;
1652 c->subdemux_reset = 0;
1653 c->pts_offset =
c->play_state.ptm_offset;
1664 st_subdemux =
c->mpeg_ctx->streams[
pkt->stream_index];
1668 for (
int i = 0;
i <
s->nb_streams;
i++) {
1669 if (
s->streams[
i]->id == st_subdemux->
id) {
1670 pkt->stream_index =
s->streams[
i]->index;
1680 if (!
c->play_started) {
1685 c->first_pts =
pkt->pts;
1686 c->play_started = 1;
1689 pkt->pts +=
c->pts_offset -
c->first_pts;
1690 pkt->dts +=
c->pts_offset -
c->first_pts;
1699 if (
pkt->pts <=
c->prev_pts[
pkt->stream_index])
1703 &ac3_bitstream_id, &ac3_frame_size);
1705 if (ret < 0 || pkt->
size != ac3_frame_size)
1710 "pts_offset=%" PRId64
" first_pts=%" PRId64
"\n",
1712 c->pts_offset,
c->first_pts);
1714 c->prev_pts[
pkt->stream_index] =
pkt->pts;
1720 "Discarding frame @ st=%d pts=%" PRId64
" dts=%" PRId64
" is_key=%d st_mapped=%d\n",
1721 st_mapped ?
pkt->stream_index : -1,
pkt->pts,
pkt->dts, is_key, st_mapped);
1724 c->prev_pts[
pkt->stream_index] =
pkt->pts;
1755 int seek_failed = 0;
1757 if (
c->opt_menu ||
c->opt_chapter_start > 1) {
1766 if (timestamp < 0 || timestamp >
s->duration)
1769 if (!
c->seek_warned) {
1771 "in imprecise timecodes from this point\n");
1776 if (
c->nb_angles > 1) {
1777 if (dvdnav_angle_change(
c->play_state.dvdnav, 1) != DVDNAV_STATUS_OK) {
1786 if (dvdnav_time_search(
c->play_state.dvdnav, timestamp) != DVDNAV_STATUS_OK) {
1790 if (
c->nb_angles > 1) {
1791 if (dvdnav_angle_change(
c->play_state.dvdnav,
c->opt_angle) != DVDNAV_STATUS_OK) {
1804 new_nav_pts = dvdnav_get_current_time (
c->play_state.dvdnav);
1805 new_nav_pci = dvdnav_get_current_nav_pci(
c->play_state.dvdnav);
1806 new_nav_dsi = dvdnav_get_current_nav_dsi(
c->play_state.dvdnav);
1808 if (new_nav_pci ==
NULL || new_nav_dsi ==
NULL) {
1814 c->play_state.in_pgc = 1;
1815 c->play_state.in_ps = 0;
1816 c->play_state.is_seeking = 1;
1817 c->play_state.nav_pts = timestamp;
1818 c->play_state.ptm_offset = timestamp;
1819 c->play_state.ptm_discont = 0;
1820 c->play_state.vobu_e_ptm = new_nav_pci->pci_gi.vobu_s_ptm;
1823 c->play_state.nb_vobu_skip =
c->nb_angles > 1 ? 3 : 0;
1826 c->play_started = 0;
1827 c->pts_offset = timestamp;
1828 c->subdemux_reset = 0;
1833 av_log(
s,
AV_LOG_DEBUG,
"seeking: requested_nav_pts=%" PRId64
" new_nav_pts=%" PRId64
"\n",
1834 timestamp, new_nav_pts);
1839#define OFFSET(x) offsetof(DVDVideoDemuxContext, x)
1857 .class_name =
"DVD-Video demuxer",
1864 .p.name =
"dvdvideo",
int av_ac3_parse_header(const uint8_t *buf, size_t size, uint8_t *bitstream_id, uint16_t *frame_size)
Extract the bitstream ID and the frame size from AC-3 data.
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
void ffio_init_context(FFIOContext *s, unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, const uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
const char * ff_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace)
Convert a language code to a target codespace.
Convenience header that includes libavutil's core.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
#define FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_LEN
static int dvdvideo_subp_stream_add(AVFormatContext *s, DVDVideoPGCSubtitleStreamEntry *entry)
#define DVDVIDEO_TIME_BASE_Q
#define DVDVIDEO_PTS_WRAP_BITS
static int dvdvideo_audio_stream_analyze(AVFormatContext *s, audio_attr_t audio_attr, uint16_t audio_control, DVDVideoPGCAudioStreamEntry *entry)
static const AVClass dvdvideo_class
static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr, DVDVideoPGCSubtitleStreamEntry *entry)
static int dvdvideo_read_header(AVFormatContext *s)
static int dvdvideo_play_open(AVFormatContext *s, DVDVideoPlaybackState *state)
static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level, const char *msg, va_list msg_va)
static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state, uint8_t *buf, int buf_size, int *p_is_nav_packet)
static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
static int dvdvideo_video_stream_add(AVFormatContext *s, DVDVideoVTSVideoStreamEntry *entry)
static int dvdvideo_is_cell_promising(AVFormatContext *s, pgc_t *pgc, int celln)
static void dvdvideo_libdvdnav_log(void *opaque, dvdnav_logger_level_t level, const char *msg, va_list msg_va)
static int dvdvideo_close(AVFormatContext *s)
static int dvdvideo_video_stream_analyze(AVFormatContext *s, video_attr_t video_attr, DVDVideoVTSVideoStreamEntry *entry)
#define DVDVIDEO_BLOCK_SIZE
static const AVOption dvdvideo_options[]
static int dvdvideo_subdemux_reset(AVFormatContext *s)
static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
static int dvdvideo_subp_stream_add_internal(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr, enum DVDVideoSubpictureViewport viewport)
static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state)
#define DVDVIDEO_MAX_PS_SEARCH_BLOCKS
#define DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE
static int dvdvideo_chapters_setup_simple(AVFormatContext *s)
static int dvdvideo_audio_stream_add(AVFormatContext *s, DVDVideoPGCAudioStreamEntry *entry)
static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state, uint8_t *buf, int buf_size, int *p_is_nav_packet)
static void dvdvideo_play_close(AVFormatContext *s, DVDVideoPlaybackState *state)
static int dvdvideo_chapters_setup_preindex(AVFormatContext *s)
static void dvdvideo_ifo_close(AVFormatContext *s)
static const uint8_t dvdvideo_nav_header[4]
static int dvdvideo_subp_stream_add_all(AVFormatContext *s)
static int dvdvideo_audio_stream_add_all(AVFormatContext *s)
static int dvdvideo_subdemux_open(AVFormatContext *s)
static int dvdvideo_video_stream_setup(AVFormatContext *s)
static void dvdvideo_subdemux_close(AVFormatContext *s)
static int dvdvideo_is_pgc_promising(AVFormatContext *s, pgc_t *pgc)
static int dvdvideo_ifo_open(AVFormatContext *s)
DVDVideoSubpictureViewport
@ DVDVIDEO_SUBP_VIEWPORT_FULLSCREEN
@ DVDVIDEO_SUBP_VIEWPORT_PANSCAN
@ DVDVIDEO_SUBP_VIEWPORT_LETTERBOX
@ DVDVIDEO_SUBP_VIEWPORT_WIDESCREEN
static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size)
static void dvdvideo_menu_close(AVFormatContext *s, DVDVideoPlaybackState *state)
static const char dvdvideo_subp_viewport_labels[4][13]
static struct @346255127015250356166251341105367306144006377143 state
static unsigned int nb_streams
static int read_header(FFV1Context *f, RangeCoder *c)
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
AVCodecID
Identify the syntax and semantics of the bitstream.
@ AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
#define AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_5POINT1
#define AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_6POINT1
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_INPUT_CHANGED
Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
#define AVERROR_EOF
End of file.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_S32
signed 32 bits
@ AV_SAMPLE_FMT_S16
signed 16 bits
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
#define AV_NOPTS_VALUE
Undefined timestamp value.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define LIBAVUTIL_VERSION_INT
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static av_cold int read_close(AVFormatContext *ctx)
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Memory handling functions.
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
An AVChannelLayout holds information about the channel layout of audio data.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
int height
The height of the video frame in pixels.
int bits_per_coded_sample
The number of bits per sample in the codedwords.
AVChannelLayout ch_layout
The channel layout and number of channels.
int width
The width of the video frame in pixels.
enum AVMediaType codec_type
General type of the encoded data.
int bits_per_raw_sample
The number of valid bits in each output sample.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int sample_rate
The number of audio samples per second.
enum AVColorRange color_range
Additional colorspace characteristics.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int id
Format-specific stream ID.
AVRational avg_frame_rate
Average framerate.
AVRational r_frame_rate
Real base framerate of the stream.
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
DVDVideoPlaybackState play_state
AVFormatContext * mpeg_ctx
AVChannelLayout ch_layout
uint32_t clut[FF_DVDCLUT_CLUT_LEN]
enum DVDVideoSubpictureViewport viewport
uint64_t pgc_duration_est
uint64_t * pgc_pg_times_est
int request_probe
stream probing state -1 -> probing finished 0 -> no probing requested rest -> perform probing with re...
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
enum AVStreamParseType need_parsing
unbuffered private I/O API