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 Sep 14 2014 18:55:54 for FFmpeg by
1.8.2