⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yuv4.c

📁 这个库实现了录象功能
💻 C
字号:
/******************************************************************************* yuv4.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include <quicktime/colormodels.h>#include <stdlib.h>#include "videocodec.h"/* U V values are signed but Y R G B values are unsigned! *//* *      R = Y               + 1.40200 * V *      G = Y - 0.34414 * U - 0.71414 * V *      B = Y + 1.77200 * U *//* *		Y =  0.2990 * R + 0.5870 * G + 0.1140 * B *		U = -0.1687 * R - 0.3310 * G + 0.5000 * B *		V =  0.5000 * R - 0.4187 * G - 0.0813 * B   *//* Now storing data as rows of UVYYYYUVYYYY */typedef struct  {  int use_float;  long rtoy_tab[256], gtoy_tab[256], btoy_tab[256];  long rtou_tab[256], gtou_tab[256], btou_tab[256];  long rtov_tab[256], gtov_tab[256], btov_tab[256];  long vtor_tab[256], vtog_tab[256];  long utog_tab[256], utob_tab[256];  long *vtor, *vtog, *utog, *utob;	  uint8_t *buffer;  int buffer_alloc;  /* The YUV4 codec requires a bytes per line that is a multiple of 4 */  int bytes_per_line;  /* Actual rows encoded in the yuv4 format */  int rows;  int initialized;  } quicktime_yuv4_codec_t;static int quicktime_delete_codec_yuv4(quicktime_video_map_t *vtrack){	quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;	free(codec->buffer);	free(codec);	return 0;}static void initialize(quicktime_video_map_t *vtrack, quicktime_yuv4_codec_t *codec){	int i;	if(!codec->initialized)	{/* Init private items */		for(i = 0; i < 256; i++)		{/* compression */			codec->rtoy_tab[i] = (long)( 0.2990 * 65536 * i);			codec->rtou_tab[i] = (long)(-0.1687 * 65536 * i);			codec->rtov_tab[i] = (long)( 0.5000 * 65536 * i);			codec->gtoy_tab[i] = (long)( 0.5870 * 65536 * i);			codec->gtou_tab[i] = (long)(-0.3320 * 65536 * i);			codec->gtov_tab[i] = (long)(-0.4187 * 65536 * i);			codec->btoy_tab[i] = (long)( 0.1140 * 65536 * i);			codec->btou_tab[i] = (long)( 0.5000 * 65536 * i);			codec->btov_tab[i] = (long)(-0.0813 * 65536 * i);		}		codec->vtor = &(codec->vtor_tab[128]);		codec->vtog = &(codec->vtog_tab[128]);		codec->utog = &(codec->utog_tab[128]);		codec->utob = &(codec->utob_tab[128]);		for(i = -128; i < 128; i++)		{/* decompression */			codec->vtor[i] = (long)( 1.4020 * 65536 * i);			codec->vtog[i] = (long)(-0.7141 * 65536 * i);			codec->utog[i] = (long)(-0.3441 * 65536 * i);			codec->utob[i] = (long)( 1.7720 * 65536 * i);		}		codec->bytes_per_line = vtrack->track->tkhd.track_width * 3;		if(codec->bytes_per_line % 6)			codec->bytes_per_line += 3;		codec->rows = vtrack->track->tkhd.track_height / 2;		if((int)(vtrack->track->tkhd.track_height) % 2)			codec->rows++;		codec->buffer = malloc(codec->bytes_per_line * codec->rows);		codec->initialized = 1;	}}static int decode(quicktime_t *file, unsigned char **row_pointers, int track){	int64_t bytes, in_y, out_y;	register int x1, x2;	quicktime_video_map_t *vtrack = &(file->vtracks[track]);	quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;	int width = vtrack->track->tkhd.track_width;	int height = vtrack->track->tkhd.track_height;	unsigned char *buffer;	uint8_t *input_row;	unsigned char *row_pointer1, *row_pointer2;	int result = 0;	int u, v;	register int y1, y2, y3, y4;	int r, g, b;	int bytes_per_row = width * 3;        if(!row_pointers)          {          vtrack->stream_cmodel = BC_RGB888;          return 0;          }                initialize(vtrack, codec);        bytes = lqt_read_video_frame(file, &codec->buffer, &codec->buffer_alloc,                                     vtrack->current_position, NULL, track);        if(bytes <= 0)          return -1;        buffer = codec->buffer;                for(out_y = 0, in_y = 0; out_y < height; in_y++)          {          input_row = &buffer[in_y * codec->bytes_per_line];          row_pointer1 = row_pointers[out_y++];                    if(out_y < height)            row_pointer2 = row_pointers[out_y];          else            row_pointer2 = row_pointer1;                    out_y++;          for(x1 = 0, x2 = 0; x1 < bytes_per_row; )            {            u = (char)*input_row++;            v = (char)*input_row++;            y1 = *input_row++;            y2 = *input_row++;            y3 = *input_row++;            y4 = *input_row++;            y1 <<= 16;            y2 <<= 16;            y3 <<= 16;            y4 <<= 16;            /* Top left pixel */            r = ((y1 + codec->vtor[v]) >> 16);            g = ((y1 + codec->utog[u] + codec->vtog[v]) >> 16);            b = ((y1 + codec->utob[u]) >> 16);            if(r < 0) r = 0;            if(g < 0) g = 0;            if(b < 0) b = 0;            if(r > 255) r = 255;            if(g > 255) g = 255;            if(b > 255) b = 255;            row_pointer1[x1++] = r;            row_pointer1[x1++] = g;            row_pointer1[x1++] = b;            /* Top right pixel */            if(x1 < bytes_per_row)              {              r = ((y2 + codec->vtor[v]) >> 16);              g = ((y2 + codec->utog[u] + codec->vtog[v]) >> 16);              b = ((y2 + codec->utob[u]) >> 16);              if(r < 0) r = 0;              if(g < 0) g = 0;              if(b < 0) b = 0;              if(r > 255) r = 255;              if(g > 255) g = 255;              if(b > 255) b = 255;              row_pointer1[x1++] = r;              row_pointer1[x1++] = g;              row_pointer1[x1++] = b;              }            /* Bottom left pixel */            r = ((y3 + codec->vtor[v]) >> 16);            g = ((y3 + codec->utog[u] + codec->vtog[v]) >> 16);            b = ((y3 + codec->utob[u]) >> 16);            if(r < 0) r = 0;            if(g < 0) g = 0;            if(b < 0) b = 0;            if(r > 255) r = 255;            if(g > 255) g = 255;            if(b > 255) b = 255;            row_pointer2[x2++] = r;            row_pointer2[x2++] = g;            row_pointer2[x2++] = b;            /* Bottom right pixel */            if(x2 < bytes_per_row)              {              r = ((y4 + codec->vtor[v]) >> 16);              g = ((y4 + codec->utog[u] + codec->vtog[v]) >> 16);              b = ((y4 + codec->utob[u]) >> 16);              if(r < 0) r = 0;              if(g < 0) g = 0;              if(b < 0) b = 0;              if(r > 255) r = 255;              if(g > 255) g = 255;              if(b > 255) b = 255;              row_pointer2[x2++] = r;              row_pointer2[x2++] = g;              row_pointer2[x2++] = b;              }            }          }        return result;}static int encode(quicktime_t *file, unsigned char **row_pointers, int track){	quicktime_video_map_t *vtrack = &(file->vtracks[track]);	quicktime_yuv4_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;	quicktime_trak_t *trak = vtrack->track;	int result = 0;	int width = vtrack->track->tkhd.track_width;	int height = vtrack->track->tkhd.track_height;	int64_t bytes;	unsigned char *buffer;	unsigned char *output_row;    /* Pointer to output row */	unsigned char *row_pointer1, *row_pointer2;  /* Pointers to input rows */	register int x1, x2;	int in_y, out_y;	register int y1, y2, y3, y4;	int u, v;	int r, g, b;	int bytes_per_row = width * 3;	quicktime_atom_t chunk_atom;        if(!row_pointers)          {          vtrack->stream_cmodel = BC_RGB888;          return 0;          }        	initialize(vtrack, codec);        buffer = codec->buffer;        bytes = codec->rows * codec->bytes_per_line;	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 < bytes_per_row; )		{/* Top left pixel */			r = row_pointer1[x1++];			g = row_pointer1[x1++];			b = row_pointer1[x1++];			y1 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);			u = (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);			v = (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);/* Top right pixel */			if(x1 < bytes_per_row)			{				r = row_pointer1[x1++];				g = row_pointer1[x1++];				b = row_pointer1[x1++];			}			y2 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);			u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);			v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);/* Bottom left pixel */			r = row_pointer2[x2++];			g = row_pointer2[x2++];			b = row_pointer2[x2++];			y3 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);			u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);			v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->btov_tab[b]);/* Bottom right pixel */			if(x2 < bytes_per_row)			{				r = row_pointer2[x2++];				g = row_pointer2[x2++];				b = row_pointer2[x2++];			}			y4 = (codec->rtoy_tab[r] + codec->gtoy_tab[g] + codec->btoy_tab[b]);			u += (codec->rtou_tab[r] + codec->gtou_tab[g] + codec->btou_tab[b]);			v += (codec->rtov_tab[r] + codec->gtov_tab[g] + codec->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;		}	}	quicktime_write_chunk_header(file, trak, &chunk_atom);	result = quicktime_write_data(file, buffer, bytes);	if(result)		result = 0; 	else 		result = 1;	quicktime_write_chunk_footer(file, 		trak,		vtrack->current_chunk,		&chunk_atom, 		1);	vtrack->current_chunk++;	return result;}void quicktime_init_codec_yuv4(quicktime_video_map_t *vtrack){	quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;/* Init public items */	codec_base->priv = calloc(1, sizeof(quicktime_yuv4_codec_t));	codec_base->delete_vcodec = quicktime_delete_codec_yuv4;	codec_base->decode_video = decode;	codec_base->encode_video = encode;	codec_base->decode_audio = 0;	codec_base->encode_audio = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -