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  for(i=0; i<16; i++){
68  a->delta[i]= *(bytestream++);
69  bytestream++;
70  }
71 
72  for(y=0; y<avctx->height; y++){
73  int offset;
74  uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
75 
76  if((y&3) == 0){
77  uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
78  uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
79 
80  for(i=0; i<4; i++)
81  a->offset[i]= *(bytestream++);
82 
83  offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
84  for(x=0; x<avctx->width; x+=4){
85  luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
86  luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
87  luma[2]=( offset += a->delta[ bytestream[0]&0xF ]);
88  luma[3]=( offset += a->delta[ bytestream[0]>>4 ]);
89  luma += 4;
90 
91  *(cb++) = bytestream[3];
92  *(cr++) = bytestream[1];
93 
94  bytestream+= 4;
95  }
96  }else{
97  offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
98 
99  for(x=0; x<avctx->width; x+=8){
100  luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
101  luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
102  luma[2]=( offset += a->delta[ bytestream[3]&0xF ]);
103  luma[3]=( offset += a->delta[ bytestream[3]>>4 ]);
104  luma[4]=( offset += a->delta[ bytestream[0]&0xF ]);
105  luma[5]=( offset += a->delta[ bytestream[0]>>4 ]);
106  luma[6]=( offset += a->delta[ bytestream[1]&0xF ]);
107  luma[7]=( offset += a->delta[ bytestream[1]>>4 ]);
108  luma += 8;
109  bytestream+= 4;
110  }
111  }
112  }
113 
114  *picture= *(AVFrame*)&a->picture;
115  *data_size = sizeof(AVPicture);
116 
117  return buf_size;
118 }
119 
120 #if CONFIG_VCR1_ENCODER
121 static 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;
129  p->key_frame= 1;
130 
131  avpriv_align_put_bits(&a->pb);
132  while(get_bit_count(&a->pb)&31)
133  put_bits(&a->pb, 8, 0);
134 
135  size= get_bit_count(&a->pb)/32;
136 
137  return size*4;
138 }
139 #endif
140 
141 static av_cold void common_init(AVCodecContext *avctx){
142  VCR1Context * const a = avctx->priv_data;
143 
144  avctx->coded_frame= (AVFrame*)&a->picture;
145  a->avctx= avctx;
146 }
147 
148 static av_cold int decode_init(AVCodecContext *avctx){
149 
150  common_init(avctx);
151 
152  avctx->pix_fmt= PIX_FMT_YUV410P;
153 
154  return 0;
155 }
156 
157 static av_cold int decode_end(AVCodecContext *avctx){
158  VCR1Context *s = avctx->priv_data;
159 
160  if (s->picture.data[0])
161  avctx->release_buffer(avctx, &s->picture);
162 
163  return 0;
164 }
165 
166 #if CONFIG_VCR1_ENCODER
167 static av_cold int encode_init(AVCodecContext *avctx){
168 
169  common_init(avctx);
170 
171  return 0;
172 }
173 #endif
174 
176  .name = "vcr1",
177  .type = AVMEDIA_TYPE_VIDEO,
178  .id = CODEC_ID_VCR1,
179  .priv_data_size = sizeof(VCR1Context),
180  .init = decode_init,
181  .close = decode_end,
182  .decode = decode_frame,
183  .capabilities = CODEC_CAP_DR1,
184  .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
185 };
186 
187 #if CONFIG_VCR1_ENCODER
188 AVCodec ff_vcr1_encoder = {
189  .name = "vcr1",
190  .type = AVMEDIA_TYPE_VIDEO,
191  .id = CODEC_ID_VCR1,
192  .priv_data_size = sizeof(VCR1Context),
193  .init = encode_init,
194  .encode = encode_frame,
195  .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
196 };
197 #endif