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