FFmpeg
2.6.9
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
static
av_always_inline
void
write16_internal
(
int
big_endian,
void
*p,
int
value
)
79
{
80
if
(big_endian)
AV_WB16
(p, value);
81
else
AV_WL16
(p, value);
82
}
83
84
static
av_always_inline
void
write32_internal
(
int
big_endian,
void
*p,
int
value
)
85
{
86
if
(big_endian)
AV_WB32
(p, value);
87
else
AV_WL32
(p, value);
88
}
89
90
#define write16(p, value) write16_internal(s->big_endian, p, value)
91
#define write32(p, value) write32_internal(s->big_endian, p, value)
92
93
static
void
encode_rgb48_10bit
(
AVCodecContext
*avctx,
const
AVPicture
*pic,
uint8_t
*dst)
94
{
95
DPXContext
*
s
= avctx->
priv_data
;
96
const
uint8_t
*
src
= pic->
data
[0];
97
int
x,
y
;
98
99
for
(y = 0; y < avctx->
height
; y++) {
100
for
(x = 0; x < avctx->
width
; x++) {
101
int
value
;
102
if
(s->
big_endian
) {
103
value = ((
AV_RB16
(src + 6*x + 4) & 0xFFC0
U
) >> 4)
104
| ((
AV_RB16
(src + 6*x + 2) & 0xFFC0
U
) << 6)
105
| ((
AV_RB16
(src + 6*x + 0) & 0xFFC0
U
) << 16);
106
}
else
{
107
value = ((
AV_RL16
(src + 6*x + 4) & 0xFFC0
U
) >> 4)
108
| ((
AV_RL16
(src + 6*x + 2) & 0xFFC0
U
) << 6)
109
| ((
AV_RL16
(src + 6*x + 0) & 0xFFC0
U
) << 16);
110
}
111
write32
(dst, value);
112
dst += 4;
113
}
114
src += pic->
linesize
[0];
115
}
116
}
117
118
static
void
encode_gbrp10
(
AVCodecContext
*avctx,
const
AVPicture
*pic,
uint8_t
*dst)
119
{
120
DPXContext
*
s
= avctx->
priv_data
;
121
const
uint8_t
*
src
[3] = {pic->
data
[0], pic->
data
[1], pic->
data
[2]};
122
int
x,
y
, i;
123
124
for
(y = 0; y < avctx->
height
; y++) {
125
for
(x = 0; x < avctx->
width
; x++) {
126
int
value
;
127
if
(s->
big_endian
) {
128
value = (
AV_RB16
(src[0] + 2*x) << 12)
129
| (
AV_RB16
(src[1] + 2*x) << 2)
130
| ((
unsigned
)
AV_RB16
(src[2] + 2*x) << 22);
131
}
else
{
132
value = (
AV_RL16
(src[0] + 2*x) << 12)
133
| (
AV_RL16
(src[1] + 2*x) << 2)
134
| ((
unsigned
)
AV_RL16
(src[2] + 2*x) << 22);
135
}
136
write32
(dst, value);
137
dst += 4;
138
}
139
for
(i = 0; i < 3; i++)
140
src[i] += pic->
linesize
[i];
141
}
142
}
143
144
static
void
encode_gbrp12
(
AVCodecContext
*avctx,
const
AVPicture
*pic, uint16_t *dst)
145
{
146
DPXContext
*
s
= avctx->
priv_data
;
147
const
uint16_t *
src
[3] = {(uint16_t*)pic->
data
[0],
148
(uint16_t*)pic->
data
[1],
149
(uint16_t*)pic->
data
[2]};
150
int
x,
y
, i, pad;
151
pad = avctx->
width
*6;
152
pad = (
FFALIGN
(pad, 4) - pad) >> 1;
153
for
(y = 0; y < avctx->
height
; y++) {
154
for
(x = 0; x < avctx->
width
; x++) {
155
uint16_t
value
[3];
156
if
(s->
big_endian
) {
157
value[1] =
AV_RB16
(src[0] + x) << 4;
158
value[2] =
AV_RB16
(src[1] + x) << 4;
159
value[0] =
AV_RB16
(src[2] + x) << 4;
160
}
else
{
161
value[1] =
AV_RL16
(src[0] + x) << 4;
162
value[2] =
AV_RL16
(src[1] + x) << 4;
163
value[0] =
AV_RL16
(src[2] + x) << 4;
164
}
165
for
(i = 0; i < 3; i++)
166
write16
(dst++, value[i]);
167
}
168
for
(i = 0; i < pad; i++)
169
*dst++ = 0;
170
for
(i = 0; i < 3; i++)
171
src[i] += pic->
linesize
[i]/2;
172
}
173
}
174
175
static
int
encode_frame
(
AVCodecContext
*avctx,
AVPacket
*
pkt
,
176
const
AVFrame
*
frame
,
int
*got_packet)
177
{
178
DPXContext
*
s
= avctx->
priv_data
;
179
int
size
,
ret
, need_align,
len
;
180
uint8_t
*
buf
;
181
182
#define HEADER_SIZE 1664
/* DPX Generic header */
183
if
(s->
bits_per_component
== 10)
184
size = avctx->
height
* avctx->
width
* 4;
185
else
if
(s->
bits_per_component
== 12) {
186
// 3 components, 12 bits put on 16 bits
187
len = avctx->
width
*6;
188
size =
FFALIGN
(len, 4);
189
need_align = size -
len
;
190
size *= avctx->
height
;
191
}
else
{
192
// N components, M bits
193
len = avctx->
width
* s->
num_components
* s->
bits_per_component
>> 3;
194
size =
FFALIGN
(len, 4);
195
need_align = size -
len
;
196
size *= avctx->
height
;
197
}
198
if
((ret =
ff_alloc_packet2
(avctx, pkt, size +
HEADER_SIZE
)) < 0)
199
return
ret
;
200
buf = pkt->
data
;
201
202
memset(buf, 0,
HEADER_SIZE
);
203
204
/* File information header */
205
write32
(buf,
MKBETAG
(
'S'
,
'D'
,
'P'
,
'X'
));
206
write32
(buf + 4,
HEADER_SIZE
);
207
memcpy (buf + 8,
"V1.0"
, 4);
208
write32
(buf + 20, 1);
/* new image */
209
write32
(buf + 24,
HEADER_SIZE
);
210
if
(!(avctx->
flags
&
CODEC_FLAG_BITEXACT
))
211
memcpy (buf + 160,
LIBAVCODEC_IDENT
,
FFMIN
(
sizeof
(
LIBAVCODEC_IDENT
), 100));
212
write32
(buf + 660, 0xFFFFFFFF);
/* unencrypted */
213
214
/* Image information header */
215
write16
(buf + 768, 0);
/* orientation; left to right, top to bottom */
216
write16
(buf + 770, 1);
/* number of elements */
217
write32
(buf + 772, avctx->
width
);
218
write32
(buf + 776, avctx->
height
);
219
buf[800] = s->
descriptor
;
220
buf[801] = 2;
/* linear transfer */
221
buf[802] = 2;
/* linear colorimetric */
222
buf[803] = s->
bits_per_component
;
223
write16
(buf + 804, (s->
bits_per_component
== 10 || s->
bits_per_component
== 12) ?
224
1 : 0);
/* packing method */
225
write32
(buf + 808,
HEADER_SIZE
);
/* data offset */
226
227
/* Image source information header */
228
write32
(buf + 1628, avctx->
sample_aspect_ratio
.
num
);
229
write32
(buf + 1632, avctx->
sample_aspect_ratio
.
den
);
230
231
switch
(s->
bits_per_component
) {
232
case
8:
233
case
16:
234
if
(need_align) {
235
int
j;
236
const
uint8_t
*
src
= frame->
data
[0];
237
uint8_t
*dst = pkt->
data
+
HEADER_SIZE
;
238
size = (len + need_align) * avctx->
height
;
239
for
(j=0; j<avctx->
height
; j++) {
240
memcpy(dst, src, len);
241
memset(dst + len, 0, need_align);
242
dst += len + need_align;
243
src += frame->
linesize
[0];
244
}
245
}
else
{
246
size =
avpicture_layout
((
const
AVPicture
*)frame, avctx->
pix_fmt
,
247
avctx->
width
, avctx->
height
,
248
buf +
HEADER_SIZE
, pkt->
size
-
HEADER_SIZE
);
249
}
250
if
(size < 0)
251
return
size
;
252
break
;
253
case
10:
254
if
(s->
planar
)
255
encode_gbrp10
(avctx, (
const
AVPicture
*)frame, buf +
HEADER_SIZE
);
256
else
257
encode_rgb48_10bit
(avctx, (
const
AVPicture
*)frame, buf +
HEADER_SIZE
);
258
break
;
259
case
12:
260
encode_gbrp12
(avctx, (
const
AVPicture
*)frame, (uint16_t*)(buf +
HEADER_SIZE
));
261
break
;
262
default
:
263
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported bit depth: %d\n"
, s->
bits_per_component
);
264
return
-1;
265
}
266
267
size +=
HEADER_SIZE
;
268
269
write32
(buf + 16, size);
/* file size */
270
271
pkt->
flags
|=
AV_PKT_FLAG_KEY
;
272
*got_packet = 1;
273
274
return
0;
275
}
276
277
AVCodec
ff_dpx_encoder
= {
278
.
name
=
"dpx"
,
279
.long_name =
NULL_IF_CONFIG_SMALL
(
"DPX (Digital Picture Exchange) image"
),
280
.type =
AVMEDIA_TYPE_VIDEO
,
281
.id =
AV_CODEC_ID_DPX
,
282
.priv_data_size =
sizeof
(
DPXContext
),
283
.
init
=
encode_init
,
284
.encode2 =
encode_frame
,
285
.pix_fmts = (
const
enum
AVPixelFormat
[]){
286
AV_PIX_FMT_GRAY8
,
287
AV_PIX_FMT_RGB24
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_ABGR
,
288
AV_PIX_FMT_GRAY16LE
,
AV_PIX_FMT_GRAY16BE
,
289
AV_PIX_FMT_RGB48LE
,
AV_PIX_FMT_RGB48BE
,
290
AV_PIX_FMT_RGBA64LE
,
AV_PIX_FMT_RGBA64BE
,
291
AV_PIX_FMT_GBRP10LE
,
AV_PIX_FMT_GBRP10BE
,
292
AV_PIX_FMT_GBRP12LE
,
AV_PIX_FMT_GBRP12BE
,
293
AV_PIX_FMT_NONE
},
294
};
Generated on Tue Jun 21 2022 16:27:45 for FFmpeg by
1.8.1.2