Encode GBRP10 pixel format into 10 bit DPX.
Encode GBRP12 pixel format into 12 bit DPX.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -30,6 +30,7 @@ typedef struct DPXContext { |
30 | 30 |
int big_endian; |
31 | 31 |
int bits_per_component; |
32 | 32 |
int descriptor; |
33 |
+ int planar; |
|
33 | 34 |
} DPXContext; |
34 | 35 |
|
35 | 36 |
static av_cold int encode_init(AVCodecContext *avctx) |
... | ... |
@@ -43,6 +44,7 @@ static av_cold int encode_init(AVCodecContext *avctx) |
43 | 43 |
s->big_endian = 1; |
44 | 44 |
s->bits_per_component = 8; |
45 | 45 |
s->descriptor = 50; /* RGB */ |
46 |
+ s->planar = 0; |
|
46 | 47 |
|
47 | 48 |
switch (avctx->pix_fmt) { |
48 | 49 |
case PIX_FMT_RGB24: |
... | ... |
@@ -61,6 +63,18 @@ static av_cold int encode_init(AVCodecContext *avctx) |
61 | 61 |
s->descriptor = 51; |
62 | 62 |
s->bits_per_component = 16; |
63 | 63 |
break; |
64 |
+ case PIX_FMT_GBRP10LE: |
|
65 |
+ s->big_endian = 0; |
|
66 |
+ case PIX_FMT_GBRP10BE: |
|
67 |
+ s->bits_per_component = 10; |
|
68 |
+ s->planar = 1; |
|
69 |
+ break; |
|
70 |
+ case PIX_FMT_GBRP12LE: |
|
71 |
+ s->big_endian = 0; |
|
72 |
+ case PIX_FMT_GBRP12BE: |
|
73 |
+ s->bits_per_component = 12; |
|
74 |
+ s->planar = 1; |
|
75 |
+ break; |
|
64 | 76 |
default: |
65 | 77 |
av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n"); |
66 | 78 |
return -1; |
... | ... |
@@ -106,6 +120,48 @@ static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, uint |
106 | 106 |
} |
107 | 107 |
} |
108 | 108 |
|
109 |
+static void encode_gbrp10(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst) |
|
110 |
+{ |
|
111 |
+ DPXContext *s = avctx->priv_data; |
|
112 |
+ const uint8_t *src[3] = {pic->data[0], pic->data[1], pic->data[2]}; |
|
113 |
+ int x, y, i; |
|
114 |
+ |
|
115 |
+ for (y = 0; y < avctx->height; y++) { |
|
116 |
+ for (x = 0; x < avctx->width; x++) { |
|
117 |
+ int value; |
|
118 |
+ if ((avctx->pix_fmt & 1)) { |
|
119 |
+ value = (AV_RB16(src[0] + 2*x) << 12) |
|
120 |
+ | (AV_RB16(src[1] + 2*x) << 2) |
|
121 |
+ | (AV_RB16(src[2] + 2*x) << 22); |
|
122 |
+ } else { |
|
123 |
+ value = (AV_RL16(src[0] + 2*x) << 12) |
|
124 |
+ | (AV_RL16(src[1] + 2*x) << 2) |
|
125 |
+ | (AV_RL16(src[2] + 2*x) << 22); |
|
126 |
+ } |
|
127 |
+ write32(dst, value); |
|
128 |
+ dst += 4; |
|
129 |
+ } |
|
130 |
+ for (i = 0; i < 3; i++) |
|
131 |
+ src[i] += pic->linesize[i]; |
|
132 |
+ } |
|
133 |
+} |
|
134 |
+ |
|
135 |
+static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t *dst) |
|
136 |
+{ |
|
137 |
+ const uint16_t *src[3] = {(uint16_t*)pic->data[0], |
|
138 |
+ (uint16_t*)pic->data[1], |
|
139 |
+ (uint16_t*)pic->data[2]}; |
|
140 |
+ int x, y, i; |
|
141 |
+ for (y = 0; y < avctx->height; y++) { |
|
142 |
+ for (x = 0; x < avctx->width; x++) { |
|
143 |
+ for (i = 0; i < 3; i++) |
|
144 |
+ *dst++ = *(src[i] + x); |
|
145 |
+ } |
|
146 |
+ for (i = 0; i < 3; i++) |
|
147 |
+ src[i] += pic->linesize[i]/2; |
|
148 |
+ } |
|
149 |
+} |
|
150 |
+ |
|
109 | 151 |
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
110 | 152 |
const AVFrame *frame, int *got_packet) |
111 | 153 |
{ |
... | ... |
@@ -143,7 +199,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
143 | 143 |
buf[801] = 2; /* linear transfer */ |
144 | 144 |
buf[802] = 2; /* linear colorimetric */ |
145 | 145 |
buf[803] = s->bits_per_component; |
146 |
- write16(buf + 804, s->bits_per_component == 10 ? 1 : 0); /* packing method */ |
|
146 |
+ write16(buf + 804, (s->bits_per_component == 10 || s->bits_per_component == 12) ? |
|
147 |
+ 1 : 0); /* packing method */ |
|
147 | 148 |
|
148 | 149 |
/* Image source information header */ |
149 | 150 |
write32(buf + 1628, avctx->sample_aspect_ratio.num); |
... | ... |
@@ -159,7 +216,13 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
159 | 159 |
return size; |
160 | 160 |
break; |
161 | 161 |
case 10: |
162 |
- encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE); |
|
162 |
+ if (s->planar) |
|
163 |
+ encode_gbrp10(avctx, (const AVPicture*)frame, buf + HEADER_SIZE); |
|
164 |
+ else |
|
165 |
+ encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE); |
|
166 |
+ break; |
|
167 |
+ case 12: |
|
168 |
+ encode_gbrp12(avctx, (const AVPicture*)frame, (uint16_t*)(buf + HEADER_SIZE)); |
|
163 | 169 |
break; |
164 | 170 |
default: |
165 | 171 |
av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", s->bits_per_component); |
... | ... |
@@ -190,6 +253,10 @@ AVCodec ff_dpx_encoder = { |
190 | 190 |
PIX_FMT_RGB48BE, |
191 | 191 |
PIX_FMT_RGBA64LE, |
192 | 192 |
PIX_FMT_RGBA64BE, |
193 |
+ PIX_FMT_GBRP10LE, |
|
194 |
+ PIX_FMT_GBRP10BE, |
|
195 |
+ PIX_FMT_GBRP12LE, |
|
196 |
+ PIX_FMT_GBRP12BE, |
|
193 | 197 |
PIX_FMT_NONE}, |
194 | 198 |
.long_name = NULL_IF_CONFIG_SMALL("DPX image"), |
195 | 199 |
}; |