00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 const uint8_t *buf, int buf_size)
00044 {
00045 VideoXLContext * const a = avctx->priv_data;
00046 AVFrame * const p= (AVFrame*)&a->pic;
00047 uint8_t *Y, *U, *V;
00048 int i, j;
00049 int stride;
00050 uint32_t val;
00051 int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0;
00052
00053 if(p->data[0])
00054 avctx->release_buffer(avctx, p);
00055
00056 p->reference = 0;
00057 if(avctx->get_buffer(avctx, p) < 0){
00058 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00059 return -1;
00060 }
00061 p->pict_type= FF_I_TYPE;
00062 p->key_frame= 1;
00063
00064 Y = a->pic.data[0];
00065 U = a->pic.data[1];
00066 V = a->pic.data[2];
00067
00068 stride = avctx->width - 4;
00069 for (i = 0; i < avctx->height; i++) {
00070
00071 buf += stride;
00072
00073 for (j = 0; j < avctx->width; j += 4) {
00074
00075 val = AV_RL32(buf);
00076 buf -= 4;
00077 val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
00078
00079 if(!j)
00080 y0 = (val & 0x1F) << 2;
00081 else
00082 y0 = y3 + xl_table[val & 0x1F];
00083 val >>= 5;
00084 y1 = y0 + xl_table[val & 0x1F];
00085 val >>= 5;
00086 y2 = y1 + xl_table[val & 0x1F];
00087 val >>= 6;
00088 y3 = y2 + xl_table[val & 0x1F];
00089 val >>= 5;
00090 if(!j)
00091 c0 = (val & 0x1F) << 2;
00092 else
00093 c0 += xl_table[val & 0x1F];
00094 val >>= 5;
00095 if(!j)
00096 c1 = (val & 0x1F) << 2;
00097 else
00098 c1 += xl_table[val & 0x1F];
00099
00100 Y[j + 0] = y0 << 1;
00101 Y[j + 1] = y1 << 1;
00102 Y[j + 2] = y2 << 1;
00103 Y[j + 3] = y3 << 1;
00104
00105 U[j >> 2] = c0 << 1;
00106 V[j >> 2] = c1 << 1;
00107 }
00108
00109 buf += avctx->width + 4;
00110 Y += a->pic.linesize[0];
00111 U += a->pic.linesize[1];
00112 V += a->pic.linesize[2];
00113 }
00114
00115 *data_size = sizeof(AVFrame);
00116 *(AVFrame*)data = a->pic;
00117
00118 return buf_size;
00119 }
00120
00121 static av_cold int decode_init(AVCodecContext *avctx){
00122
00123
00124 avctx->pix_fmt= PIX_FMT_YUV411P;
00125
00126 return 0;
00127 }
00128
00129 AVCodec xl_decoder = {
00130 "xl",
00131 CODEC_TYPE_VIDEO,
00132 CODEC_ID_VIXL,
00133 sizeof(VideoXLContext),
00134 decode_init,
00135 NULL,
00136 NULL,
00137 decode_frame,
00138 CODEC_CAP_DR1,
00139 .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
00140 };