Browse code

dpx: 10 and 12 bit encoding

Encode GBRP10 pixel format into 10 bit DPX.
Encode GBRP12 pixel format into 12 bit DPX.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Georg Lippitsch authored on 2012/08/24 22:24:15
Showing 1 changed files
... ...
@@ -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
 };