diff mbox

[FFmpeg-devel] lavc/dpx: Support 10-bit packing method b (msbpad)

Message ID CAB0OVGokov_4B2vWwAT+=TnV_6oDvb5vOvkq-nVAHU8DhoSf6Q@mail.gmail.com
State Superseded
Headers show

Commit Message

Carl Eugen Hoyos June 16, 2018, 3:49 p.m. UTC
Hi!

Attached patch allows to decode 10-bit dpx files with packing method
b, needs the 12-bit patch.

Please comment, Carl Eugen

Comments

Jerome Martinez June 16, 2018, 7:32 p.m. UTC | #1
On 16/06/2018 17:49, Carl Eugen Hoyos wrote:
> Hi!
>
> Attached patch allows to decode 10-bit dpx files with packing method
> b, needs the 12-bit patch.

Great to see the support of Method B.

>
> Please comment, Carl Eugen
> [...]
>
> +    *lbuf = (*lbuf << 10) | (*lbuf >> shift);
>

Padding bits are 0 in all DPX files I have seen up to now but in theory 
padding bits are not defined (they are set to 0 in an informative part 
of the spec, the one containing diagrams, which does not mean that they 
must be 0 as it is only an informative part; I don't see elsewhere in 
the spec that padding bits must be 0, I understand that value of padding 
bits are not defined so could be any)

Example of impact on the suggested patch if padding bits are 1:

Method A (shift is 22), hat is currently in FFmpeg:
CCCCCCCCCCBBBBBBBBBBAAAAAAAAAA11 initial after read32 then
BBBBBBBBBBAAAAAAAAAA11CCCCCCCCCC so CCCCCCCCCC with 0x3FF mask then
AAAAAAAAAA11CCCCCCCCCCBBBBBBBBBB so BBBBBBBBBB with 0x3FF mask then
11CCCCCCCCCCBBBBBBBBBBAAAAAAAAAA so AAAAAAAAAA with 0x3FF mask
Padding bits are never used, so they can have any value without impact 
on the pixels

Method B (shift is 20)
11CCCCCCCCCCBBBBBBBBBBAAAAAAAAAA initial after read32 then
CCBBBBBBBBBBAAAAAAAA11CCCCCCCCCC so CCCCCCCCCC with 0x3FF mask then
BBAAAAAAAA11CCCCCCCC??BBBBBBBBBB so BBBBBBBBBB with 0x3FF mask then
11CCCCCCCC??BBBBBBBB??AAAAAAAA11 so AAAAAAAA11 with 0x3FF mask
the last component is "corrupted" by the padding bits if they are not 0.

I suggest to not expect that padding bits are 0 (to not depend on their 
value for filling the pixel content).
For example, by using:
int shift = packing == 1 ? 0 : 2;
then in read10in32() add "<< shift" after read32 call:
*lbuf = read32(ptr, is_big) << shift;
in order to transform Method B in Method A.

Similar issue with 12-bit Method B support (No 0xFFF mask so MSB bits 
may contain 1, which is maybe not expected in other parts of FFmpeg and 
may lead to weird output if padding bits are not 0, by having pixel 
content greater than 1^12-1)

Jérôme
diff mbox

Patch

From 401bdebba6dc8fa2253c720107a971b3fbf2c312 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Sat, 16 Jun 2018 17:47:46 +0200
Subject: [PATCH] lavc/dpx: Support 10-bit packing method b (msbpad).

---
 libavcodec/dpx.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 69d594b..0650a20 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -51,7 +51,7 @@  static unsigned int read32(const uint8_t **ptr, int is_big)
 }
 
 static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
-                                  int * n_datum, int is_big)
+                                  int * n_datum, int is_big, int shift)
 {
     if (*n_datum)
         (*n_datum)--;
@@ -60,7 +60,7 @@  static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
         *n_datum = 2;
     }
 
-    *lbuf = (*lbuf << 10) | (*lbuf >> 22);
+    *lbuf = (*lbuf << 10) | (*lbuf >> shift);
 
     return *lbuf & 0x3FF;
 }
@@ -221,7 +221,7 @@  static int decode_frame(AVCodecContext *avctx,
         stride = avctx->width * elements;
         break;
     case 10:
-        if (!packing || packing > 1) {
+        if (!packing) {
             av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
             return -1;
         }
@@ -360,17 +360,18 @@  static int decode_frame(AVCodecContext *avctx,
                                 (uint16_t*)ptr[1],
                                 (uint16_t*)ptr[2],
                                 (uint16_t*)ptr[3]};
+            int shift = packing == 1 ? 22 : 20;
             for (y = 0; y < avctx->width; y++) {
                 *dst[2]++ = read10in32(&buf, &rgbBuffer,
-                                       &n_datum, endian);
+                                       &n_datum, endian, shift);
                 *dst[0]++ = read10in32(&buf, &rgbBuffer,
-                                       &n_datum, endian);
+                                       &n_datum, endian, shift);
                 *dst[1]++ = read10in32(&buf, &rgbBuffer,
-                                       &n_datum, endian);
+                                       &n_datum, endian, shift);
                 if (elements == 4)
                     *dst[3]++ =
                     read10in32(&buf, &rgbBuffer,
-                               &n_datum, endian);
+                               &n_datum, endian, shift);
             }
             n_datum = 0;
             for (i = 0; i < elements; i++)
-- 
1.7.10.4