[FFmpeg-devel] [PATCH 2/2] dpx: 10 and 12 bit encoding

Georg Lippitsch georg.lippitsch at gmx.at
Fri Aug 24 15:24:15 CEST 2012


Encode GBRP10 pixel format into 10 bit DPX.
Encode GBRP12 pixel format into 12 bit DPX.
---
 libavcodec/dpxenc.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index 09ab14a..451b7b9 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -30,6 +30,7 @@ typedef struct DPXContext {
     int big_endian;
     int bits_per_component;
     int descriptor;
+    int planar;
 } DPXContext;
 
 static av_cold int encode_init(AVCodecContext *avctx)
@@ -43,6 +44,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     s->big_endian         = 1;
     s->bits_per_component = 8;
     s->descriptor         = 50; /* RGB */
+    s->planar             = 0;
 
     switch (avctx->pix_fmt) {
     case PIX_FMT_RGB24:
@@ -61,6 +63,18 @@ static av_cold int encode_init(AVCodecContext *avctx)
         s->descriptor = 51;
         s->bits_per_component = 16;
         break;
+    case PIX_FMT_GBRP10LE:
+        s->big_endian = 0;
+    case PIX_FMT_GBRP10BE:
+        s->bits_per_component = 10;
+        s->planar = 1;
+        break;
+    case PIX_FMT_GBRP12LE:
+        s->big_endian = 0;
+    case PIX_FMT_GBRP12BE:
+        s->bits_per_component = 12;
+        s->planar = 1;
+        break;
     default:
         av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
         return -1;
@@ -106,6 +120,48 @@ static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, uint
     }
 }
 
+static void encode_gbrp10(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst)
+{
+    DPXContext *s = avctx->priv_data;
+    const uint8_t *src[3] = {pic->data[0], pic->data[1], pic->data[2]};
+    int x, y, i;
+
+    for (y = 0; y < avctx->height; y++) {
+        for (x = 0; x < avctx->width; x++) {
+            int value;
+            if ((avctx->pix_fmt & 1)) {
+                value = (AV_RB16(src[0] + 2*x) << 12)
+                      | (AV_RB16(src[1] + 2*x) << 2)
+                      | (AV_RB16(src[2] + 2*x) << 22);
+            } else {
+                value = (AV_RL16(src[0] + 2*x) << 12)
+                      | (AV_RL16(src[1] + 2*x) << 2)
+                      | (AV_RL16(src[2] + 2*x) << 22);
+            }
+            write32(dst, value);
+            dst += 4;
+        }
+        for (i = 0; i < 3; i++)
+            src[i] += pic->linesize[i];
+    }
+}
+
+static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t *dst)
+{
+    const uint16_t *src[3] = {(uint16_t*)pic->data[0],
+                              (uint16_t*)pic->data[1],
+                              (uint16_t*)pic->data[2]};
+    int x, y, i;
+    for (y = 0; y < avctx->height; y++) {
+        for (x = 0; x < avctx->width; x++) {
+            for (i = 0; i < 3; i++)
+                *dst++ = *(src[i] + x);
+        }
+        for (i = 0; i < 3; i++)
+            src[i] += pic->linesize[i]/2;
+    }
+}
+
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *frame, int *got_packet)
 {
@@ -143,7 +199,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     buf[801] = 2; /* linear transfer */
     buf[802] = 2; /* linear colorimetric */
     buf[803] = s->bits_per_component;
-    write16(buf + 804, s->bits_per_component == 10 ? 1 : 0); /* packing method */
+    write16(buf + 804, (s->bits_per_component == 10 || s->bits_per_component == 12) ?
+                       1 : 0); /* packing method */
 
     /* Image source information header */
     write32(buf + 1628, avctx->sample_aspect_ratio.num);
@@ -159,7 +216,13 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
             return size;
         break;
     case 10:
-        encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
+        if (s->planar)
+            encode_gbrp10(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
+        else
+            encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
+        break;
+    case 12:
+        encode_gbrp12(avctx, (const AVPicture*)frame, (uint16_t*)(buf + HEADER_SIZE));
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", s->bits_per_component);
@@ -190,6 +253,10 @@ AVCodec ff_dpx_encoder = {
         PIX_FMT_RGB48BE,
         PIX_FMT_RGBA64LE,
         PIX_FMT_RGBA64BE,
+        PIX_FMT_GBRP10LE,
+        PIX_FMT_GBRP10BE,
+        PIX_FMT_GBRP12LE,
+        PIX_FMT_GBRP12BE,
         PIX_FMT_NONE},
     .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
 };
-- 
1.7.3.4



More information about the ffmpeg-devel mailing list