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