Skip to content
Snippets Groups Projects
ffv1.c 34.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Michael Niedermayer's avatar
    Michael Niedermayer committed
        }else if(f->colorspace==1){
            if(f->chroma_h_shift || f->chroma_v_shift){
    
                av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n");
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                return -1;
            }
    
            f->avctx->pix_fmt= PIX_FMT_RGB32;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        }else{
    
            av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
    
    //printf("%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift,f->avctx->pix_fmt);
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        context_count=1;
        for(i=0; i<5; i++){
            context_count*= read_quant_table(c, f->quant_table[i], context_count);
    
            if(context_count < 0 || context_count > 32768){
    
                av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        }
        context_count= (context_count+1)/2;
    
        for(i=0; i<f->plane_count; i++){
            PlaneContext * const p= &f->plane[i];
    
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            p->context_count= context_count;
    
            if(f->ac){
                if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
            }else{
                if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
            }
    
    static av_cold int decode_init(AVCodecContext *avctx)
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    //    FFV1Context *s = avctx->priv_data;
    
    static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){
        const uint8_t *buf = avpkt->data;
        int buf_size = avpkt->size;
    
        RangeCoder * const c= &f->c;
    
        const int width= f->width;
        const int height= f->height;
        AVFrame * const p= &f->picture;
        int bytes_read;
    
        uint8_t keystate= 128;
    
        ff_init_range_decoder(c, buf, buf_size);
        ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
    
        if(get_rac(c, &keystate)){
    
            if(read_header(f) < 0)
                return -1;
    
        if(!f->plane[0].state && !f->plane[0].vlc_state)
            return -1;
    
    
        p->reference= 0;
        if(avctx->get_buffer(avctx, p) < 0){
    
            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
    
            av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        if(!f->ac){
    
            bytes_read = c->bytestream - c->bytestream_start - 1;
            if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
    //printf("pos=%d\n", bytes_read);
            init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        } else {
            bytes_read = 0; /* avoid warning */
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        if(f->colorspace==0){
    
            const int chroma_width = -((-width )>>f->chroma_h_shift);
            const int chroma_height= -((-height)>>f->chroma_v_shift);
            decode_plane(f, p->data[0], width, height, p->linesize[0], 0);
    
            decode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1);
    
            decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        }else{
            decode_rgb_frame(f, (uint32_t*)p->data[0], width, height, p->linesize[0]/4);
    
        avctx->release_buffer(avctx, p); //FIXME
    
        *data_size = sizeof(AVFrame);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        if(f->ac){
    
            bytes_read= c->bytestream - c->bytestream_start - 1;
    
            if(bytes_read ==0) av_log(f->avctx, AV_LOG_ERROR, "error at end of frame\n");
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        }else{
            bytes_read+= (get_bits_count(&f->gb)+7)/8;
        }
    
    
    Loren Merritt's avatar
    Loren Merritt committed
        common_end,
    
        CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
    
        .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
    
    #if CONFIG_FFV1_ENCODER
    
    Loren Merritt's avatar
    Loren Merritt committed
        common_end,
    
        .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE},
    
        .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),