00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "avcodec.h"
00027 #include "mpegvideo.h"
00028
00029 typedef struct VideoXLContext{
00030 AVCodecContext *avctx;
00031 AVFrame pic;
00032 } VideoXLContext;
00033
00034 const int xl_table[32] = {
00035 0, 1, 2, 3, 4, 5, 6, 7,
00036 8, 9, 12, 15, 20, 25, 34, 46,
00037 64, 82, 94, 103, 108, 113, 116, 119,
00038 120, 121, 122, 123, 124, 125, 126, 127};
00039
00040 static int decode_frame(AVCodecContext *avctx,
00041 void *data, int *data_size,
00042 uint8_t *buf, int buf_size)
00043 {
00044 VideoXLContext * const a = avctx->priv_data;
00045 AVFrame * const p= (AVFrame*)&a->pic;
00046 uint8_t *Y, *U, *V;
00047 int i, j;
00048 int stride;
00049 uint32_t val;
00050 int y0, y1, y2, y3, c0, c1;
00051
00052 if(p->data[0])
00053 avctx->release_buffer(avctx, p);
00054
00055 p->reference = 0;
00056 if(avctx->get_buffer(avctx, p) < 0){
00057 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00058 return -1;
00059 }
00060 p->pict_type= I_TYPE;
00061 p->key_frame= 1;
00062
00063 Y = a->pic.data[0];
00064 U = a->pic.data[1];
00065 V = a->pic.data[2];
00066
00067 stride = avctx->width - 4;
00068 for (i = 0; i < avctx->height; i++) {
00069
00070 buf += stride;
00071
00072 for (j = 0; j < avctx->width; j += 4) {
00073
00074 val = LE_32(buf);
00075 buf -= 4;
00076 val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
00077
00078 if(!j)
00079 y0 = (val & 0x1F) << 2;
00080 else
00081 y0 = y3 + xl_table[val & 0x1F];
00082 val >>= 5;
00083 y1 = y0 + xl_table[val & 0x1F];
00084 val >>= 5;
00085 y2 = y1 + xl_table[val & 0x1F];
00086 val >>= 6;
00087 y3 = y2 + xl_table[val & 0x1F];
00088 val >>= 5;
00089 if(!j)
00090 c0 = (val & 0x1F) << 2;
00091 else
00092 c0 += xl_table[val & 0x1F];
00093 val >>= 5;
00094 if(!j)
00095 c1 = (val & 0x1F) << 2;
00096 else
00097 c1 += xl_table[val & 0x1F];
00098
00099 Y[j + 0] = y0 << 1;
00100 Y[j + 1] = y1 << 1;
00101 Y[j + 2] = y2 << 1;
00102 Y[j + 3] = y3 << 1;
00103
00104 U[j >> 2] = c0 << 1;
00105 V[j >> 2] = c1 << 1;
00106 }
00107
00108 buf += avctx->width + 4;
00109 Y += a->pic.linesize[0];
00110 U += a->pic.linesize[1];
00111 V += a->pic.linesize[2];
00112 }
00113
00114 *data_size = sizeof(AVFrame);
00115 *(AVFrame*)data = a->pic;
00116
00117 return buf_size;
00118 }
00119
00120 static int decode_init(AVCodecContext *avctx){
00121
00122
00123 avctx->pix_fmt= PIX_FMT_YUV411P;
00124
00125 return 0;
00126 }
00127
00128 AVCodec xl_decoder = {
00129 "xl",
00130 CODEC_TYPE_VIDEO,
00131 CODEC_ID_VIXL,
00132 sizeof(VideoXLContext),
00133 decode_init,
00134 NULL,
00135 NULL,
00136 decode_frame,
00137 CODEC_CAP_DR1,
00138 };