Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Jul 2012 00:49:57 +0000 (02:49 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 21 Jul 2012 02:25:11 +0000 (04:25 +0200)
* qatar/master:
  libopenjpeg: introduce lowres and lowqual private options
  FATE: add a test for flac cover art.
  cafdec: allow larger ALAC magic cookie
  alac: fix channel pointer assignment for 24 and 32-bit

Conflicts:
libavcodec/alac.c
libavcodec/libopenjpegdec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/alac.c
libavcodec/libopenjpegdec.c
libavformat/cafdec.c

@@@ -338,6 -328,10 +334,10 @@@ static int decode_element(AVCodecContex
          return AVERROR_INVALIDDATA;
      }
      alac->nb_samples = output_samples;
 -    if (alac->sample_size > 16) {
++    if (alac->direct_output) {
+         for (ch = 0; ch < channels; ch++)
+             alac->output_samples_buffer[ch] = (int32_t *)alac->frame.extended_data[ch_index + ch];
+     }
  
      if (is_compressed) {
          int16_t lpc_coefs[2][32];
@@@ -24,8 -24,8 +24,9 @@@
  * JPEG 2000 decoder using libopenjpeg
  */
  
+ #include "libavutil/opt.h"
  #include "libavutil/imgutils.h"
 +#include "libavutil/pixfmt.h"
  #include "avcodec.h"
  #include "libavutil/intreadwrite.h"
  #include "thread.h"
  #define JP2_SIG_TYPE    0x6A502020
  #define JP2_SIG_VALUE   0x0D0A870A
  
 +// pix_fmts with lower bpp have to be listed before
 +// similar pix_fmts with higher bpp.
 +#define RGB_PIXEL_FORMATS   PIX_FMT_RGB24,PIX_FMT_RGBA,PIX_FMT_RGB48,PIX_FMT_RGBA64
 +#define GRAY_PIXEL_FORMATS  PIX_FMT_GRAY8,PIX_FMT_GRAY8A,PIX_FMT_GRAY16
 +#define YUV_PIXEL_FORMATS   PIX_FMT_YUV410P,PIX_FMT_YUV411P,PIX_FMT_YUVA420P, \
 +                            PIX_FMT_YUV420P,PIX_FMT_YUV422P,PIX_FMT_YUVA422P, \
 +                            PIX_FMT_YUV440P,PIX_FMT_YUV444P,PIX_FMT_YUVA444P, \
 +                            PIX_FMT_YUV420P9,PIX_FMT_YUV422P9,PIX_FMT_YUV444P9, \
 +                            PIX_FMT_YUV420P10,PIX_FMT_YUV422P10,PIX_FMT_YUV444P10, \
 +                            PIX_FMT_YUV420P12,PIX_FMT_YUV422P12,PIX_FMT_YUV444P12, \
 +                            PIX_FMT_YUV420P14,PIX_FMT_YUV422P14,PIX_FMT_YUV444P14, \
 +                            PIX_FMT_YUV420P16,PIX_FMT_YUV422P16,PIX_FMT_YUV444P16
 +
 +static const enum PixelFormat libopenjpeg_rgb_pix_fmts[]  = {RGB_PIXEL_FORMATS};
 +static const enum PixelFormat libopenjpeg_gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
 +static const enum PixelFormat libopenjpeg_yuv_pix_fmts[]  = {YUV_PIXEL_FORMATS};
 +static const enum PixelFormat libopenjpeg_all_pix_fmts[]  = {RGB_PIXEL_FORMATS,GRAY_PIXEL_FORMATS,YUV_PIXEL_FORMATS};
 +
  typedef struct {
+     AVClass *class;
      opj_dparameters_t dec_params;
      AVFrame image;
 -    int lowres;
+     int lowqual;
  } LibOpenJPEGContext;
  
 -static int check_image_attributes(opj_image_t *image)
 -{
 -    return image->comps[0].dx == image->comps[1].dx &&
 -           image->comps[1].dx == image->comps[2].dx &&
 -           image->comps[0].dy == image->comps[1].dy &&
 -           image->comps[1].dy == image->comps[2].dy &&
 -           image->comps[0].prec == image->comps[1].prec &&
 -           image->comps[1].prec == image->comps[2].prec;
 +static inline int libopenjpeg_matches_pix_fmt(const opj_image_t *image, enum PixelFormat pix_fmt){
 +    AVPixFmtDescriptor descriptor = av_pix_fmt_descriptors[pix_fmt];
 +    int match = 1;
 +
 +    if (descriptor.nb_components != image->numcomps) {
 +        return 0;
 +    }
 +
 +    switch (descriptor.nb_components) {
 +    case 4: match = match && descriptor.comp[3].depth_minus1 + 1 >= image->comps[3].prec &&
 +                             1 == image->comps[3].dx &&
 +                             1 == image->comps[3].dy;
 +    case 3: match = match && descriptor.comp[2].depth_minus1 + 1 >= image->comps[2].prec &&
 +                             1 << descriptor.log2_chroma_w == image->comps[2].dx &&
 +                             1 << descriptor.log2_chroma_h == image->comps[2].dy;
 +    case 2: match = match && descriptor.comp[1].depth_minus1 + 1 >= image->comps[1].prec &&
 +                             1 << descriptor.log2_chroma_w == image->comps[1].dx &&
 +                             1 << descriptor.log2_chroma_h == image->comps[1].dy;
 +    case 1: match = match && descriptor.comp[0].depth_minus1 + 1 >= image->comps[0].prec &&
 +                             1 == image->comps[0].dx &&
 +                             1 == image->comps[0].dy;
 +    default:
 +        break;
 +    }
 +
 +    return match;
 +}
 +
 +static inline enum PixelFormat libopenjpeg_guess_pix_fmt(const opj_image_t *image) {
 +    int index;
 +    const enum PixelFormat *possible_fmts = NULL;
 +    int possible_fmts_nb = 0;
 +
 +    switch (image->color_space) {
 +    case CLRSPC_SRGB:
 +        possible_fmts = libopenjpeg_rgb_pix_fmts;
 +        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_rgb_pix_fmts);
 +        break;
 +    case CLRSPC_GRAY:
 +        possible_fmts = libopenjpeg_gray_pix_fmts;
 +        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_gray_pix_fmts);
 +        break;
 +    case CLRSPC_SYCC:
 +        possible_fmts = libopenjpeg_yuv_pix_fmts;
 +        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_yuv_pix_fmts);
 +        break;
 +    default:
 +        possible_fmts = libopenjpeg_all_pix_fmts;
 +        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_all_pix_fmts);
 +        break;
 +    }
 +
 +    for (index = 0; index < possible_fmts_nb; ++index) {
 +        if (libopenjpeg_matches_pix_fmt(image, possible_fmts[index])) {
 +            return possible_fmts[index];
 +        }
 +    }
 +
 +    return PIX_FMT_NONE;
 +}
 +
 +static inline int libopenjpeg_ispacked(enum PixelFormat pix_fmt) {
 +    int i, component_plane;
 +
 +    if (pix_fmt == PIX_FMT_GRAY16)
 +        return 0;
 +
 +    component_plane = av_pix_fmt_descriptors[pix_fmt].comp[0].plane;
 +    for(i = 1; i < av_pix_fmt_descriptors[pix_fmt].nb_components; i++) {
 +        if (component_plane != av_pix_fmt_descriptors[pix_fmt].comp[i].plane)
 +            return 0;
 +    }
 +    return 1;
 +}
 +
 +static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) {
 +    uint8_t *img_ptr;
 +    int index, x, y, c;
 +    for(y = 0; y < picture->height; y++) {
 +        index = y*picture->width;
 +        img_ptr = picture->data[0] + y*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];
 +            }
 +        }
 +    }
 +}
 +
 +static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {
 +    uint16_t *img_ptr;
 +    int index, x, y, c;
 +    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]);
 +        for (x = 0; x < picture->width; x++, index++) {
 +            for (c = 0; c < image->numcomps; c++) {
 +                *img_ptr++ = image->comps[c].data[index] << adjust[c];
 +            }
 +        }
 +    }
 +}
 +
 +static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
 +    int *comp_data;
 +    uint8_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 = picture->data[index] + y * picture->linesize[index];
 +            for(x = 0; x < image->comps[index].w; x++) {
 +                *img_ptr = (uint8_t) *comp_data;
 +                img_ptr++;
 +                comp_data++;
 +            }
 +        }
 +    }
 +}
 +
 +static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
 +    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]);
 +            for(x = 0; x < image->comps[index].w; x++) {
 +                *img_ptr = *comp_data;
 +                img_ptr++;
 +                comp_data++;
 +            }
 +        }
 +    }
  }
  
  static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
@@@ -254,8 -106,10 +257,9 @@@ static int libopenjpeg_decode_frame(AVC
          return -1;
      }
      opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
--
      ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
 -    ctx->dec_params.cp_reduce = ctx->lowres;
++    ctx->dec_params.cp_reduce = avctx->lowres;
+     ctx->dec_params.cp_layer  = ctx->lowqual;
      // Tie decoder with decoding parameters
      opj_setup_decoder(dec, &ctx->dec_params);
      stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
      }
      width  = image->x1 - image->x0;
      height = image->y1 - image->y0;
 -    if (ctx->lowres) {
 -        width  = (width + (1 << ctx->lowres) - 1) >> ctx->lowres;
 -        height = (height + (1 << ctx->lowres) - 1) >> ctx->lowres;
 -    }
 -
      if(av_image_check_size(width, height, 0, avctx) < 0) {
          av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
          goto done;
@@@ -380,6 -220,21 +385,20 @@@ static av_cold int libopenjpeg_decode_c
      return 0 ;
  }
  
 -    { "lowres",        "Lower the decoding resolution by a power of two",      OFFSET(lowres),         AV_OPT_TYPE_INT,   { 0 }, 0, INT_MAX, VD },
+ #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
+ #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+ static const AVOption options[] = {
+     { "lowqual",       "Limit the number of layers used for decoding",         OFFSET(lowqual),        AV_OPT_TYPE_INT,   { 0 }, 0, INT_MAX, VD },
+     { NULL },
+ };
+ static const AVClass class = {
+     .class_name = "libopenjpeg",
+     .item_name  = av_default_item_name,
+     .option     = options,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
  
  AVCodec ff_libopenjpeg_decoder = {
      .name             = "libopenjpeg",
      .close            = libopenjpeg_decode_close,
      .decode           = libopenjpeg_decode_frame,
      .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
 -    .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
 +    .max_lowres       = 5,
 +    .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
+     .priv_class       = &class,
      .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy),
  };
Simple merge