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