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 typedef struct VCR1Context {
00031 AVFrame picture;
00032 int delta[16];
00033 int offset[4];
00034 } VCR1Context;
00035
00036 static av_cold int vcr1_common_init(AVCodecContext *avctx)
00037 {
00038 VCR1Context *const a = avctx->priv_data;
00039
00040 avctx->coded_frame = &a->picture;
00041 avcodec_get_frame_defaults(&a->picture);
00042
00043 return 0;
00044 }
00045
00046 static av_cold int vcr1_decode_init(AVCodecContext *avctx)
00047 {
00048 vcr1_common_init(avctx);
00049
00050 avctx->pix_fmt = PIX_FMT_YUV410P;
00051
00052 return 0;
00053 }
00054
00055 static av_cold int vcr1_decode_end(AVCodecContext *avctx)
00056 {
00057 VCR1Context *s = avctx->priv_data;
00058
00059 if (s->picture.data[0])
00060 avctx->release_buffer(avctx, &s->picture);
00061
00062 return 0;
00063 }
00064
00065 static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
00066 int *data_size, AVPacket *avpkt)
00067 {
00068 const uint8_t *buf = avpkt->data;
00069 int buf_size = avpkt->size;
00070 VCR1Context *const a = avctx->priv_data;
00071 AVFrame *picture = data;
00072 AVFrame *const p = &a->picture;
00073 const uint8_t *bytestream = buf;
00074 int i, x, y;
00075
00076 if (p->data[0])
00077 avctx->release_buffer(avctx, p);
00078
00079 if(buf_size < 16 + avctx->height + avctx->width*avctx->height*5/8){
00080 av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
00081 return AVERROR(EINVAL);
00082 }
00083
00084 p->reference = 0;
00085 if (avctx->get_buffer(avctx, p) < 0) {
00086 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00087 return -1;
00088 }
00089 p->pict_type = AV_PICTURE_TYPE_I;
00090 p->key_frame = 1;
00091
00092 for (i = 0; i < 16; i++) {
00093 a->delta[i] = *bytestream++;
00094 bytestream++;
00095 }
00096
00097 for (y = 0; y < avctx->height; y++) {
00098 int offset;
00099 uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
00100
00101 if ((y & 3) == 0) {
00102 uint8_t *cb = &a->picture.data[1][(y >> 2) * a->picture.linesize[1]];
00103 uint8_t *cr = &a->picture.data[2][(y >> 2) * a->picture.linesize[2]];
00104
00105 for (i = 0; i < 4; i++)
00106 a->offset[i] = *bytestream++;
00107
00108 offset = a->offset[0] - a->delta[bytestream[2] & 0xF];
00109 for (x = 0; x < avctx->width; x += 4) {
00110 luma[0] = offset += a->delta[bytestream[2] & 0xF];
00111 luma[1] = offset += a->delta[bytestream[2] >> 4];
00112 luma[2] = offset += a->delta[bytestream[0] & 0xF];
00113 luma[3] = offset += a->delta[bytestream[0] >> 4];
00114 luma += 4;
00115
00116 *cb++ = bytestream[3];
00117 *cr++ = bytestream[1];
00118
00119 bytestream += 4;
00120 }
00121 } else {
00122 offset = a->offset[y & 3] - a->delta[bytestream[2] & 0xF];
00123
00124 for (x = 0; x < avctx->width; x += 8) {
00125 luma[0] = offset += a->delta[bytestream[2] & 0xF];
00126 luma[1] = offset += a->delta[bytestream[2] >> 4];
00127 luma[2] = offset += a->delta[bytestream[3] & 0xF];
00128 luma[3] = offset += a->delta[bytestream[3] >> 4];
00129 luma[4] = offset += a->delta[bytestream[0] & 0xF];
00130 luma[5] = offset += a->delta[bytestream[0] >> 4];
00131 luma[6] = offset += a->delta[bytestream[1] & 0xF];
00132 luma[7] = offset += a->delta[bytestream[1] >> 4];
00133 luma += 8;
00134 bytestream += 4;
00135 }
00136 }
00137 }
00138
00139 *picture = a->picture;
00140 *data_size = sizeof(AVPicture);
00141
00142 return buf_size;
00143 }
00144
00145 AVCodec ff_vcr1_decoder = {
00146 .name = "vcr1",
00147 .type = AVMEDIA_TYPE_VIDEO,
00148 .id = CODEC_ID_VCR1,
00149 .priv_data_size = sizeof(VCR1Context),
00150 .init = vcr1_decode_init,
00151 .close = vcr1_decode_end,
00152 .decode = vcr1_decode_frame,
00153 .capabilities = CODEC_CAP_DR1,
00154 .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
00155 };
00156
00157
00158 #undef CONFIG_VCR1_ENCODER
00159 #define CONFIG_VCR1_ENCODER 0
00160
00161 #if CONFIG_VCR1_ENCODER
00162
00163 #include "put_bits.h"
00164
00165 static int vcr1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
00166 int buf_size, void *data)
00167 {
00168 VCR1Context *const a = avctx->priv_data;
00169 AVFrame *pict = data;
00170 AVFrame *const p = &a->picture;
00171 int size;
00172
00173 *p = *pict;
00174 p->pict_type = AV_PICTURE_TYPE_I;
00175 p->key_frame = 1;
00176
00177 avpriv_align_put_bits(&a->pb);
00178 flush_put_bits(&a->pb);
00179
00180 size = put_bits_count(&a->pb) / 32;
00181
00182 return size * 4;
00183 }
00184
00185 AVCodec ff_vcr1_encoder = {
00186 .name = "vcr1",
00187 .type = AVMEDIA_TYPE_VIDEO,
00188 .id = CODEC_ID_VCR1,
00189 .priv_data_size = sizeof(VCR1Context),
00190 .init = vcr1_common_init,
00191 .encode = vcr1_encode_frame,
00192 .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
00193 };
00194 #endif