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
tscc.c
Go to the documentation of this file.
1
/*
2
* TechSmith Camtasia decoder
3
* Copyright (c) 2004 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
* TechSmith Camtasia decoder
25
*
26
* Fourcc: TSCC
27
*
28
* Codec is very simple:
29
* it codes picture (picture difference, really)
30
* with algorithm almost identical to Windows RLE8,
31
* only without padding and with greater pixel sizes,
32
* then this coded picture is packed with ZLib
33
*
34
* Supports: BGR8,BGR555,BGR24 - only BGR8 and BGR555 tested
35
*
36
*/
37
38
#include <stdio.h>
39
#include <stdlib.h>
40
41
#include "
avcodec.h
"
42
#include "
internal.h
"
43
#include "
msrledec.h
"
44
45
#include <zlib.h>
46
47
48
/*
49
* Decoder context
50
*/
51
typedef
struct
TsccContext {
52
53
AVCodecContext
*
avctx
;
54
AVFrame
pic
;
55
56
// Bits per pixel
57
int
bpp
;
58
// Decompressed data size
59
unsigned
int
decomp_size
;
60
// Decompression buffer
61
unsigned
char
*
decomp_buf
;
62
GetByteContext
gb
;
63
int
height
;
64
z_stream
zstream
;
65
66
uint32_t pal[256];
67
}
CamtasiaContext
;
68
69
/*
70
*
71
* Decode a frame
72
*
73
*/
74
static
int
decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
int
*got_frame,
75
AVPacket
*avpkt)
76
{
77
const
uint8_t
*buf = avpkt->
data
;
78
int
buf_size = avpkt->
size
;
79
CamtasiaContext
*
const
c
= avctx->
priv_data
;
80
const
unsigned
char
*encoded = buf;
81
int
zret;
// Zlib return code
82
int
ret,
len
= buf_size;
83
84
c->
pic
.
reference
= 3;
85
c->
pic
.
buffer_hints
=
FF_BUFFER_HINTS_VALID
;
86
if
((ret = avctx->
reget_buffer
(avctx, &c->
pic
)) < 0){
87
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
88
return
ret;
89
}
90
91
zret = inflateReset(&c->
zstream
);
92
if
(zret != Z_OK) {
93
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate reset error: %d\n"
, zret);
94
return
AVERROR
(EINVAL);
95
}
96
c->
zstream
.next_in = (
uint8_t
*)encoded;
97
c->
zstream
.avail_in =
len
;
98
c->
zstream
.next_out = c->
decomp_buf
;
99
c->
zstream
.avail_out = c->
decomp_size
;
100
zret = inflate(&c->
zstream
, Z_FINISH);
101
// Z_DATA_ERROR means empty picture
102
if
((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
103
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate error: %d\n"
, zret);
104
return
AVERROR
(EINVAL);
105
}
106
107
108
if
(zret != Z_DATA_ERROR) {
109
bytestream2_init
(&c->
gb
, c->
decomp_buf
,
110
c->
decomp_size
- c->
zstream
.avail_out);
111
ff_msrle_decode
(avctx, (
AVPicture
*)&c->
pic
, c->
bpp
, &c->
gb
);
112
}
113
114
/* make the palette available on the way out */
115
if
(c->
avctx
->
pix_fmt
==
AV_PIX_FMT_PAL8
) {
116
const
uint8_t
*pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
,
NULL
);
117
118
if
(pal) {
119
c->
pic
.
palette_has_changed
= 1;
120
memcpy(c->
pal
, pal,
AVPALETTE_SIZE
);
121
}
122
memcpy(c->
pic
.
data
[1], c->
pal
,
AVPALETTE_SIZE
);
123
}
124
125
*got_frame = 1;
126
*(
AVFrame
*)data = c->
pic
;
127
128
/* always report that the buffer was completely consumed */
129
return
buf_size;
130
}
131
132
133
134
/*
135
*
136
* Init tscc decoder
137
*
138
*/
139
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
140
{
141
CamtasiaContext
*
const
c
= avctx->
priv_data
;
142
int
zret;
// Zlib return code
143
144
c->
avctx
= avctx;
145
146
c->
height
= avctx->
height
;
147
148
avcodec_get_frame_defaults
(&c->
pic
);
149
// Needed if zlib unused or init aborted before inflateInit
150
memset(&c->
zstream
, 0,
sizeof
(z_stream));
151
switch
(avctx->
bits_per_coded_sample
){
152
case
8: avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
break
;
153
case
16: avctx->
pix_fmt
=
AV_PIX_FMT_RGB555
;
break
;
154
case
24:
155
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
156
break
;
157
case
32: avctx->
pix_fmt
=
AV_PIX_FMT_RGB32
;
break
;
158
default
:
av_log
(avctx,
AV_LOG_ERROR
,
"Camtasia error: unknown depth %i bpp\n"
, avctx->
bits_per_coded_sample
);
159
return
AVERROR_PATCHWELCOME
;
160
}
161
c->
bpp
= avctx->
bits_per_coded_sample
;
162
// buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
163
c->
decomp_size
= (((avctx->
width
* c->
bpp
+ 7) >> 3) + 3 * avctx->
width
+ 2) * avctx->
height
+ 2;
164
165
/* Allocate decompression buffer */
166
if
(c->
decomp_size
) {
167
if
((c->
decomp_buf
=
av_malloc
(c->
decomp_size
)) ==
NULL
) {
168
av_log
(avctx,
AV_LOG_ERROR
,
"Can't allocate decompression buffer.\n"
);
169
return
AVERROR
(ENOMEM);
170
}
171
}
172
173
c->
zstream
.zalloc = Z_NULL;
174
c->
zstream
.zfree = Z_NULL;
175
c->
zstream
.opaque = Z_NULL;
176
zret = inflateInit(&c->
zstream
);
177
if
(zret != Z_OK) {
178
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate init error: %d\n"
, zret);
179
return
AVERROR
(ENOMEM);
180
}
181
182
return
0;
183
}
184
185
186
187
/*
188
*
189
* Uninit tscc decoder
190
*
191
*/
192
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
193
{
194
CamtasiaContext
*
const
c
= avctx->
priv_data
;
195
196
av_freep
(&c->
decomp_buf
);
197
198
if
(c->
pic
.
data
[0])
199
avctx->
release_buffer
(avctx, &c->
pic
);
200
inflateEnd(&c->
zstream
);
201
202
return
0;
203
}
204
205
AVCodec
ff_tscc_decoder
= {
206
.
name
=
"camtasia"
,
207
.type =
AVMEDIA_TYPE_VIDEO
,
208
.id =
AV_CODEC_ID_TSCC
,
209
.priv_data_size =
sizeof
(
CamtasiaContext
),
210
.
init
=
decode_init
,
211
.
close
=
decode_end
,
212
.
decode
=
decode_frame
,
213
.capabilities =
CODEC_CAP_DR1
,
214
.long_name =
NULL_IF_CONFIG_SMALL
(
"TechSmith Screen Capture Codec"
),
215
};
Generated on Sat May 25 2013 03:58:41 for FFmpeg by
1.8.2