• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/flashsv.c

Go to the documentation of this file.
00001 /*
00002  * Flash Screen Video decoder
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 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <zlib.h>
00039 
00040 #include "libavutil/intreadwrite.h"
00041 #include "avcodec.h"
00042 #include "bytestream.h"
00043 #include "get_bits.h"
00044 
00045 typedef struct BlockInfo {
00046     uint8_t *pos;
00047     int      size;
00048     int      unp_size;
00049 } BlockInfo;
00050 
00051 typedef struct FlashSVContext {
00052     AVCodecContext *avctx;
00053     AVFrame         frame;
00054     int             image_width, image_height;
00055     int             block_width, block_height;
00056     uint8_t        *tmpblock;
00057     int             block_size;
00058     z_stream        zstream;
00059     int             ver;
00060     const uint32_t *pal;
00061     int             is_keyframe;
00062     uint8_t        *keyframedata;
00063     uint8_t        *keyframe;
00064     BlockInfo      *blocks;
00065     uint8_t        *deflate_block;
00066     int             deflate_block_size;
00067     int             color_depth;
00068     int             zlibprime_curr, zlibprime_prev;
00069     int             diff_start, diff_height;
00070 } FlashSVContext;
00071 
00072 
00073 static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
00074                          int h, int w, int stride, const uint32_t *pal)
00075 {
00076     int x, y;
00077     const uint8_t *orig_src = sptr;
00078 
00079     for (y = dx+h; y > dx; y--) {
00080         uint8_t *dst = dptr + (y * stride) + dy * 3;
00081         for (x = 0; x < w; x++) {
00082             if (*sptr & 0x80) {
00083                 /* 15-bit color */
00084                 unsigned c = AV_RB16(sptr) & ~0x8000;
00085                 unsigned b =  c        & 0x1F;
00086                 unsigned g = (c >>  5) & 0x1F;
00087                 unsigned r =  c >> 10;
00088                 /* 000aaabb -> aaabbaaa  */
00089                 *dst++ = (b << 3) | (b >> 2);
00090                 *dst++ = (g << 3) | (g >> 2);
00091                 *dst++ = (r << 3) | (r >> 2);
00092                 sptr += 2;
00093             } else {
00094                 /* palette index */
00095                 uint32_t c = pal[*sptr++];
00096                 bytestream_put_le24(&dst, c);
00097             }
00098         }
00099     }
00100     return sptr - orig_src;
00101 }
00102 
00103 static av_cold int flashsv_decode_init(AVCodecContext *avctx)
00104 {
00105     FlashSVContext *s = avctx->priv_data;
00106     int zret; // Zlib return code
00107 
00108     s->avctx          = avctx;
00109     s->zstream.zalloc = Z_NULL;
00110     s->zstream.zfree  = Z_NULL;
00111     s->zstream.opaque = Z_NULL;
00112     zret = inflateInit(&s->zstream);
00113     if (zret != Z_OK) {
00114         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00115         return 1;
00116     }
00117     avctx->pix_fmt = PIX_FMT_BGR24;
00118     s->frame.data[0] = NULL;
00119 
00120     return 0;
00121 }
00122 
00123 
00124 static void flashsv2_prime(FlashSVContext *s, uint8_t *src,
00125                            int size, int unp_size)
00126 {
00127     z_stream zs;
00128 
00129     zs.zalloc = NULL;
00130     zs.zfree  = NULL;
00131     zs.opaque = NULL;
00132 
00133     s->zstream.next_in   = src;
00134     s->zstream.avail_in  = size;
00135     s->zstream.next_out  = s->tmpblock;
00136     s->zstream.avail_out = s->block_size * 3;
00137     inflate(&s->zstream, Z_SYNC_FLUSH);
00138 
00139     deflateInit(&zs, 0);
00140     zs.next_in   = s->tmpblock;
00141     zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
00142     zs.next_out  = s->deflate_block;
00143     zs.avail_out = s->deflate_block_size;
00144     deflate(&zs, Z_SYNC_FLUSH);
00145     deflateEnd(&zs);
00146 
00147     inflateReset(&s->zstream);
00148 
00149     s->zstream.next_in   = s->deflate_block;
00150     s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
00151     s->zstream.next_out  = s->tmpblock;
00152     s->zstream.avail_out = s->block_size * 3;
00153     inflate(&s->zstream, Z_SYNC_FLUSH);
00154 }
00155 
00156 static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
00157                                 GetBitContext *gb, int block_size,
00158                                 int width, int height, int x_pos, int y_pos,
00159                                 int blk_idx)
00160 {
00161     struct FlashSVContext *s = avctx->priv_data;
00162     uint8_t *line = s->tmpblock;
00163     int k;
00164     int ret = inflateReset(&s->zstream);
00165     if (ret != Z_OK) {
00166         //return -1;
00167     }
00168     if (s->zlibprime_curr || s->zlibprime_prev) {
00169         flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size,
00170                        s->blocks[blk_idx].unp_size);
00171     }
00172     s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
00173     s->zstream.avail_in  = block_size;
00174     s->zstream.next_out  = s->tmpblock;
00175     s->zstream.avail_out = s->block_size * 3;
00176     ret = inflate(&s->zstream, Z_FINISH);
00177     if (ret == Z_DATA_ERROR) {
00178         av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
00179         inflateSync(&s->zstream);
00180         ret = inflate(&s->zstream, Z_FINISH);
00181     }
00182 
00183     if (ret != Z_OK && ret != Z_STREAM_END) {
00184         //return -1;
00185     }
00186 
00187     if (s->is_keyframe) {
00188         s->blocks[blk_idx].pos      = s->keyframedata + (get_bits_count(gb) / 8);
00189         s->blocks[blk_idx].size     = block_size;
00190         s->blocks[blk_idx].unp_size = s->block_size * 3 - s->zstream.avail_out;
00191     }
00192     if (!s->color_depth) {
00193         /* Flash Screen Video stores the image upside down, so copy
00194          * lines to destination in reverse order. */
00195         for (k = 1; k <= s->diff_height; k++) {
00196             memcpy(s->frame.data[0] + x_pos * 3 +
00197                    (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
00198                    line, width * 3);
00199             /* advance source pointer to next line */
00200             line += width * 3;
00201         }
00202     } else {
00203         /* hybrid 15-bit/palette mode */
00204         decode_hybrid(s->tmpblock, s->frame.data[0],
00205                       s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
00206                       x_pos, s->diff_height, width,
00207                       s->frame.linesize[0], s->pal);
00208     }
00209     skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
00210     return 0;
00211 }
00212 
00213 static int calc_deflate_block_size(int tmpblock_size)
00214 {
00215     z_stream zstream;
00216     int size;
00217 
00218     zstream.zalloc = Z_NULL;
00219     zstream.zfree  = Z_NULL;
00220     zstream.opaque = Z_NULL;
00221     if (deflateInit(&zstream, 0) != Z_OK)
00222         return -1;
00223     size = deflateBound(&zstream, tmpblock_size);
00224     deflateEnd(&zstream);
00225 
00226     return size;
00227 }
00228 
00229 static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
00230                                 int *data_size, AVPacket *avpkt)
00231 {
00232     int buf_size       = avpkt->size;
00233     FlashSVContext *s  = avctx->priv_data;
00234     int h_blocks, v_blocks, h_part, v_part, i, j;
00235     GetBitContext gb;
00236 
00237     /* no supplementary picture */
00238     if (buf_size == 0)
00239         return 0;
00240     if (buf_size < 4)
00241         return -1;
00242 
00243     init_get_bits(&gb, avpkt->data, buf_size * 8);
00244 
00245     /* start to parse the bitstream */
00246     s->block_width  = 16 * (get_bits(&gb,  4) + 1);
00247     s->image_width  =       get_bits(&gb, 12);
00248     s->block_height = 16 * (get_bits(&gb,  4) + 1);
00249     s->image_height =       get_bits(&gb, 12);
00250 
00251     if (s->ver == 2) {
00252         skip_bits(&gb, 6);
00253         if (get_bits1(&gb)) {
00254             av_log_missing_feature(avctx, "iframe", 1);
00255             return AVERROR_PATCHWELCOME;
00256         }
00257         if (get_bits1(&gb)) {
00258             av_log_missing_feature(avctx, "custom palette", 1);
00259             return AVERROR_PATCHWELCOME;
00260         }
00261     }
00262 
00263     /* calculate number of blocks and size of border (partial) blocks */
00264     h_blocks = s->image_width  / s->block_width;
00265     h_part   = s->image_width  % s->block_width;
00266     v_blocks = s->image_height / s->block_height;
00267     v_part   = s->image_height % s->block_height;
00268 
00269     /* the block size could change between frames, make sure the buffer
00270      * is large enough, if not, get a larger one */
00271     if (s->block_size < s->block_width * s->block_height) {
00272         int tmpblock_size = 3 * s->block_width * s->block_height;
00273 
00274         s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
00275         if (!s->tmpblock) {
00276             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00277             return AVERROR(ENOMEM);
00278         }
00279         if (s->ver == 2) {
00280             s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
00281             if (s->deflate_block_size <= 0) {
00282                 av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
00283                 return -1;
00284             }
00285             s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
00286             if (!s->deflate_block) {
00287                 av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
00288                 return AVERROR(ENOMEM);
00289             }
00290         }
00291     }
00292     s->block_size = s->block_width * s->block_height;
00293 
00294     /* initialize the image size once */
00295     if (avctx->width == 0 && avctx->height == 0) {
00296         avctx->width  = s->image_width;
00297         avctx->height = s->image_height;
00298     }
00299 
00300     /* check for changes of image width and image height */
00301     if (avctx->width != s->image_width || avctx->height != s->image_height) {
00302         av_log(avctx, AV_LOG_ERROR,
00303                "Frame width or height differs from first frame!\n");
00304         av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
00305                avctx->height, avctx->width, s->image_height, s->image_width);
00306         return AVERROR_INVALIDDATA;
00307     }
00308 
00309     /* we care for keyframes only in Screen Video v2 */
00310     s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
00311     if (s->is_keyframe) {
00312         s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
00313         memcpy(s->keyframedata, avpkt->data, avpkt->size);
00314         s->blocks = av_realloc(s->blocks,
00315                                (v_blocks + !!v_part) * (h_blocks + !!h_part)
00316                                * sizeof(s->blocks[0]));
00317     }
00318 
00319     av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
00320             s->image_width, s->image_height, s->block_width, s->block_height,
00321             h_blocks, v_blocks, h_part, v_part);
00322 
00323     s->frame.reference    = 3;
00324     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |
00325                             FF_BUFFER_HINTS_PRESERVE |
00326                             FF_BUFFER_HINTS_REUSABLE;
00327     if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00328         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00329         return -1;
00330     }
00331 
00332     /* loop over all block columns */
00333     for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
00334 
00335         int y_pos  = j * s->block_height; // vertical position in frame
00336         int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
00337 
00338         /* loop over all block rows */
00339         for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
00340             int x_pos = i * s->block_width; // horizontal position in frame
00341             int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
00342             int has_diff = 0;
00343 
00344             /* get the size of the compressed zlib chunk */
00345             int size = get_bits(&gb, 16);
00346 
00347             s->color_depth    = 0;
00348             s->zlibprime_curr = 0;
00349             s->zlibprime_prev = 0;
00350             s->diff_start     = 0;
00351             s->diff_height    = cur_blk_height;
00352 
00353             if (8 * size > get_bits_left(&gb)) {
00354                 avctx->release_buffer(avctx, &s->frame);
00355                 s->frame.data[0] = NULL;
00356                 return AVERROR_INVALIDDATA;
00357             }
00358 
00359             if (s->ver == 2 && size) {
00360                 skip_bits(&gb, 3);
00361                 s->color_depth    = get_bits(&gb, 2);
00362                 has_diff          = get_bits1(&gb);
00363                 s->zlibprime_curr = get_bits1(&gb);
00364                 s->zlibprime_prev = get_bits1(&gb);
00365 
00366                 if (s->color_depth != 0 && s->color_depth != 2) {
00367                     av_log(avctx, AV_LOG_ERROR,
00368                            "%dx%d invalid color depth %d\n", i, j, s->color_depth);
00369                     return AVERROR_INVALIDDATA;
00370                 }
00371 
00372                 if (has_diff) {
00373                     if (!s->keyframe) {
00374                         av_log(avctx, AV_LOG_ERROR,
00375                                "inter frame without keyframe\n");
00376                         return AVERROR_INVALIDDATA;
00377                     }
00378                     s->diff_start  = get_bits(&gb, 8);
00379                     s->diff_height = get_bits(&gb, 8);
00380                     av_log(avctx, AV_LOG_DEBUG,
00381                            "%dx%d diff start %d height %d\n",
00382                            i, j, s->diff_start, s->diff_height);
00383                     size -= 2;
00384                 }
00385 
00386                 if (s->zlibprime_prev)
00387                     av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
00388 
00389                 if (s->zlibprime_curr) {
00390                     int col = get_bits(&gb, 8);
00391                     int row = get_bits(&gb, 8);
00392                     av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
00393                     size -= 2;
00394                     av_log_missing_feature(avctx, "zlibprime_curr", 1);
00395                     return AVERROR_PATCHWELCOME;
00396                 }
00397                 if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
00398                     av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
00399                            "priming\n");
00400                     return AVERROR_INVALIDDATA;
00401                 }
00402                 size--; // account for flags byte
00403             }
00404 
00405             if (has_diff) {
00406                 int k;
00407                 int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
00408 
00409                 for (k = 0; k < cur_blk_height; k++)
00410                     memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
00411                            s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
00412                            cur_blk_width * 3);
00413             }
00414 
00415             /* skip unchanged blocks, which have size 0 */
00416             if (size) {
00417                 if (flashsv_decode_block(avctx, avpkt, &gb, size,
00418                                          cur_blk_width, cur_blk_height,
00419                                          x_pos, y_pos,
00420                                          i + j * (h_blocks + !!h_part)))
00421                     av_log(avctx, AV_LOG_ERROR,
00422                            "error in decompression of block %dx%d\n", i, j);
00423             }
00424         }
00425     }
00426     if (s->is_keyframe && s->ver == 2) {
00427         if (!s->keyframe) {
00428             s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
00429             if (!s->keyframe) {
00430                 av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
00431                 return AVERROR(ENOMEM);
00432             }
00433         }
00434         memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
00435     }
00436 
00437     *data_size = sizeof(AVFrame);
00438     *(AVFrame*)data = s->frame;
00439 
00440     if ((get_bits_count(&gb) / 8) != buf_size)
00441         av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
00442                buf_size, (get_bits_count(&gb) / 8));
00443 
00444     /* report that the buffer was completely consumed */
00445     return buf_size;
00446 }
00447 
00448 
00449 static av_cold int flashsv_decode_end(AVCodecContext *avctx)
00450 {
00451     FlashSVContext *s = avctx->priv_data;
00452     inflateEnd(&s->zstream);
00453     /* release the frame if needed */
00454     if (s->frame.data[0])
00455         avctx->release_buffer(avctx, &s->frame);
00456 
00457     /* free the tmpblock */
00458     av_free(s->tmpblock);
00459 
00460     return 0;
00461 }
00462 
00463 
00464 #if CONFIG_FLASHSV_DECODER
00465 AVCodec ff_flashsv_decoder = {
00466     .name           = "flashsv",
00467     .type           = AVMEDIA_TYPE_VIDEO,
00468     .id             = CODEC_ID_FLASHSV,
00469     .priv_data_size = sizeof(FlashSVContext),
00470     .init           = flashsv_decode_init,
00471     .close          = flashsv_decode_end,
00472     .decode         = flashsv_decode_frame,
00473     .capabilities   = CODEC_CAP_DR1,
00474     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00475     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
00476 };
00477 #endif /* CONFIG_FLASHSV_DECODER */
00478 
00479 #if CONFIG_FLASHSV2_DECODER
00480 static const uint32_t ff_flashsv2_default_palette[128] = {
00481     0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
00482     0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
00483     0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
00484     0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
00485     0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
00486     0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
00487     0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
00488     0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
00489     0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
00490     0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
00491     0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
00492     0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
00493     0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
00494     0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
00495     0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
00496     0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
00497     0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
00498     0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
00499     0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
00500     0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
00501     0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
00502     0xDDDDDD, 0xEEEEEE
00503 };
00504 
00505 static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
00506 {
00507     FlashSVContext *s = avctx->priv_data;
00508     flashsv_decode_init(avctx);
00509     s->pal = ff_flashsv2_default_palette;
00510     s->ver = 2;
00511 
00512     return 0;
00513 }
00514 
00515 static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
00516 {
00517     FlashSVContext *s = avctx->priv_data;
00518 
00519     av_freep(&s->keyframedata);
00520     av_freep(&s->blocks);
00521     av_freep(&s->keyframe);
00522     av_freep(&s->deflate_block);
00523     flashsv_decode_end(avctx);
00524 
00525     return 0;
00526 }
00527 
00528 AVCodec ff_flashsv2_decoder = {
00529     .name           = "flashsv2",
00530     .type           = AVMEDIA_TYPE_VIDEO,
00531     .id             = CODEC_ID_FLASHSV2,
00532     .priv_data_size = sizeof(FlashSVContext),
00533     .init           = flashsv2_decode_init,
00534     .close          = flashsv2_decode_end,
00535     .decode         = flashsv_decode_frame,
00536     .capabilities   = CODEC_CAP_DR1,
00537     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00538     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
00539 };
00540 #endif /* CONFIG_FLASHSV2_DECODER */
Generated on Thu Jan 24 2013 17:08:51 for Libav by doxygen 1.7.1