79dfd136c5671970efbe089c8eb06590547e0468
[ffmpeg.git] / libavcodec / vcr1.c
1 /*
2  * ATI VCR1 codec
3  * Copyright (c) 2003 Michael Niedermayer
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file vcr1.c
24  * ati vcr1 codec.
25  */
26
27 #include "avcodec.h"
28 #include "dsputil.h"
29
30 //#undef NDEBUG
31 //#include <assert.h>
32
33 typedef struct VCR1Context{
34     AVCodecContext *avctx;
35     AVFrame picture;
36     int delta[16];
37     int offset[4];
38 } VCR1Context;
39
40 static int decode_frame(AVCodecContext *avctx,
41                         void *data, int *data_size,
42                         const uint8_t *buf, int buf_size)
43 {
44     VCR1Context * const a = avctx->priv_data;
45     AVFrame *picture = data;
46     AVFrame * const p= (AVFrame*)&a->picture;
47     const uint8_t *bytestream= buf;
48     int i, x, y;
49
50     if(p->data[0])
51         avctx->release_buffer(avctx, p);
52
53     p->reference= 0;
54     if(avctx->get_buffer(avctx, p) < 0){
55         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
56         return -1;
57     }
58     p->pict_type= FF_I_TYPE;
59     p->key_frame= 1;
60
61     for(i=0; i<16; i++){
62         a->delta[i]= *(bytestream++);
63         bytestream++;
64     }
65
66     for(y=0; y<avctx->height; y++){
67         int offset;
68         uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
69
70         if((y&3) == 0){
71             uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
72             uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
73
74             for(i=0; i<4; i++)
75                 a->offset[i]= *(bytestream++);
76
77             offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
78             for(x=0; x<avctx->width; x+=4){
79                 luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
80                 luma[1]=( offset += a->delta[ bytestream[2]>>4  ]);
81                 luma[2]=( offset += a->delta[ bytestream[0]&0xF ]);
82                 luma[3]=( offset += a->delta[ bytestream[0]>>4  ]);
83                 luma += 4;
84
85                 *(cb++) = bytestream[3];
86                 *(cr++) = bytestream[1];
87
88                 bytestream+= 4;
89             }
90         }else{
91             offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
92
93             for(x=0; x<avctx->width; x+=8){
94                 luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
95                 luma[1]=( offset += a->delta[ bytestream[2]>>4  ]);
96                 luma[2]=( offset += a->delta[ bytestream[3]&0xF ]);
97                 luma[3]=( offset += a->delta[ bytestream[3]>>4  ]);
98                 luma[4]=( offset += a->delta[ bytestream[0]&0xF ]);
99                 luma[5]=( offset += a->delta[ bytestream[0]>>4  ]);
100                 luma[6]=( offset += a->delta[ bytestream[1]&0xF ]);
101                 luma[7]=( offset += a->delta[ bytestream[1]>>4  ]);
102                 luma += 8;
103                 bytestream+= 4;
104             }
105         }
106     }
107
108     *picture= *(AVFrame*)&a->picture;
109     *data_size = sizeof(AVPicture);
110
111     emms_c();
112
113     return buf_size;
114 }
115
116 #if 0
117 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
118     VCR1Context * const a = avctx->priv_data;
119     AVFrame *pict = data;
120     AVFrame * const p= (AVFrame*)&a->picture;
121     int size;
122     int mb_x, mb_y;
123
124     *p = *pict;
125     p->pict_type= FF_I_TYPE;
126     p->key_frame= 1;
127
128     emms_c();
129
130     align_put_bits(&a->pb);
131     while(get_bit_count(&a->pb)&31)
132         put_bits(&a->pb, 8, 0);
133
134     size= get_bit_count(&a->pb)/32;
135
136     return size*4;
137 }
138 #endif
139
140 static av_cold void common_init(AVCodecContext *avctx){
141     VCR1Context * const a = avctx->priv_data;
142
143     avctx->coded_frame= (AVFrame*)&a->picture;
144     a->avctx= avctx;
145 }
146
147 static av_cold int decode_init(AVCodecContext *avctx){
148
149     common_init(avctx);
150
151     avctx->pix_fmt= PIX_FMT_YUV410P;
152
153     return 0;
154 }
155
156 #if 0
157 static av_cold int encode_init(AVCodecContext *avctx){
158
159     common_init(avctx);
160
161     return 0;
162 }
163 #endif
164
165 AVCodec vcr1_decoder = {
166     "vcr1",
167     CODEC_TYPE_VIDEO,
168     CODEC_ID_VCR1,
169     sizeof(VCR1Context),
170     decode_init,
171     NULL,
172     NULL,
173     decode_frame,
174     CODEC_CAP_DR1,
175 };
176 #if 0
177 #ifdef CONFIG_ENCODERS
178
179 AVCodec vcr1_encoder = {
180     "vcr1",
181     CODEC_TYPE_VIDEO,
182     CODEC_ID_VCR1,
183     sizeof(VCR1Context),
184     encode_init,
185     encode_frame,
186     //encode_end,
187 };
188
189 #endif //CONFIG_ENCODERS
190 #endif