3 * Copyright (c) 2003 Michael Niedermayer
5 * This file is part of FFmpeg.
7 * FFmpeg 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.
12 * FFmpeg 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "libavutil/avassert.h"
30 #include "libavutil/internal.h"
32 typedef struct VCR1Context
{
37 static av_cold
int vcr1_decode_init(AVCodecContext
*avctx
)
39 avctx
->pix_fmt
= AV_PIX_FMT_YUV410P
;
41 if (avctx
->width
% 8 || avctx
->height
%4) {
42 avpriv_request_sample(avctx
, "odd dimensions (%d x %d) support", avctx
->width
, avctx
->height
);
43 return AVERROR_INVALIDDATA
;
49 static int vcr1_decode_frame(AVCodecContext
*avctx
, void *data
,
50 int *got_frame
, AVPacket
*avpkt
)
52 VCR1Context
*const a
= avctx
->priv_data
;
53 AVFrame
*const p
= data
;
54 const uint8_t *bytestream
= avpkt
->data
;
55 const uint8_t *bytestream_end
= bytestream
+ avpkt
->size
;
58 if(avpkt
->size
< 32 + avctx
->height
+ avctx
->width
*avctx
->height
*5/8){
59 av_log(avctx
, AV_LOG_ERROR
, "Insufficient input data. %d < %d\n", avpkt
->size
, 32 + avctx
->height
+ avctx
->width
*avctx
->height
*5/8);
60 return AVERROR(EINVAL
);
63 if ((ret
= ff_get_buffer(avctx
, p
, 0)) < 0)
65 p
->pict_type
= AV_PICTURE_TYPE_I
;
68 for (i
= 0; i
< 16; i
++) {
69 a
->delta
[i
] = *bytestream
++;
73 for (y
= 0; y
< avctx
->height
; y
++) {
75 uint8_t *luma
= &p
->data
[0][y
* p
->linesize
[0]];
78 uint8_t *cb
= &p
->data
[1][(y
>> 2) * p
->linesize
[1]];
79 uint8_t *cr
= &p
->data
[2][(y
>> 2) * p
->linesize
[2]];
81 av_assert0 (bytestream_end
- bytestream
>= 4 + avctx
->width
);
83 for (i
= 0; i
< 4; i
++)
84 a
->offset
[i
] = *bytestream
++;
86 offset
= a
->offset
[0] - a
->delta
[bytestream
[2] & 0xF];
87 for (x
= 0; x
< avctx
->width
; x
+= 4) {
88 luma
[0] = offset
+= a
->delta
[bytestream
[2] & 0xF];
89 luma
[1] = offset
+= a
->delta
[bytestream
[2] >> 4];
90 luma
[2] = offset
+= a
->delta
[bytestream
[0] & 0xF];
91 luma
[3] = offset
+= a
->delta
[bytestream
[0] >> 4];
94 *cb
++ = bytestream
[3];
95 *cr
++ = bytestream
[1];
100 av_assert0 (bytestream_end
- bytestream
>= avctx
->width
/ 2);
102 offset
= a
->offset
[y
& 3] - a
->delta
[bytestream
[2] & 0xF];
104 for (x
= 0; x
< avctx
->width
; x
+= 8) {
105 luma
[0] = offset
+= a
->delta
[bytestream
[2] & 0xF];
106 luma
[1] = offset
+= a
->delta
[bytestream
[2] >> 4];
107 luma
[2] = offset
+= a
->delta
[bytestream
[3] & 0xF];
108 luma
[3] = offset
+= a
->delta
[bytestream
[3] >> 4];
109 luma
[4] = offset
+= a
->delta
[bytestream
[0] & 0xF];
110 luma
[5] = offset
+= a
->delta
[bytestream
[0] >> 4];
111 luma
[6] = offset
+= a
->delta
[bytestream
[1] & 0xF];
112 luma
[7] = offset
+= a
->delta
[bytestream
[1] >> 4];
121 return bytestream
- avpkt
->data
;
124 AVCodec ff_vcr1_decoder
= {
126 .long_name
= NULL_IF_CONFIG_SMALL("ATI VCR1"),
127 .type
= AVMEDIA_TYPE_VIDEO
,
128 .id
= AV_CODEC_ID_VCR1
,
129 .priv_data_size
= sizeof(VCR1Context
),
130 .init
= vcr1_decode_init
,
131 .decode
= vcr1_decode_frame
,
132 .capabilities
= CODEC_CAP_DR1
,