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
dpxenc.c
Go to the documentation of this file.
1
/*
2
* DPX (.dpx) image encoder
3
* Copyright (c) 2011 Peter Ross <pross@xvid.org>
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
#include "
libavutil/common.h
"
23
#include "
libavutil/intreadwrite.h
"
24
#include "
libavutil/imgutils.h
"
25
#include "
avcodec.h
"
26
#include "
internal.h
"
27
28
typedef
struct
DPXContext
{
29
int
big_endian
;
30
int
bits_per_component
;
31
int
num_components
;
32
int
descriptor
;
33
int
planar
;
34
}
DPXContext
;
35
36
static
av_cold
int
encode_init
(
AVCodecContext
*avctx)
37
{
38
DPXContext
*
s
= avctx->
priv_data
;
39
const
AVPixFmtDescriptor
*desc =
av_pix_fmt_desc_get
(avctx->
pix_fmt
);
40
41
s->
big_endian
= !!(desc->
flags
&
AV_PIX_FMT_FLAG_BE
);
42
s->
bits_per_component
= desc->
comp
[0].
depth_minus1
+ 1;
43
s->
num_components
= desc->
nb_components
;
44
s->
descriptor
= (desc->
flags
&
AV_PIX_FMT_FLAG_ALPHA
) ? 51 : 50;
45
s->
planar
= !!(desc->
flags
&
AV_PIX_FMT_FLAG_PLANAR
);
46
47
switch
(avctx->
pix_fmt
) {
48
case
AV_PIX_FMT_ABGR
:
49
s->
descriptor
= 52;
50
break
;
51
case
AV_PIX_FMT_GRAY16BE
:
52
case
AV_PIX_FMT_GRAY16LE
:
53
case
AV_PIX_FMT_GRAY8
:
54
s->
descriptor
= 6;
55
break
;
56
case
AV_PIX_FMT_GBRP10BE
:
57
case
AV_PIX_FMT_GBRP10LE
:
58
case
AV_PIX_FMT_GBRP12BE
:
59
case
AV_PIX_FMT_GBRP12LE
:
60
case
AV_PIX_FMT_RGB24
:
61
case
AV_PIX_FMT_RGBA64BE
:
62
case
AV_PIX_FMT_RGBA64LE
:
63
case
AV_PIX_FMT_RGBA
:
64
break
;
65
case
AV_PIX_FMT_RGB48LE
:
66
case
AV_PIX_FMT_RGB48BE
:
67
if
(avctx->
bits_per_raw_sample
)
68
s->
bits_per_component
= avctx->
bits_per_raw_sample
;
69
break
;
70
default
:
71
av_log
(avctx,
AV_LOG_INFO
,
"unsupported pixel format\n"
);
72
return
-1;
73
}
74
75
return
0;
76
}
77
78
#define write16(p, value) \
79
do { \
80
if (s->big_endian) AV_WB16(p, value); \
81
else AV_WL16(p, value); \
82
} while(0)
83
84
#define write32(p, value) \
85
do { \
86
if (s->big_endian) AV_WB32(p, value); \
87
else AV_WL32(p, value); \
88
} while(0)
89
90
static
void
encode_rgb48_10bit
(
AVCodecContext
*avctx,
const
AVPicture
*pic,
uint8_t
*dst)
91
{
92
DPXContext
*
s
= avctx->
priv_data
;
93
const
uint8_t
*
src
= pic->
data
[0];
94
int
x,
y
;
95
96
for
(y = 0; y < avctx->
height
; y++) {
97
for
(x = 0; x < avctx->
width
; x++) {
98
int
value
;
99
if
(s->
big_endian
) {
100
value = ((
AV_RB16
(src + 6*x + 4) & 0xFFC0
U
) >> 4)
101
| ((
AV_RB16
(src + 6*x + 2) & 0xFFC0
U
) << 6)
102
| ((
AV_RB16
(src + 6*x + 0) & 0xFFC0
U
) << 16);
103
}
else
{
104
value = ((
AV_RL16
(src + 6*x + 4) & 0xFFC0
U
) >> 4)
105
| ((
AV_RL16
(src + 6*x + 2) & 0xFFC0
U
) << 6)
106
| ((
AV_RL16
(src + 6*x + 0) & 0xFFC0
U
) << 16);
107
}
108
write32
(dst, value);
109
dst += 4;
110
}
111
src += pic->
linesize
[0];
112
}
113
}
114
115
static
void
encode_gbrp10
(
AVCodecContext
*avctx,
const
AVPicture
*pic,
uint8_t
*dst)
116
{
117
DPXContext
*
s
= avctx->
priv_data
;
118
const
uint8_t
*
src
[3] = {pic->
data
[0], pic->
data
[1], pic->
data
[2]};
119
int
x,
y
, i;
120
121
for
(y = 0; y < avctx->
height
; y++) {
122
for
(x = 0; x < avctx->
width
; x++) {
123
int
value
;
124
if
(s->
big_endian
) {
125
value = (
AV_RB16
(src[0] + 2*x) << 12)
126
| (
AV_RB16
(src[1] + 2*x) << 2)
127
| ((
unsigned
)
AV_RB16
(src[2] + 2*x) << 22);
128
}
else
{
129
value = (
AV_RL16
(src[0] + 2*x) << 12)
130
| (
AV_RL16
(src[1] + 2*x) << 2)
131
| ((
unsigned
)
AV_RL16
(src[2] + 2*x) << 22);
132
}
133
write32
(dst, value);
134
dst += 4;
135
}
136
for
(i = 0; i < 3; i++)
137
src[i] += pic->
linesize
[i];
138
}
139
}
140
141
static
void
encode_gbrp12
(
AVCodecContext
*avctx,
const
AVPicture
*pic, uint16_t *dst)
142
{
143
DPXContext
*
s
= avctx->
priv_data
;
144
const
uint16_t *
src
[3] = {(uint16_t*)pic->
data
[0],
145
(uint16_t*)pic->
data
[1],
146
(uint16_t*)pic->
data
[2]};
147
int
x,
y
, i, pad;
148
pad = avctx->
width
*6;
149
pad = (
FFALIGN
(pad, 4) - pad) >> 1;
150
for
(y = 0; y < avctx->
height
; y++) {
151
for
(x = 0; x < avctx->
width
; x++) {
152
uint16_t
value
[3];
153
if
(s->
big_endian
) {
154
value[1] =
AV_RB16
(src[0] + x) << 4;
155
value[2] =
AV_RB16
(src[1] + x) << 4;
156
value[0] =
AV_RB16
(src[2] + x) << 4;
157
}
else
{
158
value[1] =
AV_RL16
(src[0] + x) << 4;
159
value[2] =
AV_RL16
(src[1] + x) << 4;
160
value[0] =
AV_RL16
(src[2] + x) << 4;
161
}
162
for
(i = 0; i < 3; i++)
163
write16
(dst++, value[i]);
164
}
165
for
(i = 0; i < pad; i++)
166
*dst++ = 0;
167
for
(i = 0; i < 3; i++)
168
src[i] += pic->
linesize
[i]/2;
169
}
170
}
171
172
static
int
encode_frame
(
AVCodecContext
*avctx,
AVPacket
*
pkt
,
173
const
AVFrame
*
frame
,
int
*got_packet)
174
{
175
DPXContext
*
s
= avctx->
priv_data
;
176
int
size
,
ret
, need_align,
len
;
177
uint8_t
*
buf
;
178
179
#define HEADER_SIZE 1664
/* DPX Generic header */
180
if
(s->
bits_per_component
== 10)
181
size = avctx->
height
* avctx->
width
* 4;
182
else
if
(s->
bits_per_component
== 12) {
183
// 3 components, 12 bits put on 16 bits
184
len = avctx->
width
*6;
185
size =
FFALIGN
(len, 4);
186
need_align = size -
len
;
187
size *= avctx->
height
;
188
}
else
{
189
// N components, M bits
190
len = avctx->
width
* s->
num_components
* s->
bits_per_component
>> 3;
191
size =
FFALIGN
(len, 4);
192
need_align = size -
len
;
193
size *= avctx->
height
;
194
}
195
if
((ret =
ff_alloc_packet2
(avctx, pkt, size +
HEADER_SIZE
)) < 0)
196
return
ret
;
197
buf = pkt->
data
;
198
199
memset(buf, 0,
HEADER_SIZE
);
200
201
/* File information header */
202
write32
(buf,
MKBETAG
(
'S'
,
'D'
,
'P'
,
'X'
));
203
write32
(buf + 4,
HEADER_SIZE
);
204
memcpy (buf + 8,
"V1.0"
, 4);
205
write32
(buf + 20, 1);
/* new image */
206
write32
(buf + 24,
HEADER_SIZE
);
207
if
(!(avctx->
flags
&
CODEC_FLAG_BITEXACT
))
208
memcpy (buf + 160,
LIBAVCODEC_IDENT
,
FFMIN
(
sizeof
(
LIBAVCODEC_IDENT
), 100));
209
write32
(buf + 660, 0xFFFFFFFF);
/* unencrypted */
210
211
/* Image information header */
212
write16
(buf + 768, 0);
/* orientation; left to right, top to bottom */
213
write16
(buf + 770, 1);
/* number of elements */
214
write32
(buf + 772, avctx->
width
);
215
write32
(buf + 776, avctx->
height
);
216
buf[800] = s->
descriptor
;
217
buf[801] = 2;
/* linear transfer */
218
buf[802] = 2;
/* linear colorimetric */
219
buf[803] = s->
bits_per_component
;
220
write16
(buf + 804, (s->
bits_per_component
== 10 || s->
bits_per_component
== 12) ?
221
1 : 0);
/* packing method */
222
write32
(buf + 808,
HEADER_SIZE
);
/* data offset */
223
224
/* Image source information header */
225
write32
(buf + 1628, avctx->
sample_aspect_ratio
.
num
);
226
write32
(buf + 1632, avctx->
sample_aspect_ratio
.
den
);
227
228
switch
(s->
bits_per_component
) {
229
case
8:
230
case
16:
231
if
(need_align) {
232
int
j;
233
const
uint8_t
*
src
= frame->
data
[0];
234
uint8_t
*dst = pkt->
data
+
HEADER_SIZE
;
235
size = (len + need_align) * avctx->
height
;
236
for
(j=0; j<avctx->
height
; j++) {
237
memcpy(dst, src, len);
238
memset(dst + len, 0, need_align);
239
dst += len + need_align;
240
src += frame->
linesize
[0];
241
}
242
}
else
{
243
size =
avpicture_layout
((
const
AVPicture
*)frame, avctx->
pix_fmt
,
244
avctx->
width
, avctx->
height
,
245
buf +
HEADER_SIZE
, pkt->
size
-
HEADER_SIZE
);
246
}
247
if
(size < 0)
248
return
size
;
249
break
;
250
case
10:
251
if
(s->
planar
)
252
encode_gbrp10
(avctx, (
const
AVPicture
*)frame, buf +
HEADER_SIZE
);
253
else
254
encode_rgb48_10bit
(avctx, (
const
AVPicture
*)frame, buf +
HEADER_SIZE
);
255
break
;
256
case
12:
257
encode_gbrp12
(avctx, (
const
AVPicture
*)frame, (uint16_t*)(buf +
HEADER_SIZE
));
258
break
;
259
default
:
260
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported bit depth: %d\n"
, s->
bits_per_component
);
261
return
-1;
262
}
263
264
size +=
HEADER_SIZE
;
265
266
write32
(buf + 16, size);
/* file size */
267
268
pkt->
flags
|=
AV_PKT_FLAG_KEY
;
269
*got_packet = 1;
270
271
return
0;
272
}
273
274
AVCodec
ff_dpx_encoder
= {
275
.
name
=
"dpx"
,
276
.long_name =
NULL_IF_CONFIG_SMALL
(
"DPX (Digital Picture Exchange) image"
),
277
.type =
AVMEDIA_TYPE_VIDEO
,
278
.id =
AV_CODEC_ID_DPX
,
279
.priv_data_size =
sizeof
(
DPXContext
),
280
.
init
=
encode_init
,
281
.encode2 =
encode_frame
,
282
.pix_fmts = (
const
enum
AVPixelFormat
[]){
283
AV_PIX_FMT_GRAY8
,
284
AV_PIX_FMT_RGB24
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_ABGR
,
285
AV_PIX_FMT_GRAY16LE
,
AV_PIX_FMT_GRAY16BE
,
286
AV_PIX_FMT_RGB48LE
,
AV_PIX_FMT_RGB48BE
,
287
AV_PIX_FMT_RGBA64LE
,
AV_PIX_FMT_RGBA64BE
,
288
AV_PIX_FMT_GBRP10LE
,
AV_PIX_FMT_GBRP10BE
,
289
AV_PIX_FMT_GBRP12LE
,
AV_PIX_FMT_GBRP12BE
,
290
AV_PIX_FMT_NONE
},
291
};
Generated on Sun Mar 8 2015 02:34:50 for FFmpeg by
1.8.2