Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
vcr1.c
Go to the documentation of this file.
1
/*
2
* ATI VCR1 codec
3
* Copyright (c) 2003 Michael Niedermayer
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 "
dsputil.h
"
29
#include "
internal.h
"
30
#include "
libavutil/internal.h
"
31
32
typedef
struct
VCR1Context
{
33
AVFrame
picture
;
34
int
delta
[16];
35
int
offset
[4];
36
}
VCR1Context
;
37
38
static
av_cold
int
vcr1_common_init
(
AVCodecContext
*avctx)
39
{
40
VCR1Context
*
const
a = avctx->
priv_data
;
41
42
avctx->
coded_frame
= &a->
picture
;
43
44
return
0;
45
}
46
47
static
av_cold
int
vcr1_decode_init
(
AVCodecContext
*avctx)
48
{
49
vcr1_common_init
(avctx);
50
51
avctx->
pix_fmt
=
AV_PIX_FMT_YUV410P
;
52
53
if
(avctx->
width
& 7) {
54
av_log
(avctx,
AV_LOG_ERROR
,
"Width %d is not divisble by 8.\n"
, avctx->
width
);
55
return
AVERROR_INVALIDDATA
;
56
}
57
58
return
0;
59
}
60
61
static
av_cold
int
vcr1_decode_end
(
AVCodecContext
*avctx)
62
{
63
VCR1Context
*s = avctx->
priv_data
;
64
65
if
(s->
picture
.
data
[0])
66
avctx->
release_buffer
(avctx, &s->
picture
);
67
68
return
0;
69
}
70
71
static
int
vcr1_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
72
int
*got_frame,
AVPacket
*avpkt)
73
{
74
const
uint8_t
*buf = avpkt->
data
;
75
int
buf_size = avpkt->
size
;
76
VCR1Context
*
const
a = avctx->
priv_data
;
77
AVFrame
*
picture
=
data
;
78
AVFrame
*
const
p = &a->
picture
;
79
const
uint8_t
*bytestream = buf;
80
int
i, x, y;
81
82
if
(p->
data
[0])
83
avctx->
release_buffer
(avctx, p);
84
85
p->
reference
= 0;
86
if
(
ff_get_buffer
(avctx, p) < 0) {
87
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
88
return
-1;
89
}
90
p->
pict_type
=
AV_PICTURE_TYPE_I
;
91
p->
key_frame
= 1;
92
93
if
(buf_size < 32)
94
goto
packet_small;
95
96
for
(i = 0; i < 16; i++) {
97
a->
delta
[i] = *bytestream++;
98
bytestream++;
99
buf_size--;
100
}
101
102
for
(y = 0; y < avctx->
height
; y++) {
103
int
offset;
104
uint8_t
*luma = &a->
picture
.
data
[0][y * a->
picture
.
linesize
[0]];
105
106
if
((y & 3) == 0) {
107
uint8_t
*cb = &a->
picture
.
data
[1][(y >> 2) * a->
picture
.
linesize
[1]];
108
uint8_t
*cr = &a->
picture
.
data
[2][(y >> 2) * a->
picture
.
linesize
[2]];
109
110
if
(buf_size < 4 + avctx->
width
)
111
goto
packet_small;
112
113
for
(i = 0; i < 4; i++)
114
a->
offset
[i] = *bytestream++;
115
buf_size -= 4;
116
117
offset = a->
offset
[0] - a->
delta
[bytestream[2] & 0xF];
118
for
(x = 0; x < avctx->
width
; x += 4) {
119
luma[0] = offset += a->
delta
[bytestream[2] & 0xF];
120
luma[1] = offset += a->
delta
[bytestream[2] >> 4];
121
luma[2] = offset += a->
delta
[bytestream[0] & 0xF];
122
luma[3] = offset += a->
delta
[bytestream[0] >> 4];
123
luma += 4;
124
125
*cb++ = bytestream[3];
126
*cr++ = bytestream[1];
127
128
bytestream += 4;
129
buf_size -= 4;
130
}
131
}
else
{
132
if
(buf_size < avctx->
width
/ 2)
133
goto
packet_small;
134
135
offset = a->
offset
[y & 3] - a->
delta
[bytestream[2] & 0xF];
136
137
for
(x = 0; x < avctx->
width
; x += 8) {
138
luma[0] = offset += a->
delta
[bytestream[2] & 0xF];
139
luma[1] = offset += a->
delta
[bytestream[2] >> 4];
140
luma[2] = offset += a->
delta
[bytestream[3] & 0xF];
141
luma[3] = offset += a->
delta
[bytestream[3] >> 4];
142
luma[4] = offset += a->
delta
[bytestream[0] & 0xF];
143
luma[5] = offset += a->
delta
[bytestream[0] >> 4];
144
luma[6] = offset += a->
delta
[bytestream[1] & 0xF];
145
luma[7] = offset += a->
delta
[bytestream[1] >> 4];
146
luma += 8;
147
bytestream += 4;
148
buf_size -= 4;
149
}
150
}
151
}
152
153
*picture = a->
picture
;
154
*got_frame = 1;
155
156
return
buf_size;
157
packet_small:
158
av_log
(avctx,
AV_LOG_ERROR
,
"Input packet too small.\n"
);
159
return
AVERROR_INVALIDDATA
;
160
}
161
162
AVCodec
ff_vcr1_decoder
= {
163
.
name
=
"vcr1"
,
164
.type =
AVMEDIA_TYPE_VIDEO
,
165
.id =
AV_CODEC_ID_VCR1
,
166
.priv_data_size =
sizeof
(
VCR1Context
),
167
.
init
=
vcr1_decode_init
,
168
.
close
=
vcr1_decode_end
,
169
.
decode
=
vcr1_decode_frame
,
170
.capabilities =
CODEC_CAP_DR1
,
171
.long_name =
NULL_IF_CONFIG_SMALL
(
"ATI VCR1"
),
172
};
173
174
/* Disable the encoder. */
175
#undef CONFIG_VCR1_ENCODER
176
#define CONFIG_VCR1_ENCODER 0
177
178
#if CONFIG_VCR1_ENCODER
179
180
#include "
put_bits.h
"
181
182
static
int
vcr1_encode_frame(
AVCodecContext
*avctx,
unsigned
char
*buf,
183
int
buf_size,
void
*
data
)
184
{
185
VCR1Context
*
const
a = avctx->
priv_data
;
186
AVFrame
*pict =
data
;
187
AVFrame
*
const
p = &a->
picture
;
188
int
size
;
189
190
*p = *pict;
191
p->
pict_type
=
AV_PICTURE_TYPE_I
;
192
p->
key_frame
= 1;
193
194
avpriv_align_put_bits
(&a->pb);
195
flush_put_bits
(&a->pb);
196
197
size =
put_bits_count
(&a->pb) / 32;
198
199
return
size * 4;
200
}
201
202
AVCodec
ff_vcr1_encoder = {
203
.
name
=
"vcr1"
,
204
.type =
AVMEDIA_TYPE_VIDEO
,
205
.id =
AV_CODEC_ID_VCR1
,
206
.priv_data_size =
sizeof
(
VCR1Context
),
207
.
init
=
vcr1_common_init
,
208
.encode = vcr1_encode_frame,
209
.long_name =
NULL_IF_CONFIG_SMALL
(
"ATI VCR1"
),
210
};
211
#endif
/* CONFIG_VCR1_ENCODER */