home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek 6
/
Geek-006.iso
/
linux
/
video
/
xmovie-1.5.3.tar.gz
/
xmovie-1.5.3.tar
/
xmovie-1.5.3
/
quicktime
/
wmx1.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-11-29
|
9KB
|
298 lines
#include "quicktime.h"
#include "jpeglib.h"
#define ABS(x) ((x) < 0 ? -(x) : (x))
int quicktime_init_codec_wmx1(quicktime_video_map_t *vtrack)
{
int i;
quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
quicktime_init_yuv(&(codec->yuv_tables));
codec->bytes_per_line = vtrack->track->tkhd.track_width * 3;
if((float)codec->bytes_per_line / 6 > (int)(codec->bytes_per_line / 6))
codec->bytes_per_line += 3;
codec->rows = vtrack->track->tkhd.track_height / 2;
if((float)vtrack->track->tkhd.track_height / 2 > (int)(vtrack->track->tkhd.track_height / 2))
codec->rows++;
for(i = 0; i < WMX_CHUNK_FRAMES; i++)
codec->frame_cache[i] = 0;
codec->key_frame = 0;
codec->keyframe_position = 0;
codec->quality = 100;
codec->use_float = 0;
codec->frames_per_chunk = 0;
codec->threshold = 5;
return 0;
}
int quicktime_delete_codec_wmx1(quicktime_video_map_t *vtrack)
{
int i;
quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
quicktime_delete_yuv(&(codec->yuv_tables));
for(i = 0; i < WMX_CHUNK_FRAMES; i++)
if(codec->frame_cache[i]) free(codec->frame_cache[i]);
if(codec->key_frame) free(codec->key_frame);
return 0;
}
int wmx1_write_cache(quicktime_t *file, int track)
{
long offset = quicktime_position(file);
quicktime_video_map_t *vtrack = &(file->vtracks[track]);
quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
int width = codec->bytes_per_line;
int height = codec->rows;
int result = 0;
int frame, channel, i, j, k;
long bytes_per_row = codec->bytes_per_line;
int step = codec->frames_per_chunk * bytes_per_row;
long bytes = height * bytes_per_row * codec->frames_per_chunk;
long output_bytes;
unsigned char *input_row, *input_end, *output_row, *input_frame, *output_frame;
/*printf("wmx1_write_cache 1 %d %d %d\n", bytes_per_row, bytes_per_channel, bytes); */
if(!codec->key_frame)
{
codec->key_frame = malloc(bytes);
if(!codec->key_frame) result = 1;
}
/*printf("wmx1_write_cache 2\n"); */
/* Interlace rows */
for(frame = 0; frame < codec->frames_per_chunk; frame++)
{
input_frame = codec->frame_cache[frame];
output_frame = codec->key_frame + frame * bytes_per_row;
input_row = input_frame;
output_row = output_frame;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
output_row[j] = input_row[j];
}
output_row += step;
input_row += bytes_per_row;
}
}
/* Write as a jpeg */
/* { */
/* struct jpeg_compress_struct jpeg_compress; */
/* struct jpeg_error_mgr jpeg_error; */
/* JSAMPROW row_pointer[1]; */
/* jpeg_compress.err = jpeg_std_error(&jpeg_error); */
/* jpeg_create_compress(&jpeg_compress); */
/* jpeg_stdio_dest(&jpeg_compress, quicktime_get_fd(file)); */
/* jpeg_compress.image_width = bytes_per_row; */
/* jpeg_compress.image_height = height * codec->frames_per_chunk; */
/* jpeg_compress.input_components = 1; */
/* jpeg_compress.in_color_space = JCS_GRAYSCALE; */
/* jpeg_set_defaults(&jpeg_compress); */
/* jpeg_set_quality(&jpeg_compress, codec->quality, 0); */
/* jpeg_start_compress(&jpeg_compress, TRUE); */
/* while(jpeg_compress.next_scanline < jpeg_compress.image_height && !result) */
/* { */
/* row_pointer[0] = codec->key_frame + jpeg_compress.next_scanline * bytes_per_row; */
/* result = jpeg_write_scanlines(&jpeg_compress, row_pointer, 1); */
/* result = !result; */
/* } */
/* jpeg_finish_compress(&jpeg_compress); */
/* jpeg_destroy((j_common_ptr)&jpeg_compress); */
/* } */
/* Write as raw */
result = quicktime_write_data(file, codec->key_frame, bytes);
result = !result;
/*printf("wmx1_write_cache 4\n"); */
output_bytes = quicktime_position(file) - offset;
quicktime_update_tables(file,
vtrack->track,
offset,
vtrack->current_chunk,
vtrack->current_position,
codec->frames_per_chunk,
output_bytes);
/*printf("wmx1_write_cache 5\n"); */
codec->frames_per_chunk = 0;
vtrack->current_chunk++;
return result;
}
/* Perform YUV transform and store in cache */
int wmx1_store_in_cache(quicktime_t *file, unsigned char *cache, unsigned char **row_pointers, int track)
{
long offset = quicktime_position(file);
quicktime_video_map_t *vtrack = &(file->vtracks[track]);
quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
quicktime_yuv_t *yuv_tables = &(codec->yuv_tables);
int result = 0;
int width = vtrack->track->tkhd.track_width;
int height = vtrack->track->tkhd.track_height;
long bytes = codec->rows * codec->bytes_per_line;
unsigned char *buffer = cache;
unsigned char *output_row; /* Pointer to output row */
unsigned char *row_pointer1, *row_pointer2; /* Pointers to input rows */
int x1, x2, in_y, out_y;
int y1, y2, y3, y4, u, v;
int r, g, b;
int endpoint = width * 3;
int denominator;
for(in_y = 0, out_y = 0; in_y < height; out_y++)
{
output_row = buffer + out_y * codec->bytes_per_line;
row_pointer1 = row_pointers[in_y];
in_y++;
if(in_y < height)
row_pointer2 = row_pointers[in_y];
else
row_pointer2 = row_pointer1;
in_y++;
for(x1 = 0, x2 = 0; x1 < endpoint; )
{
/* Top left pixel */
r = row_pointer1[x1++];
g = row_pointer1[x1++];
b = row_pointer1[x1++];
y1 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
u = (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
v = (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
/* Top right pixel */
if(x1 < endpoint)
{
r = row_pointer1[x1++];
g = row_pointer1[x1++];
b = row_pointer1[x1++];
}
y2 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
u += (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
v += (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
/* Bottom left pixel */
r = row_pointer2[x2++];
g = row_pointer2[x2++];
b = row_pointer2[x2++];
y3 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
u += (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
v += (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
/* Bottom right pixel */
if(x2 < endpoint)
{
r = row_pointer2[x2++];
g = row_pointer2[x2++];
b = row_pointer2[x2++];
}
y4 = (yuv_tables->rtoy_tab[r] + yuv_tables->gtoy_tab[g] + yuv_tables->btoy_tab[b]);
u += (yuv_tables->rtou_tab[r] + yuv_tables->gtou_tab[g] + yuv_tables->btou_tab[b]);
v += (yuv_tables->rtov_tab[r] + yuv_tables->gtov_tab[g] + yuv_tables->btov_tab[b]);
y1 /= 0x10000;
y2 /= 0x10000;
y3 /= 0x10000;
y4 /= 0x10000;
u /= 0x40000;
v /= 0x40000;
if(y1 > 255) y1 = 255;
if(y2 > 255) y2 = 255;
if(y3 > 255) y3 = 255;
if(y4 > 255) y4 = 255;
if(u > 127) u = 127;
if(v > 127) v = 127;
if(y1 < 0) y1 = 0;
if(y2 < 0) y2 = 0;
if(y3 < 0) y3 = 0;
if(y4 < 0) y4 = 0;
if(u < -128) u = -128;
if(v < -128) v = -128;
*output_row++ = u;
*output_row++ = v;
*output_row++ = y1;
*output_row++ = y2;
*output_row++ = y3;
*output_row++ = y4;
}
}
return 0;
}
int quicktime_encode_wmx1(quicktime_t *file, unsigned char **row_pointers, int track)
{
int result = 0;
int written_cache = 0;
quicktime_video_map_t *vtrack = &(file->vtracks[track]);
quicktime_wmx1_codec_t *codec = &(vtrack->codecs.wmx1_codec);
int width = vtrack->track->tkhd.track_width;
int height = vtrack->track->tkhd.track_height;
int bytes = codec->rows * codec->bytes_per_line;
long frame_difference = 0;
int i;
/* Arm cache */
if(codec->frames_per_chunk < WMX_CHUNK_FRAMES)
{
unsigned char *frame_cache;
unsigned char *row_pointer1, *row_pointer2, *endpoint;
if(!codec->frame_cache[codec->frames_per_chunk])
codec->frame_cache[codec->frames_per_chunk] = malloc(bytes);
frame_cache = codec->frame_cache[codec->frames_per_chunk];
/* Copy to cache */
wmx1_store_in_cache(file, frame_cache, row_pointers, track);
codec->frames_per_chunk++;
}
else
{
/* Write cache and start new cache. */
unsigned char *frame_cache;
result = wmx1_write_cache(file, track);
written_cache = 1;
/* Copy next frame to cache */
if(!codec->frame_cache[codec->frames_per_chunk])
codec->frame_cache[codec->frames_per_chunk] = malloc(bytes);
frame_cache = codec->frame_cache[codec->frames_per_chunk];
wmx1_store_in_cache(file, codec->frame_cache[codec->frames_per_chunk], row_pointers, track);
codec->frames_per_chunk++;
}
/*printf("quicktime_encode_wmx1 3\n"); */
/* if(!written_cache) */
/* quicktime_update_tables(file, */
/* vtrack->track, */
/* offset, */
/* vtrack->current_chunk, */
/* vtrack->current_position, */
/* codec->frames_per_chunk, */
/* output_bytes); */
/* */
return result;
}
int quicktime_decode_wmx1(quicktime_t *file, unsigned char **row_pointers, int track)
{
int result = 0;
return result;
}