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