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