annotate 4xm.c @ 1795:920e6381e1fe libavcodec

2 byte shorter userdata for mpeg4 in the past it was startcode,string,00,7F,startcode now it is startcode,string,stratcode both are mpeg4 compliant, as according to the standard the userdata lasts until the next 00 00 01 (startcode prefix) but some very primitive decoders which simply skip until the first 00 byte and then expect the next valid startcode might fail with the old variant, just a theory though (didnt test if quicktime can decode it now)
author michael
date Sun, 08 Feb 2004 22:52:35 +0000
parents 932d306bf1dc
children 129236143f2e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
1 /*
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
2 * 4XM codec
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
3 * Copyright (c) 2003 Michael Niedermayer
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
4 *
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
9 *
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
13 * Lesser General Public License for more details.
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
14 *
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
18 */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
19
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
20 /**
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
21 * @file 4xm.c
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
22 * 4XM codec.
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
23 */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
24
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
25 #include "avcodec.h"
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
26 #include "dsputil.h"
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
27 #include "mpegvideo.h"
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
28
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
29 //#undef NDEBUG
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
30 //#include <assert.h>
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
31
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
32 #define BLOCK_TYPE_VLC_BITS 5
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
33 #define ACDC_VLC_BITS 9
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
34
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
35 #define CFRAME_BUFFER_COUNT 100
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
36
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
37 static const uint8_t block_type_tab[4][8][2]={
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
38 { //{8,4,2}x{8,4,2}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
39 { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
40 },{ //{8,4}x1
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
41 { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
42 },{ //1x{8,4}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
43 { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
44 },{ //1x2, 2x1
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
45 { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
46 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
47 };
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
48
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
49 static const uint8_t size2index[4][4]={
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
50 {-1, 3, 1, 1},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
51 { 3, 0, 0, 0},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
52 { 2, 0, 0, 0},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
53 { 2, 0, 0, 0},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
54 };
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
55
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
56 static const int8_t mv[256][2]={
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
57 { 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
58 { 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
59 { 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
60 { 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
61 { 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
62 { 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
63 { 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
64 { -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
65 { 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
66 { -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
67 { -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
68 { -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
69 { 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
70 { 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
71 { 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
72 { -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
73 { -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
74 { 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
75 { 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
76 { 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
77 {-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
78 { -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
79 { 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
80 { 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
81 { -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
82 { 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
83 { 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
84 { 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
85 { 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
86 {-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
87 {-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27},
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
88 {-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32}
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
89 };
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
90
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
91 // this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
92 static const uint8_t dequant_table[64]={
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
93 16, 15, 13, 19, 24, 31, 28, 17,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
94 17, 23, 25, 31, 36, 63, 45, 21,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
95 18, 24, 27, 37, 52, 59, 49, 20,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
96 16, 28, 34, 40, 60, 80, 51, 20,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
97 18, 31, 48, 66, 68, 86, 56, 21,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
98 19, 38, 56, 59, 64, 64, 48, 20,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
99 27, 48, 55, 55, 56, 51, 35, 15,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
100 20, 35, 34, 32, 31, 22, 15, 8,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
101 };
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
102
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
103 static VLC block_type_vlc[4];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
104
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
105
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
106 typedef struct CFrameBuffer{
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
107 int allocated_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
108 int size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
109 int id;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
110 uint8_t *data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
111 }CFrameBuffer;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
112
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
113 typedef struct FourXContext{
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
114 AVCodecContext *avctx;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
115 DSPContext dsp;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
116 AVFrame current_picture, last_picture;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
117 GetBitContext pre_gb; ///< ac/dc prefix
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
118 GetBitContext gb;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
119 uint8_t *bytestream;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
120 uint16_t *wordstream;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
121 int mv[256];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
122 VLC pre_vlc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
123 int last_dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
124 DCTELEM __align8 block[6][64];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
125 uint8_t *bitstream_buffer;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
126 int bitstream_buffer_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
127 CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
128 } FourXContext;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
129
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
130
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
131 #define FIX_1_082392200 70936
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
132 #define FIX_1_414213562 92682
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
133 #define FIX_1_847759065 121095
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
134 #define FIX_2_613125930 171254
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
135
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
136 #define MULTIPLY(var,const) (((var)*(const)) >> 16)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
137
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
138 static void idct(DCTELEM block[64]){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
139 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
140 int tmp10, tmp11, tmp12, tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
141 int z5, z10, z11, z12, z13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
142 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
143 int temp[64];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
144
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
145 for(i=0; i<8; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
146 tmp10 = block[8*0 + i] + block[8*4 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
147 tmp11 = block[8*0 + i] - block[8*4 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
148
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
149 tmp13 = block[8*2 + i] + block[8*6 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
150 tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
151
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
152 tmp0 = tmp10 + tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
153 tmp3 = tmp10 - tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
154 tmp1 = tmp11 + tmp12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
155 tmp2 = tmp11 - tmp12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
156
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
157 z13 = block[8*5 + i] + block[8*3 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
158 z10 = block[8*5 + i] - block[8*3 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
159 z11 = block[8*1 + i] + block[8*7 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
160 z12 = block[8*1 + i] - block[8*7 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
161
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
162 tmp7 = z11 + z13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
163 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
164
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
165 z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
166 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
167 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
168
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
169 tmp6 = tmp12 - tmp7;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
170 tmp5 = tmp11 - tmp6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
171 tmp4 = tmp10 + tmp5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
172
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
173 temp[8*0 + i] = tmp0 + tmp7;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
174 temp[8*7 + i] = tmp0 - tmp7;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
175 temp[8*1 + i] = tmp1 + tmp6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
176 temp[8*6 + i] = tmp1 - tmp6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
177 temp[8*2 + i] = tmp2 + tmp5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
178 temp[8*5 + i] = tmp2 - tmp5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
179 temp[8*4 + i] = tmp3 + tmp4;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
180 temp[8*3 + i] = tmp3 - tmp4;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
181 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
182
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
183 for(i=0; i<8*8; i+=8){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
184 tmp10 = temp[0 + i] + temp[4 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
185 tmp11 = temp[0 + i] - temp[4 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
186
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
187 tmp13 = temp[2 + i] + temp[6 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
188 tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
189
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
190 tmp0 = tmp10 + tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
191 tmp3 = tmp10 - tmp13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
192 tmp1 = tmp11 + tmp12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
193 tmp2 = tmp11 - tmp12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
194
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
195 z13 = temp[5 + i] + temp[3 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
196 z10 = temp[5 + i] - temp[3 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
197 z11 = temp[1 + i] + temp[7 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
198 z12 = temp[1 + i] - temp[7 + i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
199
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
200 tmp7 = z11 + z13;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
201 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
202
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
203 z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
204 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
205 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
206
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
207 tmp6 = tmp12 - tmp7;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
208 tmp5 = tmp11 - tmp6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
209 tmp4 = tmp10 + tmp5;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
210
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
211 block[0 + i] = (tmp0 + tmp7)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
212 block[7 + i] = (tmp0 - tmp7)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
213 block[1 + i] = (tmp1 + tmp6)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
214 block[6 + i] = (tmp1 - tmp6)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
215 block[2 + i] = (tmp2 + tmp5)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
216 block[5 + i] = (tmp2 - tmp5)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
217 block[4 + i] = (tmp3 + tmp4)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
218 block[3 + i] = (tmp3 - tmp4)>>6;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
219 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
220 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
221
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
222 static void init_vlcs(FourXContext *f){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
223 static int done = 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
224 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
225
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
226 if (!done) {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
227 done = 1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
228
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
229 for(i=0; i<4; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
230 init_vlc(&block_type_vlc[i], BLOCK_TYPE_VLC_BITS, 7,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
231 &block_type_tab[i][0][1], 2, 1,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
232 &block_type_tab[i][0][0], 2, 1);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
233 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
234 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
235 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
236
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
237 static void init_mv(FourXContext *f){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
238 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
239
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
240 for(i=0; i<256; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
241 f->mv[i] = mv[i][0] + mv[i][1]*f->current_picture.linesize[0]/2;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
242 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
243 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
244
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
245 static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
246 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
247 dc*= 0x10001;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
248
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
249 switch(log2w){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
250 case 0:
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
251 for(i=0; i<h; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
252 dst[0] = scale*src[0] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
253 if(scale) src += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
254 dst += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
255 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
256 break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
257 case 1:
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
258 for(i=0; i<h; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
259 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
260 if(scale) src += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
261 dst += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
262 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
263 break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
264 case 2:
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
265 for(i=0; i<h; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
266 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
267 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
268 if(scale) src += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
269 dst += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
270 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
271 break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
272 case 3:
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
273 for(i=0; i<h; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
274 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
275 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
276 ((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
277 ((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
278 if(scale) src += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
279 dst += stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
280 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
281 break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
282 default: assert(0);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
283 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
284 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
285
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
286 static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
287 const int index= size2index[log2h][log2w];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
288 const int h= 1<<log2h;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
289 int code= get_vlc2(&f->gb, block_type_vlc[index].table, BLOCK_TYPE_VLC_BITS, 1);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
290
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
291 assert(code>=0 && code<=6);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
292
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
293 if(code == 0){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
294 src += f->mv[ *f->bytestream++ ];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
295 mcdc(dst, src, log2w, h, stride, 1, 0);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
296 }else if(code == 1){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
297 log2h--;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
298 decode_p_block(f, dst , src , log2w, log2h, stride);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
299 decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
300 }else if(code == 2){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
301 log2w--;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
302 decode_p_block(f, dst , src , log2w, log2h, stride);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
303 decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
304 }else if(code == 4){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
305 src += f->mv[ *f->bytestream++ ];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
306 mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++));
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
307 }else if(code == 5){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
308 mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++));
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
309 }else if(code == 6){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
310 if(log2w){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
311 dst[0] = le2me_16(*f->wordstream++);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
312 dst[1] = le2me_16(*f->wordstream++);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
313 }else{
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
314 dst[0 ] = le2me_16(*f->wordstream++);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
315 dst[stride] = le2me_16(*f->wordstream++);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
316 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
317 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
318 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
319
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
320 static int get32(void *p){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
321 return le2me_32(*(uint32_t*)p);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
322 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
323
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
324 static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
325 int x, y;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
326 const int width= f->avctx->width;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
327 const int height= f->avctx->height;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
328 uint16_t *src= (uint16_t*)f->last_picture.data[0];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
329 uint16_t *dst= (uint16_t*)f->current_picture.data[0];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
330 const int stride= f->current_picture.linesize[0]>>1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
331 const int bitstream_size= get32(buf+8);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
332 const int bytestream_size= get32(buf+16);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
333 const int wordstream_size= get32(buf+12);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
334
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
335 if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length)
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
336 av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
337 bitstream_size+ bytestream_size+ wordstream_size - length);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
338
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
339 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
340 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + 20), bitstream_size/4);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
341 init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
342
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
343 f->wordstream= (uint16_t*)(buf + 20 + bitstream_size);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
344 f->bytestream= buf + 20 + bitstream_size + wordstream_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
345
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
346 init_mv(f);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
347
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
348 for(y=0; y<height; y+=8){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
349 for(x=0; x<width; x+=8){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
350 decode_p_block(f, dst + x, src + x, 3, 3, stride);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
351 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
352 src += 8*stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
353 dst += 8*stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
354 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
355
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
356 if(bitstream_size != (get_bits_count(&f->gb)+31)/32*4)
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
357 av_log(f->avctx, AV_LOG_ERROR, " %d %d %d bytes left\n",
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
358 bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
359 bytestream_size - (f->bytestream - (buf + 20 + bitstream_size + wordstream_size)),
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
360 wordstream_size - (((uint8_t*)f->wordstream) - (buf + 20 + bitstream_size))
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
361 );
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
362
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
363 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
364 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
365
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
366 /**
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
367 * decode block and dequantize.
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
368 * Note this is allmost identical to mjpeg
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
369 */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
370 static int decode_i_block(FourXContext *f, DCTELEM *block){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
371 int code, i, j, level, val;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
372
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
373 /* DC coef */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
374 val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
375 if (val>>4){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
376 av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
377 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
378
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
379 if(val)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
380 val = get_xbits(&f->gb, val);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
381
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
382 val = val * dequant_table[0] + f->last_dc;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
383 f->last_dc =
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
384 block[0] = val;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
385 /* AC coefs */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
386 i = 1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
387 for(;;) {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
388 code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
389
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
390 /* EOB */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
391 if (code == 0)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
392 break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
393 if (code == 0xf0) {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
394 i += 16;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
395 } else {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
396 level = get_xbits(&f->gb, code & 0xf);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
397 i += code >> 4;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
398 if (i >= 64) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
399 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
400 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
401 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
402
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
403 j= ff_zigzag_direct[i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
404 block[j] = level * dequant_table[j];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
405 i++;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
406 if (i >= 64)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
407 break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
408 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
409 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
410
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
411 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
412 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
413
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
414 static inline void idct_put(FourXContext *f, int x, int y){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
415 DCTELEM (*block)[64]= f->block;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
416 int stride= f->current_picture.linesize[0]>>1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
417 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
418 uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
419
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
420 for(i=0; i<4; i++){
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
421 block[i][0] += 0x80*8*8;
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
422 idct(block[i]);
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
423 }
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
424
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
425 if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
426 for(i=4; i<6; i++) idct(block[i]);
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
427 }
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
428
1514
b1a0fc3ad09f forgot to commit, i hope its correct
michael
parents: 1478
diff changeset
429 /* Note transform is:
b1a0fc3ad09f forgot to commit, i hope its correct
michael
parents: 1478
diff changeset
430 y= ( 1b + 4g + 2r)/14
b1a0fc3ad09f forgot to commit, i hope its correct
michael
parents: 1478
diff changeset
431 cb=( 3b - 2g - 1r)/14
b1a0fc3ad09f forgot to commit, i hope its correct
michael
parents: 1478
diff changeset
432 cr=(-1b - 4g + 5r)/14
b1a0fc3ad09f forgot to commit, i hope its correct
michael
parents: 1478
diff changeset
433 */
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
434 for(y=0; y<8; y++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
435 for(x=0; x<8; x++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
436 DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
437 int cb= block[4][x + 8*y];
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
438 int cr= block[5][x + 8*y];
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
439 int cg= (cb + cr)>>1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
440 int y;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
441
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
442 cb+=cb;
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
443
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
444 y = temp[0];
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
445 dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
446 y = temp[1];
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
447 dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
448 y = temp[8];
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
449 dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
450 y = temp[9];
1295
5c67ef6498ed fix 4xm yuv->rgb565 transform
michaelni
parents: 1294
diff changeset
451 dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
452 dst += 2;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
453 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
454 dst += 2*stride - 2*8;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
455 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
456 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
457
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
458 static int decode_i_mb(FourXContext *f){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
459 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
460
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
461 f->dsp.clear_blocks(f->block[0]);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
462
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
463 for(i=0; i<6; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
464 if(decode_i_block(f, f->block[i]) < 0)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
465 return -1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
466 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
467
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
468 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
469 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
470
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
471 static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
472 int frequency[512];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
473 uint8_t flag[512];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
474 int up[512];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
475 uint8_t len_tab[257];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
476 int bits_tab[257];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
477 int start, end;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
478 uint8_t *ptr= buf;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
479 int j;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
480
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
481 memset(frequency, 0, sizeof(frequency));
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
482 memset(up, -1, sizeof(up));
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
483
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
484 start= *ptr++;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
485 end= *ptr++;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
486 for(;;){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
487 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
488
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
489 for(i=start; i<=end; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
490 frequency[i]= *ptr++;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
491 // printf("%d %d %d\n", start, end, frequency[i]);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
492 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
493 start= *ptr++;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
494 if(start==0) break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
495
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
496 end= *ptr++;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
497 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
498 frequency[256]=1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
499
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
500 while((ptr - buf)&3) ptr++; // 4byte align
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
501
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
502 // for(j=0; j<16; j++)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
503 // printf("%2X", ptr[j]);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
504
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
505 for(j=257; j<512; j++){
1294
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
506 int min_freq[2]= {256*256, 256*256};
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
507 int smallest[2]= {0, 0};
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
508 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
509 for(i=0; i<j; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
510 if(frequency[i] == 0) continue;
1294
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
511 if(frequency[i] < min_freq[1]){
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
512 if(frequency[i] < min_freq[0]){
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
513 min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
514 min_freq[0]= frequency[i];smallest[0]= i;
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
515 }else{
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
516 min_freq[1]= frequency[i];smallest[1]= i;
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
517 }
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
518 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
519 }
1294
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
520 if(min_freq[1] == 256*256) break;
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
521
1294
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
522 frequency[j]= min_freq[0] + min_freq[1];
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
523 flag[ smallest[0] ]= 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
524 flag[ smallest[1] ]= 1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
525 up[ smallest[0] ]=
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
526 up[ smallest[1] ]= j;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
527 frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
528 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
529
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
530 for(j=0; j<257; j++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
531 int node;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
532 int len=0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
533 int bits=0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
534
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
535 for(node= j; up[node] != -1; node= up[node]){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
536 bits += flag[node]<<len;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
537 len++;
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
538 if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
539 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
540
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
541 bits_tab[j]= bits;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
542 len_tab[j]= len;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
543 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
544
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
545 init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
546 len_tab , 1, 1,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
547 bits_tab, 4, 4);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
548
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
549 return ptr;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
550 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
551
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
552 static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
553 int x, y;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
554 const int width= f->avctx->width;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
555 const int height= f->avctx->height;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
556 uint16_t *dst= (uint16_t*)f->current_picture.data[0];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
557 const int stride= f->current_picture.linesize[0]>>1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
558 const int bitstream_size= get32(buf);
1478
e0402982c1a0 Fix compilation with ccc
mellum
parents: 1452
diff changeset
559 const int token_count __attribute__((unused)) = get32(buf + bitstream_size + 8);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
560 int prestream_size= 4*get32(buf + bitstream_size + 4);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
561 uint8_t *prestream= buf + bitstream_size + 12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
562
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
563 if(prestream_size + bitstream_size + 12 != length)
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
564 av_log(f->avctx, AV_LOG_ERROR, "size missmatch %d %d %d\n", prestream_size, bitstream_size, length);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
565
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
566 prestream= read_huffman_tables(f, prestream);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
567
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
568 init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
569
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
570 prestream_size= length + buf - prestream;
1294
6896bc2f3bf5 10l (array[-1] ...)
michaelni
parents: 1293
diff changeset
571
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
572 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
573 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)prestream, prestream_size/4);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
574 init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
575
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
576 f->last_dc= 0*128*8*8;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
577
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
578 for(y=0; y<height; y+=16){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
579 for(x=0; x<width; x+=16){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
580 if(decode_i_mb(f) < 0)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
581 return -1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
582
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
583 idct_put(f, x, y);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
584 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
585 dst += 16*stride;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
586 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
587
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
588 if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
589 av_log(f->avctx, AV_LOG_ERROR, "end missmatch\n");
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
590
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
591 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
592 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
593
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
594 static int decode_frame(AVCodecContext *avctx,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
595 void *data, int *data_size,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
596 uint8_t *buf, int buf_size)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
597 {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
598 FourXContext * const f = avctx->priv_data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
599 AVFrame *picture = data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
600 AVFrame *p, temp;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
601 int i, frame_4cc, frame_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
602
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
603 *data_size = 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
604
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
605 /* special case for last picture */
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
606 if (buf_size == 0) {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
607 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
608 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
609
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
610 frame_4cc= get32(buf);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
611 if(buf_size != get32(buf+4)+8){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
612 av_log(f->avctx, AV_LOG_ERROR, "size missmatch %d %d\n", buf_size, get32(buf+4));
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
613 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
614
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
615 if(frame_4cc == ff_get_fourcc("cfrm")){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
616 int free_index=-1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
617 const int data_size= buf_size - 20;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
618 const int id= get32(buf+12);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
619 const int whole_size= get32(buf+16);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
620 CFrameBuffer *cfrm;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
621
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
622 for(i=0; i<CFRAME_BUFFER_COUNT; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
623 if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
624 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
625 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
626
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
627 for(i=0; i<CFRAME_BUFFER_COUNT; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
628 if(f->cfrm[i].id == id) break;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
629 if(f->cfrm[i].size == 0 ) free_index= i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
630 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
631
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
632 if(i>=CFRAME_BUFFER_COUNT){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
633 i= free_index;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
634 f->cfrm[i].id= id;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
635 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
636 cfrm= &f->cfrm[i];
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
637
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
638 cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
639
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
640 memcpy(cfrm->data + cfrm->size, buf+20, data_size);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
641 cfrm->size += data_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
642
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
643 if(cfrm->size >= whole_size){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
644 buf= cfrm->data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
645 frame_size= cfrm->size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
646
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
647 if(id != avctx->frame_number){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
648 av_log(f->avctx, AV_LOG_ERROR, "cframe id missmatch %d %d\n", id, avctx->frame_number);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
649 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
650
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
651 cfrm->size= cfrm->id= 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
652 frame_4cc= ff_get_fourcc("pfrm");
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
653 }else
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
654 return buf_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
655 }else{
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
656 buf= buf + 12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
657 frame_size= buf_size - 12;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
658 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
659
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
660 temp= f->current_picture;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
661 f->current_picture= f->last_picture;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
662 f->last_picture= temp;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
663
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
664 p= &f->current_picture;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
665 avctx->coded_frame= p;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
666
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
667 avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
668
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
669 if(p->data[0])
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
670 avctx->release_buffer(avctx, p);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
671
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
672 p->reference= 1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
673 if(avctx->get_buffer(avctx, p) < 0){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
674 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
675 return -1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
676 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
677
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
678 if(frame_4cc == ff_get_fourcc("ifrm")){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
679 p->pict_type= I_TYPE;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
680 if(decode_i_frame(f, buf, frame_size) < 0)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
681 return -1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
682 }else if(frame_4cc == ff_get_fourcc("pfrm")){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
683 p->pict_type= P_TYPE;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
684 if(decode_p_frame(f, buf, frame_size) < 0)
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
685 return -1;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
686 }else if(frame_4cc == ff_get_fourcc("snd_")){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
687 av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
688 }else{
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1514
diff changeset
689 av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
1293
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
690 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
691
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
692 #if 0
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
693 for(i=0; i<20; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
694 printf("%2X %c ", buf[i], clip(buf[i],16,126));
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
695 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
696 #endif
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
697
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
698 p->key_frame= p->pict_type == I_TYPE;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
699
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
700 *picture= *p;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
701 *data_size = sizeof(AVPicture);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
702
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
703 emms_c();
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
704
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
705 return buf_size;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
706 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
707
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
708
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
709 static void common_init(AVCodecContext *avctx){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
710 FourXContext * const f = avctx->priv_data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
711
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
712 dsputil_init(&f->dsp, avctx);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
713
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
714 f->avctx= avctx;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
715 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
716
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
717 static int decode_init(AVCodecContext *avctx){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
718 FourXContext * const f = avctx->priv_data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
719
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
720 common_init(avctx);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
721 init_vlcs(f);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
722
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
723 avctx->pix_fmt= PIX_FMT_RGB565;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
724
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
725 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
726 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
727
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
728
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
729 static int decode_end(AVCodecContext *avctx){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
730 FourXContext * const f = avctx->priv_data;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
731 int i;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
732
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
733 av_freep(&f->bitstream_buffer);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
734 f->bitstream_buffer_size=0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
735 for(i=0; i<CFRAME_BUFFER_COUNT; i++){
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
736 av_freep(&f->cfrm[i].data);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
737 f->cfrm[i].allocated_size= 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
738 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
739 free_vlc(&f->pre_vlc);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
740
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
741 avcodec_default_free_buffers(avctx);
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
742
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
743 return 0;
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
744 }
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
745
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
746 AVCodec fourxm_decoder = {
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
747 "4xm",
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
748 CODEC_TYPE_VIDEO,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
749 CODEC_ID_4XM,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
750 sizeof(FourXContext),
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
751 decode_init,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
752 NULL,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
753 decode_end,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
754 decode_frame,
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
755 /*CODEC_CAP_DR1,*/
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
756 };
a918c7d38345 4xm codec
michaelni
parents:
diff changeset
757