vcr1.c
Go to the documentation of this file.
1 /*
2  * ATI VCR1 codec
3  * Copyright (c) 2003 Michael Niedermayer
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
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 
37 typedef struct VCR1Context{
40  int delta[16];
41  int offset[4];
42 } VCR1Context;
43 
44 static int decode_frame(AVCodecContext *avctx,
45  void *data, int *data_size,
46  AVPacket *avpkt)
47 {
48  const uint8_t *buf = avpkt->data;
49  int buf_size = avpkt->size;
50  VCR1Context * const a = avctx->priv_data;
51  AVFrame *picture = data;
52  AVFrame * const p= (AVFrame*)&a->picture;
53  const uint8_t *bytestream= buf;
54  int i, x, y;
55 
56  if(p->data[0])
57  avctx->release_buffer(avctx, p);
58 
59  p->reference= 0;
60  if(avctx->get_buffer(avctx, p) < 0){
61  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
62  return -1;
63  }
65  p->key_frame= 1;
66 
67  if (buf_size < 32)
68  goto packet_small;
69 
70  for(i=0; i<16; i++){
71  a->delta[i]= *(bytestream++);
72  bytestream++;
73  buf_size--;
74  }
75 
76  for(y=0; y<avctx->height; y++){
77  int offset;
78  uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
79 
80  if((y&3) == 0){
81  uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
82  uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
83 
84  if (buf_size < 4 + avctx->width)
85  goto packet_small;
86 
87  for(i=0; i<4; i++)
88  a->offset[i]= *(bytestream++);
89  buf_size -= 4;
90 
91  offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
92  for(x=0; x<avctx->width; x+=4){
93  luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
94  luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
95  luma[2]=( offset += a->delta[ bytestream[0]&0xF ]);
96  luma[3]=( offset += a->delta[ bytestream[0]>>4 ]);
97  luma += 4;
98 
99  *(cb++) = bytestream[3];
100  *(cr++) = bytestream[1];
101 
102  bytestream+= 4;
103  buf_size -= 4;
104  }
105  }else{
106  if (buf_size < avctx->width / 2)
107  goto packet_small;
108 
109  offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
110 
111  for(x=0; x<avctx->width; x+=8){
112  luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
113  luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
114  luma[2]=( offset += a->delta[ bytestream[3]&0xF ]);
115  luma[3]=( offset += a->delta[ bytestream[3]>>4 ]);
116  luma[4]=( offset += a->delta[ bytestream[0]&0xF ]);
117  luma[5]=( offset += a->delta[ bytestream[0]>>4 ]);
118  luma[6]=( offset += a->delta[ bytestream[1]&0xF ]);
119  luma[7]=( offset += a->delta[ bytestream[1]>>4 ]);
120  luma += 8;
121  bytestream+= 4;
122  buf_size -= 4;
123  }
124  }
125  }
126 
127  *picture= *(AVFrame*)&a->picture;
128  *data_size = sizeof(AVPicture);
129 
130  return buf_size;
131 packet_small:
132  av_log(avctx, AV_LOG_ERROR, "Input packet too small.\n");
133  return AVERROR_INVALIDDATA;
134 }
135 
136 #if CONFIG_VCR1_ENCODER
137 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
138  VCR1Context * const a = avctx->priv_data;
139  AVFrame *pict = data;
140  AVFrame * const p= (AVFrame*)&a->picture;
141  int size;
142 
143  *p = *pict;
145  p->key_frame= 1;
146 
147  avpriv_align_put_bits(&a->pb);
148  while(get_bit_count(&a->pb)&31)
149  put_bits(&a->pb, 8, 0);
150 
151  size= get_bit_count(&a->pb)/32;
152 
153  return size*4;
154 }
155 #endif
156 
157 static av_cold void common_init(AVCodecContext *avctx){
158  VCR1Context * const a = avctx->priv_data;
159 
160  avctx->coded_frame= (AVFrame*)&a->picture;
161  a->avctx= avctx;
162 }
163 
164 static av_cold int decode_init(AVCodecContext *avctx){
165 
166  common_init(avctx);
167 
168  avctx->pix_fmt= PIX_FMT_YUV410P;
169 
170  if (avctx->width & 7) {
171  av_log(avctx, AV_LOG_ERROR, "Width %d is not divisble by 8.\n", avctx->width);
172  return AVERROR_INVALIDDATA;
173  }
174 
175  return 0;
176 }
177 
178 static av_cold int decode_end(AVCodecContext *avctx){
179  VCR1Context *s = avctx->priv_data;
180 
181  if (s->picture.data[0])
182  avctx->release_buffer(avctx, &s->picture);
183 
184  return 0;
185 }
186 
187 #if CONFIG_VCR1_ENCODER
188 static av_cold int encode_init(AVCodecContext *avctx){
189 
190  common_init(avctx);
191 
192  return 0;
193 }
194 #endif
195 
197  .name = "vcr1",
198  .type = AVMEDIA_TYPE_VIDEO,
199  .id = CODEC_ID_VCR1,
200  .priv_data_size = sizeof(VCR1Context),
201  .init = decode_init,
202  .close = decode_end,
203  .decode = decode_frame,
204  .capabilities = CODEC_CAP_DR1,
205  .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
206 };
207 
208 #if CONFIG_VCR1_ENCODER
209 AVCodec ff_vcr1_encoder = {
210  .name = "vcr1",
211  .type = AVMEDIA_TYPE_VIDEO,
212  .id = CODEC_ID_VCR1,
213  .priv_data_size = sizeof(VCR1Context),
214  .init = encode_init,
215  .encode = encode_frame,
216  .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
217 };
218 #endif