4 #define ABS(x) ((x) < 0 ? -(x) : (x))
6 int quicktime_init_codec_wmx1(quicktime_video_map_t
*vtrack
)
9 quicktime_wmx1_codec_t
*codec
= &(vtrack
->codecs
.wmx1_codec
);
11 quicktime_init_yuv(&(codec
->yuv_tables
));
12 codec
->bytes_per_line
= vtrack
->track
->tkhd
.track_width
* 3;
13 if((float)codec
->bytes_per_line
/ 6 > (int)(codec
->bytes_per_line
/ 6))
14 codec
->bytes_per_line
+= 3;
16 codec
->rows
= vtrack
->track
->tkhd
.track_height
/ 2;
17 if((float)vtrack
->track
->tkhd
.track_height
/ 2 > (int)(vtrack
->track
->tkhd
.track_height
/ 2))
20 for(i
= 0; i
< WMX_CHUNK_FRAMES
; i
++)
21 codec
->frame_cache
[i
] = 0;
24 codec
->keyframe_position
= 0;
27 codec
->frames_per_chunk
= 0;
32 int quicktime_delete_codec_wmx1(quicktime_video_map_t
*vtrack
)
35 quicktime_wmx1_codec_t
*codec
= &(vtrack
->codecs
.wmx1_codec
);
37 quicktime_delete_yuv(&(codec
->yuv_tables
));
38 for(i
= 0; i
< WMX_CHUNK_FRAMES
; i
++)
39 if(codec
->frame_cache
[i
]) free(codec
->frame_cache
[i
]);
41 if(codec
->key_frame
) free(codec
->key_frame
);
45 int wmx1_write_cache(quicktime_t
*file
, int track
)
47 long offset
= quicktime_position(file
);
48 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
49 quicktime_wmx1_codec_t
*codec
= &(vtrack
->codecs
.wmx1_codec
);
50 int width
= codec
->bytes_per_line
;
51 int height
= codec
->rows
;
53 int frame
, channel
, i
, j
, k
;
54 long bytes_per_row
= codec
->bytes_per_line
;
55 int step
= codec
->frames_per_chunk
* bytes_per_row
;
56 long bytes
= height
* bytes_per_row
* codec
->frames_per_chunk
;
58 unsigned char *input_row
, *input_end
, *output_row
, *input_frame
, *output_frame
;
60 /*printf("wmx1_write_cache 1 %d %d %d\n", bytes_per_row, bytes_per_channel, bytes); */
63 codec
->key_frame
= malloc(bytes
);
64 if(!codec
->key_frame
) result
= 1;
66 /*printf("wmx1_write_cache 2\n"); */
69 for(frame
= 0; frame
< codec
->frames_per_chunk
; frame
++)
71 input_frame
= codec
->frame_cache
[frame
];
72 output_frame
= codec
->key_frame
+ frame
* bytes_per_row
;
73 input_row
= input_frame
;
74 output_row
= output_frame
;
76 for(i
= 0; i
< height
; i
++)
78 for(j
= 0; j
< width
; j
++)
80 output_row
[j
] = input_row
[j
];
83 input_row
+= bytes_per_row
;
89 /* struct jpeg_compress_struct jpeg_compress; */
90 /* struct jpeg_error_mgr jpeg_error; */
91 /* JSAMPROW row_pointer[1]; */
92 /* jpeg_compress.err = jpeg_std_error(&jpeg_error); */
93 /* jpeg_create_compress(&jpeg_compress); */
94 /* jpeg_stdio_dest(&jpeg_compress, quicktime_get_fd(file)); */
95 /* jpeg_compress.image_width = bytes_per_row; */
96 /* jpeg_compress.image_height = height * codec->frames_per_chunk; */
97 /* jpeg_compress.input_components = 1; */
98 /* jpeg_compress.in_color_space = JCS_GRAYSCALE; */
99 /* jpeg_set_defaults(&jpeg_compress); */
100 /* jpeg_set_quality(&jpeg_compress, codec->quality, 0); */
101 /* jpeg_start_compress(&jpeg_compress, TRUE); */
102 /* while(jpeg_compress.next_scanline < jpeg_compress.image_height && !result) */
104 /* row_pointer[0] = codec->key_frame + jpeg_compress.next_scanline * bytes_per_row; */
105 /* result = jpeg_write_scanlines(&jpeg_compress, row_pointer, 1); */
106 /* result = !result; */
108 /* jpeg_finish_compress(&jpeg_compress); */
109 /* jpeg_destroy((j_common_ptr)&jpeg_compress); */
113 result
= quicktime_write_data(file
, codec
->key_frame
, bytes
);
115 /*printf("wmx1_write_cache 4\n"); */
117 output_bytes
= quicktime_position(file
) - offset
;
118 quicktime_update_tables(file
,
121 vtrack
->current_chunk
,
122 vtrack
->current_position
,
123 codec
->frames_per_chunk
,
125 /*printf("wmx1_write_cache 5\n"); */
127 codec
->frames_per_chunk
= 0;
128 vtrack
->current_chunk
++;
132 /* Perform YUV transform and store in cache */
133 int wmx1_store_in_cache(quicktime_t
*file
, unsigned char *cache
, unsigned char **row_pointers
, int track
)
135 long offset
= quicktime_position(file
);
136 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
137 quicktime_wmx1_codec_t
*codec
= &(vtrack
->codecs
.wmx1_codec
);
138 quicktime_yuv_t
*yuv_tables
= &(codec
->yuv_tables
);
140 int width
= vtrack
->track
->tkhd
.track_width
;
141 int height
= vtrack
->track
->tkhd
.track_height
;
142 long bytes
= codec
->rows
* codec
->bytes_per_line
;
143 unsigned char *buffer
= cache
;
144 unsigned char *output_row
; /* Pointer to output row */
145 unsigned char *row_pointer1
, *row_pointer2
; /* Pointers to input rows */
146 int x1
, x2
, in_y
, out_y
;
147 int y1
, y2
, y3
, y4
, u
, v
;
149 int endpoint
= width
* 3;
152 for(in_y
= 0, out_y
= 0; in_y
< height
; out_y
++)
154 output_row
= buffer
+ out_y
* codec
->bytes_per_line
;
155 row_pointer1
= row_pointers
[in_y
];
159 row_pointer2
= row_pointers
[in_y
];
161 row_pointer2
= row_pointer1
;
165 for(x1
= 0, x2
= 0; x1
< endpoint
; )
168 r
= row_pointer1
[x1
++];
169 g
= row_pointer1
[x1
++];
170 b
= row_pointer1
[x1
++];
172 y1
= (yuv_tables
->rtoy_tab
[r
] + yuv_tables
->gtoy_tab
[g
] + yuv_tables
->btoy_tab
[b
]);
173 u
= (yuv_tables
->rtou_tab
[r
] + yuv_tables
->gtou_tab
[g
] + yuv_tables
->btou_tab
[b
]);
174 v
= (yuv_tables
->rtov_tab
[r
] + yuv_tables
->gtov_tab
[g
] + yuv_tables
->btov_tab
[b
]);
176 /* Top right pixel */
179 r
= row_pointer1
[x1
++];
180 g
= row_pointer1
[x1
++];
181 b
= row_pointer1
[x1
++];
184 y2
= (yuv_tables
->rtoy_tab
[r
] + yuv_tables
->gtoy_tab
[g
] + yuv_tables
->btoy_tab
[b
]);
185 u
+= (yuv_tables
->rtou_tab
[r
] + yuv_tables
->gtou_tab
[g
] + yuv_tables
->btou_tab
[b
]);
186 v
+= (yuv_tables
->rtov_tab
[r
] + yuv_tables
->gtov_tab
[g
] + yuv_tables
->btov_tab
[b
]);
188 /* Bottom left pixel */
189 r
= row_pointer2
[x2
++];
190 g
= row_pointer2
[x2
++];
191 b
= row_pointer2
[x2
++];
193 y3
= (yuv_tables
->rtoy_tab
[r
] + yuv_tables
->gtoy_tab
[g
] + yuv_tables
->btoy_tab
[b
]);
194 u
+= (yuv_tables
->rtou_tab
[r
] + yuv_tables
->gtou_tab
[g
] + yuv_tables
->btou_tab
[b
]);
195 v
+= (yuv_tables
->rtov_tab
[r
] + yuv_tables
->gtov_tab
[g
] + yuv_tables
->btov_tab
[b
]);
197 /* Bottom right pixel */
200 r
= row_pointer2
[x2
++];
201 g
= row_pointer2
[x2
++];
202 b
= row_pointer2
[x2
++];
205 y4
= (yuv_tables
->rtoy_tab
[r
] + yuv_tables
->gtoy_tab
[g
] + yuv_tables
->btoy_tab
[b
]);
206 u
+= (yuv_tables
->rtou_tab
[r
] + yuv_tables
->gtou_tab
[g
] + yuv_tables
->btou_tab
[b
]);
207 v
+= (yuv_tables
->rtov_tab
[r
] + yuv_tables
->gtov_tab
[g
] + yuv_tables
->btov_tab
[b
]);
215 if(y1
> 255) y1
= 255;
216 if(y2
> 255) y2
= 255;
217 if(y3
> 255) y3
= 255;
218 if(y4
> 255) y4
= 255;
225 if(u
< -128) u
= -128;
226 if(v
< -128) v
= -128;
239 int quicktime_encode_wmx1(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
242 int written_cache
= 0;
243 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
244 quicktime_wmx1_codec_t
*codec
= &(vtrack
->codecs
.wmx1_codec
);
245 int width
= vtrack
->track
->tkhd
.track_width
;
246 int height
= vtrack
->track
->tkhd
.track_height
;
247 int bytes
= codec
->rows
* codec
->bytes_per_line
;
248 long frame_difference
= 0;
252 if(codec
->frames_per_chunk
< WMX_CHUNK_FRAMES
)
254 unsigned char *frame_cache
;
255 unsigned char *row_pointer1
, *row_pointer2
, *endpoint
;
256 if(!codec
->frame_cache
[codec
->frames_per_chunk
])
257 codec
->frame_cache
[codec
->frames_per_chunk
] = malloc(bytes
);
258 frame_cache
= codec
->frame_cache
[codec
->frames_per_chunk
];
261 wmx1_store_in_cache(file
, frame_cache
, row_pointers
, track
);
262 codec
->frames_per_chunk
++;
266 /* Write cache and start new cache. */
267 unsigned char *frame_cache
;
269 result
= wmx1_write_cache(file
, track
);
272 /* Copy next frame to cache */
273 if(!codec
->frame_cache
[codec
->frames_per_chunk
])
274 codec
->frame_cache
[codec
->frames_per_chunk
] = malloc(bytes
);
275 frame_cache
= codec
->frame_cache
[codec
->frames_per_chunk
];
276 wmx1_store_in_cache(file
, codec
->frame_cache
[codec
->frames_per_chunk
], row_pointers
, track
);
277 codec
->frames_per_chunk
++;
279 /*printf("quicktime_encode_wmx1 3\n"); */
281 /* if(!written_cache) */
282 /* quicktime_update_tables(file, */
285 /* vtrack->current_chunk, */
286 /* vtrack->current_position, */
287 /* codec->frames_per_chunk, */
293 int quicktime_decode_wmx1(quicktime_t
*file
, unsigned char **row_pointers
, int track
)