annotate ffmpeg/libavcodec/cscd.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * CamStudio decoder
yading@10 3 * Copyright (c) 2006 Reimar Doeffinger
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21 #include <stdio.h>
yading@10 22 #include <stdlib.h>
yading@10 23
yading@10 24 #include "avcodec.h"
yading@10 25 #include "internal.h"
yading@10 26 #include "libavutil/common.h"
yading@10 27
yading@10 28 #if CONFIG_ZLIB
yading@10 29 #include <zlib.h>
yading@10 30 #endif
yading@10 31 #include "libavutil/lzo.h"
yading@10 32
yading@10 33 typedef struct {
yading@10 34 AVFrame *pic;
yading@10 35 int linelen, height, bpp;
yading@10 36 unsigned int decomp_size;
yading@10 37 unsigned char* decomp_buf;
yading@10 38 } CamStudioContext;
yading@10 39
yading@10 40 static void copy_frame_default(AVFrame *f, const uint8_t *src,
yading@10 41 int linelen, int height) {
yading@10 42 int i, src_stride = FFALIGN(linelen, 4);
yading@10 43 uint8_t *dst = f->data[0];
yading@10 44 dst += (height - 1) * f->linesize[0];
yading@10 45 for (i = height; i; i--) {
yading@10 46 memcpy(dst, src, linelen);
yading@10 47 src += src_stride;
yading@10 48 dst -= f->linesize[0];
yading@10 49 }
yading@10 50 }
yading@10 51
yading@10 52 static void add_frame_default(AVFrame *f, const uint8_t *src,
yading@10 53 int linelen, int height) {
yading@10 54 int i, j, src_stride = FFALIGN(linelen, 4);
yading@10 55 uint8_t *dst = f->data[0];
yading@10 56 dst += (height - 1) * f->linesize[0];
yading@10 57 for (i = height; i; i--) {
yading@10 58 for (j = linelen; j; j--)
yading@10 59 *dst++ += *src++;
yading@10 60 src += src_stride - linelen;
yading@10 61 dst -= f->linesize[0] + linelen;
yading@10 62 }
yading@10 63 }
yading@10 64
yading@10 65 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
yading@10 66 AVPacket *avpkt) {
yading@10 67 const uint8_t *buf = avpkt->data;
yading@10 68 int buf_size = avpkt->size;
yading@10 69 CamStudioContext *c = avctx->priv_data;
yading@10 70 int ret;
yading@10 71
yading@10 72 if (buf_size < 2) {
yading@10 73 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
yading@10 74 return AVERROR_INVALIDDATA;
yading@10 75 }
yading@10 76
yading@10 77 if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
yading@10 78 return ret;
yading@10 79
yading@10 80 // decompress data
yading@10 81 switch ((buf[0] >> 1) & 7) {
yading@10 82 case 0: { // lzo compression
yading@10 83 int outlen = c->decomp_size, inlen = buf_size - 2;
yading@10 84 if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen))
yading@10 85 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
yading@10 86 break;
yading@10 87 }
yading@10 88 case 1: { // zlib compression
yading@10 89 #if CONFIG_ZLIB
yading@10 90 unsigned long dlen = c->decomp_size;
yading@10 91 if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK)
yading@10 92 av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
yading@10 93 break;
yading@10 94 #else
yading@10 95 av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n");
yading@10 96 return AVERROR(ENOSYS);
yading@10 97 #endif
yading@10 98 }
yading@10 99 default:
yading@10 100 av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
yading@10 101 return AVERROR_INVALIDDATA;
yading@10 102 }
yading@10 103
yading@10 104 // flip upside down, add difference frame
yading@10 105 if (buf[0] & 1) { // keyframe
yading@10 106 c->pic->pict_type = AV_PICTURE_TYPE_I;
yading@10 107 c->pic->key_frame = 1;
yading@10 108 copy_frame_default(c->pic, c->decomp_buf,
yading@10 109 c->linelen, c->height);
yading@10 110 } else {
yading@10 111 c->pic->pict_type = AV_PICTURE_TYPE_P;
yading@10 112 c->pic->key_frame = 0;
yading@10 113 add_frame_default(c->pic, c->decomp_buf,
yading@10 114 c->linelen, c->height);
yading@10 115 }
yading@10 116
yading@10 117 *got_frame = 1;
yading@10 118 if ((ret = av_frame_ref(data, c->pic)) < 0)
yading@10 119 return ret;
yading@10 120
yading@10 121 return buf_size;
yading@10 122 }
yading@10 123
yading@10 124 static av_cold int decode_init(AVCodecContext *avctx) {
yading@10 125 CamStudioContext *c = avctx->priv_data;
yading@10 126 int stride;
yading@10 127 switch (avctx->bits_per_coded_sample) {
yading@10 128 case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break;
yading@10 129 case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
yading@10 130 case 32: avctx->pix_fmt = AV_PIX_FMT_BGRA; break;
yading@10 131 default:
yading@10 132 av_log(avctx, AV_LOG_ERROR,
yading@10 133 "CamStudio codec error: invalid depth %i bpp\n",
yading@10 134 avctx->bits_per_coded_sample);
yading@10 135 return AVERROR_INVALIDDATA;
yading@10 136 }
yading@10 137 c->bpp = avctx->bits_per_coded_sample;
yading@10 138 c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
yading@10 139 c->height = avctx->height;
yading@10 140 stride = FFALIGN(c->linelen, 4);
yading@10 141 c->decomp_size = c->height * stride;
yading@10 142 c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING);
yading@10 143 if (!c->decomp_buf) {
yading@10 144 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
yading@10 145 return AVERROR(ENOMEM);
yading@10 146 }
yading@10 147 c->pic = av_frame_alloc();
yading@10 148 if (!c->pic)
yading@10 149 return AVERROR(ENOMEM);
yading@10 150 return 0;
yading@10 151 }
yading@10 152
yading@10 153 static av_cold int decode_end(AVCodecContext *avctx) {
yading@10 154 CamStudioContext *c = avctx->priv_data;
yading@10 155 av_freep(&c->decomp_buf);
yading@10 156 av_frame_free(&c->pic);
yading@10 157 return 0;
yading@10 158 }
yading@10 159
yading@10 160 AVCodec ff_cscd_decoder = {
yading@10 161 .name = "camstudio",
yading@10 162 .type = AVMEDIA_TYPE_VIDEO,
yading@10 163 .id = AV_CODEC_ID_CSCD,
yading@10 164 .priv_data_size = sizeof(CamStudioContext),
yading@10 165 .init = decode_init,
yading@10 166 .close = decode_end,
yading@10 167 .decode = decode_frame,
yading@10 168 .capabilities = CODEC_CAP_DR1,
yading@10 169 .long_name = NULL_IF_CONFIG_SMALL("CamStudio"),
yading@10 170 };