00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052
00053 #include "avcodec.h"
00054 #include "bitstream.h"
00055
00056 #include <zlib.h>
00057
00058 typedef struct FlashSVContext {
00059 AVCodecContext *avctx;
00060 AVFrame frame;
00061 int image_width, image_height;
00062 int block_width, block_height;
00063 uint8_t* tmpblock;
00064 int block_size;
00065 z_stream zstream;
00066 } FlashSVContext;
00067
00068
00069 static void copy_region(uint8_t *sptr, uint8_t *dptr,
00070 int dx, int dy, int h, int w, int stride)
00071 {
00072 int i;
00073
00074 for (i = dx+h; i > dx; i--)
00075 {
00076 memcpy(dptr+(i*stride)+dy*3, sptr, w*3);
00077 sptr += w*3;
00078 }
00079 }
00080
00081
00082 static av_cold int flashsv_decode_init(AVCodecContext *avctx)
00083 {
00084 FlashSVContext *s = avctx->priv_data;
00085 int zret;
00086
00087 s->avctx = avctx;
00088 s->zstream.zalloc = Z_NULL;
00089 s->zstream.zfree = Z_NULL;
00090 s->zstream.opaque = Z_NULL;
00091 zret = inflateInit(&(s->zstream));
00092 if (zret != Z_OK) {
00093 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00094 return 1;
00095 }
00096 avctx->pix_fmt = PIX_FMT_BGR24;
00097 s->frame.data[0] = NULL;
00098
00099 return 0;
00100 }
00101
00102
00103 static int flashsv_decode_frame(AVCodecContext *avctx,
00104 void *data, int *data_size,
00105 const uint8_t *buf, int buf_size)
00106 {
00107 FlashSVContext *s = avctx->priv_data;
00108 int h_blocks, v_blocks, h_part, v_part, i, j;
00109 GetBitContext gb;
00110
00111
00112 if (buf_size == 0)
00113 return 0;
00114
00115 if(s->frame.data[0])
00116 avctx->release_buffer(avctx, &s->frame);
00117
00118 init_get_bits(&gb, buf, buf_size * 8);
00119
00120
00121 s->block_width = 16* (get_bits(&gb, 4)+1);
00122 s->image_width = get_bits(&gb,12);
00123 s->block_height= 16* (get_bits(&gb, 4)+1);
00124 s->image_height= get_bits(&gb,12);
00125
00126
00127 h_blocks = s->image_width / s->block_width;
00128 h_part = s->image_width % s->block_width;
00129 v_blocks = s->image_height / s->block_height;
00130 v_part = s->image_height % s->block_height;
00131
00132
00133
00134 if(s->block_size < s->block_width*s->block_height) {
00135 if (s->tmpblock != NULL)
00136 av_free(s->tmpblock);
00137 if ((s->tmpblock = av_malloc(3*s->block_width*s->block_height)) == NULL) {
00138 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00139 return -1;
00140 }
00141 }
00142 s->block_size = s->block_width*s->block_height;
00143
00144
00145 if((avctx->width==0) && (avctx->height==0)){
00146 avctx->width = s->image_width;
00147 avctx->height = s->image_height;
00148 }
00149
00150
00151 if ((avctx->width != s->image_width) || (avctx->height != s->image_height)) {
00152 av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n");
00153 av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n",avctx->height,
00154 avctx->width,s->image_height,s->image_width);
00155 return -1;
00156 }
00157
00158 av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
00159 s->image_width, s->image_height, s->block_width, s->block_height,
00160 h_blocks, v_blocks, h_part, v_part);
00161
00162 s->frame.reference = 1;
00163 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
00164 if (avctx->get_buffer(avctx, &s->frame) < 0) {
00165 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00166 return -1;
00167 }
00168
00169
00170 for (j = 0; j < v_blocks + (v_part?1:0); j++)
00171 {
00172
00173 int hp = j*s->block_height;
00174 int hs = (j<v_blocks)?s->block_height:v_part;
00175
00176
00177
00178 for (i = 0; i < h_blocks + (h_part?1:0); i++)
00179 {
00180 int wp = i*s->block_width;
00181 int ws = (i<h_blocks)?s->block_width:h_part;
00182
00183
00184 int size = get_bits(&gb, 16);
00185
00186 if (size == 0) {
00187
00188 } else {
00189
00190 int ret = inflateReset(&(s->zstream));
00191 if (ret != Z_OK)
00192 {
00193 av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j);
00194
00195 }
00196 s->zstream.next_in = buf+(get_bits_count(&gb)/8);
00197 s->zstream.avail_in = size;
00198 s->zstream.next_out = s->tmpblock;
00199 s->zstream.avail_out = s->block_size*3;
00200 ret = inflate(&(s->zstream), Z_FINISH);
00201 if (ret == Z_DATA_ERROR)
00202 {
00203 av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
00204 inflateSync(&(s->zstream));
00205 ret = inflate(&(s->zstream), Z_FINISH);
00206 }
00207
00208 if ((ret != Z_OK) && (ret != Z_STREAM_END))
00209 {
00210 av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret);
00211
00212 }
00213 copy_region(s->tmpblock, s->frame.data[0], s->image_height-(hp+hs+1), wp, hs, ws, s->frame.linesize[0]);
00214 skip_bits_long(&gb, 8*size);
00215 }
00216 }
00217 }
00218
00219 *data_size = sizeof(AVFrame);
00220 *(AVFrame*)data = s->frame;
00221
00222 if ((get_bits_count(&gb)/8) != buf_size)
00223 av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
00224 buf_size, (get_bits_count(&gb)/8));
00225
00226
00227 return buf_size;
00228 }
00229
00230
00231 static av_cold int flashsv_decode_end(AVCodecContext *avctx)
00232 {
00233 FlashSVContext *s = avctx->priv_data;
00234 inflateEnd(&(s->zstream));
00235
00236 if (s->frame.data[0])
00237 avctx->release_buffer(avctx, &s->frame);
00238
00239
00240 if (s->tmpblock != NULL)
00241 av_free(s->tmpblock);
00242
00243 return 0;
00244 }
00245
00246
00247 AVCodec flashsv_decoder = {
00248 "flashsv",
00249 CODEC_TYPE_VIDEO,
00250 CODEC_ID_FLASHSV,
00251 sizeof(FlashSVContext),
00252 flashsv_decode_init,
00253 NULL,
00254 flashsv_decode_end,
00255 flashsv_decode_frame,
00256 CODEC_CAP_DR1,
00257 .pix_fmts = (enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00258 .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
00259 };