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