Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Lippitsch <georg.lippitsch@gmx.at>2012-08-26 16:51:13 +0400
committerMichael Niedermayer <michaelni@gmx.at>2012-08-27 20:31:21 +0400
commit5cc5d9d5f7ea2231490d11cf2a28350ebb3f06ab (patch)
treeb7e0309d01cd7d7d541c599bc1a635d2cdf1cbe8
parent99f50907143b096009682481ba4c5129ab65149e (diff)
dpx: 10 and 12 bit decoding
Rewrite 10 bit dpx decoder to decode into GBRP10 color space instead of converting to RGB48. Add 12 bit decoder to decode into GBRP12 color space. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/dpx.c87
-rw-r--r--tests/ref/lavf/dpx2
2 files changed, 58 insertions, 31 deletions
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 5e35005776..71cf4392de 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -41,14 +41,6 @@ static unsigned int read32(const uint8_t **ptr, int is_big)
return temp;
}
-static inline unsigned make_16bit(unsigned value)
-{
- // mask away invalid bits
- value &= 0xFFC0;
- // correctly expand to 16 bits
- return value + (value >> 10);
-}
-
static int decode_frame(AVCodecContext *avctx,
void *data,
int *data_size,
@@ -60,12 +52,13 @@ static int decode_frame(AVCodecContext *avctx,
DPXContext *const s = avctx->priv_data;
AVFrame *picture = data;
AVFrame *const p = &s->picture;
- uint8_t *ptr;
+ uint8_t *ptr[AV_NUM_DATA_POINTERS];
unsigned int offset;
int magic_num, endian;
- int x, y;
+ int x, y, i;
int w, h, stride, bits_per_color, descriptor, elements, target_packet_size, source_packet_size;
+ int planar;
unsigned int rgbBuffer;
@@ -138,13 +131,24 @@ static int decode_frame(AVCodecContext *avctx,
}
source_packet_size = elements;
target_packet_size = elements;
+ planar = 0;
break;
case 10:
- avctx->pix_fmt = PIX_FMT_RGB48;
+ avctx->pix_fmt = PIX_FMT_GBRP10;
target_packet_size = 6;
source_packet_size = 4;
+ planar = 1;
break;
case 12:
+ if (endian) {
+ avctx->pix_fmt = elements == 4 ? PIX_FMT_GBRP12BE : PIX_FMT_GBRP12BE;
+ } else {
+ avctx->pix_fmt = elements == 4 ? PIX_FMT_GBRP12LE : PIX_FMT_GBRP12LE;
+ }
+ target_packet_size = 6;
+ source_packet_size = 6;
+ planar = 1;
+ break;
case 16:
if (endian) {
avctx->pix_fmt = elements == 4 ? PIX_FMT_RGBA64BE : PIX_FMT_RGB48BE;
@@ -153,6 +157,7 @@ static int decode_frame(AVCodecContext *avctx,
}
target_packet_size =
source_packet_size = elements * 2;
+ planar = 0;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color);
@@ -173,7 +178,8 @@ static int decode_frame(AVCodecContext *avctx,
// Move pointer to offset from start of file
buf = avpkt->data + offset;
- ptr = p->data[0];
+ for (i=0; i<AV_NUM_DATA_POINTERS; i++)
+ ptr[i] = p->data[i];
stride = p->linesize[0];
if (source_packet_size*avctx->width*avctx->height > buf_end - buf) {
@@ -183,35 +189,56 @@ static int decode_frame(AVCodecContext *avctx,
switch (bits_per_color) {
case 10:
for (x = 0; x < avctx->height; x++) {
- uint16_t *dst = (uint16_t*)ptr;
+ uint16_t *dst[3] = {(uint16_t*)ptr[0],
+ (uint16_t*)ptr[1],
+ (uint16_t*)ptr[2]};
for (y = 0; y < avctx->width; y++) {
rgbBuffer = read32(&buf, endian);
- // Read out the 10-bit colors and convert to 16-bit
- *dst++ = make_16bit(rgbBuffer >> 16);
- *dst++ = make_16bit(rgbBuffer >> 6);
- *dst++ = make_16bit(rgbBuffer << 4);
+ *dst[0]++ = (rgbBuffer >> 12) & 0x3FF;
+ *dst[1]++ = (rgbBuffer >> 2) & 0x3FF;
+ *dst[2]++ = (rgbBuffer >> 22) & 0x3FF;
}
- ptr += stride;
+ for (i=0; i<3; i++)
+ ptr[i] += p->linesize[i];
}
break;
case 8:
- case 12: // Treat 12-bit as 16-bit
+ case 12:
case 16:
- if (source_packet_size == target_packet_size) {
+ if (planar) {
+ int source_bpc = target_packet_size / elements;
+ int target_bpc = target_packet_size / elements;
for (x = 0; x < avctx->height; x++) {
- memcpy(ptr, buf, target_packet_size*avctx->width);
- ptr += stride;
- buf += source_packet_size*avctx->width;
+ uint8_t *dst[AV_NUM_DATA_POINTERS];
+ for (i=0; i<elements; i++)
+ dst[i] = ptr[i];
+ for (y = 0; y < avctx->width; y++) {
+ for (i=0; i<3; i++) {
+ memcpy(dst[i], buf, FFMIN(source_bpc, target_bpc));
+ dst[i] += target_bpc;
+ buf += source_bpc;
+ }
+ }
+ for (i=0; i<elements; i++)
+ ptr[i] += p->linesize[i];
}
} else {
- for (x = 0; x < avctx->height; x++) {
- uint8_t *dst = ptr;
- for (y = 0; y < avctx->width; y++) {
- memcpy(dst, buf, target_packet_size);
- dst += target_packet_size;
- buf += source_packet_size;
+ if (source_packet_size == target_packet_size) {
+ for (x = 0; x < avctx->height; x++) {
+ memcpy(ptr[0], buf, target_packet_size*avctx->width);
+ ptr[0] += stride;
+ buf += source_packet_size*avctx->width;
+ }
+ } else {
+ for (x = 0; x < avctx->height; x++) {
+ uint8_t *dst = ptr[0];
+ for (y = 0; y < avctx->width; y++) {
+ memcpy(dst, buf, target_packet_size);
+ dst += target_packet_size;
+ buf += source_packet_size;
+ }
+ ptr[0] += stride;
}
- ptr += stride;
}
}
break;
diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx
index 2160809169..1196934836 100644
--- a/tests/ref/lavf/dpx
+++ b/tests/ref/lavf/dpx
@@ -5,5 +5,5 @@
./tests/data/images/dpx/%02d.dpx CRC=0xe5b9c023
609920 ./tests/data/images/dpx/02.dpx
13dc41b1e1e36399a5e1f8b7e3344a81 *./tests/data/images/dpx/02.dpx
-./tests/data/images/dpx/%02d.dpx CRC=0xf38d5830
+./tests/data/images/dpx/%02d.dpx CRC=0xf0a1c097
407168 ./tests/data/images/dpx/02.dpx