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

📄 vmnc.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
                color = !!(flags & HT_CLR);                paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);                if(src - ssrc > ssize - rects * (color * bpp + 2)) {                    av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");                    return -1;                }                for(k = 0; k < rects; k++) {                    if(color) {                        fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;                    }                    xy = *src++;                    wh = *src++;                    paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);                }            }        }        dst += stride * 16;    }    return src - ssrc;}static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){    VmncContext * const c = avctx->priv_data;    uint8_t *outptr;    const uint8_t *src = buf;    int dx, dy, w, h, depth, enc, chunks, res, size_left;    c->pic.reference = 1;    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;    if(avctx->reget_buffer(avctx, &c->pic) < 0){        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");        return -1;    }    c->pic.key_frame = 0;    c->pic.pict_type = FF_P_TYPE;    //restore screen after cursor    if(c->screendta) {        int i;        w = c->cur_w;        if(c->width < c->cur_x + w) w = c->width - c->cur_x;        h = c->cur_h;        if(c->height < c->cur_y + h) h = c->height - c->cur_y;        dx = c->cur_x;        if(dx < 0) {            w += dx;            dx = 0;        }        dy = c->cur_y;        if(dy < 0) {            h += dy;            dy = 0;        }        if((w > 0) && (h > 0)) {            outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];            for(i = 0; i < h; i++) {                memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2);                outptr += c->pic.linesize[0];            }        }    }    src += 2;    chunks = AV_RB16(src); src += 2;    while(chunks--) {        dx = AV_RB16(src); src += 2;        dy = AV_RB16(src); src += 2;        w  = AV_RB16(src); src += 2;        h  = AV_RB16(src); src += 2;        enc = AV_RB32(src); src += 4;        outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];        size_left = buf_size - (src - buf);        switch(enc) {        case MAGIC_WMVd: // cursor            if(size_left < 2 + w * h * c->bpp2 * 2) {                av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left);                return -1;            }            src += 2;            c->cur_w = w;            c->cur_h = h;            c->cur_hx = dx;            c->cur_hy = dy;            if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {                av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);                c->cur_hx = c->cur_hy = 0;            }            c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2);            c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2);            c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2);            load_cursor(c, src);            src += w * h * c->bpp2 * 2;            break;        case MAGIC_WMVe: // unknown            src += 2;            break;        case MAGIC_WMVf: // update cursor position            c->cur_x = dx - c->cur_hx;            c->cur_y = dy - c->cur_hy;            break;        case MAGIC_WMVg: // unknown            src += 10;            break;        case MAGIC_WMVh: // unknown            src += 4;            break;        case MAGIC_WMVi: // ServerInitialization struct            c->pic.key_frame = 1;            c->pic.pict_type = FF_I_TYPE;            depth = *src++;            if(depth != c->bpp) {                av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth);            }            src++;            c->bigendian = *src++;            if(c->bigendian & (~1)) {                av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian);                return -1;            }            //skip the rest of pixel format data            src += 13;            break;        case MAGIC_WMVj: // unknown            src += 2;            break;        case 0x00000000: // raw rectangle data            if((dx + w > c->width) || (dy + h > c->height)) {                av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);                return -1;            }            if(size_left < w * h * c->bpp2) {                av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left);                return -1;            }            paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]);            src += w * h * c->bpp2;            break;        case 0x00000005: // HexTile encoded rectangle            if((dx + w > c->width) || (dy + h > c->height)) {                av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);                return -1;            }            res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);            if(res < 0)                return -1;            src += res;            break;        default:            av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);            chunks = 0; // leave chunks decoding loop        }    }    if(c->screendta){        int i;        //save screen data before painting cursor        w = c->cur_w;        if(c->width < c->cur_x + w) w = c->width - c->cur_x;        h = c->cur_h;        if(c->height < c->cur_y + h) h = c->height - c->cur_y;        dx = c->cur_x;        if(dx < 0) {            w += dx;            dx = 0;        }        dy = c->cur_y;        if(dy < 0) {            h += dy;            dy = 0;        }        if((w > 0) && (h > 0)) {            outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];            for(i = 0; i < h; i++) {                memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2);                outptr += c->pic.linesize[0];            }            outptr = c->pic.data[0];            put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y);        }    }    *data_size = sizeof(AVFrame);    *(AVFrame*)data = c->pic;    /* always report that the buffer was completely consumed */    return buf_size;}/* * * Init VMnc decoder * */static int decode_init(AVCodecContext *avctx){    VmncContext * const c = avctx->priv_data;    c->avctx = avctx;    c->pic.data[0] = NULL;    c->width = avctx->width;    c->height = avctx->height;    if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {        return 1;    }    c->bpp = avctx->bits_per_sample;    c->bpp2 = c->bpp/8;    switch(c->bpp){    case 8:        avctx->pix_fmt = PIX_FMT_PAL8;        break;    case 16:        avctx->pix_fmt = PIX_FMT_RGB555;        break;    case 32:        avctx->pix_fmt = PIX_FMT_RGB32;        break;    default:        av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp);    }    return 0;}/* * * Uninit VMnc decoder * */static int decode_end(AVCodecContext *avctx){    VmncContext * const c = avctx->priv_data;    if (c->pic.data[0])        avctx->release_buffer(avctx, &c->pic);    av_free(c->curbits);    av_free(c->curmask);    av_free(c->screendta);    return 0;}AVCodec vmnc_decoder = {    "VMware video",    CODEC_TYPE_VIDEO,    CODEC_ID_VMNC,    sizeof(VmncContext),    decode_init,    NULL,    decode_end,    decode_frame};

⌨️ 快捷键说明

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