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 Mar 23 2014 23:49:53 for FFmpeg by
1.8.2