FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
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
typedef
struct
TsccContext {
48
49
AVCodecContext
*
avctx
;
50
AVFrame
*
frame
;
51
52
// Bits per pixel
53
int
bpp
;
54
// Decompressed data size
55
unsigned
int
decomp_size
;
56
// Decompression buffer
57
unsigned
char
*
decomp_buf
;
58
GetByteContext
gb
;
59
int
height
;
60
z_stream
zstream
;
61
62
uint32_t pal[256];
63
}
CamtasiaContext
;
64
65
static
int
decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
int
*got_frame,
66
AVPacket
*avpkt)
67
{
68
const
uint8_t
*
buf
= avpkt->
data
;
69
int
buf_size = avpkt->
size
;
70
CamtasiaContext
*
const
c
= avctx->
priv_data
;
71
const
unsigned
char
*encoded =
buf
;
72
AVFrame
*
frame
= c->
frame
;
73
int
zret;
// Zlib return code
74
int
ret
,
len
= buf_size;
75
76
if
((ret =
ff_reget_buffer
(avctx, frame)) < 0)
77
return
ret
;
78
79
zret = inflateReset(&c->
zstream
);
80
if
(zret != Z_OK) {
81
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate reset error: %d\n"
, zret);
82
return
AVERROR_UNKNOWN
;
83
}
84
c->
zstream
.next_in = (
uint8_t
*)encoded;
85
c->
zstream
.avail_in =
len
;
86
c->
zstream
.next_out = c->
decomp_buf
;
87
c->
zstream
.avail_out = c->
decomp_size
;
88
zret = inflate(&c->
zstream
, Z_FINISH);
89
// Z_DATA_ERROR means empty picture
90
if
((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
91
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate error: %d\n"
, zret);
92
return
AVERROR_UNKNOWN
;
93
}
94
95
96
if
(zret != Z_DATA_ERROR) {
97
bytestream2_init
(&c->
gb
, c->
decomp_buf
,
98
c->
decomp_size
- c->
zstream
.avail_out);
99
ff_msrle_decode
(avctx, (
AVPicture
*)frame, c->
bpp
, &c->
gb
);
100
}
101
102
/* make the palette available on the way out */
103
if
(c->
avctx
->
pix_fmt
==
AV_PIX_FMT_PAL8
) {
104
const
uint8_t
*pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
, NULL);
105
106
if
(pal) {
107
frame->
palette_has_changed
= 1;
108
memcpy(c->
pal
, pal,
AVPALETTE_SIZE
);
109
}
110
memcpy(frame->
data
[1], c->
pal
,
AVPALETTE_SIZE
);
111
}
112
113
if
((ret =
av_frame_ref
(data, frame)) < 0)
114
return
ret
;
115
*got_frame = 1;
116
117
/* always report that the buffer was completely consumed */
118
return
buf_size;
119
}
120
121
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
122
{
123
CamtasiaContext
*
const
c
= avctx->
priv_data
;
124
int
zret;
// Zlib return code
125
126
c->
avctx
= avctx;
127
128
c->
height
= avctx->
height
;
129
130
// Needed if zlib unused or init aborted before inflateInit
131
memset(&c->
zstream
, 0,
sizeof
(z_stream));
132
switch
(avctx->
bits_per_coded_sample
){
133
case
8: avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
break
;
134
case
16: avctx->
pix_fmt
=
AV_PIX_FMT_RGB555
;
break
;
135
case
24:
136
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
137
break
;
138
case
32: avctx->
pix_fmt
=
AV_PIX_FMT_RGB32
;
break
;
139
default
:
av_log
(avctx,
AV_LOG_ERROR
,
"Camtasia error: unknown depth %i bpp\n"
, avctx->
bits_per_coded_sample
);
140
return
AVERROR_PATCHWELCOME
;
141
}
142
c->
bpp
= avctx->
bits_per_coded_sample
;
143
// buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
144
c->
decomp_size
= (((avctx->
width
* c->
bpp
+ 7) >> 3) + 3 * avctx->
width
+ 2) * avctx->
height
+ 2;
145
146
/* Allocate decompression buffer */
147
if
(c->
decomp_size
) {
148
if
((c->
decomp_buf
=
av_malloc
(c->
decomp_size
)) == NULL) {
149
av_log
(avctx,
AV_LOG_ERROR
,
"Can't allocate decompression buffer.\n"
);
150
return
AVERROR
(ENOMEM);
151
}
152
}
153
154
c->
zstream
.zalloc = Z_NULL;
155
c->
zstream
.zfree = Z_NULL;
156
c->
zstream
.opaque = Z_NULL;
157
zret = inflateInit(&c->
zstream
);
158
if
(zret != Z_OK) {
159
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate init error: %d\n"
, zret);
160
return
AVERROR_UNKNOWN
;
161
}
162
163
c->
frame
=
av_frame_alloc
();
164
165
return
0;
166
}
167
168
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
169
{
170
CamtasiaContext
*
const
c
= avctx->
priv_data
;
171
172
av_freep
(&c->
decomp_buf
);
173
av_frame_free
(&c->
frame
);
174
175
inflateEnd(&c->
zstream
);
176
177
return
0;
178
}
179
180
AVCodec
ff_tscc_decoder
= {
181
.
name
=
"camtasia"
,
182
.long_name =
NULL_IF_CONFIG_SMALL
(
"TechSmith Screen Capture Codec"
),
183
.type =
AVMEDIA_TYPE_VIDEO
,
184
.id =
AV_CODEC_ID_TSCC
,
185
.priv_data_size =
sizeof
(
CamtasiaContext
),
186
.
init
=
decode_init
,
187
.
close
=
decode_end
,
188
.
decode
=
decode_frame
,
189
.capabilities =
CODEC_CAP_DR1
,
190
};
Generated on Sun Mar 23 2014 23:50:03 for FFmpeg by
1.8.2