Libav
|
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= FF_I_TYPE; 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 for (i = 0; i < avctx->height; i++) { 00072 /* lines are stored in reversed order */ 00073 buf += stride; 00074 00075 for (j = 0; j < avctx->width; j += 4) { 00076 /* value is stored in LE dword with word swapped */ 00077 val = AV_RL32(buf); 00078 buf -= 4; 00079 val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16); 00080 00081 if(!j) 00082 y0 = (val & 0x1F) << 2; 00083 else 00084 y0 = y3 + xl_table[val & 0x1F]; 00085 val >>= 5; 00086 y1 = y0 + xl_table[val & 0x1F]; 00087 val >>= 5; 00088 y2 = y1 + xl_table[val & 0x1F]; 00089 val >>= 6; /* align to word */ 00090 y3 = y2 + xl_table[val & 0x1F]; 00091 val >>= 5; 00092 if(!j) 00093 c0 = (val & 0x1F) << 2; 00094 else 00095 c0 += xl_table[val & 0x1F]; 00096 val >>= 5; 00097 if(!j) 00098 c1 = (val & 0x1F) << 2; 00099 else 00100 c1 += xl_table[val & 0x1F]; 00101 00102 Y[j + 0] = y0 << 1; 00103 Y[j + 1] = y1 << 1; 00104 Y[j + 2] = y2 << 1; 00105 Y[j + 3] = y3 << 1; 00106 00107 U[j >> 2] = c0 << 1; 00108 V[j >> 2] = c1 << 1; 00109 } 00110 00111 buf += avctx->width + 4; 00112 Y += a->pic.linesize[0]; 00113 U += a->pic.linesize[1]; 00114 V += a->pic.linesize[2]; 00115 } 00116 00117 *data_size = sizeof(AVFrame); 00118 *(AVFrame*)data = a->pic; 00119 00120 return buf_size; 00121 } 00122 00123 static av_cold int decode_init(AVCodecContext *avctx){ 00124 // VideoXLContext * const a = avctx->priv_data; 00125 00126 avctx->pix_fmt= PIX_FMT_YUV411P; 00127 00128 return 0; 00129 } 00130 00131 static av_cold int decode_end(AVCodecContext *avctx){ 00132 VideoXLContext * const a = avctx->priv_data; 00133 AVFrame *pic = &a->pic; 00134 00135 if (pic->data[0]) 00136 avctx->release_buffer(avctx, pic); 00137 00138 return 0; 00139 } 00140 00141 AVCodec xl_decoder = { 00142 "xl", 00143 AVMEDIA_TYPE_VIDEO, 00144 CODEC_ID_VIXL, 00145 sizeof(VideoXLContext), 00146 decode_init, 00147 NULL, 00148 decode_end, 00149 decode_frame, 00150 CODEC_CAP_DR1, 00151 .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"), 00152 };