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 libavcodec/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/* Disable the encoder. */
34#undef CONFIG_VCR1_ENCODER
35#define CONFIG_VCR1_ENCODER 0
36
37typedef struct VCR1Context{
38    AVCodecContext *avctx;
39    AVFrame picture;
40    int delta[16];
41    int offset[4];
42} VCR1Context;
43
44static int decode_frame(AVCodecContext *avctx,
45                        void *data, int *data_size,
46                        const uint8_t *buf, int buf_size)
47{
48    VCR1Context * const a = avctx->priv_data;
49    AVFrame *picture = data;
50    AVFrame * const p= (AVFrame*)&a->picture;
51    const uint8_t *bytestream= buf;
52    int i, x, y;
53
54    if(p->data[0])
55        avctx->release_buffer(avctx, p);
56
57    p->reference= 0;
58    if(avctx->get_buffer(avctx, p) < 0){
59        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
60        return -1;
61    }
62    p->pict_type= FF_I_TYPE;
63    p->key_frame= 1;
64
65    for(i=0; i<16; i++){
66        a->delta[i]= *(bytestream++);
67        bytestream++;
68    }
69
70    for(y=0; y<avctx->height; y++){
71        int offset;
72        uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
73
74        if((y&3) == 0){
75            uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
76            uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
77
78            for(i=0; i<4; i++)
79                a->offset[i]= *(bytestream++);
80
81            offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
82            for(x=0; x<avctx->width; x+=4){
83                luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
84                luma[1]=( offset += a->delta[ bytestream[2]>>4  ]);
85                luma[2]=( offset += a->delta[ bytestream[0]&0xF ]);
86                luma[3]=( offset += a->delta[ bytestream[0]>>4  ]);
87                luma += 4;
88
89                *(cb++) = bytestream[3];
90                *(cr++) = bytestream[1];
91
92                bytestream+= 4;
93            }
94        }else{
95            offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
96
97            for(x=0; x<avctx->width; x+=8){
98                luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
99                luma[1]=( offset += a->delta[ bytestream[2]>>4  ]);
100                luma[2]=( offset += a->delta[ bytestream[3]&0xF ]);
101                luma[3]=( offset += a->delta[ bytestream[3]>>4  ]);
102                luma[4]=( offset += a->delta[ bytestream[0]&0xF ]);
103                luma[5]=( offset += a->delta[ bytestream[0]>>4  ]);
104                luma[6]=( offset += a->delta[ bytestream[1]&0xF ]);
105                luma[7]=( offset += a->delta[ bytestream[1]>>4  ]);
106                luma += 8;
107                bytestream+= 4;
108            }
109        }
110    }
111
112    *picture= *(AVFrame*)&a->picture;
113    *data_size = sizeof(AVPicture);
114
115    emms_c();
116
117    return buf_size;
118}
119
120#if CONFIG_VCR1_ENCODER
121static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
122    VCR1Context * const a = avctx->priv_data;
123    AVFrame *pict = data;
124    AVFrame * const p= (AVFrame*)&a->picture;
125    int size;
126
127    *p = *pict;
128    p->pict_type= FF_I_TYPE;
129    p->key_frame= 1;
130
131    emms_c();
132
133    align_put_bits(&a->pb);
134    while(get_bit_count(&a->pb)&31)
135        put_bits(&a->pb, 8, 0);
136
137    size= get_bit_count(&a->pb)/32;
138
139    return size*4;
140}
141#endif
142
143static av_cold void common_init(AVCodecContext *avctx){
144    VCR1Context * const a = avctx->priv_data;
145
146    avctx->coded_frame= (AVFrame*)&a->picture;
147    a->avctx= avctx;
148}
149
150static av_cold int decode_init(AVCodecContext *avctx){
151
152    common_init(avctx);
153
154    avctx->pix_fmt= PIX_FMT_YUV410P;
155
156    return 0;
157}
158
159#if CONFIG_VCR1_ENCODER
160static av_cold int encode_init(AVCodecContext *avctx){
161
162    common_init(avctx);
163
164    return 0;
165}
166#endif
167
168AVCodec vcr1_decoder = {
169    "vcr1",
170    CODEC_TYPE_VIDEO,
171    CODEC_ID_VCR1,
172    sizeof(VCR1Context),
173    decode_init,
174    NULL,
175    NULL,
176    decode_frame,
177    CODEC_CAP_DR1,
178    .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
179};
180
181#if CONFIG_VCR1_ENCODER
182AVCodec vcr1_encoder = {
183    "vcr1",
184    CODEC_TYPE_VIDEO,
185    CODEC_ID_VCR1,
186    sizeof(VCR1Context),
187    encode_init,
188    encode_frame,
189    //encode_end,
190    .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
191};
192#endif
193