FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
dvdvideodec.c
Go to the documentation of this file.
1 /*
2  * DVD-Video demuxer, powered by libdvdnav and libdvdread
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * See doc/demuxers.texi for a high-level overview.
23  *
24  * The tactical approach is as follows:
25  * 1) Open the volume with dvdread
26  * 2) Analyze the user-requested title and PGC coordinates in the IFO structures
27  * 3) Request playback at the coordinates and chosen angle with dvdnav
28  * 5) Begin the playback (reading and demuxing) of MPEG-PS blocks
29  * 6) End playback if navigation goes backwards, to a menu, or a different PGC or angle
30  * 7) Close the dvdnav VM, and free dvdread's IFO structures
31  */
32 
33 #include <inttypes.h>
34 
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>
40 
41 #include "libavcodec/ac3_parser.h"
42 #include "libavutil/avstring.h"
43 #include "libavutil/avutil.h"
44 #include "libavutil/intreadwrite.h"
45 #include "libavutil/mem.h"
46 #include "libavutil/opt.h"
47 #include "libavutil/samplefmt.h"
48 
49 #include "avformat.h"
50 #include "avio_internal.h"
51 #include "avlanguage.h"
52 #include "demux.h"
53 #include "dvdclut.h"
54 #include "internal.h"
55 #include "url.h"
56 
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 /* VOBUs use 32 (PES allows 33) */
61 #define DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE 1024
62 
63 #define PCI_START_BYTE 45 /* complement dvdread's DSI_START_BYTE */
64 static const uint8_t dvdvideo_nav_header[4] = { 0x00, 0x00, 0x01, 0xBF };
65 
71 };
72 static const char dvdvideo_subp_viewport_labels[4][13] = {
73  "Fullscreen", "Widescreen", "Letterbox", "Pan and Scan"
74 };
75 
77  int startcode;
79  int width;
80  int height;
84 
86  int startcode;
90  int bit_depth;
94  const char *lang_iso;
96 
98  int startcode;
102  const char *lang_iso;
104 
105 typedef struct DVDVideoPlaybackState {
106  int celln; /* ID of the active cell */
107  int entry_pgn; /* ID of the PG we are starting in */
108  int in_pgc; /* if our navigator is in the PGC */
109  int in_ps; /* if our navigator is in the program stream */
110  int in_vts; /* if our navigator is in the VTS */
111  int is_seeking; /* relax navigation path while seeking */
112  int64_t nav_pts; /* PTS according to IFO, not frame-accurate */
113  int nb_vobu_skip; /* number of VOBUs we should skip */
114  uint64_t pgc_duration_est; /* estimated duration as reported by IFO */
115  uint64_t pgc_elapsed; /* the elapsed time of the PGC, cell-relative */
116  int pgc_nb_pg_est; /* number of PGs as reported by IFOs */
117  int pgcn; /* ID of the PGC we are playing */
118  int pgn; /* ID of the PG we are in now */
119  int ptm_discont; /* signal that a PTM discontinuity occurred */
120  int64_t ptm_offset; /* PTM discontinuity offset (as NAV value) */
121  int ptt; /* ID of the chapter we are in now */
122  uint32_t vobu_duration; /* duration of the current VOBU */
123  uint32_t vobu_e_ptm; /* end PTM of the current VOBU */
124  int vtsn; /* ID of the active VTS (video title set) */
125  uint64_t *pgc_pg_times_est; /* PG start times as reported by IFO */
126  pgc_t *pgc; /* handle to the active PGC */
127  dvdnav_t *dvdnav; /* handle to the dvdnav VM */
128 
129  /* the following fields are only used for menu playback */
130  int celln_start; /* starting cell number */
131  int celln_end; /* ending cell number */
132  int sector_offset; /* current sector relative to the current VOB */
133  uint32_t sector_end; /* end sector relative to the current VOBU */
134  uint32_t vobu_next; /* the next VOBU pointer */
135  uint32_t vobu_remaining; /* remaining blocks for current VOBU */
136  dvd_file_t *vob_file; /* handle to the menu VOB (VMG or VTS) */
138 
139 typedef struct DVDVideoDemuxContext {
140  const AVClass *class;
141 
142  /* options */
143  int opt_angle; /* the user-provided angle number (1-indexed) */
144  int opt_chapter_end; /* the user-provided exit PTT (0 for last) */
145  int opt_chapter_start; /* the user-provided entry PTT (1-indexed) */
146  int opt_menu; /* demux menu domain instead of title domain */
147  int opt_menu_lu; /* the menu language unit (logical grouping) */
148  int opt_menu_vts; /* the menu VTS, or 0 for VMG (main menu) */
149  int opt_pg; /* the user-provided PG number (1-indexed) */
150  int opt_pgc; /* the user-provided PGC number (1-indexed) */
151  int opt_preindex; /* pre-indexing mode (2-pass read) */
152  int opt_region; /* the user-provided region digit */
153  int opt_title; /* the user-provided title number (1-indexed) */
154  int opt_trim; /* trim padding cells at beginning */
155 
156  /* subdemux */
157  AVFormatContext *mpeg_ctx; /* context for inner demuxer */
158  uint8_t *mpeg_buf; /* buffer for inner demuxer */
159  FFIOContext mpeg_pb; /* buffer context for inner demuxer */
160 
161  /* volume */
162  dvd_reader_t *dvdread; /* handle to libdvdread */
163  ifo_handle_t *vmg_ifo; /* handle to the VMG (VIDEO_TS.IFO) */
164  ifo_handle_t *vts_ifo; /* handle to the active VTS (VTS_nn_n.IFO) */
165 
166  /* playback control */
167  int64_t first_pts; /* the PTS of the first video keyframe */
168  int nb_angles; /* number of angles in the current title */
169  int play_started; /* signal that playback has started */
170  DVDVideoPlaybackState play_state; /* the active playback state */
171  int64_t *prev_pts; /* track the previous PTS emitted per stream */
172  int64_t pts_offset; /* PTS discontinuity offset (ex. VOB change) */
173  int seek_warned; /* signal that we warned about seeking limits */
174  int subdemux_reset; /* signal that subdemuxer should be reset */
176 
177 static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level,
178  const char *msg, va_list msg_va)
179 {
180  AVFormatContext *s = opaque;
181  char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE];
182  int lavu_level = AV_LOG_DEBUG;
183 
184  vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va);
185 
186  if (level == DVD_LOGGER_LEVEL_ERROR)
187  lavu_level = AV_LOG_ERROR;
188  else if (level == DVD_LOGGER_LEVEL_WARN)
189  lavu_level = AV_LOG_WARNING;
190 
191  av_log(s, lavu_level, "libdvdread: %s\n", msg_buf);
192 }
193 
194 static void dvdvideo_libdvdnav_log(void *opaque, dvdnav_logger_level_t level,
195  const char *msg, va_list msg_va)
196 {
197  AVFormatContext *s = opaque;
198  char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE];
199  int lavu_level = AV_LOG_DEBUG;
200 
201  vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va);
202 
203  if (level == DVDNAV_LOGGER_LEVEL_ERROR)
204  lavu_level = AV_LOG_ERROR;
205  /* some discs have invalid language codes set for menus, which throws noisy warnings */
206  else if (level == DVDNAV_LOGGER_LEVEL_WARN && !av_strstart(msg, "Language", NULL))
207  lavu_level = AV_LOG_WARNING;
208 
209  av_log(s, lavu_level, "libdvdnav: %s\n", msg_buf);
210 }
211 
213 {
214  DVDVideoDemuxContext *c = s->priv_data;
215 
216  if (c->vts_ifo)
217  ifoClose(c->vts_ifo);
218 
219  if (c->vmg_ifo)
220  ifoClose(c->vmg_ifo);
221 
222  if (c->dvdread)
223  DVDClose(c->dvdread);
224 }
225 
227 {
228  DVDVideoDemuxContext *c = s->priv_data;
229 
230  dvd_logger_cb dvdread_log_cb;
231  title_info_t title_info;
232 
233  dvdread_log_cb = (dvd_logger_cb) { .pf_log = dvdvideo_libdvdread_log };
234  c->dvdread = DVDOpen2(s, &dvdread_log_cb, s->url);
235 
236  if (!c->dvdread) {
237  av_log(s, AV_LOG_ERROR, "Unable to open the DVD-Video structure\n");
238 
239  return AVERROR_EXTERNAL;
240  }
241 
242  if (!(c->vmg_ifo = ifoOpen(c->dvdread, 0))) {
243  av_log(s, AV_LOG_ERROR, "Unable to open the VMG (VIDEO_TS.IFO)\n");
244 
245  return AVERROR_EXTERNAL;
246  }
247 
248  if (c->opt_menu) {
249  if (c->opt_menu_vts > 0 && !(c->vts_ifo = ifoOpen(c->dvdread, c->opt_menu_vts))) {
250  av_log(s, AV_LOG_ERROR, "Unable to open IFO structure for VTS %d\n", c->opt_menu_vts);
251 
252  return AVERROR_EXTERNAL;
253  }
254 
255  return 0;
256  }
257 
258  if (c->opt_title > c->vmg_ifo->tt_srpt->nr_of_srpts) {
259  av_log(s, AV_LOG_ERROR, "Title %d not found\n", c->opt_title);
260 
262  }
263 
264  title_info = c->vmg_ifo->tt_srpt->title[c->opt_title - 1];
265  if (c->opt_angle > title_info.nr_of_angles) {
266  av_log(s, AV_LOG_ERROR, "Angle %d not found\n", c->opt_angle);
267 
269  }
270 
271  if (title_info.nr_of_ptts < 1) {
272  av_log(s, AV_LOG_ERROR, "Title %d has invalid headers (no PTTs found)\n", c->opt_title);
273 
274  return AVERROR_INVALIDDATA;
275  }
276 
277  if (c->opt_chapter_start > title_info.nr_of_ptts ||
278  (c->opt_chapter_end > 0 && c->opt_chapter_end > title_info.nr_of_ptts)) {
279  av_log(s, AV_LOG_ERROR, "Chapter (PTT) range [%d, %d] is invalid\n",
280  c->opt_chapter_start, c->opt_chapter_end);
281 
282  return AVERROR_INVALIDDATA;
283  }
284 
285  if (!(c->vts_ifo = ifoOpen(c->dvdread, title_info.title_set_nr))) {
286  av_log(s, AV_LOG_ERROR, "Unable to process IFO structure for VTS %d\n",
287  title_info.title_set_nr);
288 
289  return AVERROR_EXTERNAL;
290  }
291 
292  if (title_info.vts_ttn < 1 ||
293  title_info.vts_ttn > 99 ||
294  title_info.vts_ttn > c->vts_ifo->vts_ptt_srpt->nr_of_srpts ||
295  c->vts_ifo->vtsi_mat->nr_of_vts_audio_streams > 8 ||
296  c->vts_ifo->vtsi_mat->nr_of_vts_subp_streams > 32) {
297 
298  av_log(s, AV_LOG_ERROR, "Title %d has invalid headers in VTS\n", c->opt_title);
299  return AVERROR_INVALIDDATA;
300  }
301 
302  c->nb_angles = title_info.nr_of_angles;
303 
304  return 0;
305 }
306 
307 static int dvdvideo_is_cell_promising(AVFormatContext *s, pgc_t *pgc, int celln)
308 {
309  dvd_time_t cell_duration = pgc->cell_playback[celln - 1].playback_time;
310 
311  return cell_duration.second >= 1 || cell_duration.minute >= 1 || cell_duration.hour >= 1;
312 }
313 
315 {
316  for (int i = 1; i <= pgc->nr_of_cells; i++)
317  if (dvdvideo_is_cell_promising(s, pgc, i))
318  return 1;
319 
320  return 0;
321 }
322 
324 {
325  if (state->vob_file)
326  DVDCloseFile(state->vob_file);
327 }
328 
330 {
331  DVDVideoDemuxContext *c = s->priv_data;
332  pgci_ut_t *pgci_ut;
333 
334  pgci_ut = c->opt_menu_vts ? c->vts_ifo->pgci_ut : c->vmg_ifo->pgci_ut;
335  if (!pgci_ut) {
336  av_log(s, AV_LOG_ERROR, "Invalid PGC table for menu [LU %d, PGC %d]\n",
337  c->opt_menu_lu, c->opt_pgc);
338 
339  return AVERROR_INVALIDDATA;
340  }
341 
342  if (c->opt_pgc < 1 ||
343  c->opt_menu_lu < 1 ||
344  c->opt_menu_lu > pgci_ut->nr_of_lus ||
345  c->opt_pgc > pgci_ut->lu[c->opt_menu_lu - 1].pgcit->nr_of_pgci_srp) {
346 
347  av_log(s, AV_LOG_ERROR, "Menu [LU %d, PGC %d] not found\n", c->opt_menu_lu, c->opt_pgc);
348 
349  return AVERROR(EINVAL);
350  }
351 
352  /* make sure the PGC is valid */
353  state->pgcn = c->opt_pgc;
354  state->pgc = pgci_ut->lu[c->opt_menu_lu - 1].pgcit->pgci_srp[c->opt_pgc - 1].pgc;
355  if (!state->pgc || !state->pgc->program_map || !state->pgc->cell_playback) {
356  av_log(s, AV_LOG_ERROR, "Invalid PGC structure for menu [LU %d, PGC %d]\n",
357  c->opt_menu_lu, c->opt_pgc);
358 
359  return AVERROR_INVALIDDATA;
360  }
361 
362  /* make sure the PG is valid */
363  state->entry_pgn = c->opt_pg;
364  if (state->entry_pgn < 1 || state->entry_pgn > state->pgc->nr_of_programs) {
365  av_log(s, AV_LOG_ERROR, "Entry PG %d not found\n", state->entry_pgn);
366 
367  return AVERROR(EINVAL);
368  }
369 
370  /* make sure the program map isn't leading us to nowhere */
371  state->celln_start = state->pgc->program_map[state->entry_pgn - 1];
372  state->celln_end = state->pgc->nr_of_cells;
373  state->celln = state->celln_start;
374  if (state->celln_start > state->pgc->nr_of_cells) {
375  av_log(s, AV_LOG_ERROR, "Invalid PGC structure: program map points to unknown cell\n");
376 
377  return AVERROR_INVALIDDATA;
378  }
379 
380  state->sector_end = state->pgc->cell_playback[state->celln - 1].last_sector;
381  state->vobu_next = state->pgc->cell_playback[state->celln - 1].first_sector;
382  state->sector_offset = state->vobu_next;
383 
384  if (c->opt_menu_vts > 0)
385  state->in_vts = 1;
386 
387  if (!(state->vob_file = DVDOpenFile(c->dvdread, c->opt_menu_vts, DVD_READ_MENU_VOBS))) {
388  av_log(s, AV_LOG_ERROR, !c->opt_menu_vts ?
389  "Unable to open main menu VOB (VIDEO_TS.VOB)\n" :
390  "Unable to open menu VOBs for VTS %d\n", c->opt_menu_vts);
391 
392  return AVERROR_EXTERNAL;
393  }
394 
395  return 0;
396 }
397 
399  uint8_t *buf, int buf_size, int *p_is_nav_packet)
400 {
401  int64_t blocks_read = 0;
402  uint8_t read_buf[DVDVIDEO_BLOCK_SIZE] = {0};
403  pci_t pci = (pci_t) {0};
404  dsi_t dsi = (dsi_t) {0};
405 
406  (*p_is_nav_packet) = 0;
407  state->ptm_discont = 0;
408 
409  if (buf_size != DVDVIDEO_BLOCK_SIZE) {
410  av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
411  DVDVIDEO_BLOCK_SIZE, buf_size);
412 
413  return AVERROR(EINVAL);
414  }
415 
416  /* we were at the end of a vobu, so now go to the next one or EOF */
417  if (!state->vobu_remaining && state->in_pgc) {
418  if (state->vobu_next == SRI_END_OF_CELL) {
419  if (state->celln == state->celln_end && state->sector_offset > state->sector_end)
420  return AVERROR_EOF;
421 
422  state->celln++;
423  state->sector_offset = state->pgc->cell_playback[state->celln - 1].first_sector;
424  state->sector_end = state->pgc->cell_playback[state->celln - 1].last_sector;
425  } else {
426  state->sector_offset = state->vobu_next;
427  }
428  }
429 
430  /* continue reading the VOBU */
431  av_log(s, AV_LOG_TRACE, "reading block at offset %d\n", state->sector_offset);
432 
433  blocks_read = DVDReadBlocks(state->vob_file, state->sector_offset, 1, read_buf);
434  if (blocks_read != 1) {
435  av_log(s, AV_LOG_ERROR, "Unable to read VOB block: offset=%d blocks_read=%" PRId64 "\n",
436  state->sector_offset, blocks_read);
437 
438  return AVERROR_INVALIDDATA;
439  }
440 
441  /* we are at the start of a VOBU, so we are expecting a NAV packet */
442  if (!state->vobu_remaining) {
443  if (!memcmp(&read_buf[PCI_START_BYTE - 4], dvdvideo_nav_header, 4) ||
444  !memcmp(&read_buf[DSI_START_BYTE - 4], dvdvideo_nav_header, 4) ||
445  read_buf[PCI_START_BYTE - 1] != 0x00 ||
446  read_buf[DSI_START_BYTE - 1] != 0x01) {
447 
448  av_log(s, AV_LOG_ERROR, "Invalid NAV packet at offset %d: PCI or DSI header mismatch\n",
449  state->sector_offset);
450 
451  return AVERROR_INVALIDDATA;
452  }
453 
454  navRead_PCI(&pci, &read_buf[PCI_START_BYTE]);
455  navRead_DSI(&dsi, &read_buf[DSI_START_BYTE]);
456 
457  if (!pci.pci_gi.vobu_s_ptm ||
458  !pci.pci_gi.vobu_e_ptm ||
459  pci.pci_gi.vobu_s_ptm > pci.pci_gi.vobu_e_ptm) {
460 
461  av_log(s, AV_LOG_ERROR, "Invalid NAV packet at offset %d: PCI header is invalid\n",
462  state->sector_offset);
463 
464  return AVERROR_INVALIDDATA;
465  }
466 
467  state->vobu_remaining = dsi.dsi_gi.vobu_ea;
468  state->vobu_next = dsi.vobu_sri.next_vobu == SRI_END_OF_CELL ? SRI_END_OF_CELL :
469  dsi.dsi_gi.nv_pck_lbn + (dsi.vobu_sri.next_vobu & 0x7FFFFFFF);
470  state->sector_offset++;
471 
472  if (state->in_pgc) {
473  if (state->vobu_e_ptm != pci.pci_gi.vobu_s_ptm) {
474  state->ptm_discont = 1;
475  state->ptm_offset += state->vobu_e_ptm - pci.pci_gi.vobu_s_ptm;
476  }
477  } else {
478  state->in_pgc = 1;
479  state->in_ps = 1;
480  }
481 
482  state->vobu_e_ptm = pci.pci_gi.vobu_e_ptm;
483  state->vobu_duration = pci.pci_gi.vobu_e_ptm - pci.pci_gi.vobu_s_ptm;
484 
485  av_log(s, AV_LOG_DEBUG, "NAV packet: sector=%d "
486  "vobu_s_ptm=%d vobu_e_ptm=%d ptm_offset=%" PRId64 "\n",
487  dsi.dsi_gi.nv_pck_lbn,
488  pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm, state->ptm_offset);
489 
490 
491  (*p_is_nav_packet) = 1;
492 
493  return 0;
494  }
495 
496  /* we are in the middle of a VOBU, so pass on the PS packet */
497  memcpy(buf, &read_buf, DVDVIDEO_BLOCK_SIZE);
498  state->sector_offset++;
499  state->vobu_remaining--;
500 
501  return DVDVIDEO_BLOCK_SIZE;
502 }
503 
505 {
506  if (!state->dvdnav)
507  return;
508 
509  /* not allocated by av_malloc() */
510  if (state->pgc_pg_times_est)
511  free(state->pgc_pg_times_est);
512 
513  if (dvdnav_close(state->dvdnav) != DVDNAV_STATUS_OK)
514  av_log(s, AV_LOG_ERROR, "Unable to close dvdnav successfully, dvdnav error: %s\n",
515  dvdnav_err_to_string(state->dvdnav));
516 }
517 
519 {
520  DVDVideoDemuxContext *c = s->priv_data;
521 
522  dvdnav_logger_cb dvdnav_log_cb;
523  dvdnav_status_t dvdnav_open_status;
524  int32_t disc_region_mask;
525  int32_t player_region_mask;
526  int cur_title, cur_pgcn, cur_pgn;
527  pgc_t *pgc;
528 
529  dvdnav_log_cb = (dvdnav_logger_cb) { .pf_log = dvdvideo_libdvdnav_log };
530  dvdnav_open_status = dvdnav_open2(&state->dvdnav, s, &dvdnav_log_cb, s->url);
531 
532  if (!state->dvdnav ||
533  dvdnav_open_status != DVDNAV_STATUS_OK ||
534  dvdnav_set_readahead_flag(state->dvdnav, 0) != DVDNAV_STATUS_OK ||
535  dvdnav_set_PGC_positioning_flag(state->dvdnav, 1) != DVDNAV_STATUS_OK ||
536  dvdnav_get_region_mask(state->dvdnav, &disc_region_mask) != DVDNAV_STATUS_OK) {
537 
538  av_log(s, AV_LOG_ERROR, "Unable to open the DVD for playback\n");
539  goto end_dvdnav_error;
540  }
541 
542  player_region_mask = c->opt_region > 0 ? (1 << (c->opt_region - 1)) : disc_region_mask;
543  if (dvdnav_set_region_mask(state->dvdnav, player_region_mask) != DVDNAV_STATUS_OK) {
544  av_log(s, AV_LOG_ERROR, "Unable to set the playback region code %d\n", c->opt_region);
545 
546  goto end_dvdnav_error;
547  }
548 
549  if (c->opt_pgc > 0) {
550  if (dvdnav_program_play(state->dvdnav, c->opt_title, c->opt_pgc, c->opt_pg) != DVDNAV_STATUS_OK) {
551  av_log(s, AV_LOG_ERROR, "Unable to start playback at title %d, PGC %d, PG %d\n",
552  c->opt_title, c->opt_pgc, c->opt_pg);
553 
554  goto end_dvdnav_error;
555  }
556 
557  state->pgcn = c->opt_pgc;
558  state->entry_pgn = c->opt_pg;
559  } else {
560  if (dvdnav_part_play(state->dvdnav, c->opt_title, c->opt_chapter_start) != DVDNAV_STATUS_OK ||
561  dvdnav_current_title_program(state->dvdnav, &cur_title, &cur_pgcn, &cur_pgn) != DVDNAV_STATUS_OK) {
562 
563  av_log(s, AV_LOG_ERROR, "Unable to start playback at title %d, chapter (PTT) %d\n",
564  c->opt_title, c->opt_chapter_start);
565  goto end_dvdnav_error;
566  }
567 
568  state->pgcn = cur_pgcn;
569  state->entry_pgn = cur_pgn;
570  }
571 
572  pgc = c->vts_ifo->vts_pgcit->pgci_srp[state->pgcn - 1].pgc;
573 
574  if (pgc->pg_playback_mode != 0) {
575  av_log(s, AV_LOG_ERROR, "Non-sequential PGCs, such as shuffles, are not supported\n");
576 
577  return AVERROR_PATCHWELCOME;
578  }
579 
580  if (c->opt_trim && !dvdvideo_is_pgc_promising(s, pgc)) {
581  av_log(s, AV_LOG_ERROR, "Title %d, PGC %d looks empty (may consist of padding cells), "
582  "if you want to try anyway, disable the -trim option\n",
583  c->opt_title, state->pgcn);
584 
585  return AVERROR_INVALIDDATA;
586  }
587 
588  if (dvdnav_angle_change(state->dvdnav, c->opt_angle) != DVDNAV_STATUS_OK) {
589  av_log(s, AV_LOG_ERROR, "Unable to start playback at angle %d\n", c->opt_angle);
590 
591  goto end_dvdnav_error;
592  }
593 
594  /* dvdnav_describe_title_chapters() performs several validations on the title structure */
595  /* take advantage of this side effect to increase chances of a safe navigation path */
596  state->pgc_nb_pg_est = dvdnav_describe_title_chapters(state->dvdnav, c->opt_title,
597  &state->pgc_pg_times_est,
598  &state->pgc_duration_est);
599 
600  /* dvdnav returning 0 PGs is documented as an error condition */
601  if (!state->pgc_nb_pg_est) {
602  av_log(s, AV_LOG_ERROR, "Unable to read chapter information for title %d\n", c->opt_title);
603 
604  goto end_dvdnav_error;
605  }
606 
607  state->nav_pts = dvdnav_get_current_time(state->dvdnav);
608  state->vtsn = c->vmg_ifo->tt_srpt->title[c->opt_title - 1].title_set_nr;
609  state->pgc = pgc;
610 
611  return 0;
612 
613 end_dvdnav_error:
614  if (state->dvdnav)
615  av_log(s, AV_LOG_ERROR, "dvdnav error: %s\n", dvdnav_err_to_string(state->dvdnav));
616  else
617  av_log(s, AV_LOG_ERROR, "dvdnav could not be initialized\n");
618 
619  return AVERROR_EXTERNAL;
620 }
621 
623  uint8_t *buf, int buf_size, int *p_is_nav_packet)
624 {
625  DVDVideoDemuxContext *c = s->priv_data;
626 
627  uint8_t nav_buf[DVDVIDEO_BLOCK_SIZE] = {0};
628  int nav_event;
629  int nav_len;
630 
631  dvdnav_vts_change_event_t *e_vts;
632  dvdnav_cell_change_event_t *e_cell;
633  int cur_title, cur_pgcn, cur_pgn, cur_angle, cur_title_unused, cur_ptt, cur_nb_angles;
634  pci_t *e_pci;
635  dsi_t *e_dsi;
636 
637  (*p_is_nav_packet) = 0;
638  state->ptm_discont = 0;
639 
640  if (buf_size != DVDVIDEO_BLOCK_SIZE) {
641  av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
642  DVDVIDEO_BLOCK_SIZE, buf_size);
643 
644  return AVERROR(EINVAL);
645  }
646 
647  for (int i = 0; i < DVDVIDEO_MAX_PS_SEARCH_BLOCKS; i++) {
648  if (ff_check_interrupt(&s->interrupt_callback))
649  return AVERROR_EXIT;
650 
651  if (dvdnav_get_next_block(state->dvdnav, nav_buf, &nav_event, &nav_len) != DVDNAV_STATUS_OK) {
652  av_log(s, AV_LOG_ERROR, "Unable to read next block of PGC\n");
653 
654  goto end_dvdnav_error;
655  }
656 
657  /* STOP event can come at any time and should be honored */
658  if (nav_event == DVDNAV_STOP)
659  return AVERROR_EOF;
660 
661  if (nav_len > DVDVIDEO_BLOCK_SIZE) {
662  av_log(s, AV_LOG_ERROR, "Invalid block size (expected<=%d actual=%d)\n",
663  DVDVIDEO_BLOCK_SIZE, nav_len);
664 
665  return AVERROR_INVALIDDATA;
666  }
667 
668  if (dvdnav_current_title_info(state->dvdnav, &cur_title, &cur_ptt) != DVDNAV_STATUS_OK) {
669  av_log(s, AV_LOG_ERROR, "Unable to determine current title coordinates\n");
670 
671  goto end_dvdnav_error;
672  }
673 
674  /* we somehow navigated to a menu */
675  if (cur_title == 0 || !dvdnav_is_domain_vts(state->dvdnav))
676  return AVERROR_EOF;
677 
678  if (dvdnav_current_title_program(state->dvdnav, &cur_title_unused, &cur_pgcn, &cur_pgn) != DVDNAV_STATUS_OK) {
679  av_log(s, AV_LOG_ERROR, "Unable to determine current PGC coordinates\n");
680 
681  goto end_dvdnav_error;
682  }
683 
684  /* we somehow left the PGC */
685  if (state->in_pgc && cur_pgcn != state->pgcn)
686  return AVERROR_EOF;
687 
688  if (dvdnav_get_angle_info(state->dvdnav, &cur_angle, &cur_nb_angles) != DVDNAV_STATUS_OK) {
689  av_log(s, AV_LOG_ERROR, "Unable to determine current video angle\n");
690 
691  goto end_dvdnav_error;
692  }
693 
694  av_log(s, nav_event == DVDNAV_BLOCK_OK ? AV_LOG_TRACE : AV_LOG_DEBUG,
695  "new block: i=%d nav_event=%d nav_len=%d cur_title=%d "
696  "cur_ptt=%d cur_angle=%d cur_celln=%d cur_pgcn=%d cur_pgn=%d "
697  "play_in_vts=%d play_in_pgc=%d play_in_ps=%d\n",
698  i, nav_event, nav_len, cur_title,
699  cur_ptt, cur_angle, state->celln, cur_pgcn, cur_pgn,
700  state->in_vts, state->in_pgc, state->in_ps);
701 
702  switch (nav_event) {
703  case DVDNAV_VTS_CHANGE:
704  if (state->in_vts)
705  return AVERROR_EOF;
706 
707  e_vts = (dvdnav_vts_change_event_t *) nav_buf;
708 
709  if (e_vts->new_vtsN == state->vtsn && e_vts->new_domain == DVD_DOMAIN_VTSTitle)
710  state->in_vts = 1;
711 
712  continue;
713  case DVDNAV_CELL_CHANGE:
714  if (!state->in_vts)
715  continue;
716 
717  e_cell = (dvdnav_cell_change_event_t *) nav_buf;
718 
719  av_log(s, AV_LOG_DEBUG, "new cell: prev=%d new=%d\n", state->celln, e_cell->cellN);
720 
721  if (!state->in_ps && !state->in_pgc) {
722  if (cur_title == c->opt_title &&
723  (c->opt_pgc || cur_ptt == c->opt_chapter_start) &&
724  cur_pgcn == state->pgcn &&
725  cur_pgn == state->entry_pgn) {
726 
727  state->in_pgc = 1;
728  }
729  } else if (!state->is_seeking &&
730  (state->celln >= e_cell->cellN || state->pgn > cur_pgn)) {
731  return AVERROR_EOF;
732  }
733 
734  state->celln = e_cell->cellN;
735  state->ptt = cur_ptt;
736  state->pgn = cur_pgn;
737 
738  continue;
739  case DVDNAV_NAV_PACKET:
740  if (!state->in_pgc)
741  continue;
742 
743  if ((!state->is_seeking && state->ptt > 0 && state->ptt > cur_ptt) ||
744  (c->opt_chapter_end > 0 && cur_ptt > c->opt_chapter_end)) {
745  return AVERROR_EOF;
746  }
747 
748  if (nav_len != DVDVIDEO_BLOCK_SIZE) {
749  av_log(s, AV_LOG_ERROR, "Invalid NAV packet size (expected=%d actual=%d)\n",
750  DVDVIDEO_BLOCK_SIZE, nav_len);
751 
752  return AVERROR_INVALIDDATA;
753  }
754 
755  e_pci = dvdnav_get_current_nav_pci(state->dvdnav);
756  e_dsi = dvdnav_get_current_nav_dsi(state->dvdnav);
757 
758  if (e_pci == NULL || e_dsi == NULL ||
759  e_pci->pci_gi.vobu_s_ptm > e_pci->pci_gi.vobu_e_ptm) {
760 
761  av_log(s, AV_LOG_ERROR, "Invalid NAV packet\n");
762  return AVERROR_INVALIDDATA;
763  }
764 
765  if (state->nb_vobu_skip > 0) {
766  av_log(s, AV_LOG_VERBOSE, "Skipping VOBU at SCR %d\n",
767  e_dsi->dsi_gi.nv_pck_scr);
768  state->nb_vobu_skip -= 1;
769  continue;
770  }
771 
772  state->vobu_duration = e_pci->pci_gi.vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
773  state->pgc_elapsed += state->vobu_duration;
774  state->nav_pts = dvdnav_get_current_time(state->dvdnav);
775  state->ptt = cur_ptt;
776  state->pgn = cur_pgn;
777 
779  "NAV packet: s_ptm=%d e_ptm=%d "
780  "scr=%d lbn=%d vobu_duration=%d nav_pts=%" PRId64 "\n",
781  e_pci->pci_gi.vobu_s_ptm, e_pci->pci_gi.vobu_e_ptm,
782  e_dsi->dsi_gi.nv_pck_scr,
783  e_pci->pci_gi.nv_pck_lbn, state->vobu_duration, state->nav_pts);
784 
785  if (!state->in_ps) {
786  if (c->opt_trim && !dvdvideo_is_cell_promising(s, state->pgc, state->celln)) {
787  av_log(s, AV_LOG_INFO, "Skipping padding cell #%d\n", state->celln);
788 
789  i = 0;
790  continue;
791  }
792 
793  av_log(s, AV_LOG_DEBUG, "navigation: locked to program stream\n");
794 
795  state->in_ps = 1;
796  } else {
797  if (state->vobu_e_ptm != e_pci->pci_gi.vobu_s_ptm) {
798  state->ptm_discont = 1;
799  state->ptm_offset += state->vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
800  }
801  }
802 
803  state->vobu_e_ptm = e_pci->pci_gi.vobu_e_ptm;
804 
805  (*p_is_nav_packet) = 1;
806 
807  return 0;
808  case DVDNAV_BLOCK_OK:
809  if (!state->in_ps) {
810  if (state->in_pgc)
811  i = 0; /* necessary in case we are skipping junk cells at the beginning */
812  continue;
813  }
814 
815  if (nav_len != DVDVIDEO_BLOCK_SIZE) {
816  av_log(s, AV_LOG_ERROR, "Invalid MPEG block size (expected=%d actual=%d)\n",
817  DVDVIDEO_BLOCK_SIZE, nav_len);
818 
819  return AVERROR_INVALIDDATA;
820  }
821 
822  if (cur_angle != c->opt_angle) {
823  av_log(s, AV_LOG_ERROR, "Unexpected angle change (expected=%d new=%d)\n",
824  c->opt_angle, cur_angle);
825 
826  return AVERROR_INPUT_CHANGED;
827  }
828 
829  if (state->pgn != cur_pgn)
830  av_log(s, AV_LOG_WARNING, "Unexpected PG change (expected=%d actual=%d); "
831  "this could be due to a missed NAV packet\n",
832  state->pgn, cur_pgn);
833 
834  memcpy(buf, &nav_buf, nav_len);
835 
836  state->is_seeking = 0;
837 
838  return nav_len;
839  case DVDNAV_WAIT:
840  if (dvdnav_wait_skip(state->dvdnav) != DVDNAV_STATUS_OK) {
841  av_log(s, AV_LOG_ERROR, "Unable to skip WAIT event\n");
842 
843  goto end_dvdnav_error;
844  }
845 
846  continue;
847  case DVDNAV_STILL_FRAME:
848  case DVDNAV_HOP_CHANNEL:
849  case DVDNAV_HIGHLIGHT:
850  if (state->in_ps)
851  return AVERROR_EOF;
852 
853  if (nav_event == DVDNAV_STILL_FRAME) {
854  if (dvdnav_still_skip(state->dvdnav) != DVDNAV_STATUS_OK) {
855  av_log(s, AV_LOG_ERROR, "Unable to skip still image\n");
856 
857  goto end_dvdnav_error;
858  }
859  }
860 
861  continue;
862  default:
863  continue;
864  }
865  }
866 
867  av_log(s, AV_LOG_ERROR, "Unable to find next program stream block\n");
868 
869  return AVERROR_INVALIDDATA;
870 
871 end_dvdnav_error:
872  av_log(s, AV_LOG_ERROR, "dvdnav error (title=%d pgc=%d pg=%d cell=%d): %s\n",
873  cur_title, cur_pgcn, cur_pgn, state->celln,
874  dvdnav_err_to_string(state->dvdnav));
875 
876  return AVERROR_EXTERNAL;
877 }
878 
880 {
881  DVDVideoDemuxContext *c = s->priv_data;
882 
883  uint64_t time_prev = 0;
884  int64_t total_duration = 0;
885 
886  int chapter_start = c->opt_chapter_start;
887  int chapter_end = c->opt_chapter_end > 0 ? c->opt_chapter_end : c->play_state.pgc_nb_pg_est;
888 
889  /* dvdnav_describe_title_chapters() describes PGs rather than PTTs, so validate our range */
890  if (c->play_state.pgc_nb_pg_est == 1 ||
891  chapter_start > c->play_state.pgc_nb_pg_est ||
892  chapter_end > c->play_state.pgc_nb_pg_est) {
893 
894  s->duration = av_rescale_q(c->play_state.pgc_duration_est,
896  return 0;
897  }
898 
899  for (int i = chapter_start - 1; i < chapter_end; i++) {
900  uint64_t time_effective = c->play_state.pgc_pg_times_est[i] - c->play_state.nav_pts;
901 
902  if (time_effective - time_prev == 0)
903  continue;
904 
905  if (chapter_start != chapter_end &&
906  !avpriv_new_chapter(s, i, DVDVIDEO_TIME_BASE_Q, time_prev, time_effective, NULL)) {
907 
908  return AVERROR(ENOMEM);
909  }
910 
911  time_prev = time_effective;
912  total_duration = time_effective;
913  }
914 
915  if (c->opt_chapter_start == 1 && c->opt_chapter_end == 0)
916  s->duration = av_rescale_q(c->play_state.pgc_duration_est,
918  else
919  s->duration = av_rescale_q(total_duration,
921 
922  return 0;
923 }
924 
926 {
927  DVDVideoDemuxContext *c = s->priv_data;
928 
929  int ret, partn, last_partn;
930  int interrupt = 0, nb_chapters = 0;
931  uint64_t cur_chapter_offset = 0, cur_chapter_duration = 0;
933 
934  uint8_t nav_buf[DVDVIDEO_BLOCK_SIZE];
935  int is_nav_packet;
936 
937  if (c->opt_chapter_start == c->opt_chapter_end)
938  return 0;
939 
940  if (c->opt_menu) {
941  if ((ret = dvdvideo_menu_open(s, &state)) < 0)
942  return ret;
943  last_partn = state.celln;
944  } else {
945  if ((ret = dvdvideo_play_open(s, &state)) < 0)
946  return ret;
947  last_partn = c->opt_chapter_start;
948  }
949 
950  if (state.pgc->nr_of_programs == 1)
951  goto end_close;
952 
954  "Indexing chapter markers, this will take a long time. Please wait...\n");
955 
956  while (!(interrupt = ff_check_interrupt(&s->interrupt_callback))) {
957  if (c->opt_menu)
958  ret = dvdvideo_menu_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet);
959  else
960  ret = dvdvideo_play_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet);
961 
962  if (ret < 0 && ret != AVERROR_EOF)
963  goto end_close;
964 
965  if (!is_nav_packet && ret != AVERROR_EOF)
966  continue;
967 
968  partn = c->opt_menu ? state.celln : state.ptt;
969 
970  if (partn == last_partn) {
971  cur_chapter_duration += state.vobu_duration;
972  /* ensure we add the last chapter */
973  if (ret != AVERROR_EOF)
974  continue;
975  }
976 
977  if (cur_chapter_duration > 0) {
978  if (!avpriv_new_chapter(s, nb_chapters, DVDVIDEO_TIME_BASE_Q, cur_chapter_offset,
979  cur_chapter_offset + cur_chapter_duration, NULL)) {
980  ret = AVERROR(ENOMEM);
981  goto end_close;
982  }
983 
984  nb_chapters++;
985  }
986 
987  cur_chapter_offset += cur_chapter_duration;
988  cur_chapter_duration = state.vobu_duration;
989  last_partn = partn;
990 
991  if (ret == AVERROR_EOF)
992  break;
993  }
994 
995  if (interrupt) {
996  ret = AVERROR_EXIT;
997  goto end_close;
998  }
999 
1000  if (ret < 0 && ret != AVERROR_EOF)
1001  goto end_close;
1002 
1003  s->duration = av_rescale_q(state.pgc_elapsed, DVDVIDEO_TIME_BASE_Q, AV_TIME_BASE_Q);
1004 
1005  av_log(s, AV_LOG_INFO, "Chapter marker indexing complete\n");
1006  ret = 0;
1007 
1008 end_close:
1009  if (c->opt_menu)
1011  else
1013 
1014  return ret;
1015 }
1016 
1017 static int dvdvideo_video_stream_analyze(AVFormatContext *s, video_attr_t video_attr,
1019 {
1021  int height = 0;
1022  int width = 0;
1023  int is_pal = video_attr.video_format == 1;
1024 
1025  framerate = is_pal ? (AVRational) { 25, 1 } : (AVRational) { 30000, 1001 };
1026  height = is_pal ? 576 : 480;
1027 
1028  if (height > 0) {
1029  switch (video_attr.picture_size) {
1030  case 0: /* D1 */
1031  width = 720;
1032  break;
1033  case 1: /* 4CIF */
1034  width = 704;
1035  break;
1036  case 2: /* Half D1 */
1037  width = 352;
1038  break;
1039  case 3: /* CIF */
1040  width = 352;
1041  height /= 2;
1042  break;
1043  }
1044  }
1045 
1046  if (!width || !height) {
1047  av_log(s, AV_LOG_ERROR, "Invalid video stream parameters in the IFO headers, "
1048  "this could be an authoring error or empty title "
1049  "(video_format=%d picture_size=%d)\n",
1050  video_attr.video_format, video_attr.picture_size);
1051 
1052  return AVERROR_INVALIDDATA;
1053  }
1054 
1055  entry->startcode = 0x1E0;
1056  entry->codec_id = !video_attr.mpeg_version ? AV_CODEC_ID_MPEG1VIDEO : AV_CODEC_ID_MPEG2VIDEO;
1057  entry->width = width;
1058  entry->height = height;
1059  entry->dar = video_attr.display_aspect_ratio ? (AVRational) { 16, 9 } : (AVRational) { 4, 3 };
1060  entry->framerate = framerate;
1061 
1062  return 0;
1063 }
1064 
1066 {
1067  AVStream *st;
1068  FFStream *sti;
1069 
1070  st = avformat_new_stream(s, NULL);
1071  if (!st)
1072  return AVERROR(ENOMEM);
1073 
1074  st->id = entry->startcode;
1076  st->codecpar->codec_id = entry->codec_id;
1077  st->codecpar->width = entry->width;
1078  st->codecpar->height = entry->height;
1081 
1082 #if FF_API_R_FRAME_RATE
1083  st->r_frame_rate = entry->framerate;
1084 #endif
1085  st->avg_frame_rate = entry->framerate;
1086 
1087  sti = ffstream(st);
1088  sti->request_probe = 0;
1090  sti->display_aspect_ratio = entry->dar;
1091 
1094 
1095  return 0;
1096 }
1097 
1099 {
1100  DVDVideoDemuxContext *c = s->priv_data;
1101 
1102  int ret;
1104  video_attr_t video_attr;
1105 
1106  if (c->opt_menu)
1107  video_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_video_attr :
1108  c->vts_ifo->vtsi_mat->vtsm_video_attr;
1109  else
1110  video_attr = c->vts_ifo->vtsi_mat->vts_video_attr;
1111 
1112  if ((ret = dvdvideo_video_stream_analyze(s, video_attr, &entry)) < 0 ||
1113  (ret = dvdvideo_video_stream_add(s, &entry)) < 0) {
1114 
1115  av_log(s, AV_LOG_ERROR, "Unable to add video stream\n");
1116  return ret;
1117  }
1118 
1119  return 0;
1120 }
1121 
1122 static int dvdvideo_audio_stream_analyze(AVFormatContext *s, audio_attr_t audio_attr,
1123  uint16_t audio_control, DVDVideoPGCAudioStreamEntry *entry)
1124 {
1125  int startcode = 0;
1127  int sample_fmt = AV_SAMPLE_FMT_NONE;
1128  int sample_rate = 0;
1129  int bit_depth = 0;
1130  int nb_channels = 0;
1131  AVChannelLayout ch_layout = (AVChannelLayout) {0};
1132  char lang_dvd[3] = {0};
1133 
1134  int position = (audio_control & 0x7F00) >> 8;
1135 
1136  /* XXX(PATCHWELCOME): SDDS is not supported due to lack of sample material */
1137  switch (audio_attr.audio_format) {
1138  case 0: /* AC3 */
1140  sample_fmt = AV_SAMPLE_FMT_FLTP;
1141  sample_rate = 48000;
1142  startcode = 0x80 + position;
1143  break;
1144  case 2: /* MP1 */
1146  sample_fmt = audio_attr.quantization ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
1147  sample_rate = 48000;
1148  bit_depth = audio_attr.quantization ? 20 : 16;
1149  startcode = 0x1C0 + position;
1150  break;
1151  case 3: /* MP2 */
1153  sample_fmt = audio_attr.quantization ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
1154  sample_rate = 48000;
1155  bit_depth = audio_attr.quantization ? 20 : 16;
1156  startcode = 0x1C0 + position;
1157  break;
1158  case 4: /* DVD PCM */
1160  sample_fmt = audio_attr.quantization ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
1161  sample_rate = audio_attr.sample_frequency ? 96000 : 48000;
1162  bit_depth = audio_attr.quantization == 2 ? 24 : (audio_attr.quantization ? 20 : 16);
1163  startcode = 0xA0 + position;
1164  break;
1165  case 6: /* DCA */
1167  sample_fmt = AV_SAMPLE_FMT_FLTP;
1168  sample_rate = 48000;
1169  bit_depth = audio_attr.quantization == 2 ? 24 : (audio_attr.quantization ? 20 : 16);
1170  startcode = 0x88 + position;
1171  break;
1172  }
1173 
1174  nb_channels = audio_attr.channels + 1;
1175 
1176  if (codec_id == AV_CODEC_ID_NONE ||
1177  startcode == 0 ||
1178  sample_fmt == AV_SAMPLE_FMT_NONE ||
1179  sample_rate == 0 ||
1180  nb_channels == 0) {
1181 
1182  av_log(s, AV_LOG_ERROR, "Invalid audio stream parameters in the IFO headers, "
1183  "this could be an authoring error or dummy title "
1184  "(stream position %d in IFO)\n", position);
1185  return AVERROR_INVALIDDATA;
1186  }
1187 
1188  if (nb_channels == 1)
1190  else if (nb_channels == 2)
1192  else if (nb_channels == 6)
1194  else if (nb_channels == 7)
1196  else if (nb_channels == 8)
1198 
1199  /* XXX(PATCHWELCOME): IFO structures have metadata on karaoke tracks for additional features */
1200  if (audio_attr.application_mode == 1) {
1201  entry->disposition |= AV_DISPOSITION_KARAOKE;
1202 
1203  av_log(s, AV_LOG_WARNING, "Extended karaoke metadata is not supported at this time "
1204  "(stream id=%d)\n", startcode);
1205  }
1206 
1207  if (audio_attr.code_extension == 2)
1208  entry->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
1209  if (audio_attr.code_extension == 3 || audio_attr.code_extension == 4)
1210  entry->disposition |= AV_DISPOSITION_COMMENT;
1211 
1212  AV_WB16(lang_dvd, audio_attr.lang_code);
1213 
1214  entry->startcode = startcode;
1215  entry->codec_id = codec_id;
1216  entry->sample_rate = sample_rate;
1217  entry->bit_depth = bit_depth;
1218  entry->nb_channels = nb_channels;
1219  entry->ch_layout = ch_layout;
1220  entry->lang_iso = ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL);
1221 
1222  return 0;
1223 }
1224 
1226 {
1227  AVStream *st;
1228  FFStream *sti;
1229 
1230  st = avformat_new_stream(s, NULL);
1231  if (!st)
1232  return AVERROR(ENOMEM);
1233 
1234  st->id = entry->startcode;
1236  st->codecpar->codec_id = entry->codec_id;
1237  st->codecpar->format = entry->sample_fmt;
1238  st->codecpar->sample_rate = entry->sample_rate;
1239  st->codecpar->bits_per_coded_sample = entry->bit_depth;
1240  st->codecpar->bits_per_raw_sample = entry->bit_depth;
1241  st->codecpar->ch_layout = entry->ch_layout;
1242  st->codecpar->ch_layout.nb_channels = entry->nb_channels;
1243  st->disposition = entry->disposition;
1244 
1245  if (entry->lang_iso)
1246  av_dict_set(&st->metadata, "language", entry->lang_iso, 0);
1247 
1248  sti = ffstream(st);
1249  sti->request_probe = 0;
1251 
1254 
1255  return 0;
1256 }
1257 
1259 {
1260  DVDVideoDemuxContext *c = s->priv_data;
1261 
1262  int ret;
1263  int nb_streams;
1264 
1265  if (c->opt_menu)
1266  nb_streams = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->nr_of_vmgm_audio_streams :
1267  c->vts_ifo->vtsi_mat->nr_of_vtsm_audio_streams;
1268  else
1269  nb_streams = c->vts_ifo->vtsi_mat->nr_of_vts_audio_streams;
1270 
1271  for (int i = 0; i < nb_streams; i++) {
1273  audio_attr_t audio_attr;
1274 
1275  if (c->opt_menu)
1276  audio_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_audio_attr :
1277  c->vts_ifo->vtsi_mat->vtsm_audio_attr;
1278  else
1279  audio_attr = c->vts_ifo->vtsi_mat->vts_audio_attr[i];
1280 
1281  if (!(c->play_state.pgc->audio_control[i] & 0x8000))
1282  continue;
1283 
1284  if ((ret = dvdvideo_audio_stream_analyze(s, audio_attr, c->play_state.pgc->audio_control[i],
1285  &entry)) < 0)
1286  goto break_error;
1287 
1288  /* IFO structures can declare duplicate entries for the same startcode */
1289  for (int j = 0; j < s->nb_streams; j++)
1290  if (s->streams[j]->id == entry.startcode)
1291  continue;
1292 
1293  if ((ret = dvdvideo_audio_stream_add(s, &entry)) < 0)
1294  goto break_error;
1295 
1296  continue;
1297 
1298 break_error:
1299  av_log(s, AV_LOG_ERROR, "Unable to add audio stream at position %d\n", i);
1300  return ret;
1301  }
1302 
1303  return 0;
1304 }
1305 
1306 static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr,
1308 {
1309  DVDVideoDemuxContext *c = s->priv_data;
1310 
1311  int ret;
1312  char lang_dvd[3] = {0};
1313 
1314  entry->startcode = 0x20 + (offset & 0x1F);
1315 
1316  if (subp_attr.lang_extension == 9)
1317  entry->disposition |= AV_DISPOSITION_FORCED;
1318 
1319  memcpy(&entry->clut, c->play_state.pgc->palette, FF_DVDCLUT_CLUT_SIZE);
1320 
1321  /* dvdsub palettes currently have no colorspace tagging and all muxers only support RGB */
1322  /* this is not a lossless conversion, but no use cases are supported for the original YUV */
1324  if (ret < 0)
1325  return ret;
1326 
1327  AV_WB16(lang_dvd, subp_attr.lang_code);
1328  entry->lang_iso = ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL);
1329 
1330  return 0;
1331 }
1332 
1334 {
1335  AVStream *st;
1336  FFStream *sti;
1337  int ret;
1338 
1339  st = avformat_new_stream(s, NULL);
1340  if (!st)
1341  return AVERROR(ENOMEM);
1342 
1343  st->id = entry->startcode;
1346 
1348  return ret;
1349 
1350  if (entry->lang_iso)
1351  av_dict_set(&st->metadata, "language", entry->lang_iso, 0);
1352 
1353  av_dict_set(&st->metadata, "VIEWPORT", dvdvideo_subp_viewport_labels[entry->viewport], 0);
1354 
1355  st->disposition = entry->disposition;
1356 
1357  sti = ffstream(st);
1358  sti->request_probe = 0;
1360 
1363 
1364  return 0;
1365 }
1366 
1368  subp_attr_t subp_attr,
1369  enum DVDVideoSubpictureViewport viewport)
1370 {
1371  int ret;
1373 
1374  entry.viewport = viewport;
1375 
1376  if ((ret = dvdvideo_subp_stream_analyze(s, offset, subp_attr, &entry)) < 0)
1377  goto end_error;
1378 
1379  /* IFO structures can declare duplicate entries for the same startcode */
1380  for (int i = 0; i < s->nb_streams; i++)
1381  if (s->streams[i]->id == entry.startcode)
1382  return 0;
1383 
1384  if ((ret = dvdvideo_subp_stream_add(s, &entry)) < 0)
1385  goto end_error;
1386 
1387  return 0;
1388 
1389 end_error:
1390  av_log(s, AV_LOG_ERROR, "Unable to add subtitle stream\n");
1391  return ret;
1392 }
1393 
1395 {
1396  DVDVideoDemuxContext *c = s->priv_data;
1397 
1398  int nb_streams;
1399 
1400  if (c->opt_menu)
1401  nb_streams = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->nr_of_vmgm_subp_streams :
1402  c->vts_ifo->vtsi_mat->nr_of_vtsm_subp_streams;
1403  else
1404  nb_streams = c->vts_ifo->vtsi_mat->nr_of_vts_subp_streams;
1405 
1406 
1407  for (int i = 0; i < nb_streams; i++) {
1408  int ret;
1409  uint32_t subp_control;
1410  subp_attr_t subp_attr;
1411  video_attr_t video_attr;
1412 
1413  subp_control = c->play_state.pgc->subp_control[i];
1414  if (!(subp_control & 0x80000000))
1415  continue;
1416 
1417  /* there can be several presentations for one SPU */
1418  /* the DAR check is flexible in order to support weird authoring */
1419  if (c->opt_menu) {
1420  video_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_video_attr :
1421  c->vts_ifo->vtsi_mat->vtsm_video_attr;
1422 
1423  subp_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_subp_attr :
1424  c->vts_ifo->vtsi_mat->vtsm_subp_attr;
1425  } else {
1426  video_attr = c->vts_ifo->vtsi_mat->vts_video_attr;
1427  subp_attr = c->vts_ifo->vtsi_mat->vts_subp_attr[i];
1428  }
1429 
1430  /* 4:3 */
1431  if (!video_attr.display_aspect_ratio) {
1432  if ((ret = dvdvideo_subp_stream_add_internal(s, subp_control >> 24, subp_attr,
1434  return ret;
1435 
1436  continue;
1437  }
1438 
1439  /* 16:9 */
1440  if (( ret = dvdvideo_subp_stream_add_internal(s, subp_control >> 16, subp_attr,
1442  return ret;
1443 
1444  /* 16:9 letterbox */
1445  if (video_attr.permitted_df == 2 || video_attr.permitted_df == 0)
1446  if ((ret = dvdvideo_subp_stream_add_internal(s, subp_control >> 8, subp_attr,
1448  return ret;
1449 
1450  /* 16:9 pan-and-scan */
1451  if (video_attr.permitted_df == 1 || video_attr.permitted_df == 0)
1452  if ((ret = dvdvideo_subp_stream_add_internal(s, subp_control, subp_attr,
1454  return ret;
1455  }
1456 
1457  return 0;
1458 }
1459 
1460 static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size)
1461 {
1462  AVFormatContext *s = opaque;
1463  DVDVideoDemuxContext *c = s->priv_data;
1464 
1465  int ret;
1466  int is_nav_packet;
1467 
1468  if (c->opt_menu)
1469  ret = dvdvideo_menu_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet);
1470  else
1471  ret = dvdvideo_play_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet);
1472 
1473  if (ret < 0)
1474  goto subdemux_eof;
1475 
1476  if (is_nav_packet) {
1477  if (c->play_state.ptm_discont) {
1478  c->subdemux_reset = 1;
1479 
1480  ret = AVERROR_EOF;
1481  goto subdemux_eof;
1482  }
1483 
1484  return FFERROR_REDO;
1485  }
1486 
1487  return ret;
1488 
1489 subdemux_eof:
1490  c->mpeg_pb.pub.eof_reached = 1;
1491  c->mpeg_pb.pub.error = ret;
1492  c->mpeg_pb.pub.read_packet = NULL;
1493  c->mpeg_pb.pub.buf_end = c->mpeg_pb.pub.buf_ptr = c->mpeg_pb.pub.buffer;
1494 
1495  return ret;
1496 }
1497 
1499 {
1500  DVDVideoDemuxContext *c = s->priv_data;
1501 
1502  av_freep(&c->mpeg_pb.pub.buffer);
1503  avformat_close_input(&c->mpeg_ctx);
1504 }
1505 
1507 {
1508  DVDVideoDemuxContext *c = s->priv_data;
1509  extern const FFInputFormat ff_mpegps_demuxer;
1510  int ret;
1511 
1512  if (!(c->mpeg_buf = av_mallocz(DVDVIDEO_BLOCK_SIZE)))
1513  return AVERROR(ENOMEM);
1514 
1515  ffio_init_context(&c->mpeg_pb, c->mpeg_buf, DVDVIDEO_BLOCK_SIZE, 0, s,
1517  c->mpeg_pb.pub.seekable = 0;
1518 
1519  if (!(c->mpeg_ctx = avformat_alloc_context()))
1520  return AVERROR(ENOMEM);
1521 
1522  if ((ret = ff_copy_whiteblacklists(c->mpeg_ctx, s)) < 0) {
1523  avformat_free_context(c->mpeg_ctx);
1524  c->mpeg_ctx = NULL;
1525 
1526  return ret;
1527  }
1528 
1529  c->mpeg_ctx->flags = AVFMT_FLAG_CUSTOM_IO | AVFMT_FLAG_GENPTS;
1530  c->mpeg_ctx->ctx_flags |= AVFMTCTX_UNSEEKABLE;
1531  c->mpeg_ctx->probesize = 0;
1532  c->mpeg_ctx->max_analyze_duration = 0;
1533  c->mpeg_ctx->interrupt_callback = s->interrupt_callback;
1534  c->mpeg_ctx->pb = &c->mpeg_pb.pub;
1535  c->mpeg_ctx->io_open = NULL;
1536 
1537  return avformat_open_input(&c->mpeg_ctx, "", &ff_mpegps_demuxer.p, NULL);
1538 }
1539 
1541 {
1542  int ret;
1543 
1544  av_log(s, AV_LOG_VERBOSE, "Resetting sub-demuxer\n");
1545 
1547  if ((ret = dvdvideo_subdemux_open(s)) < 0)
1548  return ret;
1549 
1550  return 0;
1551 }
1552 
1554 {
1555  DVDVideoDemuxContext *c = s->priv_data;
1556 
1557  int ret;
1558 
1559  if (c->opt_menu) {
1560  if (c->opt_region ||
1561  c->opt_title > 1 ||
1562  c->opt_chapter_start > 1 ||
1563  c->opt_chapter_end > 0) {
1564  av_log(s, AV_LOG_ERROR, "-menu is not compatible with the -region, -title, "
1565  "or -chapter_start/-chapter_end options\n");
1566  return AVERROR(EINVAL);
1567  }
1568 
1569  if (!c->opt_pgc) {
1570  av_log(s, AV_LOG_ERROR, "If -menu is enabled, -pgc must be set to a non-zero value\n");
1571 
1572  return AVERROR(EINVAL);
1573  }
1574 
1575  if ((ret = dvdvideo_ifo_open(s)) < 0 ||
1576  (c->opt_preindex && (ret = dvdvideo_chapters_setup_preindex(s)) < 0) ||
1577  (ret = dvdvideo_menu_open(s, &c->play_state)) < 0 ||
1578  (ret = dvdvideo_video_stream_setup(s)) < 0 ||
1579  (ret = dvdvideo_audio_stream_add_all(s)) < 0 ||
1580  (ret = dvdvideo_subdemux_open(s)) < 0)
1581  return ret;
1582 
1583  goto end_ready;
1584  }
1585 
1586  if (c->opt_pgc && (c->opt_chapter_start > 1 || c->opt_chapter_end > 0 || c->opt_preindex)) {
1587  av_log(s, AV_LOG_ERROR, "PGC extraction not compatible with chapter or preindex options\n");
1588 
1589  return AVERROR(EINVAL);
1590  }
1591 
1592  if (!c->opt_pgc && (c->opt_chapter_end != 0 && c->opt_chapter_start > c->opt_chapter_end)) {
1593  av_log(s, AV_LOG_ERROR, "Chapter (PTT) range [%d, %d] is invalid\n",
1594  c->opt_chapter_start, c->opt_chapter_end);
1595 
1596  return AVERROR(EINVAL);
1597  }
1598 
1599  if (c->opt_title == 0) {
1600  av_log(s, AV_LOG_INFO, "Defaulting to title #1. "
1601  "This is not always the main feature, validation suggested.\n");
1602 
1603  c->opt_title = 1;
1604  }
1605 
1606  if ((ret = dvdvideo_ifo_open(s)) < 0)
1607  return ret;
1608 
1609  if (!c->opt_pgc && c->opt_preindex && (ret = dvdvideo_chapters_setup_preindex(s)) < 0)
1610  return ret;
1611 
1612  if ((ret = dvdvideo_play_open(s, &c->play_state)) < 0 ||
1613  (!c->opt_pgc && !c->opt_preindex && (ret = dvdvideo_chapters_setup_simple(s)) < 0) ||
1614  (ret = dvdvideo_video_stream_setup(s)) < 0 ||
1615  (ret = dvdvideo_audio_stream_add_all(s)) < 0 ||
1616  (ret = dvdvideo_subp_stream_add_all(s)) < 0 ||
1617  (ret = dvdvideo_subdemux_open(s)) < 0)
1618  return ret;
1619 
1620 end_ready:
1621  c->prev_pts = av_malloc(s->nb_streams * sizeof(int64_t));
1622  if (!c->prev_pts)
1623  return AVERROR(ENOMEM);
1624 
1625  for (int i = 0; i < s->nb_streams; i++)
1626  c->prev_pts[i] = AV_NOPTS_VALUE;
1627 
1628  return 0;
1629 }
1630 
1632 {
1633  DVDVideoDemuxContext *c = s->priv_data;
1634 
1635  int ret;
1636  int is_key = 0;
1637  int st_mapped = 0;
1638  AVStream *st_subdemux;
1639  uint8_t ac3_bitstream_id;
1640  uint16_t ac3_frame_size;
1641 
1642  ret = av_read_frame(c->mpeg_ctx, pkt);
1643  if (ret < 0) {
1644  if (c->subdemux_reset && ret == AVERROR_EOF) {
1645  c->subdemux_reset = 0;
1646  c->pts_offset = c->play_state.ptm_offset;
1647 
1648  if ((ret = dvdvideo_subdemux_reset(s)) < 0)
1649  return ret;
1650 
1651  return FFERROR_REDO;
1652  }
1653 
1654  return ret;
1655  }
1656 
1657  st_subdemux = c->mpeg_ctx->streams[pkt->stream_index];
1658  is_key = pkt->flags & AV_PKT_FLAG_KEY;
1659 
1660  /* map the subdemuxer stream to the parent demuxer's stream (by startcode) */
1661  for (int i = 0; i < s->nb_streams; i++) {
1662  if (s->streams[i]->id == st_subdemux->id) {
1663  pkt->stream_index = s->streams[i]->index;
1664  st_mapped = 1;
1665 
1666  break;
1667  }
1668  }
1669 
1670  if (!st_mapped || pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE)
1671  goto discard;
1672 
1673  if (!c->play_started) {
1674  /* try to start at the beginning of a GOP */
1675  if (st_subdemux->codecpar->codec_type != AVMEDIA_TYPE_VIDEO || !is_key)
1676  goto discard;
1677 
1678  c->first_pts = pkt->pts;
1679  c->play_started = 1;
1680  }
1681 
1682  pkt->pts += c->pts_offset - c->first_pts;
1683  pkt->dts += c->pts_offset - c->first_pts;
1684 
1685  if (pkt->pts < 0)
1686  goto discard;
1687 
1688  /* clean up after DVD muxers which end seamless PGs on duplicate or partial AC3 samples */
1689  if (st_subdemux->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
1690  st_subdemux->codecpar->codec_id == AV_CODEC_ID_AC3) {
1691 
1692  if (pkt->pts <= c->prev_pts[pkt->stream_index])
1693  goto discard;
1694 
1696  &ac3_bitstream_id, &ac3_frame_size);
1697 
1698  if (ret < 0 || pkt->size != ac3_frame_size)
1699  goto discard;
1700  }
1701 
1702  av_log(s, AV_LOG_TRACE, "st=%d pts=%" PRId64 " dts=%" PRId64 " "
1703  "pts_offset=%" PRId64 " first_pts=%" PRId64 "\n",
1704  pkt->stream_index, pkt->pts, pkt->dts,
1705  c->pts_offset, c->first_pts);
1706 
1707  c->prev_pts[pkt->stream_index] = pkt->pts;
1708 
1709  return 0;
1710 
1711 discard:
1712  av_log(s, st_mapped ? AV_LOG_VERBOSE : AV_LOG_DEBUG,
1713  "Discarding frame @ st=%d pts=%" PRId64 " dts=%" PRId64 " is_key=%d st_mapped=%d\n",
1714  st_mapped ? pkt->stream_index : -1, pkt->pts, pkt->dts, is_key, st_mapped);
1715 
1716  if (st_mapped)
1717  c->prev_pts[pkt->stream_index] = pkt->pts;
1718 
1719  return FFERROR_REDO;
1720 }
1721 
1723 {
1724  DVDVideoDemuxContext *c = s->priv_data;
1725 
1727 
1728  if (c->opt_menu)
1729  dvdvideo_menu_close(s, &c->play_state);
1730  else
1731  dvdvideo_play_close(s, &c->play_state);
1732 
1734 
1735  if (c->prev_pts)
1736  av_freep(&c->prev_pts);
1737 
1738  return 0;
1739 }
1740 
1741 static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
1742 {
1743  DVDVideoDemuxContext *c = s->priv_data;
1744  int ret;
1745  int64_t new_nav_pts;
1746  pci_t* new_nav_pci;
1747  dsi_t* new_nav_dsi;
1748  int seek_failed = 0;
1749 
1750  if (c->opt_menu || c->opt_chapter_start > 1) {
1751  av_log(s, AV_LOG_ERROR, "Seeking is not compatible with menus or chapter extraction\n");
1752 
1753  return AVERROR_PATCHWELCOME;
1754  }
1755 
1756  if ((flags & AVSEEK_FLAG_BYTE))
1757  return AVERROR(ENOSYS);
1758 
1759  if (timestamp < 0 || timestamp > s->duration)
1760  return AVERROR(EINVAL);
1761 
1762  if (!c->seek_warned) {
1763  av_log(s, AV_LOG_WARNING, "Seeking is inherently unreliable and will result "
1764  "in imprecise timecodes from this point\n");
1765  c->seek_warned = 1;
1766  }
1767 
1768  /* dvdnav loses NAV packets when seeking on multi-angle discs, so enforce angle 1 then revert */
1769  if (c->nb_angles > 1) {
1770  if (dvdnav_angle_change(c->play_state.dvdnav, 1) != DVDNAV_STATUS_OK) {
1771  av_log(s, AV_LOG_ERROR, "Unable to open angle 1 for seeking\n");
1772 
1773  return AVERROR_EXTERNAL;
1774  }
1775  }
1776 
1777  /* XXX(PATCHWELCOME): use dvdnav_jump_to_sector_by_time(c->play_state.dvdnav, timestamp, 0)
1778  * when it is available in a released version of libdvdnav; it is more accurate */
1779  if (dvdnav_time_search(c->play_state.dvdnav, timestamp) != DVDNAV_STATUS_OK) {
1780  seek_failed = 1;
1781  }
1782 
1783  if (c->nb_angles > 1) {
1784  if (dvdnav_angle_change(c->play_state.dvdnav, c->opt_angle) != DVDNAV_STATUS_OK) {
1785  av_log(s, AV_LOG_ERROR, "Unable to revert to angle %d after seeking\n", c->opt_angle);
1786 
1787  return AVERROR_EXTERNAL;
1788  }
1789  }
1790 
1791  if (seek_failed) {
1792  av_log(s, AV_LOG_ERROR, "libdvdnav: seeking to %" PRId64 " failed\n", timestamp);
1793 
1794  return AVERROR_EXTERNAL;
1795  }
1796 
1797  new_nav_pts = dvdnav_get_current_time (c->play_state.dvdnav);
1798  new_nav_pci = dvdnav_get_current_nav_pci(c->play_state.dvdnav);
1799  new_nav_dsi = dvdnav_get_current_nav_dsi(c->play_state.dvdnav);
1800 
1801  if (new_nav_pci == NULL || new_nav_dsi == NULL) {
1802  av_log(s, AV_LOG_ERROR, "Invalid NAV packet after seeking\n");
1803 
1804  return AVERROR_INVALIDDATA;
1805  }
1806 
1807  c->play_state.in_pgc = 1;
1808  c->play_state.in_ps = 0;
1809  c->play_state.is_seeking = 1;
1810  c->play_state.nav_pts = timestamp;
1811  c->play_state.ptm_offset = timestamp;
1812  c->play_state.ptm_discont = 0;
1813  c->play_state.vobu_e_ptm = new_nav_pci->pci_gi.vobu_s_ptm;
1814 
1815  /* if there are multiple angles, skip the next 3 VOBUs as dvdnav will be at the wrong angle */
1816  c->play_state.nb_vobu_skip = c->nb_angles > 1 ? 3 : 0;
1817 
1818  c->first_pts = 0;
1819  c->play_started = 0;
1820  c->pts_offset = timestamp;
1821  c->subdemux_reset = 0;
1822 
1823  if ((ret = dvdvideo_subdemux_reset(s)) < 0)
1824  return ret;
1825 
1826  av_log(s, AV_LOG_DEBUG, "seeking: requested_nav_pts=%" PRId64 " new_nav_pts=%" PRId64 "\n",
1827  timestamp, new_nav_pts);
1828 
1829  return 0;
1830 }
1831 
1832 #define OFFSET(x) offsetof(DVDVideoDemuxContext, x)
1833 static const AVOption dvdvideo_options[] = {
1834  {"angle", "playback angle number", OFFSET(opt_angle), AV_OPT_TYPE_INT, { .i64=1 }, 1, 9, AV_OPT_FLAG_DECODING_PARAM },
1835  {"chapter_end", "exit chapter (PTT) number (0=end)", OFFSET(opt_chapter_end), AV_OPT_TYPE_INT, { .i64=0 }, 0, 99, AV_OPT_FLAG_DECODING_PARAM },
1836  {"chapter_start", "entry chapter (PTT) number", OFFSET(opt_chapter_start), AV_OPT_TYPE_INT, { .i64=1 }, 1, 99, AV_OPT_FLAG_DECODING_PARAM },
1837  {"menu", "demux menu domain", OFFSET(opt_menu), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
1838  {"menu_lu", "menu language unit", OFFSET(opt_menu_lu), AV_OPT_TYPE_INT, { .i64=1 }, 1, 99, AV_OPT_FLAG_DECODING_PARAM },
1839  {"menu_vts", "menu VTS (0=VMG root menu)", OFFSET(opt_menu_vts), AV_OPT_TYPE_INT, { .i64=1 }, 0, 99, AV_OPT_FLAG_DECODING_PARAM },
1840  {"pg", "entry PG number (when paired with PGC number)", OFFSET(opt_pg), AV_OPT_TYPE_INT, { .i64=1 }, 1, 255, AV_OPT_FLAG_DECODING_PARAM },
1841  {"pgc", "entry PGC number (0=auto)", OFFSET(opt_pgc), AV_OPT_TYPE_INT, { .i64=0 }, 0, 999, AV_OPT_FLAG_DECODING_PARAM },
1842  {"preindex", "enable for accurate chapter markers, slow (2-pass read)", OFFSET(opt_preindex), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
1843  {"region", "playback region number (0=free)", OFFSET(opt_region), AV_OPT_TYPE_INT, { .i64=0 }, 0, 8, AV_OPT_FLAG_DECODING_PARAM },
1844  {"title", "title number (0=auto)", OFFSET(opt_title), AV_OPT_TYPE_INT, { .i64=0 }, 0, 99, AV_OPT_FLAG_DECODING_PARAM },
1845  {"trim", "trim padding cells from start", OFFSET(opt_trim), AV_OPT_TYPE_BOOL, { .i64=1 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
1846  {NULL}
1847 };
1848 
1849 static const AVClass dvdvideo_class = {
1850  .class_name = "DVD-Video demuxer",
1851  .item_name = av_default_item_name,
1852  .option = dvdvideo_options,
1853  .version = LIBAVUTIL_VERSION_INT
1854 };
1855 
1857  .p.name = "dvdvideo",
1858  .p.long_name = NULL_IF_CONFIG_SMALL("DVD-Video"),
1859  .p.priv_class = &dvdvideo_class,
1862  .priv_data_size = sizeof(DVDVideoDemuxContext),
1863  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
1868 };
avpriv_new_chapter
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.
Definition: demux_utils.c:43
flags
const SwsFlags flags[]
Definition: swscale.c:61
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
dvdvideo_subp_stream_analyze
static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr, DVDVideoPGCSubtitleStreamEntry *entry)
Definition: dvdvideodec.c:1306
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:486
level
uint8_t level
Definition: svq3.c:208
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:452
ffio_init_context
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))
Definition: aviobuf.c:50
DVDVIDEO_MAX_PS_SEARCH_BLOCKS
#define DVDVIDEO_MAX_PS_SEARCH_BLOCKS
Definition: dvdvideodec.c:57
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
state
static struct @508 state
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:395
DVDVideoPGCAudioStreamEntry::ch_layout
AVChannelLayout ch_layout
Definition: dvdvideodec.c:92
dvdvideo_is_pgc_promising
static int dvdvideo_is_pgc_promising(AVFormatContext *s, pgc_t *pgc)
Definition: dvdvideodec.c:314
DVDVideoVTSVideoStreamEntry::width
int width
Definition: dvdvideodec.c:79
DVDVideoDemuxContext::opt_region
int opt_region
Definition: dvdvideodec.c:152
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
dvdvideo_play_open
static int dvdvideo_play_open(AVFormatContext *s, DVDVideoPlaybackState *state)
Definition: dvdvideodec.c:518
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
int64_t
long long int64_t
Definition: coverity.c:34
DVDVideoVTSVideoStreamEntry::height
int height
Definition: dvdvideodec.c:80
avlanguage.h
DVDVideoVTSVideoStreamEntry::codec_id
enum AVCodecID codec_id
Definition: dvdvideodec.c:78
DVDVideoVTSVideoStreamEntry::framerate
AVRational framerate
Definition: dvdvideodec.c:82
DVDVideoDemuxContext::opt_trim
int opt_trim
Definition: dvdvideodec.c:154
dvdvideo_audio_stream_analyze
static int dvdvideo_audio_stream_analyze(AVFormatContext *s, audio_attr_t audio_attr, uint16_t audio_control, DVDVideoPGCAudioStreamEntry *entry)
Definition: dvdvideodec.c:1122
DVDVideoDemuxContext::vts_ifo
ifo_handle_t * vts_ifo
Definition: dvdvideodec.c:164
dvdvideo_play_close
static void dvdvideo_play_close(AVFormatContext *s, DVDVideoPlaybackState *state)
Definition: dvdvideodec.c:504
OFFSET
#define OFFSET(x)
Definition: dvdvideodec.c:1832
AVOption
AVOption.
Definition: opt.h:429
DVDVideoPlaybackState::celln
int celln
Definition: dvdvideodec.c:106
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
AVFMT_FLAG_CUSTOM_IO
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition: avformat.h:1423
DVDVideoPlaybackState::vtsn
int vtsn
Definition: dvdvideodec.c:124
AVSEEK_FLAG_BYTE
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:2375
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
DVDVideoPlaybackState::pgc_duration_est
uint64_t pgc_duration_est
Definition: dvdvideodec.c:114
DVDVideoPlaybackState::pgcn
int pgcn
Definition: dvdvideodec.c:117
DVDVideoPGCAudioStreamEntry::bit_depth
int bit_depth
Definition: dvdvideodec.c:90
DVDVideoPlaybackState::vobu_next
uint32_t vobu_next
Definition: dvdvideodec.c:134
av_read_frame
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: demux.c:1528
AVFMT_NOBINSEARCH
#define AVFMT_NOBINSEARCH
Format does not allow to fall back on binary search via read_timestamp.
Definition: avformat.h:484
DVDVideoDemuxContext::first_pts
int64_t first_pts
Definition: dvdvideodec.c:167
DVDVideoPlaybackState::in_vts
int in_vts
Definition: dvdvideodec.c:110
ac3_parser.h
DVDVideoDemuxContext::dvdread
dvd_reader_t * dvdread
Definition: dvdvideodec.c:162
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:590
DVDVideoPGCSubtitleStreamEntry::lang_iso
const char * lang_iso
Definition: dvdvideodec.c:102
DVDVideoPlaybackState::in_ps
int in_ps
Definition: dvdvideodec.c:109
DVDVideoPlaybackState::vobu_duration
uint32_t vobu_duration
Definition: dvdvideodec.c:122
av_ac3_parse_header
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.
Definition: ac3_parser.c:496
DVDVideoPlaybackState::ptm_discont
int ptm_discont
Definition: dvdvideodec.c:119
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
DVDVideoPGCSubtitleStreamEntry::disposition
int disposition
Definition: dvdvideodec.c:100
DVDVideoDemuxContext::vmg_ifo
ifo_handle_t * vmg_ifo
Definition: dvdvideodec.c:163
dvdvideo_ifo_open
static int dvdvideo_ifo_open(AVFormatContext *s)
Definition: dvdvideodec.c:226
dvdvideo_menu_next_ps_block
static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state, uint8_t *buf, int buf_size, int *p_is_nav_packet)
Definition: dvdvideodec.c:398
DVDVideoDemuxContext::mpeg_pb
FFIOContext mpeg_pb
Definition: dvdvideodec.c:159
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:367
DVDVideoDemuxContext
Definition: dvdvideodec.c:139
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:777
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
dvdvideo_subdemux_read_data
static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size)
Definition: dvdvideodec.c:1460
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
DVDVideoPlaybackState::vobu_e_ptm
uint32_t vobu_e_ptm
Definition: dvdvideodec.c:123
AVCodecParameters::bits_per_raw_sample
int bits_per_raw_sample
This is the number of valid bits in each output sample.
Definition: codec_par.h:123
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
samplefmt.h
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
DVDVideoPlaybackState::sector_offset
int sector_offset
Definition: dvdvideodec.c:132
AV_DISPOSITION_FORCED
#define AV_DISPOSITION_FORCED
Track should be used during playback by default.
Definition: avformat.h:650
ff_check_interrupt
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition: avio.c:855
DVDVideoVTSVideoStreamEntry::dar
AVRational dar
Definition: dvdvideodec.c:81
DVDVideoPGCAudioStreamEntry::sample_fmt
int sample_fmt
Definition: dvdvideodec.c:88
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
DVDVideoPlaybackState::vobu_remaining
uint32_t vobu_remaining
Definition: dvdvideodec.c:135
DVDVideoDemuxContext::opt_chapter_start
int opt_chapter_start
Definition: dvdvideodec.c:145
DVDVideoPlaybackState::celln_end
int celln_end
Definition: dvdvideodec.c:131
avformat_open_input
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
Definition: demux.c:217
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
DVDVideoPGCAudioStreamEntry::startcode
int startcode
Definition: dvdvideodec.c:86
DVDVideoPlaybackState::dvdnav
dvdnav_t * dvdnav
Definition: dvdvideodec.c:127
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:417
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
dvdvideo_video_stream_analyze
static int dvdvideo_video_stream_analyze(AVFormatContext *s, video_attr_t video_attr, DVDVideoVTSVideoStreamEntry *entry)
Definition: dvdvideodec.c:1017
dvdvideo_video_stream_setup
static int dvdvideo_video_stream_setup(AVFormatContext *s)
Definition: dvdvideodec.c:1098
dvdvideo_subp_viewport_labels
static const char dvdvideo_subp_viewport_labels[4][13]
Definition: dvdvideodec.c:72
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
dvdvideo_chapters_setup_simple
static int dvdvideo_chapters_setup_simple(AVFormatContext *s)
Definition: dvdvideodec.c:879
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:449
DVDVideoDemuxContext::opt_menu_lu
int opt_menu_lu
Definition: dvdvideodec.c:147
dvdvideo_libdvdread_log
static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level, const char *msg, va_list msg_va)
Definition: dvdvideodec.c:177
AVERROR_INPUT_CHANGED
#define AVERROR_INPUT_CHANGED
Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED)
Definition: error.h:75
DVDVideoVTSVideoStreamEntry
Definition: dvdvideodec.c:76
dvdvideo_read_header
static int dvdvideo_read_header(AVFormatContext *s)
Definition: dvdvideodec.c:1553
dvdclut.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
DVDVideoPGCSubtitleStreamEntry
Definition: dvdvideodec.c:97
DVDVideoPlaybackState::ptt
int ptt
Definition: dvdvideodec.c:121
nb_streams
static int nb_streams
Definition: ffprobe.c:334
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:296
DVDVideoPlaybackState::pgc
pgc_t * pgc
Definition: dvdvideodec.c:126
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_PCM_DVD
@ AV_CODEC_ID_PCM_DVD
Definition: codec_id.h:355
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
DVDVideoPlaybackState::sector_end
uint32_t sector_end
Definition: dvdvideodec.c:133
DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE
#define DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE
Definition: dvdvideodec.c:61
dvdvideo_chapters_setup_preindex
static int dvdvideo_chapters_setup_preindex(AVFormatContext *s)
Definition: dvdvideodec.c:925
FF_INFMT_FLAG_INIT_CLEANUP
#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...
Definition: demux.h:35
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
DVDVideoDemuxContext::opt_angle
int opt_angle
Definition: dvdvideodec.c:143
internal.h
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:518
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
AV_LANG_ISO639_2_BIBL
@ AV_LANG_ISO639_2_BIBL
Definition: avlanguage.h:28
framerate
float framerate
Definition: av1_levels.c:29
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
DVDVideoPlaybackState::celln_start
int celln_start
Definition: dvdvideodec.c:130
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
dvdvideo_class
static const AVClass dvdvideo_class
Definition: dvdvideodec.c:1849
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVFMTCTX_UNSEEKABLE
#define AVFMTCTX_UNSEEKABLE
signal that the stream is definitely not seekable, and attempts to call the seek function will fail.
Definition: avformat.h:1217
DVDVideoDemuxContext::mpeg_buf
uint8_t * mpeg_buf
Definition: dvdvideodec.c:158
ff_copy_whiteblacklists
int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
Copies the whilelists from one context to the other.
Definition: avformat.c:822
DVDVideoPlaybackState::pgn
int pgn
Definition: dvdvideodec.c:118
dvdvideo_read_packet
static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dvdvideodec.c:1631
DVDVideoDemuxContext::prev_pts
int64_t * prev_pts
Definition: dvdvideodec.c:171
AV_DISPOSITION_COMMENT
#define AV_DISPOSITION_COMMENT
The stream is a commentary track.
Definition: avformat.h:635
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:560
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
DVDVideoDemuxContext::seek_warned
int seek_warned
Definition: dvdvideodec.c:173
DVDVideoDemuxContext::subdemux_reset
int subdemux_reset
Definition: dvdvideodec.c:174
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
dvdvideo_close
static int dvdvideo_close(AVFormatContext *s)
Definition: dvdvideodec.c:1722
DVDVideoPGCAudioStreamEntry::disposition
int disposition
Definition: dvdvideodec.c:93
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
dvdvideo_libdvdnav_log
static void dvdvideo_libdvdnav_log(void *opaque, dvdnav_logger_level_t level, const char *msg, va_list msg_va)
Definition: dvdvideodec.c:194
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
dvdvideo_subdemux_close
static void dvdvideo_subdemux_close(AVFormatContext *s)
Definition: dvdvideodec.c:1498
DVDVideoDemuxContext::nb_angles
int nb_angles
Definition: dvdvideodec.c:168
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
dvdvideo_audio_stream_add_all
static int dvdvideo_audio_stream_add_all(AVFormatContext *s)
Definition: dvdvideodec.c:1258
dvdvideo_menu_close
static void dvdvideo_menu_close(AVFormatContext *s, DVDVideoPlaybackState *state)
Definition: dvdvideodec.c:323
DVDVideoDemuxContext::play_state
DVDVideoPlaybackState play_state
Definition: dvdvideodec.c:170
DVDVideoDemuxContext::opt_menu
int opt_menu
Definition: dvdvideodec.c:146
DVDVideoDemuxContext::opt_menu_vts
int opt_menu_vts
Definition: dvdvideodec.c:148
DVDVideoPlaybackState::nav_pts
int64_t nav_pts
Definition: dvdvideodec.c:112
dvdvideo_subp_stream_add
static int dvdvideo_subp_stream_add(AVFormatContext *s, DVDVideoPGCSubtitleStreamEntry *entry)
Definition: dvdvideodec.c:1333
DVDVideoPGCSubtitleStreamEntry::clut
uint32_t clut[FF_DVDCLUT_CLUT_LEN]
Definition: dvdvideodec.c:101
AVPacket::size
int size
Definition: packet.h:536
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
DVDVideoPGCAudioStreamEntry::codec_id
enum AVCodecID codec_id
Definition: dvdvideodec.c:87
height
#define height
Definition: dsp.h:89
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
ff_convert_lang_to
const char * ff_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace)
Convert a language code to a target codespace.
Definition: avlanguage.c:741
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
AV_CODEC_ID_DTS
@ AV_CODEC_ID_DTS
Definition: codec_id.h:453
DVDVideoPlaybackState::pgc_nb_pg_est
int pgc_nb_pg_est
Definition: dvdvideodec.c:116
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
DVDVideoPGCSubtitleStreamEntry::startcode
int startcode
Definition: dvdvideodec.c:98
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
DVDVideoPGCSubtitleStreamEntry::viewport
enum DVDVideoSubpictureViewport viewport
Definition: dvdvideodec.c:99
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
DVDVideoDemuxContext::opt_pg
int opt_pg
Definition: dvdvideodec.c:149
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:534
dvdvideo_ifo_close
static void dvdvideo_ifo_close(AVFormatContext *s)
Definition: dvdvideodec.c:212
DVDVideoSubpictureViewport
DVDVideoSubpictureViewport
Definition: dvdvideodec.c:66
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:541
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:489
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
DVDVideoDemuxContext::mpeg_ctx
AVFormatContext * mpeg_ctx
Definition: dvdvideodec.c:157
DVDVideoDemuxContext::pts_offset
int64_t pts_offset
Definition: dvdvideodec.c:172
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:176
DVDVideoDemuxContext::opt_pgc
int opt_pgc
Definition: dvdvideodec.c:150
DVDVIDEO_BLOCK_SIZE
#define DVDVIDEO_BLOCK_SIZE
Definition: dvdvideodec.c:58
DVDVIDEO_PTS_WRAP_BITS
#define DVDVIDEO_PTS_WRAP_BITS
Definition: dvdvideodec.c:60
DVDVideoPlaybackState::is_seeking
int is_seeking
Definition: dvdvideodec.c:111
DVDVIDEO_SUBP_VIEWPORT_PANSCAN
@ DVDVIDEO_SUBP_VIEWPORT_PANSCAN
Definition: dvdvideodec.c:70
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:528
dvdvideo_menu_open
static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state)
Definition: dvdvideodec.c:329
avio_internal.h
DVDVideoDemuxContext::opt_chapter_end
int opt_chapter_end
Definition: dvdvideodec.c:144
DVDVideoVTSVideoStreamEntry::startcode
int startcode
Definition: dvdvideodec.c:77
AVCodecParameters::height
int height
Definition: codec_par.h:135
DVDVideoPlaybackState::entry_pgn
int entry_pgn
Definition: dvdvideodec.c:107
vsnprintf
#define vsnprintf
Definition: snprintf.h:36
AV_DISPOSITION_KARAOKE
#define AV_DISPOSITION_KARAOKE
The stream contains karaoke audio.
Definition: avformat.h:643
DVDVideoPlaybackState::nb_vobu_skip
int nb_vobu_skip
Definition: dvdvideodec.c:113
url.h
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
DVDVideoPlaybackState::in_pgc
int in_pgc
Definition: dvdvideodec.c:108
ff_dvdvideo_demuxer
const FFInputFormat ff_dvdvideo_demuxer
Definition: dvdvideodec.c:1856
demux.h
DVDVIDEO_SUBP_VIEWPORT_LETTERBOX
@ DVDVIDEO_SUBP_VIEWPORT_LETTERBOX
Definition: dvdvideodec.c:69
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:733
DVDVideoPlaybackState::ptm_offset
int64_t ptm_offset
Definition: dvdvideodec.c:120
dvdvideo_is_cell_promising
static int dvdvideo_is_cell_promising(AVFormatContext *s, pgc_t *pgc, int celln)
Definition: dvdvideodec.c:307
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:813
AVFMT_FLAG_GENPTS
#define AVFMT_FLAG_GENPTS
Generate missing pts even if it requires parsing future frames.
Definition: avformat.h:1416
AV_DISPOSITION_VISUAL_IMPAIRED
#define AV_DISPOSITION_VISUAL_IMPAIRED
The stream is intended for visually impaired audiences.
Definition: avformat.h:658
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
DVDVideoPlaybackState::pgc_pg_times_est
uint64_t * pgc_pg_times_est
Definition: dvdvideodec.c:125
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:590
avformat.h
PCI_START_BYTE
#define PCI_START_BYTE
Definition: dvdvideodec.c:63
dvdvideo_options
static const AVOption dvdvideo_options[]
Definition: dvdvideodec.c:1833
AVERROR_STREAM_NOT_FOUND
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition: error.h:67
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
AVFMT_NOGENSEARCH
#define AVFMT_NOGENSEARCH
Format does not allow to fall back on generic search.
Definition: avformat.h:485
ff_mpegps_demuxer
const FFInputFormat ff_mpegps_demuxer
Definition: mpeg.c:704
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
dvdvideo_play_next_ps_block
static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state, uint8_t *buf, int buf_size, int *p_is_nav_packet)
Definition: dvdvideodec.c:622
AVPacket::stream_index
int stream_index
Definition: packet.h:537
dvdvideo_read_seek
static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: dvdvideodec.c:1741
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
avutil.h
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
AVFMT_TS_DISCONT
#define AVFMT_TS_DISCONT
Format allows timestamp discontinuities.
Definition: avformat.h:480
mem.h
DVDVideoDemuxContext::opt_title
int opt_title
Definition: dvdvideodec.c:153
AVCodecParameters::format
int format
Definition: codec_par.h:92
dvdvideo_subdemux_open
static int dvdvideo_subdemux_open(AVFormatContext *s)
Definition: dvdvideodec.c:1506
DVDVideoPGCAudioStreamEntry::nb_channels
int nb_channels
Definition: dvdvideodec.c:91
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
FFStream::request_probe
int request_probe
stream probing state -1 -> probing finished 0 -> no probing requested rest -> perform probing with re...
Definition: internal.h:198
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:512
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
dvdvideo_video_stream_add
static int dvdvideo_video_stream_add(AVFormatContext *s, DVDVideoVTSVideoStreamEntry *entry)
Definition: dvdvideodec.c:1065
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
FFInputFormat
Definition: demux.h:42
dvdvideo_subp_stream_add_all
static int dvdvideo_subp_stream_add_all(AVFormatContext *s)
Definition: dvdvideodec.c:1394
int32_t
int32_t
Definition: audioconvert.c:56
DVDVIDEO_SUBP_VIEWPORT_WIDESCREEN
@ DVDVIDEO_SUBP_VIEWPORT_WIDESCREEN
Definition: dvdvideodec.c:68
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_CHANNEL_LAYOUT_6POINT1
#define AV_CHANNEL_LAYOUT_6POINT1
Definition: channel_layout.h:412
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
DVDVideoPGCAudioStreamEntry::sample_rate
int sample_rate
Definition: dvdvideodec.c:89
dvdvideo_subp_stream_add_internal
static int dvdvideo_subp_stream_add_internal(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr, enum DVDVideoSubpictureViewport viewport)
Definition: dvdvideodec.c:1367
DVDVideoPGCAudioStreamEntry
Definition: dvdvideodec.c:85
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
DVDVideoPlaybackState::vob_file
dvd_file_t * vob_file
Definition: dvdvideodec.c:136
avstring.h
DVDVIDEO_SUBP_VIEWPORT_FULLSCREEN
@ DVDVIDEO_SUBP_VIEWPORT_FULLSCREEN
Definition: dvdvideodec.c:67
width
#define width
Definition: dsp.h:89
AV_CHANNEL_LAYOUT_5POINT1
#define AV_CHANNEL_LAYOUT_5POINT1
Definition: channel_layout.h:405
dvdvideo_subdemux_reset
static int dvdvideo_subdemux_reset(AVFormatContext *s)
Definition: dvdvideodec.c:1540
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:59
DVDVIDEO_TIME_BASE_Q
#define DVDVIDEO_TIME_BASE_Q
Definition: dvdvideodec.c:59
AV_CODEC_ID_MP1
@ AV_CODEC_ID_MP1
Definition: codec_id.h:491
dvdvideo_nav_header
static const uint8_t dvdvideo_nav_header[4]
Definition: dvdvideodec.c:64
dvdvideo_audio_stream_add
static int dvdvideo_audio_stream_add(AVFormatContext *s, DVDVideoPGCAudioStreamEntry *entry)
Definition: dvdvideodec.c:1225
DVDVideoPlaybackState::pgc_elapsed
uint64_t pgc_elapsed
Definition: dvdvideodec.c:115
DVDVideoDemuxContext::opt_preindex
int opt_preindex
Definition: dvdvideodec.c:151
DVDVideoPGCAudioStreamEntry::lang_iso
const char * lang_iso
Definition: dvdvideodec.c:94
DVDVideoPlaybackState
Definition: dvdvideodec.c:105
DVDVideoDemuxContext::play_started
int play_started
Definition: dvdvideodec.c:169