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

libavcodec/xl.c

Go to the documentation of this file.
00001 /*
00002  * Miro VideoXL codec
00003  * Copyright (c) 2004 Konstantin Shishkov
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "libavutil/intreadwrite.h"
00028 #include "avcodec.h"
00029 
00030 typedef struct VideoXLContext{
00031     AVCodecContext *avctx;
00032     AVFrame pic;
00033 } VideoXLContext;
00034 
00035 static const int xl_table[32] = {
00036    0,   1,   2,   3,   4,   5,   6,   7,
00037    8,   9,  12,  15,  20,  25,  34,  46,
00038   64,  82,  94, 103, 108, 113, 116, 119,
00039  120, 121, 122, 123, 124, 125, 126, 127};
00040 
00041 static int decode_frame(AVCodecContext *avctx,
00042                         void *data, int *data_size,
00043                         AVPacket *avpkt)
00044 {
00045     const uint8_t *buf = avpkt->data;
00046     int buf_size = avpkt->size;
00047     VideoXLContext * const a = avctx->priv_data;
00048     AVFrame * const p= (AVFrame*)&a->pic;
00049     uint8_t *Y, *U, *V;
00050     int i, j;
00051     int stride;
00052     uint32_t val;
00053     int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0;
00054 
00055     if(p->data[0])
00056         avctx->release_buffer(avctx, p);
00057 
00058     p->reference = 0;
00059     if(avctx->get_buffer(avctx, p) < 0){
00060         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00061         return -1;
00062     }
00063     p->pict_type= AV_PICTURE_TYPE_I;
00064     p->key_frame= 1;
00065 
00066     Y = a->pic.data[0];
00067     U = a->pic.data[1];
00068     V = a->pic.data[2];
00069 
00070     stride = avctx->width - 4;
00071 
00072     if (buf_size < avctx->width * avctx->height) {
00073         av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
00074         return AVERROR_INVALIDDATA;
00075     }
00076 
00077     for (i = 0; i < avctx->height; i++) {
00078         /* lines are stored in reversed order */
00079         buf += stride;
00080 
00081         for (j = 0; j < avctx->width; j += 4) {
00082             /* value is stored in LE dword with word swapped */
00083             val = AV_RL32(buf);
00084             buf -= 4;
00085             val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
00086 
00087             if(!j)
00088                 y0 = (val & 0x1F) << 2;
00089             else
00090                 y0 = y3 + xl_table[val & 0x1F];
00091             val >>= 5;
00092             y1 = y0 + xl_table[val & 0x1F];
00093             val >>= 5;
00094             y2 = y1 + xl_table[val & 0x1F];
00095             val >>= 6; /* align to word */
00096             y3 = y2 + xl_table[val & 0x1F];
00097             val >>= 5;
00098             if(!j)
00099                 c0 = (val & 0x1F) << 2;
00100             else
00101                 c0 += xl_table[val & 0x1F];
00102             val >>= 5;
00103             if(!j)
00104                 c1 = (val & 0x1F) << 2;
00105             else
00106                 c1 += xl_table[val & 0x1F];
00107 
00108             Y[j + 0] = y0 << 1;
00109             Y[j + 1] = y1 << 1;
00110             Y[j + 2] = y2 << 1;
00111             Y[j + 3] = y3 << 1;
00112 
00113             U[j >> 2] = c0 << 1;
00114             V[j >> 2] = c1 << 1;
00115         }
00116 
00117         buf += avctx->width + 4;
00118         Y += a->pic.linesize[0];
00119         U += a->pic.linesize[1];
00120         V += a->pic.linesize[2];
00121     }
00122 
00123     *data_size = sizeof(AVFrame);
00124     *(AVFrame*)data = a->pic;
00125 
00126     return buf_size;
00127 }
00128 
00129 static av_cold int decode_init(AVCodecContext *avctx){
00130 //    VideoXLContext * const a = avctx->priv_data;
00131 
00132     avctx->pix_fmt= PIX_FMT_YUV411P;
00133 
00134     return 0;
00135 }
00136 
00137 static av_cold int decode_end(AVCodecContext *avctx){
00138     VideoXLContext * const a = avctx->priv_data;
00139     AVFrame *pic = &a->pic;
00140 
00141     if (pic->data[0])
00142         avctx->release_buffer(avctx, pic);
00143 
00144     return 0;
00145 }
00146 
00147 AVCodec ff_xl_decoder = {
00148     .name           = "xl",
00149     .type           = AVMEDIA_TYPE_VIDEO,
00150     .id             = CODEC_ID_VIXL,
00151     .priv_data_size = sizeof(VideoXLContext),
00152     .init           = decode_init,
00153     .close          = decode_end,
00154     .decode         = decode_frame,
00155     .capabilities   = CODEC_CAP_DR1,
00156     .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
00157 };
Generated on Sun Apr 22 2012 21:54:06 for Libav by doxygen 1.7.1