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