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