On Thu, Oct 18, 2012 at 04:00:02AM +0200, Luca Barbato wrote:
> Code mainly written by Carl Eugen Hoyos, Michael Niedermayer, Paul B
> Mahol.
> ---
> 
> Here the initial patch, it is a tad monstruous and probably could be
> split in two chunks nicely sooner or later.
> 
>  libavcodec/ffv1.c | 1124 
> ++++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 815 insertions(+), 309 deletions(-)
> 
> diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
> index f290b94..0d5cfcd 100644
> --- a/libavcodec/ffv1.c
> +++ b/libavcodec/ffv1.c
[...]
> @@ -565,56 +582,81 @@ static void encode_plane(FFV1Context *s, uint8_t *src, 
> int w, int h,
>          sample[0][-1] = sample[1][0];
>          sample[1][w]  = sample[1][w - 1];
>  // { START_TIMER
> -        if (s->avctx->bits_per_raw_sample <= 8) {
> +        if (s->bits_per_raw_sample <= 8) {
>              for (x = 0; x < w; x++)
>                  sample[0][x] = src[x + stride * y];
>              encode_line(s, w, sample, plane_index, 8);
>          } else {
> -            for (x = 0; x < w; x++)
> -                sample[0][x] = ((uint16_t *)(src + stride * y))[x] >>
> -                               (16 - s->avctx->bits_per_raw_sample);
> -            encode_line(s, w, sample, plane_index, 
> s->avctx->bits_per_raw_sample);
> +            if (s->packed_at_lsb) {
> +                for (x = 0; x < w; x++)
> +                    sample[0][x] = ((uint16_t *)(src + stride * y))[x];
> +            } else {
> +                for (x = 0; x < w; x++)
> +                    sample[0][x] =
> +                        ((uint16_t *)(src + stride *
> +                                      y))[x] >> (16 - 
> s->bits_per_raw_sample);

Does Diego approve that formatting?
Also I'd merge these - the loops differ only by shift parameters, but I don't
care about minicycles obviously.

> +            }
> +            encode_line(s, w, sample, plane_index, s->bits_per_raw_sample);
>          }
>  // STOP_TIMER("encode line") }
>      }
>  }
>  
> -static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h,
> -                             int stride)
> +static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h,
> +                             int stride[3])
>  {
>      int x, y, p, i;
>      const int ring_size = s->avctx->context_model ? 3 : 2;
> -    int16_t *sample[3][3];
> +    int16_t *sample[MAX_PLANES][3];
> +    int lbd  = s->avctx->bits_per_raw_sample <= 8;
> +    int bits = s->avctx->bits_per_raw_sample >
> +               0 ? s->avctx->bits_per_raw_sample : 8;

what would Diego say?

[...]
>  
> +    v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0,
> +                                f->avctx->extradata,
> +                                f->avctx->extradata_size);

weird alignment

> +    AV_WL32(f->avctx->extradata + f->avctx->extradata_size, v);
> +    f->avctx->extradata_size += 4;
> +
>      return 0;
>  }
>  
[...]
> @@ -896,21 +971,133 @@ static int sort_stt(FFV1Context *s, uint8_t stt[256])
>      return print;
>  }
>  
> -static av_cold int encode_init(AVCodecContext *avctx)
> +static av_cold int ffv1_encode_init(AVCodecContext *avctx)
>  {
>      FFV1Context *s = avctx->priv_data;
> +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
>      int i, j, k, m;
>  
>      common_init(avctx);
>  
>      s->version = 0;
> -    s->ac      = avctx->coder_type ? 2 : 0;
> +
> +    if ((avctx->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) ||
> +        avctx->slices > 1)
> +        s->version = FFMAX(s->version, 2);
> +
> +    if (avctx->level == 3) {
> +        s->version = 3;
> +    }
> +
> +    if (s->ec < 0) {
> +        s->ec = (s->version >= 3);
> +    }
> +
> +    if (s->version >= 2 &&
> +        avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
> +        av_log(avctx, AV_LOG_ERROR,
> +               "Version %d requested, please set -strict experimental in "
> +               "order to enable it\n",
> +               s->version);
> +        return AVERROR(ENOSYS);
> +    }
> +
> +    s->ac = avctx->coder_type > 0 ? 2 : 0;
> +
> +    s->plane_count = 3;
> +    switch (avctx->pix_fmt) {
> +    case AV_PIX_FMT_YUV444P9:
> +    case AV_PIX_FMT_YUV422P9:
> +    case AV_PIX_FMT_YUV420P9:
> +        if (!avctx->bits_per_raw_sample)
> +            s->bits_per_raw_sample = 9;
> +    case AV_PIX_FMT_YUV444P10:
> +    case AV_PIX_FMT_YUV420P10:
> +    case AV_PIX_FMT_YUV422P10:
> +        s->packed_at_lsb = 1;
> +        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
> +            s->bits_per_raw_sample = 10;
> +    case AV_PIX_FMT_GRAY16:
> +    case AV_PIX_FMT_YUV444P16:
> +    case AV_PIX_FMT_YUV422P16:
> +    case AV_PIX_FMT_YUV420P16:
> +        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) {
> +            s->bits_per_raw_sample = 16;
> +        } else if (!s->bits_per_raw_sample) {
> +            s->bits_per_raw_sample = avctx->bits_per_raw_sample;
> +        }
> +        if (s->bits_per_raw_sample <= 8) {
> +            av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n");
> +            return AVERROR_INVALIDDATA;
> +        }
> +        if (!s->ac && avctx->coder_type == -1) {
> +            av_log(avctx, AV_LOG_INFO,
> +                   "bits_per_raw_sample > 8, forcing coder 1\n");
> +            s->ac = 2;
> +        }
> +        if (!s->ac) {
> +            av_log(
> +                avctx, AV_LOG_ERROR,
> +                "bits_per_raw_sample of more than 8 needs -coder 1 
> currently\n");
> +            return AVERROR_INVALIDDATA;
> +        }
> +        s->version = FFMAX(s->version, 1);
> +    case AV_PIX_FMT_GRAY8:
> +    case AV_PIX_FMT_YUV444P:
> +    case AV_PIX_FMT_YUV440P:
> +    case AV_PIX_FMT_YUV422P:
> +    case AV_PIX_FMT_YUV420P:
> +    case AV_PIX_FMT_YUV411P:
> +    case AV_PIX_FMT_YUV410P:
> +        s->chroma_planes = desc->nb_components < 3 ? 0 : 1;
> +        s->colorspace    = 0;
> +        break;
> +    case AV_PIX_FMT_YUVA444P:
> +    case AV_PIX_FMT_YUVA422P:
> +    case AV_PIX_FMT_YUVA420P:
> +        s->chroma_planes = 1;
> +        s->colorspace    = 0;
> +        s->transparency  = 1;
> +        break;
> +    case AV_PIX_FMT_RGB32:
> +        s->colorspace   = 1;
> +        s->transparency = 1;
> +        break;
> +    case AV_PIX_FMT_GBRP9:
> +        if (!avctx->bits_per_raw_sample)
> +            s->bits_per_raw_sample = 9;
> +    case AV_PIX_FMT_GBRP10:
> +        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
> +            s->bits_per_raw_sample = 10;
> +    case AV_PIX_FMT_GBRP16:
> +        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
> +            s->bits_per_raw_sample = 16;
> +        else if (!s->bits_per_raw_sample)
> +            s->bits_per_raw_sample = avctx->bits_per_raw_sample;
> +        s->colorspace    = 1;
> +        s->chroma_planes = 1;
> +        s->version       = FFMAX(s->version, 1);
> +        break;
> +    default:
> +        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +    if (s->transparency) {
> +        av_log(
> +            avctx, AV_LOG_WARNING,
> +            "Storing alpha plane, this will require a recent FFV1 decoder to 
> playback!\n");
> +    }
> +    if (avctx->context_model > 1U) {
> +        av_log(avctx, AV_LOG_ERROR,
> +               "Invalid context model %d, valid values are 0 and 1\n",
> +               avctx->context_model);
> +        return AVERROR(EINVAL);
> +    }

This colourspace selection looks unnecessarily overcomplicated.
  
>      if (s->ac > 1)
>          for (i = 1; i < 256; i++)
>              s->state_transition[i] = ver2_state[i];
>  
> -    s->plane_count = 2;
>      for (i = 0; i < 256; i++) {
>          s->quant_table_count = 2;
>          if (avctx->bits_per_raw_sample <= 8) {
[...]
> @@ -1421,86 +1638,210 @@ static void decode_plane(FFV1Context *s, uint8_t 
> *src,
>          } else {
>              decode_line(s, w, sample, plane_index,
>                          s->avctx->bits_per_raw_sample);
> -            for (x = 0; x < w; x++)
> -                ((uint16_t *)(src + stride * y))[x] =
> -                    sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
> +            if (s->packed_at_lsb) {
> +                for (x = 0; x < w; x++)
> +                    ((uint16_t *)(src + stride * y))[x] = sample[1][x];
> +            } else {
> +                for (x = 0; x < w; x++)
> +                    ((uint16_t *)(src + stride *
> +                                  y))[x] = sample[1][x] <<
> +                                           (16 - 
> s->avctx->bits_per_raw_sample);
> +            }

see above

[...]
> +        } else if (f->avctx->bits_per_raw_sample <= 8 && !f->transparency) {
>              switch (16 * f->chroma_h_shift + f->chroma_v_shift) {
> -            case 0x00:
> -                f->avctx->pix_fmt = AV_PIX_FMT_YUV444P;
> +            case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P;
> +                break;
> +            case 0x01: f->avctx->pix_fmt = AV_PIX_FMT_YUV440P;
>                  break;
> -            case 0x10:
> -                f->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
> +            case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
>                  break;
> -            case 0x11:
> -                f->avctx->pix_fmt = AV_PIX_FMT_YUV420P;
> +            case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P;
>                  break;
> -            case 0x20:
> -                f->avctx->pix_fmt = AV_PIX_FMT_YUV411P;
> +            case 0x20: f->avctx->pix_fmt = AV_PIX_FMT_YUV411P;
>                  break;
> -            case 0x22:
> -                f->avctx->pix_fmt = AV_PIX_FMT_YUV410P;
> +            case 0x22: f->avctx->pix_fmt = AV_PIX_FMT_YUV410P;
>                  break;

either leave it as as is or do it in one line (including break)

[...]

in general it doesn't look that bad
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to