summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/VC1BitstreamParser.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
committermanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
commitbe933ef2241d79558f91796cc5b3a161f72ebf9c (patch)
treefe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/utils/VC1BitstreamParser.cpp
parent5f8335c1e49ce108ef3481863833c98efa00411b (diff)
downloadkodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.gz
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.bz2
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.zip
sync with upstream
Diffstat (limited to 'xbmc/utils/VC1BitstreamParser.cpp')
-rw-r--r--xbmc/utils/VC1BitstreamParser.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/xbmc/utils/VC1BitstreamParser.cpp b/xbmc/utils/VC1BitstreamParser.cpp
new file mode 100644
index 0000000..8ac1b6e
--- /dev/null
+++ b/xbmc/utils/VC1BitstreamParser.cpp
@@ -0,0 +1,149 @@
1/*
2 * Copyright (C) 2017-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "VC1BitstreamParser.h"
10
11#include "BitstreamReader.h"
12
13enum
14{
15 VC1_PROFILE_SIMPLE,
16 VC1_PROFILE_MAIN,
17 VC1_PROFILE_RESERVED,
18 VC1_PROFILE_ADVANCED,
19 VC1_PROFILE_NOPROFILE
20};
21
22enum
23{
24 VC1_END_OF_SEQ = 0x0A,
25 VC1_SLICE = 0x0B,
26 VC1_FIELD = 0x0C,
27 VC1_FRAME = 0x0D,
28 VC1_ENTRYPOINT = 0x0E,
29 VC1_SEQUENCE = 0x0F,
30 VC1_SLICE_USER = 0x1B,
31 VC1_FIELD_USER = 0x1C,
32 VC1_FRAME_USER = 0x1D,
33 VC1_ENTRY_POINT_USER = 0x1E,
34 VC1_SEQUENCE_USER = 0x1F
35};
36
37enum
38{
39 VC1_FRAME_PROGRESSIVE = 0x0,
40 VC1_FRAME_INTERLACE = 0x10,
41 VC1_FIELD_INTERLACE = 0x11
42};
43
44CVC1BitstreamParser::CVC1BitstreamParser()
45{
46 Reset();
47}
48
49void CVC1BitstreamParser::Reset()
50{
51 m_Profile = VC1_PROFILE_NOPROFILE;
52}
53
54bool CVC1BitstreamParser::IsRecoveryPoint(const uint8_t *buf, int buf_size)
55{
56 return vc1_parse_frame(buf, buf + buf_size, true);
57};
58
59bool CVC1BitstreamParser::IsIFrame(const uint8_t *buf, int buf_size)
60{
61 return vc1_parse_frame(buf, buf + buf_size, false);
62};
63
64bool CVC1BitstreamParser::vc1_parse_frame(const uint8_t *buf, const uint8_t *buf_end, bool sequence_only)
65{
66 uint32_t state = -1;
67 for (;;)
68 {
69 buf = find_start_code(buf, buf_end, &state);
70 if (buf >= buf_end)
71 break;
72 if (buf[-1] == VC1_SEQUENCE)
73 {
74 if (m_Profile != VC1_PROFILE_NOPROFILE)
75 return false;
76 CBitstreamReader br(buf, buf_end - buf);
77 // Read the profile
78 m_Profile = static_cast<uint8_t>(br.ReadBits(2));
79 if (m_Profile == VC1_PROFILE_ADVANCED)
80 {
81 br.SkipBits(39);
82 m_AdvInterlace = br.ReadBits(1);
83 }
84 else
85 {
86 br.SkipBits(22);
87
88 m_SimpleSkipBits = 2;
89 if (br.ReadBits(1)) //rangered
90 ++m_SimpleSkipBits;
91
92 m_MaxBFrames = br.ReadBits(3);
93
94 br.SkipBits(2); // quantizer
95 if (br.ReadBits(1)) //finterpflag
96 ++m_SimpleSkipBits;
97 }
98 if (sequence_only)
99 return true;
100 }
101 else if (buf[-1] == VC1_FRAME)
102 {
103 CBitstreamReader br(buf, buf_end - buf);
104
105 if (sequence_only)
106 return false;
107 if (m_Profile == VC1_PROFILE_ADVANCED)
108 {
109 uint8_t fcm;
110 if (m_AdvInterlace) {
111 fcm = br.ReadBits(1);
112 if (fcm)
113 fcm = br.ReadBits(1) + 1;
114 }
115 else
116 fcm = VC1_FRAME_PROGRESSIVE;
117 if (fcm == VC1_FIELD_INTERLACE) {
118 uint8_t pic = br.ReadBits(3);
119 return pic == 0x00 || pic == 0x01;
120 }
121 else
122 {
123 uint8_t pic(0);
124 while (pic < 4 && br.ReadBits(1))++pic;
125 return pic == 2;
126 }
127 return false;
128 }
129 else if (m_Profile != VC1_PROFILE_NOPROFILE)
130 {
131 br.SkipBits(m_SimpleSkipBits); // quantizer
132 uint8_t pic(br.ReadBits(1));
133 if (m_MaxBFrames) {
134 if (!pic) {
135 pic = br.ReadBits(1);
136 return pic != 0;
137 }
138 else
139 return false;
140 }
141 else
142 return pic != 0;
143 }
144 else
145 break;
146 }
147 }
148 return false;
149}