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

📄 v210.c

📁 这个库实现了录象功能
💻 C
字号:
/******************************************************************************* v210.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 "workarounds.h"#include "videocodec.h"#include <quicktime/colormodels.h>#include <stdlib.h>typedef struct    {    uint8_t *buffer;    int buffer_alloc;    /* The V210 codec reqires a bytes/line that is a multiple of 128 (48 pixels). */    int64_t    bytes_per_line;    int    initialized;    } quicktime_v210_codec_t;static int delete_codec(quicktime_video_map_t *vtrack)    {    quicktime_v210_codec_t *codec;    codec = ((quicktime_codec_t*)vtrack->codec)->priv;    if  (codec->buffer)        free(codec->buffer);    free(codec);    return 0;    }/* * http://developer.apple.com/quicktime/icefloe/dispatch019.html * * Lines must be a multiple of 48 pixels.  Bytes per luma sample is 8/3.  * Alignment of 48 pixels * bytes/luma = 128.  Q.E.D.*/static void initialize(quicktime_video_map_t *vtrack,                quicktime_v210_codec_t *codec, int width, int height)     {            if  (codec->initialized != 0)        return;    codec->bytes_per_line = ((((width + 47) / 48) * 48 * 8) / 3);;    codec->buffer_alloc = codec->bytes_per_line * vtrack->track->tkhd.track_height;    if  (!codec->buffer)        codec->buffer = malloc(codec->buffer_alloc);        codec->initialized = 1;    }static int decode(quicktime_t *file, unsigned char **row_pointers, int track)    {    uint32_t i1, i2, i3, i4;    uint8_t *in_ptr, *iptr;    uint16_t * out_y, * out_u, * out_v;    int i, j;    int64_t bytes;    int result = 0;    quicktime_video_map_t *vtrack = &(file->vtracks[track]);    quicktime_v210_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;    int width = vtrack->track->tkhd.track_width;    int height = vtrack->track->tkhd.track_height;    if  (!row_pointers)        {        vtrack->stream_cmodel = BC_YUV422P16;        return 0;        }    initialize(vtrack, codec, width, height);    bytes = lqt_read_video_frame(file, &codec->buffer, &codec->buffer_alloc,                                 vtrack->current_position, NULL, track);    if(bytes <= 0)      return -1;    in_ptr = codec->buffer;    for (i = 0; i < height; i++, in_ptr += codec->bytes_per_line)        {        out_y = (uint16_t*)(row_pointers[0] + i * file->vtracks[track].stream_row_span);        out_u = (uint16_t*)(row_pointers[1] + i * file->vtracks[track].stream_row_span_uv);        out_v = (uint16_t*)(row_pointers[2] + i * file->vtracks[track].stream_row_span_uv);/* * 4 32bit words unpack into 6 pixels.  Due to padding (v210 pads lines to * the nearest 48pixel boundary) the last several pixels can be mingled with  * padding zeroes.  For example 1280 is not a multiple of 48 and is padded  * to 1296. * * Do as many groups of  6 pixels that do not exceed the (unpadded) width. The * remaining 2 or 4 pixels will done outside the loop.*/        for (iptr = in_ptr, j = 0; j < width / 6; j++, iptr += 16)            {            /* v210 is LITTLE endian!! */            i1 = iptr[0] | (iptr[1] << 8) | (iptr[2] << 16) | (iptr[3] << 24);            i2 = iptr[4] | (iptr[5] << 8) | (iptr[6] << 16) | (iptr[7] << 24);            i3 = iptr[8] | (iptr[9] << 8) | (iptr[10] << 16) | (iptr[11] << 24);            i4 = iptr[12] | (iptr[13] << 8) | (iptr[14] << 16) | (iptr[15] << 24);/* These are grouped to show the "pixel pairs" of  4:2:2 */            *(out_u++) = (i1 & 0x3ff) << 6;       /* Cb0 */            *(out_y++) = (i1 & 0xffc00) >> 4;     /* Y0 */            *(out_v++) = (i1 & 0x3ff00000) >> 14; /* Cr0 */            *(out_y++) = (i2 & 0x3ff) << 6;       /* Y1 */            *(out_u++) = (i2 & 0xffc00) >> 4;     /* Cb1 */            *(out_y++) = (i2 & 0x3ff00000) >> 14; /* Y2 */            *(out_v++) = (i3 & 0x3ff) << 6;       /* Cr1 */            *(out_y++) = (i3 & 0xffc00) >> 4;     /* Y3 */            *(out_u++) = (i3 & 0x3ff00000) >> 14; /* Cb2 */            *(out_y++) = (i4 & 0x3ff) << 6;       /* Y4 */            *(out_v++) = (i4 & 0xffc00) >> 4;     /* Cr2 */            *(out_y++) = (i4 & 0x3ff00000) >> 14; /* Y5 */            }/* Handle the 2 or 4 pixels possibly remaining */         j = (width - ((width / 6) * 6));	 if (j != 0)	    {            i1 = iptr[0] | (iptr[1] << 8) | (iptr[2] << 16) | (iptr[3] << 24);            i2 = iptr[4] | (iptr[5] << 8) | (iptr[6] << 16) | (iptr[7] << 24);            i3 = iptr[8] | (iptr[9] << 8) | (iptr[10] << 16) | (iptr[11] << 24);            i4 = iptr[12] | (iptr[13] << 8) | (iptr[14] << 16) | (iptr[15] << 24);            *(out_u++) = (i1 & 0x3ff) << 6;       /* Cb0 */            *(out_y++) = (i1 & 0xffc00) >> 4;     /* Y0 */            *(out_v++) = (i1 & 0x3ff00000) >> 14; /* Cr0 */            *(out_y++) = (i2 & 0x3ff) << 6;       /* Y1 */	    if (j == 4)	       {               *(out_u++) = (i2 & 0xffc00) >> 4;     /* Cb1 */               *(out_y++) = (i2 & 0x3ff00000) >> 14; /* Y2 */               *(out_v++) = (i3 & 0x3ff) << 6;       /* Cr1 */               *(out_y++) = (i3 & 0xffc00) >> 4;     /* Y3 */	       }	   }	}    return result;    }static int encode(quicktime_t *file, unsigned char **row_pointers, int track)    {    quicktime_video_map_t *vtrack = &(file->vtracks[track]);    quicktime_v210_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;    quicktime_trak_t *trak = vtrack->track;    int width = vtrack->track->tkhd.track_width;    int height = vtrack->track->tkhd.track_height;    int result = 0;    int i, j;    quicktime_atom_t chunk_atom;    uint16_t * in_y, * in_u, * in_v;    uint8_t *out_ptr, *optr;    uint32_t o1, o2, o3 = 0, o4;            if  (!row_pointers)        {        vtrack->stream_cmodel = BC_YUV422P16;        return 0;        }    if(!codec->initialized)      lqt_set_fiel_uncompressed(file, track);        initialize(vtrack, codec, width, height);    out_ptr = codec->buffer;    for (i = 0; i < height; i++, out_ptr += codec->bytes_per_line)        {        in_y = (uint16_t*)(row_pointers[0] + i * file->vtracks[track].stream_row_span);        in_u = (uint16_t*)(row_pointers[1] + i * file->vtracks[track].stream_row_span_uv);        in_v = (uint16_t*)(row_pointers[2] + i * file->vtracks[track].stream_row_span_uv);          /* * 12 values (6 pixels = 2 Y', 1 Cb/u and 1 Cr/v) pack into 4 32bit words.*/	optr = out_ptr;        for (j = 0; j < width / 6; j++)            {            o1 = ((*in_v & 0xffc0) << 14) |       /* Cr0 */                 ((*in_y & 0xffc0) << 4) |        /* Y0 */                 ((*in_u & 0xffc0) >> 6);         /* Cb0 */            in_y++; in_u++; in_v++;            o2 = ((in_y[1] & 0xffc0) << 14) |       /* Y2 */                 ((*in_u & 0xffc0) << 4) |           /* Cb1 */                 ((in_y[0] & 0xffc0) >> 6);         /* Y1 */            in_y ++; in_u++; in_y++;            o3 = ((*in_u & 0xffc0) << 14) |       /* Cb2 */                 ((*in_y & 0xffc0) << 4) |        /* Y3 */                 ((*in_v & 0xffc0) >> 6);         /* Cr1 */	    in_u++; in_y++; in_v++;            o4 = ((in_y[1] & 0xffc0) << 14) |    /* Y5 */                 ((*in_v & 0xffc0) << 4) |        /* Cr2 */                 ((in_y[0] & 0xffc0) >> 6);         /* Y4 */	    in_y++; in_v++; in_y++;            *(optr++) = (o1 & 0xff);            *(optr++) = (o1 & 0xff00) >> 8;            *(optr++) = (o1 & 0xff0000) >> 16;            *(optr++) = (o1 & 0xff000000) >> 24;            *(optr++) = (o2 & 0xff);            *(optr++) = (o2 & 0xff00) >> 8;            *(optr++) = (o2 & 0xff0000) >> 16;            *(optr++) = (o2 & 0xff000000) >> 24;            *(optr++) = (o3 & 0xff);            *(optr++) = (o3 & 0xff00) >> 8;            *(optr++) = (o3 & 0xff0000) >> 16;            *(optr++) = (o3 & 0xff000000) >> 24;            *(optr++) = (o4 & 0xff);            *(optr++) = (o4 & 0xff00) >> 8;            *(optr++) = (o4 & 0xff0000) >> 16;            *(optr++) = (o4 & 0xff000000) >> 24;            }/* Handle the 2 or 4 pixels remaining before the padding */        j = (width - ((width / 6) * 6));	if  (j != 0)	    {            o1 = ((*in_v & 0xffc0) << 14) |       /* Cr0 */                 ((*in_y & 0xffc0) << 4) |        /* Y0 */                 ((*in_u & 0xffc0) >> 6);         /* Cb0 */            in_y++; in_u++; in_v++;	    o2 = (*in_y & 0xffc0) >> 6;            /* Y1 */	    in_y++;	    	    if  (j == 4)	        {                o2 |= (((in_y[1] & 0xffc0) << 14) |       /* Y2 */                      ((*in_u & 0xffc0) << 4));          /* Cb1 */                in_y ++; in_u++;                o3 = ((*in_y & 0xffc0) << 4) |        /* Y3 */                     ((*in_v & 0xffc0) >> 6);         /* Cr1 */	        in_y++; in_v++;		}            *(optr++) = (o1 & 0xff);            *(optr++) = (o1 & 0xff00) >> 8;            *(optr++) = (o1 & 0xff0000) >> 16;            *(optr++) = (o1 & 0xff000000) >> 24;            *(optr++) = (o2 & 0xff);            *(optr++) = (o2 & 0xff00) >> 8;            *(optr++) = (o2 & 0xff0000) >> 16;            *(optr++) = (o2 & 0xff000000) >> 24;	                *(optr++) = (o3 & 0xff);            *(optr++) = (o3 & 0xff00) >> 8;            *(optr++) = (o3 & 0xff0000) >> 16;            *(optr++) = (o3 & 0xff000000) >> 24;/* * The above are sufficient for 2 or 4 pixels, the 4th word (which would be o4) * contains the two Y' samples (Y4 and Y5) and the Cr (Cr2) for pixels 5 and 6. * We don't need Y4/Y5/Cr2 so don't put any more bytes into the out buffer.*/	    }/* * Now compute the number of bytes used in the current line.  Zero pad until * the padded width is reached.  If the line does not require padding (for * 720xN) then the number of bytes used will be equal to bytes_per_line and * no padding will be performed.*/	j = optr - out_ptr;	while (j++ < codec->bytes_per_line)	      *(optr++) = '\0';        }    quicktime_write_chunk_header(file, trak, &chunk_atom);    result = !quicktime_write_data(file,                                   codec->buffer,                                   codec->bytes_per_line * height);    quicktime_write_chunk_footer(file,                                 trak,                                 vtrack->current_chunk,&chunk_atom,				 1);    vtrack->current_chunk++;    return result;    }void quicktime_init_codec_v210(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_v210_codec_t));    codec_base->delete_vcodec = delete_codec;    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 + -