Libav 0.7.1
|
00001 /* 00002 * Flash Screen Video encoder 00003 * Copyright (C) 2004 Alex Beregszaszi 00004 * Copyright (C) 2006 Benjamin Larsson 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 /* Encoding development sponsored by http://fh-campuswien.ac.at */ 00024 00032 /* Bitstream description 00033 * The picture is divided into blocks that are zlib-compressed. 00034 * 00035 * The decoder is fed complete frames, the frameheader contains: 00036 * 4bits of block width 00037 * 12bits of frame width 00038 * 4bits of block height 00039 * 12bits of frame height 00040 * 00041 * Directly after the header are the compressed blocks. The blocks 00042 * have their compressed size represented with 16bits in the beginig. 00043 * If the size = 0 then the block is unchanged from the previous frame. 00044 * All blocks are decompressed until the buffer is consumed. 00045 * 00046 * Encoding ideas, a basic encoder would just use a fixed block size. 00047 * Block sizes can be multipels of 16, from 16 to 256. The blocks don't 00048 * have to be quadratic. A brute force search with a set of different 00049 * block sizes should give a better result than to just use a fixed size. 00050 */ 00051 00052 /* TODO: 00053 * Don't reencode the frame in brute force mode if the frame is a dupe. Speed up. 00054 * Make the difference check faster. 00055 */ 00056 00057 #include <stdio.h> 00058 #include <stdlib.h> 00059 #include <zlib.h> 00060 00061 #include "avcodec.h" 00062 #include "put_bits.h" 00063 #include "bytestream.h" 00064 00065 00066 typedef struct FlashSVContext { 00067 AVCodecContext *avctx; 00068 uint8_t *previous_frame; 00069 AVFrame frame; 00070 int image_width, image_height; 00071 int block_width, block_height; 00072 uint8_t *tmpblock; 00073 uint8_t *encbuffer; 00074 int block_size; 00075 z_stream zstream; 00076 int last_key_frame; 00077 } FlashSVContext; 00078 00079 static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy, 00080 int h, int w, int stride, uint8_t *pfptr) 00081 { 00082 int i, j; 00083 uint8_t *nsptr; 00084 uint8_t *npfptr; 00085 int diff = 0; 00086 00087 for (i = dx + h; i > dx; i--) { 00088 nsptr = sptr + (i * stride) + dy * 3; 00089 npfptr = pfptr + (i * stride) + dy * 3; 00090 for (j = 0; j < w * 3; j++) { 00091 diff |= npfptr[j] ^ nsptr[j]; 00092 dptr[j] = nsptr[j]; 00093 } 00094 dptr += w * 3; 00095 } 00096 if (diff) 00097 return 1; 00098 return 0; 00099 } 00100 00101 static av_cold int flashsv_encode_init(AVCodecContext *avctx) 00102 { 00103 FlashSVContext *s = avctx->priv_data; 00104 00105 s->avctx = avctx; 00106 00107 if ((avctx->width > 4095) || (avctx->height > 4095)) { 00108 av_log(avctx, AV_LOG_ERROR, "Input dimensions too large, input must be max 4096x4096 !\n"); 00109 return AVERROR_INVALIDDATA; 00110 } 00111 00112 // Needed if zlib unused or init aborted before deflateInit 00113 memset(&(s->zstream), 0, sizeof(z_stream)); 00114 00115 s->last_key_frame = 0; 00116 00117 s->image_width = avctx->width; 00118 s->image_height = avctx->height; 00119 00120 s->tmpblock = av_mallocz(3 * 256 * 256); 00121 s->encbuffer = av_mallocz(s->image_width * s->image_height * 3); 00122 00123 if (!s->tmpblock || !s->encbuffer) { 00124 av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); 00125 return AVERROR(ENOMEM); 00126 } 00127 00128 return 0; 00129 } 00130 00131 00132 static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, 00133 int buf_size, int block_width, int block_height, 00134 uint8_t *previous_frame, int *I_frame) 00135 { 00136 00137 PutBitContext pb; 00138 int h_blocks, v_blocks, h_part, v_part, i, j; 00139 int buf_pos, res; 00140 int pred_blocks = 0; 00141 00142 init_put_bits(&pb, buf, buf_size * 8); 00143 00144 put_bits(&pb, 4, (block_width / 16) - 1); 00145 put_bits(&pb, 12, s->image_width); 00146 put_bits(&pb, 4, (block_height / 16) - 1); 00147 put_bits(&pb, 12, s->image_height); 00148 flush_put_bits(&pb); 00149 buf_pos = 4; 00150 00151 h_blocks = s->image_width / block_width; 00152 h_part = s->image_width % block_width; 00153 v_blocks = s->image_height / block_height; 00154 v_part = s->image_height % block_height; 00155 00156 /* loop over all block columns */ 00157 for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) { 00158 00159 int hp = j * block_height; // horiz position in frame 00160 int hs = (j < v_blocks) ? block_height : v_part; // size of block 00161 00162 /* loop over all block rows */ 00163 for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) { 00164 int wp = i * block_width; // vert position in frame 00165 int ws = (i < h_blocks) ? block_width : h_part; // size of block 00166 int ret = Z_OK; 00167 uint8_t *ptr; 00168 00169 ptr = buf + buf_pos; 00170 00171 /* copy the block to the temp buffer before compression 00172 * (if it differs from the previous frame's block) */ 00173 res = copy_region_enc(p->data[0], s->tmpblock, 00174 s->image_height - (hp + hs + 1), 00175 wp, hs, ws, p->linesize[0], previous_frame); 00176 00177 if (res || *I_frame) { 00178 unsigned long zsize; 00179 zsize = 3 * block_width * block_height; 00180 ret = compress2(ptr + 2, &zsize, s->tmpblock, 3 * ws * hs, 9); 00181 00182 00183 //ret = deflateReset(&(s->zstream)); 00184 if (ret != Z_OK) 00185 av_log(s->avctx, AV_LOG_ERROR, "error while compressing block %dx%d\n", i, j); 00186 00187 bytestream_put_be16(&ptr, (unsigned int) zsize); 00188 buf_pos += zsize + 2; 00189 //av_log(avctx, AV_LOG_ERROR, "buf_pos = %d\n", buf_pos); 00190 } else { 00191 pred_blocks++; 00192 bytestream_put_be16(&ptr, 0); 00193 buf_pos += 2; 00194 } 00195 } 00196 } 00197 00198 if (pred_blocks) 00199 *I_frame = 0; 00200 else 00201 *I_frame = 1; 00202 00203 return buf_pos; 00204 } 00205 00206 00207 static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, 00208 int buf_size, void *data) 00209 { 00210 FlashSVContext * const s = avctx->priv_data; 00211 AVFrame *pict = data; 00212 AVFrame * const p = &s->frame; 00213 uint8_t *pfptr; 00214 int res; 00215 int I_frame = 0; 00216 int opt_w, opt_h; 00217 00218 *p = *pict; 00219 00220 /* First frame needs to be a keyframe */ 00221 if (avctx->frame_number == 0) { 00222 s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height); 00223 if (!s->previous_frame) { 00224 av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); 00225 return AVERROR(ENOMEM); 00226 } 00227 I_frame = 1; 00228 } 00229 00230 if (p->linesize[0] < 0) 00231 pfptr = s->previous_frame - ((s->image_height - 1) * p->linesize[0]); 00232 else 00233 pfptr = s->previous_frame; 00234 00235 /* Check the placement of keyframes */ 00236 if (avctx->gop_size > 0) { 00237 if (avctx->frame_number >= s->last_key_frame + avctx->gop_size) { 00238 I_frame = 1; 00239 } 00240 } 00241 00242 opt_w = 4; 00243 opt_h = 4; 00244 00245 if (buf_size < s->image_width*s->image_height*3) { 00246 //Conservative upper bound check for compressed data 00247 av_log(avctx, AV_LOG_ERROR, "buf_size %d < %d\n", 00248 buf_size, s->image_width * s->image_height * 3); 00249 return -1; 00250 } 00251 00252 res = encode_bitstream(s, p, buf, buf_size, opt_w * 16, opt_h * 16, pfptr, &I_frame); 00253 00254 //save the current frame 00255 if (p->linesize[0] > 0) 00256 memcpy(s->previous_frame, p->data[0], s->image_height * p->linesize[0]); 00257 else 00258 memcpy(s->previous_frame, p->data[0] + p->linesize[0] * (s->image_height - 1), 00259 s->image_height * FFABS(p->linesize[0])); 00260 00261 //mark the frame type so the muxer can mux it correctly 00262 if (I_frame) { 00263 p->pict_type = AV_PICTURE_TYPE_I; 00264 p->key_frame = 1; 00265 s->last_key_frame = avctx->frame_number; 00266 av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number); 00267 } else { 00268 p->pict_type = AV_PICTURE_TYPE_P; 00269 p->key_frame = 0; 00270 } 00271 00272 avctx->coded_frame = p; 00273 00274 return res; 00275 } 00276 00277 static av_cold int flashsv_encode_end(AVCodecContext *avctx) 00278 { 00279 FlashSVContext *s = avctx->priv_data; 00280 00281 deflateEnd(&(s->zstream)); 00282 00283 av_free(s->encbuffer); 00284 av_free(s->previous_frame); 00285 av_free(s->tmpblock); 00286 00287 return 0; 00288 } 00289 00290 AVCodec ff_flashsv_encoder = { 00291 .name = "flashsv", 00292 .type = AVMEDIA_TYPE_VIDEO, 00293 .id = CODEC_ID_FLASHSV, 00294 .priv_data_size = sizeof(FlashSVContext), 00295 .init = flashsv_encode_init, 00296 .encode = flashsv_encode_frame, 00297 .close = flashsv_encode_end, 00298 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE}, 00299 .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"), 00300 }; 00301