static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; CamStudioContext *c = avctx->priv_data; AVFrame *picture = data; int ret; if (buf_size < 2) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); return AVERROR_INVALIDDATA; } if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } // decompress data switch ((buf[0] >> 1) & 7) { case 0: { // lzo compression int outlen = c->decomp_size, inlen = buf_size - 2; if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen)) av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); break; } case 1: { // zlib compression #if CONFIG_ZLIB unsigned long dlen = c->decomp_size; if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); break; #else av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n"); return AVERROR(ENOSYS); #endif } default: av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); return AVERROR_INVALIDDATA; } // flip upside down, add difference frame if (buf[0] & 1) { // keyframe picture->pict_type = AV_PICTURE_TYPE_I; picture->key_frame = 1; switch (c->bpp) { case 16: copy_frame_16(picture, c->decomp_buf, c->linelen, c->height); break; case 32: copy_frame_32(picture, c->decomp_buf, c->linelen, c->height); break; default: copy_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4), c->linelen, c->height); } } else { picture->pict_type = AV_PICTURE_TYPE_P; picture->key_frame = 0; switch (c->bpp) { case 16: add_frame_16(picture, c->decomp_buf, c->linelen, c->height); break; case 32: add_frame_32(picture, c->decomp_buf, c->linelen, c->height); break; default: add_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4), c->linelen, c->height); } } *got_frame = 1; return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { CamStudioContext *c = avctx->priv_data; AVFrame *picture = data; if (buf_size < 2) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); return -1; } if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); c->pic.reference = 1; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->get_buffer(avctx, &c->pic) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } // decompress data switch ((buf[0] >> 1) & 7) { case 0: { // lzo compression int outlen = c->decomp_size, inlen = buf_size - 2; if (lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen)) av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); break; } case 1: { // zlib compression #ifdef CONFIG_ZLIB unsigned long dlen = c->decomp_size; if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); break; #else av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n"); return -1; #endif } default: av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); return -1; } // flip upside down, add difference frame if (buf[0] & 1) { // keyframe c->pic.pict_type = FF_I_TYPE; c->pic.key_frame = 1; switch (c->bpp) { case 16: copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); break; case 32: copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); break; default: copy_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); } } else { c->pic.pict_type = FF_P_TYPE; c->pic.key_frame = 0; switch (c->bpp) { case 16: add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); break; case 32: add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); break; default: add_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); } } *picture = c->pic; *data_size = sizeof(AVFrame); return buf_size; }