Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
wnv1.c
Go to the documentation of this file.
1
/*
2
* Winnov WNV1 codec
3
* Copyright (c) 2005 Konstantin Shishkov
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
27
#include "
avcodec.h
"
28
#include "
get_bits.h
"
29
#include "
internal.h
"
30
#include "
mathops.h
"
31
32
33
typedef
struct
WNV1Context
{
34
AVCodecContext
*
avctx
;
35
36
int
shift
;
37
GetBitContext
gb
;
38
}
WNV1Context
;
39
40
static
const
uint16_t
code_tab
[16][2] = {
41
{ 0x1FD, 9 }, { 0xFD, 8 }, { 0x7D, 7 }, { 0x3D, 6 }, { 0x1D, 5 }, { 0x0D, 4 }, { 0x005, 3 },
42
{ 0x000, 1 },
43
{ 0x004, 3 }, { 0x0C, 4 }, { 0x1C, 5 }, { 0x3C, 6 }, { 0x7C, 7 }, { 0xFC, 8 }, { 0x1FC, 9 }, { 0xFF, 8 }
44
};
45
46
#define CODE_VLC_BITS 9
47
static
VLC
code_vlc
;
48
49
/* returns modified base_value */
50
static
inline
int
wnv1_get_code
(
WNV1Context
*w,
int
base_value)
51
{
52
int
v =
get_vlc2
(&w->
gb
, code_vlc.
table
,
CODE_VLC_BITS
, 1);
53
54
if
(v == 15)
55
return
ff_reverse
[
get_bits
(&w->
gb
, 8 - w->
shift
)];
56
else
57
return
base_value + ((v - 7) << w->
shift
);
58
}
59
60
static
int
decode_frame
(
AVCodecContext
*avctx,
61
void
*
data
,
int
*got_frame,
62
AVPacket
*avpkt)
63
{
64
WNV1Context
*
const
l = avctx->
priv_data
;
65
const
uint8_t
*buf = avpkt->
data
;
66
int
buf_size = avpkt->
size
;
67
AVFrame
*
const
p =
data
;
68
unsigned
char
*
Y
,*
U
,*
V
;
69
int
i, j, ret;
70
int
prev_y = 0, prev_u = 0, prev_v = 0;
71
uint8_t
*rbuf;
72
73
if
(buf_size < 8) {
74
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too short\n"
);
75
return
AVERROR_INVALIDDATA
;
76
}
77
78
rbuf =
av_malloc
(buf_size +
FF_INPUT_BUFFER_PADDING_SIZE
);
79
if
(!rbuf) {
80
av_log
(avctx,
AV_LOG_ERROR
,
"Cannot allocate temporary buffer\n"
);
81
return
AVERROR
(ENOMEM);
82
}
83
84
if
((ret =
ff_get_buffer
(avctx, p, 0)) < 0) {
85
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
86
av_free
(rbuf);
87
return
ret;
88
}
89
p->
key_frame
= 1;
90
91
for
(i = 8; i < buf_size; i++)
92
rbuf[i] =
ff_reverse
[buf[i]];
93
init_get_bits
(&l->
gb
, rbuf + 8, (buf_size - 8) * 8);
94
95
if
(buf[2] >> 4 == 6)
96
l->
shift
= 2;
97
else
{
98
l->
shift
= 8 - (buf[2] >> 4);
99
if
(l->
shift
> 4) {
100
avpriv_request_sample
(avctx,
101
"Unknown WNV1 frame header value %i"
,
102
buf[2] >> 4);
103
l->
shift
= 4;
104
}
105
if
(l->
shift
< 1) {
106
avpriv_request_sample
(avctx,
107
"Unknown WNV1 frame header value %i"
,
108
buf[2] >> 4);
109
l->
shift
= 1;
110
}
111
}
112
113
Y = p->
data
[0];
114
U = p->
data
[1];
115
V = p->
data
[2];
116
for
(j = 0; j < avctx->
height
; j++) {
117
for
(i = 0; i < avctx->
width
/ 2; i++) {
118
Y[i * 2] =
wnv1_get_code
(l, prev_y);
119
prev_u = U[i] =
wnv1_get_code
(l, prev_u);
120
prev_y = Y[(i * 2) + 1] =
wnv1_get_code
(l, Y[i * 2]);
121
prev_v = V[i] =
wnv1_get_code
(l, prev_v);
122
}
123
Y += p->
linesize
[0];
124
U += p->
linesize
[1];
125
V += p->
linesize
[2];
126
}
127
128
129
*got_frame = 1;
130
av_free
(rbuf);
131
132
return
buf_size;
133
}
134
135
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
136
{
137
WNV1Context
*
const
l = avctx->
priv_data
;
138
static
VLC_TYPE
code_table[1 <<
CODE_VLC_BITS
][2];
139
140
l->
avctx
= avctx;
141
avctx->
pix_fmt
=
AV_PIX_FMT_YUV422P
;
142
143
code_vlc.
table
= code_table;
144
code_vlc.
table_allocated
= 1 <<
CODE_VLC_BITS
;
145
init_vlc
(&code_vlc,
CODE_VLC_BITS
, 16,
146
&
code_tab
[0][1], 4, 2,
147
&
code_tab
[0][0], 4, 2,
INIT_VLC_USE_NEW_STATIC
);
148
149
return
0;
150
}
151
152
AVCodec
ff_wnv1_decoder
= {
153
.
name
=
"wnv1"
,
154
.long_name =
NULL_IF_CONFIG_SMALL
(
"Winnov WNV1"
),
155
.type =
AVMEDIA_TYPE_VIDEO
,
156
.id =
AV_CODEC_ID_WNV1
,
157
.priv_data_size =
sizeof
(
WNV1Context
),
158
.
init
=
decode_init
,
159
.
decode
=
decode_frame
,
160
.capabilities =
CODEC_CAP_DR1
,
161
};
Generated on Thu Sep 30 2021 23:03:17 for Libav by
1.8.1.2