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