[FFmpeg-devel] [PATCH 3/3] lavc/libopenjpegdec: support interlaced layout
Matthieu Bouron
matthieu.bouron at gmail.com
Sat Feb 16 13:52:31 CET 2013
Fixes tickets #1102.
---
libavcodec/libopenjpegdec.c | 61 +++++++++++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 16 deletions(-)
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index eeb3dd6..ad7866c 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -69,6 +69,7 @@ typedef struct {
opj_dparameters_t dec_params;
AVFrame image;
int lowqual;
+ int curpict;
} LibOpenJPEGContext;
static inline int libopenjpeg_matches_pix_fmt(const opj_image_t *image, enum AVPixelFormat pix_fmt)
@@ -149,12 +150,13 @@ static inline int libopenjpeg_ispacked(enum AVPixelFormat pix_fmt)
return 1;
}
-static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) {
+static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image, int field) {
uint8_t *img_ptr;
- int index, x, y, c;
+ int index, x, y, c, line;
for (y = 0; y < picture->height; y++) {
index = y*picture->width;
- img_ptr = picture->data[0] + y*picture->linesize[0];
+ line = picture->interlaced_frame * (field + y) + y;
+ img_ptr = picture->data[0] + line*picture->linesize[0];
for (x = 0; x < picture->width; x++, index++) {
for (c = 0; c < image->numcomps; c++) {
*img_ptr++ = image->comps[c].data[index];
@@ -163,16 +165,17 @@ static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *im
}
}
-static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {
+static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image, int field) {
uint16_t *img_ptr;
- int index, x, y, c;
+ int index, x, y, c, line;
int adjust[4];
for (x = 0; x < image->numcomps; x++)
adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0);
for (y = 0; y < picture->height; y++) {
index = y*picture->width;
- img_ptr = (uint16_t*) (picture->data[0] + y*picture->linesize[0]);
+ line = picture->interlaced_frame * (field + y) + y;
+ img_ptr = (uint16_t*) (picture->data[0] + line*picture->linesize[0]);
for (x = 0; x < picture->width; x++, index++) {
for (c = 0; c < image->numcomps; c++) {
*img_ptr++ = image->comps[c].data[index] << adjust[c];
@@ -181,7 +184,7 @@ static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *i
}
}
-static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
+static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image, int field) {
int *comp_data;
uint8_t *img_ptr;
int index, x, y;
@@ -189,7 +192,8 @@ static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
for (index = 0; index < image->numcomps; index++) {
comp_data = image->comps[index].data;
for (y = 0; y < image->comps[index].h; y++) {
- img_ptr = picture->data[index] + y * picture->linesize[index];
+ int line = picture->interlaced_frame * (field + y) + y;
+ img_ptr = picture->data[index] + line * picture->linesize[index];
for (x = 0; x < image->comps[index].w; x++) {
*img_ptr = (uint8_t) *comp_data;
img_ptr++;
@@ -199,14 +203,15 @@ static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
}
}
-static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
+static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image, int field) {
int *comp_data;
uint16_t *img_ptr;
int index, x, y;
for (index = 0; index < image->numcomps; index++) {
comp_data = image->comps[index].data;
for (y = 0; y < image->comps[index].h; y++) {
- img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]);
+ int line = picture->interlaced_frame * (field + y) + y;
+ img_ptr = (uint16_t*) (picture->data[index] + line * picture->linesize[index]);
for (x = 0; x < image->comps[index].w; x++) {
*img_ptr = *comp_data;
img_ptr++;
@@ -249,9 +254,18 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
int width, height, ret = -1;
int pixel_size = 0;
int ispacked = 0;
+ int field;
int i;
*got_frame = 0;
+ picture->interlaced_frame = avctx->field_order > AV_FIELD_PROGRESSIVE;
+ picture->top_field_first = avctx->field_order == AV_FIELD_TT;
+ field = ctx->curpict ^ !picture->top_field_first;
+
+ if (picture->interlaced_frame && avctx->thread_count > 1) {
+ av_log(avctx, AV_LOG_ERROR, "Interlaced layout does not support threading. Please specify -threads 1 before input.\n");
+ return AVERROR(EINVAL);
+ }
// Check if input is a raw jpeg2k codestream or in jp2 wrapping
if ((AV_RB32(buf) == 12) &&
@@ -297,6 +311,9 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
width = image->x1 - image->x0;
height = image->y1 - image->y0;
+ if (picture->interlaced_frame)
+ height *= 2;
+
if (av_image_check_size(width, height, 0, avctx) < 0) {
av_log(avctx, AV_LOG_ERROR,
"%dx%d dimension invalid.\n", width, height);
@@ -356,28 +373,28 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
switch (pixel_size) {
case 1:
if (ispacked) {
- libopenjpeg_copy_to_packed8(picture, image);
+ libopenjpeg_copy_to_packed8(picture, image, field);
} else {
- libopenjpeg_copyto8(picture, image);
+ libopenjpeg_copyto8(picture, image, field);
}
break;
case 2:
if (ispacked) {
- libopenjpeg_copy_to_packed8(picture, image);
+ libopenjpeg_copy_to_packed8(picture, image, field);
} else {
- libopenjpeg_copyto16(picture, image);
+ libopenjpeg_copyto16(picture, image, field);
}
break;
case 3:
case 4:
if (ispacked) {
- libopenjpeg_copy_to_packed8(picture, image);
+ libopenjpeg_copy_to_packed8(picture, image, field);
}
break;
case 6:
case 8:
if (ispacked) {
- libopenjpeg_copy_to_packed16(picture, image);
+ libopenjpeg_copy_to_packed16(picture, image, field);
}
break;
default:
@@ -389,6 +406,18 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
*got_frame = 1;
ret = buf_size;
+ if (picture->interlaced_frame)
+ switch(ctx->curpict) {
+ case 0:
+ ret = 0;
+ *got_frame = 0;
+ ctx->curpict = 1;
+ break;
+ case 1:
+ ctx->curpict = 0;
+ break;
+ }
+
done:
opj_image_destroy(image);
opj_destroy_decompress(dec);
--
1.8.1.3
More information about the ffmpeg-devel
mailing list