FFmpeg
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;
83  int has_cc;
85 
87  int startcode;
91  int bit_depth;
95  const char *lang_iso;
97 
99  int startcode;
103  const char *lang_iso;
105 
106 typedef struct DVDVideoPlaybackState {
107  int celln; /* ID of the active cell */
108  int entry_pgn; /* ID of the PG we are starting in */
109  int in_pgc; /* if our navigator is in the PGC */
110  int in_ps; /* if our navigator is in the program stream */
111  int in_vts; /* if our navigator is in the VTS */
112  int is_seeking; /* relax navigation path while seeking */
113  int64_t nav_pts; /* PTS according to IFO, not frame-accurate */
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 play_started; /* signal that playback has started */
169  DVDVideoPlaybackState play_state; /* the active playback state */
170  int64_t *prev_pts; /* track the previous PTS emitted per stream */
171  int64_t pts_offset; /* PTS discontinuity offset (ex. VOB change) */
172  int seek_warned; /* signal that we warned about seeking limits */
173  int subdemux_reset; /* signal that subdemuxer should be reset */
175 
176 static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level,
177  const char *msg, va_list msg_va)
178 {
179  AVFormatContext *s = opaque;
180  char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE];
181  int lavu_level = AV_LOG_DEBUG;
182 
183  vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va);
184 
185  if (level == DVD_LOGGER_LEVEL_ERROR)
186  lavu_level = AV_LOG_ERROR;
187  else if (level == DVD_LOGGER_LEVEL_WARN)
188  lavu_level = AV_LOG_WARNING;
189 
190  av_log(s, lavu_level, "libdvdread: %s\n", msg_buf);
191 }
192 
193 static void dvdvideo_libdvdnav_log(void *opaque, dvdnav_logger_level_t level,
194  const char *msg, va_list msg_va)
195 {
196  AVFormatContext *s = opaque;
197  char msg_buf[DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE];
198  int lavu_level = AV_LOG_DEBUG;
199 
200  vsnprintf(msg_buf, sizeof(msg_buf), msg, msg_va);
201 
202  if (level == DVDNAV_LOGGER_LEVEL_ERROR)
203  lavu_level = AV_LOG_ERROR;
204  /* some discs have invalid language codes set for menus, which throws noisy warnings */
205  else if (level == DVDNAV_LOGGER_LEVEL_WARN && !av_strstart(msg, "Language", NULL))
206  lavu_level = AV_LOG_WARNING;
207 
208  av_log(s, lavu_level, "libdvdnav: %s\n", msg_buf);
209 }
210 
212 {
213  DVDVideoDemuxContext *c = s->priv_data;
214 
215  if (c->vts_ifo)
216  ifoClose(c->vts_ifo);
217 
218  if (c->vmg_ifo)
219  ifoClose(c->vmg_ifo);
220 
221  if (c->dvdread)
222  DVDClose(c->dvdread);
223 }
224 
226 {
227  DVDVideoDemuxContext *c = s->priv_data;
228 
229  dvd_logger_cb dvdread_log_cb;
230  title_info_t title_info;
231 
232  dvdread_log_cb = (dvd_logger_cb) { .pf_log = dvdvideo_libdvdread_log };
233  c->dvdread = DVDOpen2(s, &dvdread_log_cb, s->url);
234 
235  if (!c->dvdread) {
236  av_log(s, AV_LOG_ERROR, "Unable to open the DVD-Video structure\n");
237 
238  return AVERROR_EXTERNAL;
239  }
240 
241  if (!(c->vmg_ifo = ifoOpen(c->dvdread, 0))) {
242  av_log(s, AV_LOG_ERROR, "Unable to open the VMG (VIDEO_TS.IFO)\n");
243 
244  return AVERROR_EXTERNAL;
245  }
246 
247  if (c->opt_menu) {
248  if (c->opt_menu_vts > 0 && !(c->vts_ifo = ifoOpen(c->dvdread, c->opt_menu_vts))) {
249  av_log(s, AV_LOG_ERROR, "Unable to open IFO structure for VTS %d\n", c->opt_menu_vts);
250 
251  return AVERROR_EXTERNAL;
252  }
253 
254  return 0;
255  }
256 
257  if (c->opt_title > c->vmg_ifo->tt_srpt->nr_of_srpts) {
258  av_log(s, AV_LOG_ERROR, "Title %d not found\n", c->opt_title);
259 
261  }
262 
263  title_info = c->vmg_ifo->tt_srpt->title[c->opt_title - 1];
264  if (c->opt_angle > title_info.nr_of_angles) {
265  av_log(s, AV_LOG_ERROR, "Angle %d not found\n", c->opt_angle);
266 
268  }
269 
270  if (title_info.nr_of_ptts < 1) {
271  av_log(s, AV_LOG_ERROR, "Title %d has invalid headers (no PTTs found)\n", c->opt_title);
272 
273  return AVERROR_INVALIDDATA;
274  }
275 
276  if (c->opt_chapter_start > title_info.nr_of_ptts ||
277  (c->opt_chapter_end > 0 && c->opt_chapter_end > title_info.nr_of_ptts)) {
278  av_log(s, AV_LOG_ERROR, "Chapter (PTT) range [%d, %d] is invalid\n",
279  c->opt_chapter_start, c->opt_chapter_end);
280 
281  return AVERROR_INVALIDDATA;
282  }
283 
284  if (!(c->vts_ifo = ifoOpen(c->dvdread, title_info.title_set_nr))) {
285  av_log(s, AV_LOG_ERROR, "Unable to process IFO structure for VTS %d\n",
286  title_info.title_set_nr);
287 
288  return AVERROR_EXTERNAL;
289  }
290 
291  if (title_info.vts_ttn < 1 ||
292  title_info.vts_ttn > 99 ||
293  title_info.vts_ttn > c->vts_ifo->vts_ptt_srpt->nr_of_srpts ||
294  c->vts_ifo->vtsi_mat->nr_of_vts_audio_streams > 8 ||
295  c->vts_ifo->vtsi_mat->nr_of_vts_subp_streams > 32) {
296 
297  av_log(s, AV_LOG_ERROR, "Title %d has invalid headers in VTS\n", c->opt_title);
298  return AVERROR_INVALIDDATA;
299  }
300 
301  return 0;
302 }
303 
304 static int dvdvideo_is_cell_promising(AVFormatContext *s, pgc_t *pgc, int celln)
305 {
306  dvd_time_t cell_duration = pgc->cell_playback[celln - 1].playback_time;
307 
308  return cell_duration.second >= 1 || cell_duration.minute >= 1 || cell_duration.hour >= 1;
309 }
310 
312 {
313  for (int i = 1; i <= pgc->nr_of_cells; i++)
314  if (dvdvideo_is_cell_promising(s, pgc, i))
315  return 1;
316 
317  return 0;
318 }
319 
321 {
322  if (state->vob_file)
323  DVDCloseFile(state->vob_file);
324 }
325 
327 {
328  DVDVideoDemuxContext *c = s->priv_data;
329  pgci_ut_t *pgci_ut;
330 
331  pgci_ut = c->opt_menu_vts ? c->vts_ifo->pgci_ut : c->vmg_ifo->pgci_ut;
332  if (!pgci_ut) {
333  av_log(s, AV_LOG_ERROR, "Invalid PGC table for menu [LU %d, PGC %d]\n",
334  c->opt_menu_lu, c->opt_pgc);
335 
336  return AVERROR_INVALIDDATA;
337  }
338 
339  if (c->opt_pgc < 1 ||
340  c->opt_menu_lu < 1 ||
341  c->opt_menu_lu > pgci_ut->nr_of_lus ||
342  c->opt_pgc > pgci_ut->lu[c->opt_menu_lu - 1].pgcit->nr_of_pgci_srp) {
343 
344  av_log(s, AV_LOG_ERROR, "Menu [LU %d, PGC %d] not found\n", c->opt_menu_lu, c->opt_pgc);
345 
346  return AVERROR(EINVAL);
347  }
348 
349  /* make sure the PGC is valid */
350  state->pgcn = c->opt_pgc;
351  state->pgc = pgci_ut->lu[c->opt_menu_lu - 1].pgcit->pgci_srp[c->opt_pgc - 1].pgc;
352  if (!state->pgc || !state->pgc->program_map || !state->pgc->cell_playback) {
353  av_log(s, AV_LOG_ERROR, "Invalid PGC structure for menu [LU %d, PGC %d]\n",
354  c->opt_menu_lu, c->opt_pgc);
355 
356  return AVERROR_INVALIDDATA;
357  }
358 
359  /* make sure the PG is valid */
360  state->entry_pgn = c->opt_pg;
361  if (state->entry_pgn < 1 || state->entry_pgn > state->pgc->nr_of_programs) {
362  av_log(s, AV_LOG_ERROR, "Entry PG %d not found\n", state->entry_pgn);
363 
364  return AVERROR(EINVAL);
365  }
366 
367  /* make sure the program map isn't leading us to nowhere */
368  state->celln_start = state->pgc->program_map[state->entry_pgn - 1];
369  state->celln_end = state->pgc->nr_of_cells;
370  state->celln = state->celln_start;
371  if (state->celln_start > state->pgc->nr_of_cells) {
372  av_log(s, AV_LOG_ERROR, "Invalid PGC structure: program map points to unknown cell\n");
373 
374  return AVERROR_INVALIDDATA;
375  }
376 
377  state->sector_end = state->pgc->cell_playback[state->celln - 1].last_sector;
378  state->vobu_next = state->pgc->cell_playback[state->celln - 1].first_sector;
379  state->sector_offset = state->vobu_next;
380 
381  if (c->opt_menu_vts > 0)
382  state->in_vts = 1;
383 
384  if (!(state->vob_file = DVDOpenFile(c->dvdread, c->opt_menu_vts, DVD_READ_MENU_VOBS))) {
385  av_log(s, AV_LOG_ERROR, !c->opt_menu_vts ?
386  "Unable to open main menu VOB (VIDEO_TS.VOB)\n" :
387  "Unable to open menu VOBs for VTS %d\n", c->opt_menu_vts);
388 
389  return AVERROR_EXTERNAL;
390  }
391 
392  return 0;
393 }
394 
396  uint8_t *buf, int buf_size, int *p_is_nav_packet)
397 {
398  int64_t blocks_read = 0;
399  uint8_t read_buf[DVDVIDEO_BLOCK_SIZE] = {0};
400  pci_t pci = (pci_t) {0};
401  dsi_t dsi = (dsi_t) {0};
402 
403  (*p_is_nav_packet) = 0;
404  state->ptm_discont = 0;
405 
406  if (buf_size != DVDVIDEO_BLOCK_SIZE) {
407  av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
408  DVDVIDEO_BLOCK_SIZE, buf_size);
409 
410  return AVERROR(EINVAL);
411  }
412 
413  /* we were at the end of a vobu, so now go to the next one or EOF */
414  if (!state->vobu_remaining && state->in_pgc) {
415  if (state->vobu_next == SRI_END_OF_CELL) {
416  if (state->celln == state->celln_end && state->sector_offset > state->sector_end)
417  return AVERROR_EOF;
418 
419  state->celln++;
420  state->sector_offset = state->pgc->cell_playback[state->celln - 1].first_sector;
421  state->sector_end = state->pgc->cell_playback[state->celln - 1].last_sector;
422  } else {
423  state->sector_offset = state->vobu_next;
424  }
425  }
426 
427  /* continue reading the VOBU */
428  av_log(s, AV_LOG_TRACE, "reading block at offset %d\n", state->sector_offset);
429 
430  blocks_read = DVDReadBlocks(state->vob_file, state->sector_offset, 1, read_buf);
431  if (blocks_read != 1) {
432  av_log(s, AV_LOG_ERROR, "Unable to read VOB block: offset=%d blocks_read=%" PRId64 "\n",
433  state->sector_offset, blocks_read);
434 
435  return AVERROR_INVALIDDATA;
436  }
437 
438  /* we are at the start of a VOBU, so we are expecting a NAV packet */
439  if (!state->vobu_remaining) {
440  if (!memcmp(&read_buf[PCI_START_BYTE - 4], dvdvideo_nav_header, 4) ||
441  !memcmp(&read_buf[DSI_START_BYTE - 4], dvdvideo_nav_header, 4) ||
442  read_buf[PCI_START_BYTE - 1] != 0x00 ||
443  read_buf[DSI_START_BYTE - 1] != 0x01) {
444 
445  av_log(s, AV_LOG_ERROR, "Invalid NAV packet at offset %d: PCI or DSI header mismatch\n",
446  state->sector_offset);
447 
448  return AVERROR_INVALIDDATA;
449  }
450 
451  navRead_PCI(&pci, &read_buf[PCI_START_BYTE]);
452  navRead_DSI(&dsi, &read_buf[DSI_START_BYTE]);
453 
454  if (!pci.pci_gi.vobu_s_ptm ||
455  !pci.pci_gi.vobu_e_ptm ||
456  pci.pci_gi.vobu_s_ptm > pci.pci_gi.vobu_e_ptm) {
457 
458  av_log(s, AV_LOG_ERROR, "Invalid NAV packet at offset %d: PCI header is invalid\n",
459  state->sector_offset);
460 
461  return AVERROR_INVALIDDATA;
462  }
463 
464  state->vobu_remaining = dsi.dsi_gi.vobu_ea;
465  state->vobu_next = dsi.vobu_sri.next_vobu == SRI_END_OF_CELL ? SRI_END_OF_CELL :
466  dsi.dsi_gi.nv_pck_lbn + (dsi.vobu_sri.next_vobu & 0x7FFFFFFF);
467  state->sector_offset++;
468 
469  if (state->in_pgc) {
470  if (state->vobu_e_ptm != pci.pci_gi.vobu_s_ptm) {
471  state->ptm_discont = 1;
472  state->ptm_offset += state->vobu_e_ptm - pci.pci_gi.vobu_s_ptm;
473  }
474  } else {
475  state->in_pgc = 1;
476  state->in_ps = 1;
477  }
478 
479  state->vobu_e_ptm = pci.pci_gi.vobu_e_ptm;
480  state->vobu_duration = pci.pci_gi.vobu_e_ptm - pci.pci_gi.vobu_s_ptm;
481 
482  av_log(s, AV_LOG_DEBUG, "NAV packet: sector=%d "
483  "vobu_s_ptm=%d vobu_e_ptm=%d ptm_offset=%" PRId64 "\n",
484  dsi.dsi_gi.nv_pck_lbn,
485  pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm, state->ptm_offset);
486 
487 
488  (*p_is_nav_packet) = 1;
489 
490  return 0;
491  }
492 
493  /* we are in the middle of a VOBU, so pass on the PS packet */
494  memcpy(buf, &read_buf, DVDVIDEO_BLOCK_SIZE);
495  state->sector_offset++;
496  state->vobu_remaining--;
497 
498  return DVDVIDEO_BLOCK_SIZE;
499 }
500 
502 {
503  if (!state->dvdnav)
504  return;
505 
506  /* not allocated by av_malloc() */
507  if (state->pgc_pg_times_est)
508  free(state->pgc_pg_times_est);
509 
510  if (dvdnav_close(state->dvdnav) != DVDNAV_STATUS_OK)
511  av_log(s, AV_LOG_ERROR, "Unable to close dvdnav successfully, dvdnav error: %s\n",
512  dvdnav_err_to_string(state->dvdnav));
513 }
514 
516 {
517  DVDVideoDemuxContext *c = s->priv_data;
518 
519  dvdnav_logger_cb dvdnav_log_cb;
520  dvdnav_status_t dvdnav_open_status;
521  int32_t disc_region_mask;
522  int32_t player_region_mask;
523  int cur_title, cur_pgcn, cur_pgn;
524  pgc_t *pgc;
525 
526  dvdnav_log_cb = (dvdnav_logger_cb) { .pf_log = dvdvideo_libdvdnav_log };
527  dvdnav_open_status = dvdnav_open2(&state->dvdnav, s, &dvdnav_log_cb, s->url);
528 
529  if (!state->dvdnav ||
530  dvdnav_open_status != DVDNAV_STATUS_OK ||
531  dvdnav_set_readahead_flag(state->dvdnav, 0) != DVDNAV_STATUS_OK ||
532  dvdnav_set_PGC_positioning_flag(state->dvdnav, 1) != DVDNAV_STATUS_OK ||
533  dvdnav_get_region_mask(state->dvdnav, &disc_region_mask) != DVDNAV_STATUS_OK) {
534 
535  av_log(s, AV_LOG_ERROR, "Unable to open the DVD for playback\n");
536  goto end_dvdnav_error;
537  }
538 
539  player_region_mask = c->opt_region > 0 ? (1 << (c->opt_region - 1)) : disc_region_mask;
540  if (dvdnav_set_region_mask(state->dvdnav, player_region_mask) != DVDNAV_STATUS_OK) {
541  av_log(s, AV_LOG_ERROR, "Unable to set the playback region code %d\n", c->opt_region);
542 
543  goto end_dvdnav_error;
544  }
545 
546  if (c->opt_pgc > 0) {
547  if (dvdnav_program_play(state->dvdnav, c->opt_title, c->opt_pgc, c->opt_pg) != DVDNAV_STATUS_OK) {
548  av_log(s, AV_LOG_ERROR, "Unable to start playback at title %d, PGC %d, PG %d\n",
549  c->opt_title, c->opt_pgc, c->opt_pg);
550 
551  goto end_dvdnav_error;
552  }
553 
554  state->pgcn = c->opt_pgc;
555  state->entry_pgn = c->opt_pg;
556  } else {
557  if (dvdnav_part_play(state->dvdnav, c->opt_title, c->opt_chapter_start) != DVDNAV_STATUS_OK ||
558  dvdnav_current_title_program(state->dvdnav, &cur_title, &cur_pgcn, &cur_pgn) != DVDNAV_STATUS_OK) {
559 
560  av_log(s, AV_LOG_ERROR, "Unable to start playback at title %d, chapter (PTT) %d\n",
561  c->opt_title, c->opt_chapter_start);
562  goto end_dvdnav_error;
563  }
564 
565  state->pgcn = cur_pgcn;
566  state->entry_pgn = cur_pgn;
567  }
568 
569  pgc = c->vts_ifo->vts_pgcit->pgci_srp[state->pgcn - 1].pgc;
570 
571  if (pgc->pg_playback_mode != 0) {
572  av_log(s, AV_LOG_ERROR, "Non-sequential PGCs, such as shuffles, are not supported\n");
573 
574  return AVERROR_PATCHWELCOME;
575  }
576 
577  if (c->opt_trim && !dvdvideo_is_pgc_promising(s, pgc)) {
578  av_log(s, AV_LOG_ERROR, "Title %d, PGC %d looks empty (may consist of padding cells), "
579  "if you want to try anyway, disable the -trim option\n",
580  c->opt_title, state->pgcn);
581 
582  return AVERROR_INVALIDDATA;
583  }
584 
585  if (dvdnav_angle_change(state->dvdnav, c->opt_angle) != DVDNAV_STATUS_OK) {
586  av_log(s, AV_LOG_ERROR, "Unable to start playback at angle %d\n", c->opt_angle);
587 
588  goto end_dvdnav_error;
589  }
590 
591  /* dvdnav_describe_title_chapters() performs several validations on the title structure */
592  /* take advantage of this side effect to increase chances of a safe navigation path */
593  state->pgc_nb_pg_est = dvdnav_describe_title_chapters(state->dvdnav, c->opt_title,
594  &state->pgc_pg_times_est,
595  &state->pgc_duration_est);
596 
597  /* dvdnav returning 0 PGs is documented as an error condition */
598  if (!state->pgc_nb_pg_est) {
599  av_log(s, AV_LOG_ERROR, "Unable to read chapter information for title %d\n", c->opt_title);
600 
601  goto end_dvdnav_error;
602  }
603 
604  state->nav_pts = dvdnav_get_current_time(state->dvdnav);
605  state->vtsn = c->vmg_ifo->tt_srpt->title[c->opt_title - 1].title_set_nr;
606  state->pgc = pgc;
607 
608  return 0;
609 
610 end_dvdnav_error:
611  if (state->dvdnav)
612  av_log(s, AV_LOG_ERROR, "dvdnav error: %s\n", dvdnav_err_to_string(state->dvdnav));
613  else
614  av_log(s, AV_LOG_ERROR, "dvdnav could not be initialized\n");
615 
616  return AVERROR_EXTERNAL;
617 }
618 
620  uint8_t *buf, int buf_size, int *p_is_nav_packet)
621 {
622  DVDVideoDemuxContext *c = s->priv_data;
623 
624  uint8_t nav_buf[DVDVIDEO_BLOCK_SIZE] = {0};
625  int nav_event;
626  int nav_len;
627 
628  dvdnav_vts_change_event_t *e_vts;
629  dvdnav_cell_change_event_t *e_cell;
630  int cur_title, cur_pgcn, cur_pgn, cur_angle, cur_title_unused, cur_ptt, cur_nb_angles;
631  pci_t *e_pci;
632  dsi_t *e_dsi;
633 
634  (*p_is_nav_packet) = 0;
635  state->ptm_discont = 0;
636 
637  if (buf_size != DVDVIDEO_BLOCK_SIZE) {
638  av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n",
639  DVDVIDEO_BLOCK_SIZE, buf_size);
640 
641  return AVERROR(EINVAL);
642  }
643 
644  for (int i = 0; i < DVDVIDEO_MAX_PS_SEARCH_BLOCKS; i++) {
645  if (ff_check_interrupt(&s->interrupt_callback))
646  return AVERROR_EXIT;
647 
648  if (dvdnav_get_next_block(state->dvdnav, nav_buf, &nav_event, &nav_len) != DVDNAV_STATUS_OK) {
649  av_log(s, AV_LOG_ERROR, "Unable to read next block of PGC\n");
650 
651  goto end_dvdnav_error;
652  }
653 
654  /* STOP event can come at any time and should be honored */
655  if (nav_event == DVDNAV_STOP)
656  return AVERROR_EOF;
657 
658  if (nav_len > DVDVIDEO_BLOCK_SIZE) {
659  av_log(s, AV_LOG_ERROR, "Invalid block size (expected<=%d actual=%d)\n",
660  DVDVIDEO_BLOCK_SIZE, nav_len);
661 
662  return AVERROR_INVALIDDATA;
663  }
664 
665  if (dvdnav_current_title_info(state->dvdnav, &cur_title, &cur_ptt) != DVDNAV_STATUS_OK) {
666  av_log(s, AV_LOG_ERROR, "Unable to determine current title coordinates\n");
667 
668  goto end_dvdnav_error;
669  }
670 
671  /* we somehow navigated to a menu */
672  if (cur_title == 0 || !dvdnav_is_domain_vts(state->dvdnav))
673  return AVERROR_EOF;
674 
675  if (dvdnav_current_title_program(state->dvdnav, &cur_title_unused, &cur_pgcn, &cur_pgn) != DVDNAV_STATUS_OK) {
676  av_log(s, AV_LOG_ERROR, "Unable to determine current PGC coordinates\n");
677 
678  goto end_dvdnav_error;
679  }
680 
681  /* we somehow left the PGC */
682  if (state->in_pgc && cur_pgcn != state->pgcn)
683  return AVERROR_EOF;
684 
685  if (dvdnav_get_angle_info(state->dvdnav, &cur_angle, &cur_nb_angles) != DVDNAV_STATUS_OK) {
686  av_log(s, AV_LOG_ERROR, "Unable to determine current video angle\n");
687 
688  goto end_dvdnav_error;
689  }
690 
691  av_log(s, nav_event == DVDNAV_BLOCK_OK ? AV_LOG_TRACE : AV_LOG_DEBUG,
692  "new block: i=%d nav_event=%d nav_len=%d cur_title=%d "
693  "cur_ptt=%d cur_angle=%d cur_celln=%d cur_pgcn=%d cur_pgn=%d "
694  "play_in_vts=%d play_in_pgc=%d play_in_ps=%d\n",
695  i, nav_event, nav_len, cur_title,
696  cur_ptt, cur_angle, state->celln, cur_pgcn, cur_pgn,
697  state->in_vts, state->in_pgc, state->in_ps);
698 
699  switch (nav_event) {
700  case DVDNAV_VTS_CHANGE:
701  if (state->in_vts)
702  return AVERROR_EOF;
703 
704  e_vts = (dvdnav_vts_change_event_t *) nav_buf;
705 
706  if (e_vts->new_vtsN == state->vtsn && e_vts->new_domain == DVD_DOMAIN_VTSTitle)
707  state->in_vts = 1;
708 
709  continue;
710  case DVDNAV_CELL_CHANGE:
711  if (!state->in_vts)
712  continue;
713 
714  e_cell = (dvdnav_cell_change_event_t *) nav_buf;
715 
716  av_log(s, AV_LOG_DEBUG, "new cell: prev=%d new=%d\n", state->celln, e_cell->cellN);
717 
718  if (!state->in_ps && !state->in_pgc) {
719  if (cur_title == c->opt_title &&
720  (c->opt_pgc || cur_ptt == c->opt_chapter_start) &&
721  cur_pgcn == state->pgcn &&
722  cur_pgn == state->entry_pgn) {
723 
724  state->in_pgc = 1;
725  }
726  } else if (!state->is_seeking &&
727  (state->celln >= e_cell->cellN || state->pgn > cur_pgn)) {
728  return AVERROR_EOF;
729  }
730 
731  state->celln = e_cell->cellN;
732  state->ptt = cur_ptt;
733  state->pgn = cur_pgn;
734 
735  continue;
736  case DVDNAV_NAV_PACKET:
737  if (!state->in_pgc)
738  continue;
739 
740  if ((!state->is_seeking && state->ptt > 0 && state->ptt > cur_ptt) ||
741  (c->opt_chapter_end > 0 && cur_ptt > c->opt_chapter_end)) {
742  return AVERROR_EOF;
743  }
744 
745  if (nav_len != DVDVIDEO_BLOCK_SIZE) {
746  av_log(s, AV_LOG_ERROR, "Invalid NAV packet size (expected=%d actual=%d)\n",
747  DVDVIDEO_BLOCK_SIZE, nav_len);
748 
749  return AVERROR_INVALIDDATA;
750  }
751 
752  e_pci = dvdnav_get_current_nav_pci(state->dvdnav);
753  e_dsi = dvdnav_get_current_nav_dsi(state->dvdnav);
754 
755  if (e_pci == NULL || e_dsi == NULL ||
756  e_pci->pci_gi.vobu_s_ptm > e_pci->pci_gi.vobu_e_ptm) {
757 
758  av_log(s, AV_LOG_ERROR, "Invalid NAV packet\n");
759  return AVERROR_INVALIDDATA;
760  }
761 
762  state->vobu_duration = e_pci->pci_gi.vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
763  state->pgc_elapsed += state->vobu_duration;
764  state->nav_pts = dvdnav_get_current_time(state->dvdnav);
765  state->ptt = cur_ptt;
766  state->pgn = cur_pgn;
767 
769  "NAV packet: s_ptm=%d e_ptm=%d "
770  "scr=%d lbn=%d vobu_duration=%d nav_pts=%" PRId64 "\n",
771  e_pci->pci_gi.vobu_s_ptm, e_pci->pci_gi.vobu_e_ptm,
772  e_dsi->dsi_gi.nv_pck_scr,
773  e_pci->pci_gi.nv_pck_lbn, state->vobu_duration, state->nav_pts);
774 
775  if (!state->in_ps) {
776  if (c->opt_trim && !dvdvideo_is_cell_promising(s, state->pgc, state->celln)) {
777  av_log(s, AV_LOG_INFO, "Skipping padding cell #%d\n", state->celln);
778 
779  i = 0;
780  continue;
781  }
782 
783  av_log(s, AV_LOG_DEBUG, "navigation: locked to program stream\n");
784 
785  state->in_ps = 1;
786  } else {
787  if (state->vobu_e_ptm != e_pci->pci_gi.vobu_s_ptm) {
788  state->ptm_discont = 1;
789  state->ptm_offset += state->vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
790  }
791  }
792 
793  state->vobu_e_ptm = e_pci->pci_gi.vobu_e_ptm;
794 
795  (*p_is_nav_packet) = 1;
796 
797  return 0;
798  case DVDNAV_BLOCK_OK:
799  if (!state->in_ps) {
800  if (state->in_pgc)
801  i = 0; /* necessary in case we are skipping junk cells at the beginning */
802  continue;
803  }
804 
805  if (nav_len != DVDVIDEO_BLOCK_SIZE) {
806  av_log(s, AV_LOG_ERROR, "Invalid MPEG block size (expected=%d actual=%d)\n",
807  DVDVIDEO_BLOCK_SIZE, nav_len);
808 
809  return AVERROR_INVALIDDATA;
810  }
811 
812  if (cur_angle != c->opt_angle) {
813  av_log(s, AV_LOG_ERROR, "Unexpected angle change (expected=%d new=%d)\n",
814  c->opt_angle, cur_angle);
815 
816  return AVERROR_INPUT_CHANGED;
817  }
818 
819  if (state->pgn != cur_pgn)
820  av_log(s, AV_LOG_WARNING, "Unexpected PG change (expected=%d actual=%d); "
821  "this could be due to a missed NAV packet\n",
822  state->pgn, cur_pgn);
823 
824  memcpy(buf, &nav_buf, nav_len);
825 
826  state->is_seeking = 0;
827 
828  return nav_len;
829  case DVDNAV_WAIT:
830  if (dvdnav_wait_skip(state->dvdnav) != DVDNAV_STATUS_OK) {
831  av_log(s, AV_LOG_ERROR, "Unable to skip WAIT event\n");
832 
833  goto end_dvdnav_error;
834  }
835 
836  continue;
837  case DVDNAV_STILL_FRAME:
838  case DVDNAV_HOP_CHANNEL:
839  case DVDNAV_HIGHLIGHT:
840  if (state->in_ps)
841  return AVERROR_EOF;
842 
843  if (nav_event == DVDNAV_STILL_FRAME) {
844  if (dvdnav_still_skip(state->dvdnav) != DVDNAV_STATUS_OK) {
845  av_log(s, AV_LOG_ERROR, "Unable to skip still image\n");
846 
847  goto end_dvdnav_error;
848  }
849  }
850 
851  continue;
852  default:
853  continue;
854  }
855  }
856 
857  av_log(s, AV_LOG_ERROR, "Unable to find next program stream block\n");
858 
859  return AVERROR_INVALIDDATA;
860 
861 end_dvdnav_error:
862  av_log(s, AV_LOG_ERROR, "dvdnav error (title=%d pgc=%d pg=%d cell=%d): %s\n",
863  cur_title, cur_pgcn, cur_pgn, state->celln,
864  dvdnav_err_to_string(state->dvdnav));
865 
866  return AVERROR_EXTERNAL;
867 }
868 
870 {
871  DVDVideoDemuxContext *c = s->priv_data;
872 
873  uint64_t time_prev = 0;
874  int64_t total_duration = 0;
875 
876  int chapter_start = c->opt_chapter_start;
877  int chapter_end = c->opt_chapter_end > 0 ? c->opt_chapter_end : c->play_state.pgc_nb_pg_est;
878 
879  /* dvdnav_describe_title_chapters() describes PGs rather than PTTs, so validate our range */
880  if (c->play_state.pgc_nb_pg_est == 1 ||
881  chapter_start > c->play_state.pgc_nb_pg_est ||
882  chapter_end > c->play_state.pgc_nb_pg_est) {
883 
884  s->duration = av_rescale_q(c->play_state.pgc_duration_est,
886  return 0;
887  }
888 
889  for (int i = chapter_start - 1; i < chapter_end; i++) {
890  uint64_t time_effective = c->play_state.pgc_pg_times_est[i] - c->play_state.nav_pts;
891 
892  if (time_effective - time_prev == 0)
893  continue;
894 
895  if (chapter_start != chapter_end &&
896  !avpriv_new_chapter(s, i, DVDVIDEO_TIME_BASE_Q, time_prev, time_effective, NULL)) {
897 
898  return AVERROR(ENOMEM);
899  }
900 
901  time_prev = time_effective;
902  total_duration = time_effective;
903  }
904 
905  if (c->opt_chapter_start == 1 && c->opt_chapter_end == 0)
906  s->duration = av_rescale_q(c->play_state.pgc_duration_est,
908  else
909  s->duration = av_rescale_q(total_duration,
911 
912  return 0;
913 }
914 
916 {
917  DVDVideoDemuxContext *c = s->priv_data;
918 
919  int ret, partn, last_partn;
920  int interrupt = 0, nb_chapters = 0;
921  uint64_t cur_chapter_offset = 0, cur_chapter_duration = 0;
923 
924  uint8_t nav_buf[DVDVIDEO_BLOCK_SIZE];
925  int is_nav_packet;
926 
927  if (c->opt_chapter_start == c->opt_chapter_end)
928  return 0;
929 
930  if (c->opt_menu) {
931  if ((ret = dvdvideo_menu_open(s, &state)) < 0)
932  return ret;
933  last_partn = state.celln;
934  } else {
935  if ((ret = dvdvideo_play_open(s, &state)) < 0)
936  return ret;
937  last_partn = c->opt_chapter_start;
938  }
939 
940  if (state.pgc->nr_of_programs == 1)
941  goto end_close;
942 
944  "Indexing chapter markers, this will take a long time. Please wait...\n");
945 
946  while (!(interrupt = ff_check_interrupt(&s->interrupt_callback))) {
947  if (c->opt_menu)
948  ret = dvdvideo_menu_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet);
949  else
950  ret = dvdvideo_play_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet);
951 
952  if (ret < 0 && ret != AVERROR_EOF)
953  goto end_close;
954 
955  if (!is_nav_packet && ret != AVERROR_EOF)
956  continue;
957 
958  partn = c->opt_menu ? state.celln : state.ptt;
959 
960  if (partn == last_partn) {
961  cur_chapter_duration += state.vobu_duration;
962  /* ensure we add the last chapter */
963  if (ret != AVERROR_EOF)
964  continue;
965  }
966 
967  if (cur_chapter_duration > 0) {
968  if (!avpriv_new_chapter(s, nb_chapters, DVDVIDEO_TIME_BASE_Q, cur_chapter_offset,
969  cur_chapter_offset + cur_chapter_duration, NULL)) {
970  ret = AVERROR(ENOMEM);
971  goto end_close;
972  }
973 
974  nb_chapters++;
975  }
976 
977  cur_chapter_offset += cur_chapter_duration;
978  cur_chapter_duration = state.vobu_duration;
979  last_partn = partn;
980 
981  if (ret == AVERROR_EOF)
982  break;
983  }
984 
985  if (interrupt) {
986  ret = AVERROR_EXIT;
987  goto end_close;
988  }
989 
990  if (ret < 0 && ret != AVERROR_EOF)
991  goto end_close;
992 
993  s->duration = av_rescale_q(state.pgc_elapsed, DVDVIDEO_TIME_BASE_Q, AV_TIME_BASE_Q);
994 
995  av_log(s, AV_LOG_INFO, "Chapter marker indexing complete\n");
996  ret = 0;
997 
998 end_close:
999  if (c->opt_menu)
1001  else
1003 
1004  return ret;
1005 }
1006 
1007 static int dvdvideo_video_stream_analyze(AVFormatContext *s, video_attr_t video_attr,
1009 {
1011  int height = 0;
1012  int width = 0;
1013  int is_pal = video_attr.video_format == 1;
1014 
1015  framerate = is_pal ? (AVRational) { 25, 1 } : (AVRational) { 30000, 1001 };
1016  height = is_pal ? 576 : 480;
1017 
1018  if (height > 0) {
1019  switch (video_attr.picture_size) {
1020  case 0: /* D1 */
1021  width = 720;
1022  break;
1023  case 1: /* 4CIF */
1024  width = 704;
1025  break;
1026  case 2: /* Half D1 */
1027  width = 352;
1028  break;
1029  case 3: /* CIF */
1030  width = 352;
1031  height /= 2;
1032  break;
1033  }
1034  }
1035 
1036  if (!width || !height) {
1037  av_log(s, AV_LOG_ERROR, "Invalid video stream parameters in the IFO headers, "
1038  "this could be an authoring error or empty title "
1039  "(video_format=%d picture_size=%d)\n",
1040  video_attr.video_format, video_attr.picture_size);
1041 
1042  return AVERROR_INVALIDDATA;
1043  }
1044 
1045  entry->startcode = 0x1E0;
1046  entry->codec_id = !video_attr.mpeg_version ? AV_CODEC_ID_MPEG1VIDEO : AV_CODEC_ID_MPEG2VIDEO;
1047  entry->width = width;
1048  entry->height = height;
1049  entry->dar = video_attr.display_aspect_ratio ? (AVRational) { 16, 9 } : (AVRational) { 4, 3 };
1050  entry->framerate = framerate;
1051  entry->has_cc = !is_pal && (video_attr.line21_cc_1 || video_attr.line21_cc_2);
1052 
1053  return 0;
1054 }
1055 
1057 {
1058  AVStream *st;
1059  FFStream *sti;
1060 
1061  st = avformat_new_stream(s, NULL);
1062  if (!st)
1063  return AVERROR(ENOMEM);
1064 
1065  st->id = entry->startcode;
1067  st->codecpar->codec_id = entry->codec_id;
1068  st->codecpar->width = entry->width;
1069  st->codecpar->height = entry->height;
1072 
1073 #if FF_API_R_FRAME_RATE
1074  st->r_frame_rate = entry->framerate;
1075 #endif
1076  st->avg_frame_rate = entry->framerate;
1077 
1078  sti = ffstream(st);
1079  sti->request_probe = 0;
1081  sti->display_aspect_ratio = entry->dar;
1082 
1085 
1086  return 0;
1087 }
1088 
1090 {
1091  DVDVideoDemuxContext *c = s->priv_data;
1092 
1093  int ret;
1095  video_attr_t video_attr;
1096 
1097  if (c->opt_menu)
1098  video_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_video_attr :
1099  c->vts_ifo->vtsi_mat->vtsm_video_attr;
1100  else
1101  video_attr = c->vts_ifo->vtsi_mat->vts_video_attr;
1102 
1103  if ((ret = dvdvideo_video_stream_analyze(s, video_attr, &entry)) < 0 ||
1104  (ret = dvdvideo_video_stream_add(s, &entry)) < 0) {
1105 
1106  av_log(s, AV_LOG_ERROR, "Unable to add video stream\n");
1107  return ret;
1108  }
1109 
1110  return 0;
1111 }
1112 
1113 static int dvdvideo_audio_stream_analyze(AVFormatContext *s, audio_attr_t audio_attr,
1114  uint16_t audio_control, DVDVideoPGCAudioStreamEntry *entry)
1115 {
1116  int startcode = 0;
1118  int sample_fmt = AV_SAMPLE_FMT_NONE;
1119  int sample_rate = 0;
1120  int bit_depth = 0;
1121  int nb_channels = 0;
1122  AVChannelLayout ch_layout = (AVChannelLayout) {0};
1123  char lang_dvd[3] = {0};
1124 
1125  int position = (audio_control & 0x7F00) >> 8;
1126 
1127  /* XXX(PATCHWELCOME): SDDS is not supported due to lack of sample material */
1128  switch (audio_attr.audio_format) {
1129  case 0: /* AC3 */
1131  sample_fmt = AV_SAMPLE_FMT_FLTP;
1132  sample_rate = 48000;
1133  startcode = 0x80 + position;
1134  break;
1135  case 2: /* MP1 */
1137  sample_fmt = audio_attr.quantization ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
1138  sample_rate = 48000;
1139  bit_depth = audio_attr.quantization ? 20 : 16;
1140  startcode = 0x1C0 + position;
1141  break;
1142  case 3: /* MP2 */
1144  sample_fmt = audio_attr.quantization ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
1145  sample_rate = 48000;
1146  bit_depth = audio_attr.quantization ? 20 : 16;
1147  startcode = 0x1C0 + position;
1148  break;
1149  case 4: /* DVD PCM */
1151  sample_fmt = audio_attr.quantization ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
1152  sample_rate = audio_attr.sample_frequency ? 96000 : 48000;
1153  bit_depth = audio_attr.quantization == 2 ? 24 : (audio_attr.quantization ? 20 : 16);
1154  startcode = 0xA0 + position;
1155  break;
1156  case 6: /* DCA */
1158  sample_fmt = AV_SAMPLE_FMT_FLTP;
1159  sample_rate = 48000;
1160  bit_depth = audio_attr.quantization == 2 ? 24 : (audio_attr.quantization ? 20 : 16);
1161  startcode = 0x88 + position;
1162  break;
1163  }
1164 
1165  nb_channels = audio_attr.channels + 1;
1166 
1167  if (codec_id == AV_CODEC_ID_NONE ||
1168  startcode == 0 ||
1169  sample_fmt == AV_SAMPLE_FMT_NONE ||
1170  sample_rate == 0 ||
1171  nb_channels == 0) {
1172 
1173  av_log(s, AV_LOG_ERROR, "Invalid audio stream parameters in the IFO headers, "
1174  "this could be an authoring error or dummy title "
1175  "(stream position %d in IFO)\n", position);
1176  return AVERROR_INVALIDDATA;
1177  }
1178 
1179  if (nb_channels == 1)
1181  else if (nb_channels == 2)
1183  else if (nb_channels == 6)
1185  else if (nb_channels == 7)
1187  else if (nb_channels == 8)
1189 
1190  /* XXX(PATCHWELCOME): IFO structures have metadata on karaoke tracks for additional features */
1191  if (audio_attr.application_mode == 1) {
1192  entry->disposition |= AV_DISPOSITION_KARAOKE;
1193 
1194  av_log(s, AV_LOG_WARNING, "Extended karaoke metadata is not supported at this time "
1195  "(stream id=%d)\n", startcode);
1196  }
1197 
1198  if (audio_attr.code_extension == 2)
1199  entry->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
1200  if (audio_attr.code_extension == 3 || audio_attr.code_extension == 4)
1201  entry->disposition |= AV_DISPOSITION_COMMENT;
1202 
1203  AV_WB16(lang_dvd, audio_attr.lang_code);
1204 
1205  entry->startcode = startcode;
1206  entry->codec_id = codec_id;
1207  entry->sample_rate = sample_rate;
1208  entry->bit_depth = bit_depth;
1209  entry->nb_channels = nb_channels;
1210  entry->ch_layout = ch_layout;
1211  entry->lang_iso = ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL);
1212 
1213  return 0;
1214 }
1215 
1217 {
1218  AVStream *st;
1219  FFStream *sti;
1220 
1221  st = avformat_new_stream(s, NULL);
1222  if (!st)
1223  return AVERROR(ENOMEM);
1224 
1225  st->id = entry->startcode;
1227  st->codecpar->codec_id = entry->codec_id;
1228  st->codecpar->format = entry->sample_fmt;
1229  st->codecpar->sample_rate = entry->sample_rate;
1230  st->codecpar->bits_per_coded_sample = entry->bit_depth;
1231  st->codecpar->bits_per_raw_sample = entry->bit_depth;
1232  st->codecpar->ch_layout = entry->ch_layout;
1233  st->codecpar->ch_layout.nb_channels = entry->nb_channels;
1234  st->disposition = entry->disposition;
1235 
1236  if (entry->lang_iso)
1237  av_dict_set(&st->metadata, "language", entry->lang_iso, 0);
1238 
1239  sti = ffstream(st);
1240  sti->request_probe = 0;
1242 
1245 
1246  return 0;
1247 }
1248 
1250 {
1251  DVDVideoDemuxContext *c = s->priv_data;
1252 
1253  int ret;
1254  int nb_streams;
1255 
1256  if (c->opt_menu)
1257  nb_streams = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->nr_of_vmgm_audio_streams :
1258  c->vts_ifo->vtsi_mat->nr_of_vtsm_audio_streams;
1259  else
1260  nb_streams = c->vts_ifo->vtsi_mat->nr_of_vts_audio_streams;
1261 
1262  for (int i = 0; i < nb_streams; i++) {
1264  audio_attr_t audio_attr;
1265 
1266  if (c->opt_menu)
1267  audio_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_audio_attr :
1268  c->vts_ifo->vtsi_mat->vtsm_audio_attr;
1269  else
1270  audio_attr = c->vts_ifo->vtsi_mat->vts_audio_attr[i];
1271 
1272  if (!(c->play_state.pgc->audio_control[i] & 0x8000))
1273  continue;
1274 
1275  if ((ret = dvdvideo_audio_stream_analyze(s, audio_attr, c->play_state.pgc->audio_control[i],
1276  &entry)) < 0)
1277  goto break_error;
1278 
1279  /* IFO structures can declare duplicate entries for the same startcode */
1280  for (int j = 0; j < s->nb_streams; j++)
1281  if (s->streams[j]->id == entry.startcode)
1282  continue;
1283 
1284  if ((ret = dvdvideo_audio_stream_add(s, &entry)) < 0)
1285  goto break_error;
1286 
1287  continue;
1288 
1289 break_error:
1290  av_log(s, AV_LOG_ERROR, "Unable to add audio stream at position %d\n", i);
1291  return ret;
1292  }
1293 
1294  return 0;
1295 }
1296 
1297 static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr,
1299 {
1300  DVDVideoDemuxContext *c = s->priv_data;
1301 
1302  int ret;
1303  char lang_dvd[3] = {0};
1304 
1305  entry->startcode = 0x20 + (offset & 0x1F);
1306 
1307  if (subp_attr.lang_extension == 9)
1308  entry->disposition |= AV_DISPOSITION_FORCED;
1309 
1310  memcpy(&entry->clut, c->play_state.pgc->palette, FF_DVDCLUT_CLUT_SIZE);
1311 
1312  /* dvdsub palettes currently have no colorspace tagging and all muxers only support RGB */
1313  /* this is not a lossless conversion, but no use cases are supported for the original YUV */
1315  if (ret < 0)
1316  return ret;
1317 
1318  AV_WB16(lang_dvd, subp_attr.lang_code);
1319  entry->lang_iso = ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL);
1320 
1321  return 0;
1322 }
1323 
1325 {
1326  AVStream *st;
1327  FFStream *sti;
1328  int ret;
1329 
1330  st = avformat_new_stream(s, NULL);
1331  if (!st)
1332  return AVERROR(ENOMEM);
1333 
1334  st->id = entry->startcode;
1337 
1339  return ret;
1340 
1341  if (entry->lang_iso)
1342  av_dict_set(&st->metadata, "language", entry->lang_iso, 0);
1343 
1344  av_dict_set(&st->metadata, "VIEWPORT", dvdvideo_subp_viewport_labels[entry->viewport], 0);
1345 
1346  st->disposition = entry->disposition;
1347 
1348  sti = ffstream(st);
1349  sti->request_probe = 0;
1351 
1354 
1355  return 0;
1356 }
1357 
1359  subp_attr_t subp_attr,
1360  enum DVDVideoSubpictureViewport viewport)
1361 {
1362  int ret;
1364 
1365  entry.viewport = viewport;
1366 
1367  if ((ret = dvdvideo_subp_stream_analyze(s, offset, subp_attr, &entry)) < 0)
1368  goto end_error;
1369 
1370  /* IFO structures can declare duplicate entries for the same startcode */
1371  for (int i = 0; i < s->nb_streams; i++)
1372  if (s->streams[i]->id == entry.startcode)
1373  return 0;
1374 
1375  if ((ret = dvdvideo_subp_stream_add(s, &entry)) < 0)
1376  goto end_error;
1377 
1378  return 0;
1379 
1380 end_error:
1381  av_log(s, AV_LOG_ERROR, "Unable to add subtitle stream\n");
1382  return ret;
1383 }
1384 
1386 {
1387  DVDVideoDemuxContext *c = s->priv_data;
1388 
1389  int nb_streams;
1390 
1391  if (c->opt_menu)
1392  nb_streams = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->nr_of_vmgm_subp_streams :
1393  c->vts_ifo->vtsi_mat->nr_of_vtsm_subp_streams;
1394  else
1395  nb_streams = c->vts_ifo->vtsi_mat->nr_of_vts_subp_streams;
1396 
1397 
1398  for (int i = 0; i < nb_streams; i++) {
1399  int ret;
1400  uint32_t subp_control;
1401  subp_attr_t subp_attr;
1402  video_attr_t video_attr;
1403 
1404  subp_control = c->play_state.pgc->subp_control[i];
1405  if (!(subp_control & 0x80000000))
1406  continue;
1407 
1408  /* there can be several presentations for one SPU */
1409  /* the DAR check is flexible in order to support weird authoring */
1410  if (c->opt_menu) {
1411  video_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_video_attr :
1412  c->vts_ifo->vtsi_mat->vtsm_video_attr;
1413 
1414  subp_attr = !c->opt_menu_vts ? c->vmg_ifo->vmgi_mat->vmgm_subp_attr :
1415  c->vts_ifo->vtsi_mat->vtsm_subp_attr;
1416  } else {
1417  video_attr = c->vts_ifo->vtsi_mat->vts_video_attr;
1418  subp_attr = c->vts_ifo->vtsi_mat->vts_subp_attr[i];
1419  }
1420 
1421  /* 4:3 */
1422  if (!video_attr.display_aspect_ratio) {
1423  if ((ret = dvdvideo_subp_stream_add_internal(s, subp_control >> 24, subp_attr,
1425  return ret;
1426 
1427  continue;
1428  }
1429 
1430  /* 16:9 */
1431  if (( ret = dvdvideo_subp_stream_add_internal(s, subp_control >> 16, subp_attr,
1433  return ret;
1434 
1435  /* 16:9 letterbox */
1436  if (video_attr.permitted_df == 2 || video_attr.permitted_df == 0)
1437  if ((ret = dvdvideo_subp_stream_add_internal(s, subp_control >> 8, subp_attr,
1439  return ret;
1440 
1441  /* 16:9 pan-and-scan */
1442  if (video_attr.permitted_df == 1 || video_attr.permitted_df == 0)
1443  if ((ret = dvdvideo_subp_stream_add_internal(s, subp_control, subp_attr,
1445  return ret;
1446  }
1447 
1448  return 0;
1449 }
1450 
1451 static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size)
1452 {
1453  AVFormatContext *s = opaque;
1454  DVDVideoDemuxContext *c = s->priv_data;
1455 
1456  int ret;
1457  int is_nav_packet;
1458 
1459  if (c->opt_menu)
1460  ret = dvdvideo_menu_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet);
1461  else
1462  ret = dvdvideo_play_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet);
1463 
1464  if (ret < 0)
1465  goto subdemux_eof;
1466 
1467  if (is_nav_packet) {
1468  if (c->play_state.ptm_discont) {
1469  c->subdemux_reset = 1;
1470 
1471  ret = AVERROR_EOF;
1472  goto subdemux_eof;
1473  }
1474 
1475  return FFERROR_REDO;
1476  }
1477 
1478  return ret;
1479 
1480 subdemux_eof:
1481  c->mpeg_pb.pub.eof_reached = 1;
1482  c->mpeg_pb.pub.error = ret;
1483  c->mpeg_pb.pub.read_packet = NULL;
1484  c->mpeg_pb.pub.buf_end = c->mpeg_pb.pub.buf_ptr = c->mpeg_pb.pub.buffer;
1485 
1486  return ret;
1487 }
1488 
1490 {
1491  DVDVideoDemuxContext *c = s->priv_data;
1492 
1493  av_freep(&c->mpeg_pb.pub.buffer);
1494  avformat_close_input(&c->mpeg_ctx);
1495 }
1496 
1498 {
1499  DVDVideoDemuxContext *c = s->priv_data;
1500  extern const FFInputFormat ff_mpegps_demuxer;
1501  int ret;
1502 
1503  if (!(c->mpeg_buf = av_mallocz(DVDVIDEO_BLOCK_SIZE)))
1504  return AVERROR(ENOMEM);
1505 
1506  ffio_init_context(&c->mpeg_pb, c->mpeg_buf, DVDVIDEO_BLOCK_SIZE, 0, s,
1508  c->mpeg_pb.pub.seekable = 0;
1509 
1510  if (!(c->mpeg_ctx = avformat_alloc_context()))
1511  return AVERROR(ENOMEM);
1512 
1513  if ((ret = ff_copy_whiteblacklists(c->mpeg_ctx, s)) < 0) {
1514  avformat_free_context(c->mpeg_ctx);
1515  c->mpeg_ctx = NULL;
1516 
1517  return ret;
1518  }
1519 
1520  c->mpeg_ctx->flags = AVFMT_FLAG_CUSTOM_IO | AVFMT_FLAG_GENPTS;
1521  c->mpeg_ctx->ctx_flags |= AVFMTCTX_UNSEEKABLE;
1522  c->mpeg_ctx->probesize = 0;
1523  c->mpeg_ctx->max_analyze_duration = 0;
1524  c->mpeg_ctx->interrupt_callback = s->interrupt_callback;
1525  c->mpeg_ctx->pb = &c->mpeg_pb.pub;
1526  c->mpeg_ctx->io_open = NULL;
1527 
1528  return avformat_open_input(&c->mpeg_ctx, "", &ff_mpegps_demuxer.p, NULL);
1529 }
1530 
1532 {
1533  int ret;
1534 
1535  av_log(s, AV_LOG_VERBOSE, "Resetting sub-demuxer\n");
1536 
1538  if ((ret = dvdvideo_subdemux_open(s)) < 0)
1539  return ret;
1540 
1541  return 0;
1542 }
1543 
1545 {
1546  DVDVideoDemuxContext *c = s->priv_data;
1547 
1548  int ret;
1549 
1550  if (c->opt_menu) {
1551  if (c->opt_region ||
1552  c->opt_title > 1 ||
1553  c->opt_chapter_start > 1 ||
1554  c->opt_chapter_end > 0) {
1555  av_log(s, AV_LOG_ERROR, "-menu is not compatible with the -region, -title, "
1556  "or -chapter_start/-chapter_end options\n");
1557  return AVERROR(EINVAL);
1558  }
1559 
1560  if (!c->opt_pgc) {
1561  av_log(s, AV_LOG_ERROR, "If -menu is enabled, -pgc must be set to a non-zero value\n");
1562 
1563  return AVERROR(EINVAL);
1564  }
1565 
1566  if ((ret = dvdvideo_ifo_open(s)) < 0 ||
1567  (c->opt_preindex && (ret = dvdvideo_chapters_setup_preindex(s)) < 0) ||
1568  (ret = dvdvideo_menu_open(s, &c->play_state)) < 0 ||
1569  (ret = dvdvideo_video_stream_setup(s)) < 0 ||
1570  (ret = dvdvideo_audio_stream_add_all(s)) < 0 ||
1571  (ret = dvdvideo_subdemux_open(s)) < 0)
1572  return ret;
1573 
1574  goto end_ready;
1575  }
1576 
1577  if (c->opt_pgc && (c->opt_chapter_start > 1 || c->opt_chapter_end > 0 || c->opt_preindex)) {
1578  av_log(s, AV_LOG_ERROR, "PGC extraction not compatible with chapter or preindex options\n");
1579 
1580  return AVERROR(EINVAL);
1581  }
1582 
1583  if (!c->opt_pgc && (c->opt_chapter_end != 0 && c->opt_chapter_start > c->opt_chapter_end)) {
1584  av_log(s, AV_LOG_ERROR, "Chapter (PTT) range [%d, %d] is invalid\n",
1585  c->opt_chapter_start, c->opt_chapter_end);
1586 
1587  return AVERROR(EINVAL);
1588  }
1589 
1590  if (c->opt_title == 0) {
1591  av_log(s, AV_LOG_INFO, "Defaulting to title #1. "
1592  "This is not always the main feature, validation suggested.\n");
1593 
1594  c->opt_title = 1;
1595  }
1596 
1597  if ((ret = dvdvideo_ifo_open(s)) < 0)
1598  return ret;
1599 
1600  if (!c->opt_pgc && c->opt_preindex && (ret = dvdvideo_chapters_setup_preindex(s)) < 0)
1601  return ret;
1602 
1603  if ((ret = dvdvideo_play_open(s, &c->play_state)) < 0 ||
1604  (!c->opt_pgc && !c->opt_preindex && (ret = dvdvideo_chapters_setup_simple(s)) < 0) ||
1605  (ret = dvdvideo_video_stream_setup(s)) < 0 ||
1606  (ret = dvdvideo_audio_stream_add_all(s)) < 0 ||
1607  (ret = dvdvideo_subp_stream_add_all(s)) < 0 ||
1608  (ret = dvdvideo_subdemux_open(s)) < 0)
1609  return ret;
1610 
1611 end_ready:
1612  c->prev_pts = av_malloc(s->nb_streams * sizeof(int64_t));
1613  if (!c->prev_pts)
1614  return AVERROR(ENOMEM);
1615 
1616  for (int i = 0; i < s->nb_streams; i++)
1617  c->prev_pts[i] = AV_NOPTS_VALUE;
1618 
1619  return 0;
1620 }
1621 
1623 {
1624  DVDVideoDemuxContext *c = s->priv_data;
1625 
1626  int ret;
1627  int is_key = 0;
1628  int st_mapped = 0;
1629  AVStream *st_subdemux;
1630  uint8_t ac3_bitstream_id;
1631  uint16_t ac3_frame_size;
1632 
1633  ret = av_read_frame(c->mpeg_ctx, pkt);
1634  if (ret < 0) {
1635  if (c->subdemux_reset && ret == AVERROR_EOF) {
1636  c->subdemux_reset = 0;
1637  c->pts_offset = c->play_state.ptm_offset;
1638 
1639  if ((ret = dvdvideo_subdemux_reset(s)) < 0)
1640  return ret;
1641 
1642  return FFERROR_REDO;
1643  }
1644 
1645  return ret;
1646  }
1647 
1648  st_subdemux = c->mpeg_ctx->streams[pkt->stream_index];
1649  is_key = pkt->flags & AV_PKT_FLAG_KEY;
1650 
1651  /* map the subdemuxer stream to the parent demuxer's stream (by startcode) */
1652  for (int i = 0; i < s->nb_streams; i++) {
1653  if (s->streams[i]->id == st_subdemux->id) {
1654  pkt->stream_index = s->streams[i]->index;
1655  st_mapped = 1;
1656 
1657  break;
1658  }
1659  }
1660 
1661  if (!st_mapped || pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE)
1662  goto discard;
1663 
1664  if (!c->play_started) {
1665  /* try to start at the beginning of a GOP */
1666  if (st_subdemux->codecpar->codec_type != AVMEDIA_TYPE_VIDEO || !is_key)
1667  goto discard;
1668 
1669  c->first_pts = pkt->pts;
1670  c->play_started = 1;
1671  }
1672 
1673  pkt->pts += c->pts_offset - c->first_pts;
1674  pkt->dts += c->pts_offset - c->first_pts;
1675 
1676  if (pkt->pts < 0)
1677  goto discard;
1678 
1679  /* clean up after DVD muxers which end seamless PGs on duplicate or partial AC3 samples */
1680  if (st_subdemux->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
1681  st_subdemux->codecpar->codec_id == AV_CODEC_ID_AC3) {
1682 
1683  if (pkt->pts <= c->prev_pts[pkt->stream_index])
1684  goto discard;
1685 
1687  &ac3_bitstream_id, &ac3_frame_size);
1688 
1689  if (ret < 0 || pkt->size != ac3_frame_size)
1690  goto discard;
1691  }
1692 
1693  av_log(s, AV_LOG_TRACE, "st=%d pts=%" PRId64 " dts=%" PRId64 " "
1694  "pts_offset=%" PRId64 " first_pts=%" PRId64 "\n",
1695  pkt->stream_index, pkt->pts, pkt->dts,
1696  c->pts_offset, c->first_pts);
1697 
1698  c->prev_pts[pkt->stream_index] = pkt->pts;
1699 
1700  return 0;
1701 
1702 discard:
1703  av_log(s, st_mapped ? AV_LOG_VERBOSE : AV_LOG_DEBUG,
1704  "Discarding frame @ st=%d pts=%" PRId64 " dts=%" PRId64 " is_key=%d st_mapped=%d\n",
1705  st_mapped ? pkt->stream_index : -1, pkt->pts, pkt->dts, is_key, st_mapped);
1706 
1707  if (st_mapped)
1708  c->prev_pts[pkt->stream_index] = pkt->pts;
1709 
1710  return FFERROR_REDO;
1711 }
1712 
1714 {
1715  DVDVideoDemuxContext *c = s->priv_data;
1716 
1718 
1719  if (c->opt_menu)
1720  dvdvideo_menu_close(s, &c->play_state);
1721  else
1722  dvdvideo_play_close(s, &c->play_state);
1723 
1725 
1726  if (c->prev_pts)
1727  av_freep(&c->prev_pts);
1728 
1729  return 0;
1730 }
1731 
1732 static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
1733 {
1734  DVDVideoDemuxContext *c = s->priv_data;
1735  int ret;
1736  int64_t new_nav_pts;
1737  pci_t* new_nav_pci;
1738  dsi_t* new_nav_dsi;
1739 
1740  if (c->opt_menu || c->opt_chapter_start > 1) {
1741  av_log(s, AV_LOG_ERROR, "Seeking is not compatible with menus or chapter extraction\n");
1742 
1743  return AVERROR_PATCHWELCOME;
1744  }
1745 
1746  if ((flags & AVSEEK_FLAG_BYTE))
1747  return AVERROR(ENOSYS);
1748 
1749  if (timestamp < 0 || timestamp > s->duration)
1750  return AVERROR(EINVAL);
1751 
1752  if (!c->seek_warned) {
1753  av_log(s, AV_LOG_WARNING, "Seeking is inherently unreliable and will result "
1754  "in imprecise timecodes from this point\n");
1755  c->seek_warned = 1;
1756  }
1757 
1758  /* XXX(PATCHWELCOME): use dvdnav_jump_to_sector_by_time(c->play_state.dvdnav, timestamp, 0)
1759  * when it is available in a released version of libdvdnav; it is more accurate */
1760  if (dvdnav_time_search(c->play_state.dvdnav, timestamp) != DVDNAV_STATUS_OK) {
1761  av_log(s, AV_LOG_ERROR, "libdvdnav: seeking to %" PRId64 " failed\n", timestamp);
1762 
1763  return AVERROR_EXTERNAL;
1764  }
1765 
1766  new_nav_pts = dvdnav_get_current_time (c->play_state.dvdnav);
1767  new_nav_pci = dvdnav_get_current_nav_pci(c->play_state.dvdnav);
1768  new_nav_dsi = dvdnav_get_current_nav_dsi(c->play_state.dvdnav);
1769 
1770  if (new_nav_pci == NULL || new_nav_dsi == NULL) {
1771  av_log(s, AV_LOG_ERROR, "Invalid NAV packet after seeking\n");
1772 
1773  return AVERROR_INVALIDDATA;
1774  }
1775 
1776  c->play_state.in_pgc = 1;
1777  c->play_state.in_ps = 0;
1778  c->play_state.is_seeking = 1;
1779  c->play_state.nav_pts = timestamp;
1780  c->play_state.ptm_offset = timestamp;
1781  c->play_state.ptm_discont = 0;
1782  c->play_state.vobu_e_ptm = new_nav_pci->pci_gi.vobu_s_ptm;
1783 
1784  c->first_pts = 0;
1785  c->play_started = 0;
1786  c->pts_offset = timestamp;
1787  c->subdemux_reset = 0;
1788 
1789  if ((ret = dvdvideo_subdemux_reset(s)) < 0)
1790  return ret;
1791 
1792  av_log(s, AV_LOG_DEBUG, "seeking: requested_nav_pts=%" PRId64 " new_nav_pts=%" PRId64 "\n",
1793  timestamp, new_nav_pts);
1794 
1795  return 0;
1796 }
1797 
1798 #define OFFSET(x) offsetof(DVDVideoDemuxContext, x)
1799 static const AVOption dvdvideo_options[] = {
1800  {"angle", "playback angle number", OFFSET(opt_angle), AV_OPT_TYPE_INT, { .i64=1 }, 1, 9, AV_OPT_FLAG_DECODING_PARAM },
1801  {"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 },
1802  {"chapter_start", "entry chapter (PTT) number", OFFSET(opt_chapter_start), AV_OPT_TYPE_INT, { .i64=1 }, 1, 99, AV_OPT_FLAG_DECODING_PARAM },
1803  {"menu", "demux menu domain", OFFSET(opt_menu), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
1804  {"menu_lu", "menu language unit", OFFSET(opt_menu_lu), AV_OPT_TYPE_INT, { .i64=1 }, 1, 99, AV_OPT_FLAG_DECODING_PARAM },
1805  {"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 },
1806  {"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 },
1807  {"pgc", "entry PGC number (0=auto)", OFFSET(opt_pgc), AV_OPT_TYPE_INT, { .i64=0 }, 0, 999, AV_OPT_FLAG_DECODING_PARAM },
1808  {"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 },
1809  {"region", "playback region number (0=free)", OFFSET(opt_region), AV_OPT_TYPE_INT, { .i64=0 }, 0, 8, AV_OPT_FLAG_DECODING_PARAM },
1810  {"title", "title number (0=auto)", OFFSET(opt_title), AV_OPT_TYPE_INT, { .i64=0 }, 0, 99, AV_OPT_FLAG_DECODING_PARAM },
1811  {"trim", "trim padding cells from start", OFFSET(opt_trim), AV_OPT_TYPE_BOOL, { .i64=1 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
1812  {NULL}
1813 };
1814 
1815 static const AVClass dvdvideo_class = {
1816  .class_name = "DVD-Video demuxer",
1817  .item_name = av_default_item_name,
1818  .option = dvdvideo_options,
1819  .version = LIBAVUTIL_VERSION_INT
1820 };
1821 
1823  .p.name = "dvdvideo",
1824  .p.long_name = NULL_IF_CONFIG_SMALL("DVD-Video"),
1825  .p.priv_class = &dvdvideo_class,
1828  .priv_data_size = sizeof(DVDVideoDemuxContext),
1829  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
1834 };
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
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:1297
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
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:487
level
uint8_t level
Definition: svq3.c:205
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:450
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:477
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:394
DVDVideoPGCAudioStreamEntry::ch_layout
AVChannelLayout ch_layout
Definition: dvdvideodec.c:93
dvdvideo_is_pgc_promising
static int dvdvideo_is_pgc_promising(AVFormatContext *s, pgc_t *pgc)
Definition: dvdvideodec.c:311
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:515
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:264
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:1113
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:501
OFFSET
#define OFFSET(x)
Definition: dvdvideodec.c:1798
AVOption
AVOption.
Definition: opt.h:429
DVDVideoPlaybackState::celln
int celln
Definition: dvdvideodec.c:107
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:837
AVFMT_FLAG_CUSTOM_IO
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition: avformat.h:1459
DVDVideoPlaybackState::vtsn
int vtsn
Definition: dvdvideodec.c:124
AVSEEK_FLAG_BYTE
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:2499
DVDVideoVTSVideoStreamEntry::has_cc
int has_cc
Definition: dvdvideodec.c:83
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
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:91
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:1547
AVFMT_NOBINSEARCH
#define AVFMT_NOBINSEARCH
Format does not allow to fall back on binary search via read_timestamp.
Definition: avformat.h:485
DVDVideoDemuxContext::first_pts
int64_t first_pts
Definition: dvdvideodec.c:167
DVDVideoPlaybackState::in_vts
int in_vts
Definition: dvdvideodec.c:111
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:328
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:594
DVDVideoPGCSubtitleStreamEntry::lang_iso
const char * lang_iso
Definition: dvdvideodec.c:103
DVDVideoPlaybackState::in_ps
int in_ps
Definition: dvdvideodec.c:110
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:273
DVDVideoPlaybackState::ptm_discont
int ptm_discont
Definition: dvdvideodec.c:119
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
DVDVideoPGCSubtitleStreamEntry::disposition
int disposition
Definition: dvdvideodec.c:101
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:225
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:395
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:366
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:867
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:1451
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:358
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:503
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:654
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:854
DVDVideoVTSVideoStreamEntry::dar
AVRational dar
Definition: dvdvideodec.c:81
DVDVideoPGCAudioStreamEntry::sample_fmt
int sample_fmt
Definition: dvdvideodec.c:89
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:235
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:209
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:216
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:87
DVDVideoPlaybackState::dvdnav
dvdnav_t * dvdnav
Definition: dvdvideodec.c:127
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:416
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:1007
dvdvideo_video_stream_setup
static int dvdvideo_video_stream_setup(AVFormatContext *s)
Definition: dvdvideodec.c:1089
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:553
dvdvideo_chapters_setup_simple
static int dvdvideo_chapters_setup_simple(AVFormatContext *s)
Definition: dvdvideodec.c:869
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:447
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:176
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:1544
dvdclut.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
DVDVideoPGCSubtitleStreamEntry
Definition: dvdvideodec.c:98
DVDVideoPlaybackState::ptt
int ptt
Definition: dvdvideodec.c:121
nb_streams
static int nb_streams
Definition: ffprobe.c:385
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:307
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:353
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:915
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:325
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
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:522
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
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
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:540
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
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:1815
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:1253
state
static struct @466 state
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:912
DVDVideoPlaybackState::pgn
int pgn
Definition: dvdvideodec.c:118
dvdvideo_read_packet
static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dvdvideodec.c:1622
DVDVideoDemuxContext::prev_pts
int64_t * prev_pts
Definition: dvdvideodec.c:170
AV_DISPOSITION_COMMENT
#define AV_DISPOSITION_COMMENT
The stream is a commentary track.
Definition: avformat.h:639
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:557
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
DVDVideoDemuxContext::seek_warned
int seek_warned
Definition: dvdvideodec.c:172
DVDVideoDemuxContext::subdemux_reset
int subdemux_reset
Definition: dvdvideodec.c:173
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:828
dvdvideo_close
static int dvdvideo_close(AVFormatContext *s)
Definition: dvdvideodec.c:1713
DVDVideoPGCAudioStreamEntry::disposition
int disposition
Definition: dvdvideodec.c:94
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:193
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:1489
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:1249
dvdvideo_menu_close
static void dvdvideo_menu_close(AVFormatContext *s, DVDVideoPlaybackState *state)
Definition: dvdvideodec.c:320
DVDVideoDemuxContext::play_state
DVDVideoPlaybackState play_state
Definition: dvdvideodec.c:169
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:113
dvdvideo_subp_stream_add
static int dvdvideo_subp_stream_add(AVFormatContext *s, DVDVideoPGCSubtitleStreamEntry *entry)
Definition: dvdvideodec.c:1324
DVDVideoPGCSubtitleStreamEntry::clut
uint32_t clut[FF_DVDCLUT_CLUT_LEN]
Definition: dvdvideodec.c:102
AVPacket::size
int size
Definition: packet.h:540
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:88
height
#define height
Definition: dsp.h:85
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:318
FFStream
Definition: internal.h:132
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:451
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:99
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
DVDVideoPGCSubtitleStreamEntry::viewport
enum DVDVideoSubpictureViewport viewport
Definition: dvdvideodec.c:100
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:538
dvdvideo_ifo_close
static void dvdvideo_ifo_close(AVFormatContext *s)
Definition: dvdvideodec.c:211
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:545
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:171
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
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:112
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:532
dvdvideo_menu_open
static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state)
Definition: dvdvideodec.c:326
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:108
vsnprintf
#define vsnprintf
Definition: snprintf.h:36
AV_DISPOSITION_KARAOKE
#define AV_DISPOSITION_KARAOKE
The stream contains karaoke audio.
Definition: avformat.h:647
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:109
ff_dvdvideo_demuxer
const FFInputFormat ff_dvdvideo_demuxer
Definition: dvdvideodec.c:1822
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:700
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:304
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:817
AVFMT_FLAG_GENPTS
#define AVFMT_FLAG_GENPTS
Generate missing pts even if it requires parsing future frames.
Definition: avformat.h:1452
AV_DISPOSITION_VISUAL_IMPAIRED
#define AV_DISPOSITION_VISUAL_IMPAIRED
The stream is intended for visually impaired audiences.
Definition: avformat.h:662
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:760
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
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:80
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:594
avformat.h
PCI_START_BYTE
#define PCI_START_BYTE
Definition: dvdvideodec.c:63
dvdvideo_options
static const AVOption dvdvideo_options[]
Definition: dvdvideodec.c:1799
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:149
AVFMT_NOGENSEARCH
#define AVFMT_NOGENSEARCH
Format does not allow to fall back on generic search.
Definition: avformat.h:486
ff_mpegps_demuxer
const FFInputFormat ff_mpegps_demuxer
Definition: mpeg.c:701
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:914
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:619
AVPacket::stream_index
int stream_index
Definition: packet.h:541
dvdvideo_read_seek
static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: dvdvideodec.c:1732
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:201
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:481
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:1497
DVDVideoPGCAudioStreamEntry::nb_channels
int nb_channels
Definition: dvdvideodec.c:92
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:393
FFStream::request_probe
int request_probe
stream probing state -1 -> probing finished 0 -> no probing requested rest -> perform probing with re...
Definition: internal.h:202
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:516
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:1056
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:88
FFInputFormat
Definition: demux.h:42
dvdvideo_subp_stream_add_all
static int dvdvideo_subp_stream_add_all(AVFormatContext *s)
Definition: dvdvideodec.c:1385
int32_t
int32_t
Definition: audioconvert.c:56
DVDVIDEO_SUBP_VIEWPORT_WIDESCREEN
@ DVDVIDEO_SUBP_VIEWPORT_WIDESCREEN
Definition: dvdvideodec.c:68
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_CHANNEL_LAYOUT_6POINT1
#define AV_CHANNEL_LAYOUT_6POINT1
Definition: channel_layout.h:411
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
DVDVideoPGCAudioStreamEntry::sample_rate
int sample_rate
Definition: dvdvideodec.c:90
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:1358
DVDVideoPGCAudioStreamEntry
Definition: dvdvideodec.c:86
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:85
AV_CHANNEL_LAYOUT_5POINT1
#define AV_CHANNEL_LAYOUT_5POINT1
Definition: channel_layout.h:404
dvdvideo_subdemux_reset
static int dvdvideo_subdemux_reset(AVFormatContext *s)
Definition: dvdvideodec.c:1531
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:489
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:1216
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:95
DVDVideoPlaybackState
Definition: dvdvideodec.c:106
DVDVideoDemuxContext::play_started
int play_started
Definition: dvdvideodec.c:168