⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mjpeg.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
    s->picture_number++;    flush_put_bits(&s->pb);    return pbBufPtr(&s->pb) - s->pb.buf;//    return (put_bits_count(&f->pb)+7)/8;}#endif //CONFIG_ENCODERS/******************************************//* decoding */#define MAX_COMPONENTS 4typedef struct MJpegDecodeContext {    AVCodecContext *avctx;    GetBitContext gb;    int mpeg_enc_ctx_allocated; /* true if decoding context allocated */    int start_code; /* current start code */    int buffer_size;    uint8_t *buffer;    int16_t quant_matrixes[4][64];    VLC vlcs[2][4];    int qscale[4];      ///< quantizer scale calculated from quant_matrixes    int org_height;  /* size given at codec init */    int first_picture;    /* true if decoding first picture */    int interlaced;     /* true if interlaced */    int bottom_field;   /* true if bottom field */    int lossless;    int ls;    int rgb;    int rct;            /* standard rct */    int pegasus_rct;    /* pegasus reversible colorspace transform */    int bits;           /* bits per component */    int maxval;    int near;         ///< near lossless bound (si 0 for lossless)    int t1,t2,t3;    int reset;        ///< context halfing intervall ?rename    int width, height;    int mb_width, mb_height;    int nb_components;    int component_id[MAX_COMPONENTS];    int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */    int v_count[MAX_COMPONENTS];    int comp_index[MAX_COMPONENTS];    int dc_index[MAX_COMPONENTS];    int ac_index[MAX_COMPONENTS];    int nb_blocks[MAX_COMPONENTS];    int h_scount[MAX_COMPONENTS];    int v_scount[MAX_COMPONENTS];    int h_max, v_max; /* maximum h and v counts */    int quant_index[4];   /* quant table index for each component */    int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */    AVFrame picture; /* picture structure */    int linesize[MAX_COMPONENTS];                   ///< linesize << interlaced    int8_t *qscale_table;    DECLARE_ALIGNED_8(DCTELEM, block[64]);    ScanTable scantable;    void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);    int restart_interval;    int restart_count;    int buggy_avid;    int cs_itu601;    int interlace_polarity;    int mjpb_skiptosod;    int cur_scan; /* current scan, used by JPEG-LS */} MJpegDecodeContext;#include "jpeg_ls.c" //FIXME make jpeg-ls more independantstatic int mjpeg_decode_dht(MJpegDecodeContext *s);static int build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_table,                      int nb_codes, int use_static, int is_ac){    uint8_t huff_size[256+16];    uint16_t huff_code[256+16];    assert(nb_codes <= 256);    memset(huff_size, 0, sizeof(huff_size));    build_huffman_codes(huff_size, huff_code, bits_table, val_table);    if(is_ac){        memmove(huff_size+16, huff_size, sizeof(uint8_t)*nb_codes);        memmove(huff_code+16, huff_code, sizeof(uint16_t)*nb_codes);        memset(huff_size, 0, sizeof(uint8_t)*16);        memset(huff_code, 0, sizeof(uint16_t)*16);        nb_codes += 16;    }    return init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2, use_static);}static int mjpeg_decode_init(AVCodecContext *avctx){    MJpegDecodeContext *s = avctx->priv_data;    MpegEncContext s2;    memset(s, 0, sizeof(MJpegDecodeContext));    s->avctx = avctx;    /* ugly way to get the idct & scantable FIXME */    memset(&s2, 0, sizeof(MpegEncContext));    s2.avctx= avctx;//    s2->out_format = FMT_MJPEG;    dsputil_init(&s2.dsp, avctx);    DCT_common_init(&s2);    s->scantable= s2.intra_scantable;    s->idct_put= s2.dsp.idct_put;    s->mpeg_enc_ctx_allocated = 0;    s->buffer_size = 0;    s->buffer = NULL;    s->start_code = -1;    s->first_picture = 1;    s->org_height = avctx->coded_height;    build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12, 0, 0);    build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12, 0, 0);    build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251, 0, 1);    build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251, 0, 1);    if (avctx->flags & CODEC_FLAG_EXTERN_HUFF)    {        av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n");        init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8);        mjpeg_decode_dht(s);        /* should check for error - but dunno */    }    return 0;}/** * finds the end of the current frame in the bitstream. * @return the position of the first byte of the next frame, or -1 */static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){    int vop_found, i;    uint16_t state;    vop_found= pc->frame_start_found;    state= pc->state;    i=0;    if(!vop_found){        for(i=0; i<buf_size; i++){            state= (state<<8) | buf[i];            if(state == 0xFFD8){                i++;                vop_found=1;                break;            }        }    }    if(vop_found){        /* EOF considered as end of frame */        if (buf_size == 0)            return 0;        for(; i<buf_size; i++){            state= (state<<8) | buf[i];            if(state == 0xFFD8){                pc->frame_start_found=0;                pc->state=0;                return i-1;            }        }    }    pc->frame_start_found= vop_found;    pc->state= state;    return END_NOT_FOUND;}static int jpeg_parse(AVCodecParserContext *s,                           AVCodecContext *avctx,                           uint8_t **poutbuf, int *poutbuf_size,                           const uint8_t *buf, int buf_size){    ParseContext *pc = s->priv_data;    int next;    next= find_frame_end(pc, buf, buf_size);    if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {        *poutbuf = NULL;        *poutbuf_size = 0;        return buf_size;    }    *poutbuf = (uint8_t *)buf;    *poutbuf_size = buf_size;    return next;}/* quantize tables */static int mjpeg_decode_dqt(MJpegDecodeContext *s){    int len, index, i, j;    len = get_bits(&s->gb, 16) - 2;    while (len >= 65) {        /* only 8 bit precision handled */        if (get_bits(&s->gb, 4) != 0)        {            dprintf("dqt: 16bit precision\n");            return -1;        }        index = get_bits(&s->gb, 4);        if (index >= 4)            return -1;        dprintf("index=%d\n", index);        /* read quant table */        for(i=0;i<64;i++) {            j = s->scantable.permutated[i];            s->quant_matrixes[index][j] = get_bits(&s->gb, 8);        }        //XXX FIXME finetune, and perhaps add dc too        s->qscale[index]= FFMAX(            s->quant_matrixes[index][s->scantable.permutated[1]],            s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1;        dprintf("qscale[%d]: %d\n", index, s->qscale[index]);        len -= 65;    }    return 0;}/* decode huffman tables and build VLC decoders */static int mjpeg_decode_dht(MJpegDecodeContext *s){    int len, index, i, class, n, v, code_max;    uint8_t bits_table[17];    uint8_t val_table[256];    len = get_bits(&s->gb, 16) - 2;    while (len > 0) {        if (len < 17)            return -1;        class = get_bits(&s->gb, 4);        if (class >= 2)            return -1;        index = get_bits(&s->gb, 4);        if (index >= 4)            return -1;        n = 0;        for(i=1;i<=16;i++) {            bits_table[i] = get_bits(&s->gb, 8);            n += bits_table[i];        }        len -= 17;        if (len < n || n > 256)            return -1;        code_max = 0;        for(i=0;i<n;i++) {            v = get_bits(&s->gb, 8);            if (v > code_max)                code_max = v;            val_table[i] = v;        }        len -= n;        /* build VLC and flush previous vlc if present */        free_vlc(&s->vlcs[class][index]);        dprintf("class=%d index=%d nb_codes=%d\n",               class, index, code_max + 1);        if(build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1, 0, class > 0) < 0){            return -1;        }    }    return 0;}static int mjpeg_decode_sof(MJpegDecodeContext *s){    int len, nb_components, i, width, height;    /* XXX: verify len field validity */    len = get_bits(&s->gb, 16);    s->bits= get_bits(&s->gb, 8);    if(s->pegasus_rct) s->bits=9;    if(s->bits==9 && !s->pegasus_rct) s->rct=1;    //FIXME ugly    if (s->bits != 8 && !s->lossless){        av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n");        return -1;    }    if (s->bits > 8 && s->ls){        av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component accepted for JPEG-LS\n");        return -1;    }    height = get_bits(&s->gb, 16);    width = get_bits(&s->gb, 16);    dprintf("sof0: picture: %dx%d\n", width, height);    if(avcodec_check_dimensions(s->avctx, width, height))        return -1;    nb_components = get_bits(&s->gb, 8);    if (nb_components <= 0 ||        nb_components > MAX_COMPONENTS)        return -1;    s->nb_components = nb_components;    s->h_max = 1;    s->v_max = 1;    for(i=0;i<nb_components;i++) {        /* component id */        s->component_id[i] = get_bits(&s->gb, 8) - 1;        s->h_count[i] = get_bits(&s->gb, 4);        s->v_count[i] = get_bits(&s->gb, 4);        /* compute hmax and vmax (only used in interleaved case) */        if (s->h_count[i] > s->h_max)            s->h_max = s->h_count[i];        if (s->v_count[i] > s->v_max)            s->v_max = s->v_count[i];        s->quant_index[i] = get_bits(&s->gb, 8);        if (s->quant_index[i] >= 4)            return -1;        dprintf("component %d %d:%d id: %d quant:%d\n", i, s->h_count[i],            s->v_count[i], s->component_id[i], s->quant_index[i]);    }    if(s->ls && (s->h_max > 1 || s->v_max > 1)) {        av_log(s->avctx, AV_LOG_ERROR, "Subsampling in JPEG-LS is not supported.\n");        return -1;    }    if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1;    /* if different size, realloc/alloc picture */    /* XXX: also check h_count and v_count */    if (width != s->width || height != s->height) {        av_freep(&s->qscale_table);        s->width = width;        s->height = height;        /* test interlaced mode */        if (s->first_picture &&            s->org_height != 0 &&            s->height < ((s->org_height * 3) / 4)) {            s->interlaced = 1;//            s->bottom_field = (s->interlace_polarity) ? 1 : 0;            s->bottom_field = 0;            height *= 2;        }        avcodec_set_dimensions(s->avctx, width, height);        s->qscale_table= av_mallocz((s->width+15)/16);        s->first_picture = 0;    }    if(s->interlaced && s->bottom_field)        return 0;    /* XXX: not complete test ! */    switch((s->h_count[0] << 4) | s->v_count[0]) {    case 0x11:        if(s->rgb){            s->avctx->pix_fmt = PIX_FMT_RGBA32;        }else if(s->nb_components==3)            s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P;        else            s->avctx->pix_fmt = PIX_FMT_GRAY8;        break;    case 0x21:        s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P;        break;    default:    case 0x22:        s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P;        break;    }    if(s->ls){        if(s->nb_components > 1)            s->avctx->pix_fmt = PIX_FMT_RGB24;        else            s->avctx->pix_fmt = PIX_FMT_GRAY8;    }    if(s->picture.data[0])        s->avctx->release_buffer(s->avctx, &s->picture);    s->picture.reference= 0;    if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");        return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -