Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include "dsputil.h"
00029
00030
00031
00032
00033
00034 #undef CONFIG_VCR1_ENCODER
00035 #define CONFIG_VCR1_ENCODER 0
00036
00037 typedef struct VCR1Context{
00038 AVCodecContext *avctx;
00039 AVFrame picture;
00040 int delta[16];
00041 int offset[4];
00042 } VCR1Context;
00043
00044 static int decode_frame(AVCodecContext *avctx,
00045 void *data, int *data_size,
00046 AVPacket *avpkt)
00047 {
00048 const uint8_t *buf = avpkt->data;
00049 int buf_size = avpkt->size;
00050 VCR1Context * const a = avctx->priv_data;
00051 AVFrame *picture = data;
00052 AVFrame * const p= (AVFrame*)&a->picture;
00053 const uint8_t *bytestream= buf;
00054 int i, x, y;
00055
00056 if(p->data[0])
00057 avctx->release_buffer(avctx, p);
00058
00059 p->reference= 0;
00060 if(avctx->get_buffer(avctx, p) < 0){
00061 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00062 return -1;
00063 }
00064 p->pict_type= AV_PICTURE_TYPE_I;
00065 p->key_frame= 1;
00066
00067 if (buf_size < 32)
00068 goto packet_small;
00069
00070 for(i=0; i<16; i++){
00071 a->delta[i]= *(bytestream++);
00072 bytestream++;
00073 buf_size--;
00074 }
00075
00076 for(y=0; y<avctx->height; y++){
00077 int offset;
00078 uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
00079
00080 if((y&3) == 0){
00081 uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
00082 uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
00083
00084 if (buf_size < 4 + avctx->width)
00085 goto packet_small;
00086
00087 for(i=0; i<4; i++)
00088 a->offset[i]= *(bytestream++);
00089 buf_size -= 4;
00090
00091 offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
00092 for(x=0; x<avctx->width; x+=4){
00093 luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
00094 luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
00095 luma[2]=( offset += a->delta[ bytestream[0]&0xF ]);
00096 luma[3]=( offset += a->delta[ bytestream[0]>>4 ]);
00097 luma += 4;
00098
00099 *(cb++) = bytestream[3];
00100 *(cr++) = bytestream[1];
00101
00102 bytestream+= 4;
00103 buf_size -= 4;
00104 }
00105 }else{
00106 if (buf_size < avctx->width / 2)
00107 goto packet_small;
00108
00109 offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
00110
00111 for(x=0; x<avctx->width; x+=8){
00112 luma[0]=( offset += a->delta[ bytestream[2]&0xF ]);
00113 luma[1]=( offset += a->delta[ bytestream[2]>>4 ]);
00114 luma[2]=( offset += a->delta[ bytestream[3]&0xF ]);
00115 luma[3]=( offset += a->delta[ bytestream[3]>>4 ]);
00116 luma[4]=( offset += a->delta[ bytestream[0]&0xF ]);
00117 luma[5]=( offset += a->delta[ bytestream[0]>>4 ]);
00118 luma[6]=( offset += a->delta[ bytestream[1]&0xF ]);
00119 luma[7]=( offset += a->delta[ bytestream[1]>>4 ]);
00120 luma += 8;
00121 bytestream+= 4;
00122 buf_size -= 4;
00123 }
00124 }
00125 }
00126
00127 *picture= *(AVFrame*)&a->picture;
00128 *data_size = sizeof(AVPicture);
00129
00130 return buf_size;
00131 packet_small:
00132 av_log(avctx, AV_LOG_ERROR, "Input packet too small.\n");
00133 return AVERROR_INVALIDDATA;
00134 }
00135
00136 #if CONFIG_VCR1_ENCODER
00137 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
00138 VCR1Context * const a = avctx->priv_data;
00139 AVFrame *pict = data;
00140 AVFrame * const p= (AVFrame*)&a->picture;
00141 int size;
00142
00143 *p = *pict;
00144 p->pict_type= AV_PICTURE_TYPE_I;
00145 p->key_frame= 1;
00146
00147 avpriv_align_put_bits(&a->pb);
00148 while(get_bit_count(&a->pb)&31)
00149 put_bits(&a->pb, 8, 0);
00150
00151 size= get_bit_count(&a->pb)/32;
00152
00153 return size*4;
00154 }
00155 #endif
00156
00157 static av_cold void common_init(AVCodecContext *avctx){
00158 VCR1Context * const a = avctx->priv_data;
00159
00160 avctx->coded_frame= (AVFrame*)&a->picture;
00161 a->avctx= avctx;
00162 }
00163
00164 static av_cold int decode_init(AVCodecContext *avctx){
00165
00166 common_init(avctx);
00167
00168 avctx->pix_fmt= PIX_FMT_YUV410P;
00169
00170 if (avctx->width & 7) {
00171 av_log(avctx, AV_LOG_ERROR, "Width %d is not divisble by 8.\n", avctx->width);
00172 return AVERROR_INVALIDDATA;
00173 }
00174
00175 return 0;
00176 }
00177
00178 static av_cold int decode_end(AVCodecContext *avctx){
00179 VCR1Context *s = avctx->priv_data;
00180
00181 if (s->picture.data[0])
00182 avctx->release_buffer(avctx, &s->picture);
00183
00184 return 0;
00185 }
00186
00187 #if CONFIG_VCR1_ENCODER
00188 static av_cold int encode_init(AVCodecContext *avctx){
00189
00190 common_init(avctx);
00191
00192 return 0;
00193 }
00194 #endif
00195
00196 AVCodec ff_vcr1_decoder = {
00197 .name = "vcr1",
00198 .type = AVMEDIA_TYPE_VIDEO,
00199 .id = CODEC_ID_VCR1,
00200 .priv_data_size = sizeof(VCR1Context),
00201 .init = decode_init,
00202 .close = decode_end,
00203 .decode = decode_frame,
00204 .capabilities = CODEC_CAP_DR1,
00205 .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
00206 };
00207
00208 #if CONFIG_VCR1_ENCODER
00209 AVCodec ff_vcr1_encoder = {
00210 .name = "vcr1",
00211 .type = AVMEDIA_TYPE_VIDEO,
00212 .id = CODEC_ID_VCR1,
00213 .priv_data_size = sizeof(VCR1Context),
00214 .init = encode_init,
00215 .encode = encode_frame,
00216 .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
00217 };
00218 #endif