FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 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
* @file
24
* Winnov WNV1 codec.
25
*/
26
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
AVFrame
pic
;
36
37
int
shift
;
38
GetBitContext
gb
;
39
}
WNV1Context
;
40
41
static
const
uint16_t
code_tab
[16][2] = {
42
{ 0x1FD, 9 }, { 0xFD, 8 }, { 0x7D, 7 }, { 0x3D, 6 }, { 0x1D, 5 }, { 0x0D, 4 }, { 0x005, 3 },
43
{ 0x000, 1 },
44
{ 0x004, 3 }, { 0x0C, 4 }, { 0x1C, 5 }, { 0x3C, 6 }, { 0x7C, 7 }, { 0xFC, 8 }, { 0x1FC, 9 }, { 0xFF, 8 }
45
};
46
47
#define CODE_VLC_BITS 9
48
static
VLC
code_vlc
;
49
50
/* returns modified base_value */
51
static
inline
int
wnv1_get_code
(
WNV1Context
*w,
int
base_value)
52
{
53
int
v =
get_vlc2
(&w->
gb
, code_vlc.
table
,
CODE_VLC_BITS
, 1);
54
55
if
(v == 15)
56
return
ff_reverse
[
get_bits
(&w->
gb
, 8 - w->
shift
)];
57
else
58
return
base_value + ((v - 7) << w->
shift
);
59
}
60
61
static
int
decode_frame
(
AVCodecContext
*avctx,
62
void
*
data
,
int
*got_frame,
63
AVPacket
*avpkt)
64
{
65
WNV1Context
*
const
l = avctx->
priv_data
;
66
const
uint8_t
*buf = avpkt->
data
;
67
int
buf_size = avpkt->
size
;
68
AVFrame
*
const
p = &l->
pic
;
69
unsigned
char
*
Y
,*
U
,*
V
;
70
int
i, j, ret;
71
int
prev_y = 0, prev_u = 0, prev_v = 0;
72
uint8_t
*rbuf;
73
74
if
(buf_size<=8) {
75
av_log
(avctx,
AV_LOG_ERROR
,
"buf_size %d is too small\n"
, buf_size);
76
return
AVERROR_INVALIDDATA
;
77
}
78
79
rbuf =
av_malloc
(buf_size +
FF_INPUT_BUFFER_PADDING_SIZE
);
80
if
(!rbuf) {
81
av_log
(avctx,
AV_LOG_ERROR
,
"Cannot allocate temporary buffer\n"
);
82
return
AVERROR
(ENOMEM);
83
}
84
85
if
(p->
data
[0])
86
avctx->
release_buffer
(avctx, p);
87
88
p->
reference
= 0;
89
if
((ret =
ff_get_buffer
(avctx, p)) < 0) {
90
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
91
av_free
(rbuf);
92
return
ret;
93
}
94
p->
key_frame
= 1;
95
96
for
(i = 8; i < buf_size; i++)
97
rbuf[i] =
ff_reverse
[buf[i]];
98
init_get_bits
(&l->
gb
, rbuf + 8, (buf_size - 8) * 8);
99
100
if
(buf[2] >> 4 == 6)
101
l->
shift
= 2;
102
else
{
103
l->
shift
= 8 - (buf[2] >> 4);
104
if
(l->
shift
> 4) {
105
av_log_ask_for_sample
(avctx,
"Unknown WNV1 frame header value %i\n"
,
106
buf[2] >> 4);
107
l->
shift
= 4;
108
}
109
if
(l->
shift
< 1) {
110
av_log_ask_for_sample
(avctx,
"Unknown WNV1 frame header value %i\n"
,
111
buf[2] >> 4);
112
l->
shift
= 1;
113
}
114
}
115
116
Y = p->
data
[0];
117
U = p->
data
[1];
118
V = p->
data
[2];
119
for
(j = 0; j < avctx->
height
; j++) {
120
for
(i = 0; i < avctx->
width
/ 2; i++) {
121
Y[i * 2] =
wnv1_get_code
(l, prev_y);
122
prev_u = U[i] =
wnv1_get_code
(l, prev_u);
123
prev_y = Y[(i * 2) + 1] =
wnv1_get_code
(l, Y[i * 2]);
124
prev_v = V[i] =
wnv1_get_code
(l, prev_v);
125
}
126
Y += p->
linesize
[0];
127
U += p->
linesize
[1];
128
V += p->
linesize
[2];
129
}
130
131
132
*got_frame = 1;
133
*(
AVFrame
*)data = l->
pic
;
134
av_free
(rbuf);
135
136
return
buf_size;
137
}
138
139
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
140
{
141
WNV1Context
*
const
l = avctx->
priv_data
;
142
static
VLC_TYPE
code_table[1 <<
CODE_VLC_BITS
][2];
143
144
l->
avctx
= avctx;
145
avctx->
pix_fmt
=
AV_PIX_FMT_YUV422P
;
146
avcodec_get_frame_defaults
(&l->
pic
);
147
148
code_vlc.
table
= code_table;
149
code_vlc.
table_allocated
= 1 <<
CODE_VLC_BITS
;
150
init_vlc
(&code_vlc,
CODE_VLC_BITS
, 16,
151
&
code_tab
[0][1], 4, 2,
152
&
code_tab
[0][0], 4, 2,
INIT_VLC_USE_NEW_STATIC
);
153
154
return
0;
155
}
156
157
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
158
{
159
WNV1Context
*
const
l = avctx->
priv_data
;
160
AVFrame
*pic = &l->
pic
;
161
162
if
(pic->
data
[0])
163
avctx->
release_buffer
(avctx, pic);
164
165
return
0;
166
}
167
168
AVCodec
ff_wnv1_decoder
= {
169
.
name
=
"wnv1"
,
170
.type =
AVMEDIA_TYPE_VIDEO
,
171
.id =
AV_CODEC_ID_WNV1
,
172
.priv_data_size =
sizeof
(
WNV1Context
),
173
.
init
=
decode_init
,
174
.
close
=
decode_end
,
175
.
decode
=
decode_frame
,
176
.capabilities =
CODEC_CAP_DR1
,
177
.long_name =
NULL_IF_CONFIG_SMALL
(
"Winnov WNV1"
),
178
};
Generated on Sat May 25 2013 03:58:43 for FFmpeg by
1.8.2