• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • 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 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 
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     avcodec_get_frame_defaults(&a->pic);
00133     avctx->pix_fmt= PIX_FMT_YUV411P;
00134 
00135     return 0;
00136 }
00137 
00138 static av_cold int decode_end(AVCodecContext *avctx){
00139     VideoXLContext * const a = avctx->priv_data;
00140     AVFrame *pic = &a->pic;
00141 
00142     if (pic->data[0])
00143         avctx->release_buffer(avctx, pic);
00144 
00145     return 0;
00146 }
00147 
00148 AVCodec ff_xl_decoder = {
00149     .name           = "xl",
00150     .type           = AVMEDIA_TYPE_VIDEO,
00151     .id             = CODEC_ID_VIXL,
00152     .priv_data_size = sizeof(VideoXLContext),
00153     .init           = decode_init,
00154     .close          = decode_end,
00155     .decode         = decode_frame,
00156     .capabilities   = CODEC_CAP_DR1,
00157     .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
00158 };
Generated on Fri Feb 1 2013 14:34:47 for FFmpeg by doxygen 1.7.1