1 |
|
|
/* |
2 |
|
|
* MQ-coder encoder |
3 |
|
|
* Copyright (c) 2007 Kamil Nowosad |
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 |
|
|
|
22 |
|
|
/** |
23 |
|
|
* MQ-coder encoder |
24 |
|
|
* @file |
25 |
|
|
* @author Kamil Nowosad |
26 |
|
|
*/ |
27 |
|
|
|
28 |
|
|
#include "libavutil/avassert.h" |
29 |
|
|
#include "mqc.h" |
30 |
|
|
|
31 |
|
72808564 |
static void byteout(MqcState *mqc) |
32 |
|
|
{ |
33 |
|
72808564 |
retry: |
34 |
✓✓ |
72808564 |
if (*mqc->bp == 0xff){ |
35 |
|
427677 |
mqc->bp++; |
36 |
|
427677 |
*mqc->bp = mqc->c >> 20; |
37 |
|
427677 |
mqc->c &= 0xfffff; |
38 |
|
427677 |
mqc->ct = 7; |
39 |
✓✓ |
72380887 |
} else if ((mqc->c & 0x8000000)){ |
40 |
|
2121958 |
(*mqc->bp)++; |
41 |
|
2121958 |
mqc->c &= 0x7ffffff; |
42 |
|
2121958 |
goto retry; |
43 |
|
|
} else{ |
44 |
|
70258929 |
mqc->bp++; |
45 |
|
70258929 |
*mqc->bp = mqc->c >> 19; |
46 |
|
70258929 |
mqc->c &= 0x7ffff; |
47 |
|
70258929 |
mqc->ct = 8; |
48 |
|
|
} |
49 |
|
70686606 |
} |
50 |
|
|
|
51 |
|
442748377 |
static void renorme(MqcState *mqc) |
52 |
|
|
{ |
53 |
|
|
do{ |
54 |
|
442748377 |
mqc->a += mqc->a; |
55 |
|
442748377 |
mqc->c += mqc->c; |
56 |
✓✓ |
442748377 |
if (!--mqc->ct) |
57 |
|
54983056 |
byteout(mqc); |
58 |
✓✓ |
442748377 |
} while (!(mqc->a & 0x8000)); |
59 |
|
331695661 |
} |
60 |
|
|
|
61 |
|
7851775 |
static void setbits(MqcState *mqc) |
62 |
|
|
{ |
63 |
|
7851775 |
int tmp = mqc->c + mqc->a; |
64 |
|
7851775 |
mqc->c |= 0xffff; |
65 |
✓✓ |
7851775 |
if (mqc->c >= tmp) |
66 |
|
2181134 |
mqc->c -= 0x8000; |
67 |
|
7851775 |
} |
68 |
|
|
|
69 |
|
413400 |
void ff_mqc_initenc(MqcState *mqc, uint8_t *bp) |
70 |
|
|
{ |
71 |
|
413400 |
ff_mqc_init_contexts(mqc); |
72 |
|
413400 |
mqc->a = 0x8000; |
73 |
|
413400 |
mqc->c = 0; |
74 |
|
413400 |
mqc->bp = bp-1; |
75 |
|
413400 |
mqc->bpstart = bp; |
76 |
✗✓ |
413400 |
mqc->ct = 12 + (*mqc->bp == 0xff); |
77 |
|
413400 |
} |
78 |
|
|
|
79 |
|
538704935 |
void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d) |
80 |
|
|
{ |
81 |
|
|
int qe; |
82 |
|
|
|
83 |
|
538704935 |
qe = ff_mqc_qe[*cxstate]; |
84 |
|
538704935 |
mqc->a -= qe; |
85 |
✓✓ |
538704935 |
if ((*cxstate & 1) == d){ |
86 |
✓✓ |
369558361 |
if (!(mqc->a & 0x8000)){ |
87 |
✓✓ |
162549087 |
if (mqc->a < qe) |
88 |
|
39555258 |
mqc->a = qe; |
89 |
|
|
else |
90 |
|
122993829 |
mqc->c += qe; |
91 |
|
162549087 |
*cxstate = ff_mqc_nmps[*cxstate]; |
92 |
|
162549087 |
renorme(mqc); |
93 |
|
|
} else |
94 |
|
207009274 |
mqc->c += qe; |
95 |
|
|
} else{ |
96 |
✓✓ |
169146574 |
if (mqc->a < qe) |
97 |
|
34367689 |
mqc->c += qe; |
98 |
|
|
else |
99 |
|
134778885 |
mqc->a = qe; |
100 |
|
169146574 |
*cxstate = ff_mqc_nlps[*cxstate]; |
101 |
|
169146574 |
renorme(mqc); |
102 |
|
|
} |
103 |
|
538704935 |
} |
104 |
|
|
|
105 |
|
|
int ff_mqc_length(MqcState *mqc) |
106 |
|
|
{ |
107 |
|
|
return mqc->bp - mqc->bpstart; |
108 |
|
|
} |
109 |
|
|
|
110 |
|
7851775 |
int ff_mqc_flush(MqcState *mqc) |
111 |
|
|
{ |
112 |
|
7851775 |
setbits(mqc); |
113 |
|
7851775 |
mqc->c = mqc->c << mqc->ct; |
114 |
|
7851775 |
byteout(mqc); |
115 |
|
7851775 |
mqc->c = mqc->c << mqc->ct; |
116 |
|
7851775 |
byteout(mqc); |
117 |
✓✓ |
7851775 |
if (*mqc->bp != 0xff) |
118 |
|
1873969 |
mqc->bp++; |
119 |
|
7851775 |
return mqc->bp - mqc->bpstart; |
120 |
|
|
} |
121 |
|
|
|
122 |
|
7851775 |
int ff_mqc_flush_to(MqcState *mqc, uint8_t *dst, int *dst_len) |
123 |
|
|
{ |
124 |
|
7851775 |
MqcState mqc2 = *mqc; |
125 |
|
7851775 |
mqc2.bpstart= |
126 |
|
7851775 |
mqc2.bp = dst; |
127 |
|
7851775 |
*mqc2.bp = *mqc->bp; |
128 |
|
7851775 |
ff_mqc_flush(&mqc2); |
129 |
|
7851775 |
*dst_len = mqc2.bp - dst; |
130 |
✓✓ |
7851775 |
if (mqc->bp < mqc->bpstart) { |
131 |
|
|
av_assert1(mqc->bpstart - mqc->bp == 1); |
132 |
|
|
av_assert1(*dst_len > 0); |
133 |
|
|
av_assert1(mqc->bp[0] == 0 && dst[0] == 0); |
134 |
|
79777 |
(*dst_len) --; |
135 |
|
79777 |
memmove(dst, dst+1, *dst_len); |
136 |
|
79777 |
return mqc->bp - mqc->bpstart + 1 + *dst_len; |
137 |
|
|
} |
138 |
|
7771998 |
return mqc->bp - mqc->bpstart + *dst_len; |
139 |
|
|
} |