On 09/02/2018 11:32, Carl Eugen Hoyos wrote:
[...] please mention ticket #5639 in the commit message.


I should definitely have indicated this source instead of my copy, my mistake.
Commit message extended with it.
FYI I am running tests on several DPX flavors (to FFV1 and back to DPX, checking that framemd5 is same in order to be sure the lossless compression is really lossless), including the ones in this ticket, I'll post a message in this ticket when I finish and all files are well supported in FFmpeg.

On 09/02/2018 11:39, Carl Eugen Hoyos wrote:

Sorry, I thought you had access to such a sample and we would
just have to test it, no?

I use to stay on a technical side, if the DPX header says alpha I map to alpha (no way to differentiate from an illegitimate content, technically speaking), whatever are the hacks used by users (my goal is to store content with FFV1 in order to save disk space then convert back to DPX when needed, so such hack are the user problem and are not visible by FFmpeg). Sometimes I have contact with the source provider, sometimes not. I think some of the files I get are hacked with infrared instead of alpha, if you are interested in a sample file with infrared-hacked content for sure I'll ask if it is the case for some files I have. But not blocking for the patch IMO (especially because the files I am thinking to are not 12-bit)


One more minor issue:
+                }
+                else {
This is getting very common now (do you know why?),

Different projects, different C style standards, so sometimes some mistakes when people work on several projects. (here, it was due to automatic edition from a code editor having a different standard by default, and I missed it when I reviewed the style)

  please fix it.

Fixed, updated patch attached.
From 986379350bc788701e39e2d6f9fce55b61b5fbb8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Martinez?= <jer...@mediaarea.net>
Date: Thu, 8 Feb 2018 09:22:08 +0100
Subject: [PATCH] avcodec/dpx: Support for RGB and RGBA 12-bit packed decoding

Limited to widths multiple of 8 (RGB) and 2 (RGBA) due to lack of test files 
for such corner case

This partially fixes ticket #5639
---
 libavcodec/dpx.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 66 insertions(+), 3 deletions(-)

diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 1aa2cbd1c8..7535de6c23 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -65,6 +65,38 @@ static uint16_t read10in32(const uint8_t **ptr, uint32_t * 
lbuf,
     return *lbuf & 0x3FF;
 }
 
+static uint16_t read12in32(const uint8_t **ptr, uint32_t * lbuf,
+                                  int * n_datum, int is_big)
+{
+    if (*n_datum)
+        (*n_datum)--;
+    else {
+        *lbuf = read32(ptr, is_big);
+        *n_datum = 7;
+    }
+
+    switch (*n_datum){
+    case 7: return *lbuf & 0xFFF;
+    case 6: return (*lbuf >> 12) & 0xFFF;
+    case 5: {
+            uint32_t c = *lbuf >> 24;
+            *lbuf = read32(ptr, is_big);
+            c |= *lbuf << 8;
+            return c & 0xFFF;
+            }
+    case 4: return (*lbuf >> 4) & 0xFFF;
+    case 3: return (*lbuf >> 16) & 0xFFF;
+    case 2: {
+            uint32_t c = *lbuf >> 28;
+            *lbuf = read32(ptr, is_big);
+            c |= *lbuf << 4;
+            return c & 0xFFF;
+            }
+    case 1: return (*lbuf >> 8) & 0xFFF;
+    default: return *lbuf >> 20;
+    }
+}
+
 static int decode_frame(AVCodecContext *avctx,
                         void *data,
                         int *got_frame,
@@ -201,10 +233,29 @@ static int decode_frame(AVCodecContext *avctx,
         break;
     case 12:
         if (!packing) {
-            av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
-            return -1;
+            int tested = 0;
+            if (endian && descriptor == 50 && (avctx->width%8) == 0) // Little 
endian and widths not a multiple of 8 need tests
+                tested = 1;
+            if (endian && descriptor == 51 && (avctx->width%2) == 0) // Little 
endian and widths not a multiple of 2 need tests
+                tested = 1;
+            if (!tested) {
+                av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
+                return -1;
+            }
+        }
+        stride = avctx->width * elements;
+        if (packing)
+            stride *= 2;
+        else {
+            stride *= 3; // 12 bits are 1.5 byte so multiplied by 3 then 
divided by 2
+            if (stride % 8) {
+                // Align to 32-bit boundaries (not tested)
+                stride /= 8;
+                stride++;
+                stride *= 8;
+            }
+            stride /= 2;
         }
-        stride = 2 * avctx->width * elements;
         break;
     case 16:
         stride = 2 * avctx->width * elements;
@@ -349,6 +400,7 @@ static int decode_frame(AVCodecContext *avctx,
                                 (uint16_t*)ptr[2],
                                 (uint16_t*)ptr[3]};
             for (y = 0; y < avctx->width; y++) {
+                if (packing) {
                 if (elements >= 3)
                     *dst[2]++ = read16(&buf, endian) >> 4;
                 *dst[0] = read16(&buf, endian) >> 4;
@@ -357,6 +409,17 @@ static int decode_frame(AVCodecContext *avctx,
                     *dst[1]++ = read16(&buf, endian) >> 4;
                 if (elements == 4)
                     *dst[3]++ = read16(&buf, endian) >> 4;
+                } else {
+                    *dst[2]++ = read12in32(&buf, &rgbBuffer,
+                                           &n_datum, endian);
+                    *dst[0]++ = read12in32(&buf, &rgbBuffer,
+                                           &n_datum, endian);
+                    *dst[1]++ = read12in32(&buf, &rgbBuffer,
+                                           &n_datum, endian);
+                    if (elements == 4)
+                        *dst[3]++ = read12in32(&buf, &rgbBuffer,
+                                               &n_datum, endian);
+                }
             }
             for (i = 0; i < elements; i++)
                 ptr[i] += p->linesize[i];
-- 
2.13.3.windows.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to