FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dvd_nav_parser.c
Go to the documentation of this file.
1 /*
2  * DVD navigation block parser for FFmpeg
3  * Copyright (c) 2013 The FFmpeg Project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #include "avcodec.h"
22 #include "dsputil.h"
23 #include "get_bits.h"
24 #include "parser.h"
25 
26 #define PCI_SIZE 980
27 #define DSI_SIZE 1018
28 
29 /* parser definition */
30 typedef struct DVDNavParseContext {
31  uint32_t lba;
33  int copied;
35 
37 {
39 
40  pc->lba = 0xFFFFFFFF;
41  pc->copied = 0;
42  return 0;
43 }
44 
46  AVCodecContext *avctx,
47  const uint8_t **poutbuf, int *poutbuf_size,
48  const uint8_t *buf, int buf_size)
49 {
50  DVDNavParseContext *pc1 = s->priv_data;
51  int lastPacket = 0;
52  int valid = 0;
53 
55 
56  avctx->time_base.num = 1;
57  avctx->time_base.den = 90000;
58 
59  if (buf && buf_size) {
60  switch(buf[0]) {
61  case 0x00:
62  if (buf_size == PCI_SIZE) {
63  /* PCI */
64  uint32_t lba = AV_RB32(&buf[0x01]);
65  uint32_t startpts = AV_RB32(&buf[0x0D]);
66  uint32_t endpts = AV_RB32(&buf[0x11]);
67 
68  if (endpts > startpts) {
69  pc1->lba = lba;
70  s->pts = (int64_t)startpts;
71  s->duration = endpts - startpts;
72 
73  memcpy(pc1->buffer, buf, PCI_SIZE);
74  pc1->copied = PCI_SIZE;
75  valid = 1;
76  }
77  }
78  break;
79 
80  case 0x01:
81  if ((buf_size == DSI_SIZE) && (pc1->copied == PCI_SIZE)) {
82  /* DSI */
83  uint32_t lba = AV_RB32(&buf[0x05]);
84 
85  if (lba == pc1->lba) {
86  memcpy(pc1->buffer + pc1->copied, buf, DSI_SIZE);
87  lastPacket = 1;
88  valid = 1;
89  }
90  }
91  break;
92  }
93  }
94 
95  if (!valid || lastPacket) {
96  pc1->copied = 0;
97  pc1->lba = 0xFFFFFFFF;
98  }
99 
100  if (lastPacket) {
101  *poutbuf = pc1->buffer;
102  *poutbuf_size = sizeof(pc1->buffer);
103  } else {
104  *poutbuf = NULL;
105  *poutbuf_size = 0;
106  }
107 
108  return buf_size;
109 }
110 
113  .priv_data_size = sizeof(DVDNavParseContext),
114  .parser_init = dvd_nav_parse_init,
115  .parser_parse = dvd_nav_parse,
116 };