Libav
|
00001 /* 00002 * id Quake II CIN Video Decoder 00003 * Copyright (C) 2003 the ffmpeg project 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00047 #include <stdio.h> 00048 #include <stdlib.h> 00049 #include <string.h> 00050 00051 #include "avcodec.h" 00052 00053 #define HUFFMAN_TABLE_SIZE 64 * 1024 00054 #define HUF_TOKENS 256 00055 #define PALETTE_COUNT 256 00056 00057 typedef struct 00058 { 00059 int count; 00060 unsigned char used; 00061 int children[2]; 00062 } hnode; 00063 00064 typedef struct IdcinContext { 00065 00066 AVCodecContext *avctx; 00067 AVFrame frame; 00068 00069 const unsigned char *buf; 00070 int size; 00071 00072 hnode huff_nodes[256][HUF_TOKENS*2]; 00073 int num_huff_nodes[256]; 00074 00075 } IdcinContext; 00076 00077 /* 00078 * Find the lowest probability node in a Huffman table, and mark it as 00079 * being assigned to a higher probability. 00080 * Returns the node index of the lowest unused node, or -1 if all nodes 00081 * are used. 00082 */ 00083 static int huff_smallest_node(hnode *hnodes, int num_hnodes) { 00084 int i; 00085 int best, best_node; 00086 00087 best = 99999999; 00088 best_node = -1; 00089 for(i = 0; i < num_hnodes; i++) { 00090 if(hnodes[i].used) 00091 continue; 00092 if(!hnodes[i].count) 00093 continue; 00094 if(hnodes[i].count < best) { 00095 best = hnodes[i].count; 00096 best_node = i; 00097 } 00098 } 00099 00100 if(best_node == -1) 00101 return -1; 00102 hnodes[best_node].used = 1; 00103 return best_node; 00104 } 00105 00106 /* 00107 * Build the Huffman tree using the generated/loaded probabilities histogram. 00108 * 00109 * On completion: 00110 * huff_nodes[prev][i < HUF_TOKENS] - are the nodes at the base of the tree. 00111 * huff_nodes[prev][i >= HUF_TOKENS] - are used to construct the tree. 00112 * num_huff_nodes[prev] - contains the index to the root node of the tree. 00113 * That is: huff_nodes[prev][num_huff_nodes[prev]] is the root node. 00114 */ 00115 static av_cold void huff_build_tree(IdcinContext *s, int prev) { 00116 hnode *node, *hnodes; 00117 int num_hnodes, i; 00118 00119 num_hnodes = HUF_TOKENS; 00120 hnodes = s->huff_nodes[prev]; 00121 for(i = 0; i < HUF_TOKENS * 2; i++) 00122 hnodes[i].used = 0; 00123 00124 while (1) { 00125 node = &hnodes[num_hnodes]; /* next free node */ 00126 00127 /* pick two lowest counts */ 00128 node->children[0] = huff_smallest_node(hnodes, num_hnodes); 00129 if(node->children[0] == -1) 00130 break; /* reached the root node */ 00131 00132 node->children[1] = huff_smallest_node(hnodes, num_hnodes); 00133 if(node->children[1] == -1) 00134 break; /* reached the root node */ 00135 00136 /* combine nodes probability for new node */ 00137 node->count = hnodes[node->children[0]].count + 00138 hnodes[node->children[1]].count; 00139 num_hnodes++; 00140 } 00141 00142 s->num_huff_nodes[prev] = num_hnodes - 1; 00143 } 00144 00145 static av_cold int idcin_decode_init(AVCodecContext *avctx) 00146 { 00147 IdcinContext *s = avctx->priv_data; 00148 int i, j, histogram_index = 0; 00149 unsigned char *histograms; 00150 00151 s->avctx = avctx; 00152 avctx->pix_fmt = PIX_FMT_PAL8; 00153 00154 /* make sure the Huffman tables make it */ 00155 if (s->avctx->extradata_size != HUFFMAN_TABLE_SIZE) { 00156 av_log(s->avctx, AV_LOG_ERROR, " id CIN video: expected extradata size of %d\n", HUFFMAN_TABLE_SIZE); 00157 return -1; 00158 } 00159 00160 /* build the 256 Huffman decode trees */ 00161 histograms = (unsigned char *)s->avctx->extradata; 00162 for (i = 0; i < 256; i++) { 00163 for(j = 0; j < HUF_TOKENS; j++) 00164 s->huff_nodes[i][j].count = histograms[histogram_index++]; 00165 huff_build_tree(s, i); 00166 } 00167 00168 s->frame.data[0] = NULL; 00169 00170 return 0; 00171 } 00172 00173 static void idcin_decode_vlcs(IdcinContext *s) 00174 { 00175 hnode *hnodes; 00176 long x, y; 00177 int prev; 00178 unsigned char v = 0; 00179 int bit_pos, node_num, dat_pos; 00180 00181 prev = bit_pos = dat_pos = 0; 00182 for (y = 0; y < (s->frame.linesize[0] * s->avctx->height); 00183 y += s->frame.linesize[0]) { 00184 for (x = y; x < y + s->avctx->width; x++) { 00185 node_num = s->num_huff_nodes[prev]; 00186 hnodes = s->huff_nodes[prev]; 00187 00188 while(node_num >= HUF_TOKENS) { 00189 if(!bit_pos) { 00190 if(dat_pos >= s->size) { 00191 av_log(s->avctx, AV_LOG_ERROR, "Huffman decode error.\n"); 00192 return; 00193 } 00194 bit_pos = 8; 00195 v = s->buf[dat_pos++]; 00196 } 00197 00198 node_num = hnodes[node_num].children[v & 0x01]; 00199 v = v >> 1; 00200 bit_pos--; 00201 } 00202 00203 s->frame.data[0][x] = node_num; 00204 prev = node_num; 00205 } 00206 } 00207 } 00208 00209 static int idcin_decode_frame(AVCodecContext *avctx, 00210 void *data, int *data_size, 00211 AVPacket *avpkt) 00212 { 00213 const uint8_t *buf = avpkt->data; 00214 int buf_size = avpkt->size; 00215 IdcinContext *s = avctx->priv_data; 00216 AVPaletteControl *palette_control = avctx->palctrl; 00217 00218 s->buf = buf; 00219 s->size = buf_size; 00220 00221 if (s->frame.data[0]) 00222 avctx->release_buffer(avctx, &s->frame); 00223 00224 if (avctx->get_buffer(avctx, &s->frame)) { 00225 av_log(avctx, AV_LOG_ERROR, " id CIN Video: get_buffer() failed\n"); 00226 return -1; 00227 } 00228 00229 idcin_decode_vlcs(s); 00230 00231 /* make the palette available on the way out */ 00232 memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4); 00233 /* If palette changed inform application*/ 00234 if (palette_control->palette_changed) { 00235 palette_control->palette_changed = 0; 00236 s->frame.palette_has_changed = 1; 00237 } 00238 00239 *data_size = sizeof(AVFrame); 00240 *(AVFrame*)data = s->frame; 00241 00242 /* report that the buffer was completely consumed */ 00243 return buf_size; 00244 } 00245 00246 static av_cold int idcin_decode_end(AVCodecContext *avctx) 00247 { 00248 IdcinContext *s = avctx->priv_data; 00249 00250 if (s->frame.data[0]) 00251 avctx->release_buffer(avctx, &s->frame); 00252 00253 return 0; 00254 } 00255 00256 AVCodec idcin_decoder = { 00257 "idcinvideo", 00258 AVMEDIA_TYPE_VIDEO, 00259 CODEC_ID_IDCIN, 00260 sizeof(IdcinContext), 00261 idcin_decode_init, 00262 NULL, 00263 idcin_decode_end, 00264 idcin_decode_frame, 00265 CODEC_CAP_DR1, 00266 .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"), 00267 }; 00268