common.c
来自「VLC媒体播放程序」· C语言 代码 · 共 555 行 · 第 1/2 页
C
555 行
/***************************************************************************** * Common SVCD and CVD subtitle routines. ***************************************************************************** * Copyright (C) 2003, 2004 VideoLAN * $Id: common.c,v 1.13 2004/02/22 10:52:23 rocky Exp $ * * Author: Rocky Bernstein <rocky@panix.com> * based on code from: * Julio Sanchez Fernandez (http://subhandler.sourceforge.net) * Samuel Hocevar <sam@zoy.org> * Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <vlc/vlc.h>#include <vlc/vout.h>#include <vlc/decoder.h>#include "subtitle.h"#include "pixmap.h"#include "common.h"#ifdef HAVE_LIBPNG#include "write_png.h"#endif/***************************************************************************** Free Resources associated with subtitle packet. *****************************************************************************/void VCDSubClose( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys = p_dec->p_sys; dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , ""); if( !p_sys->b_packetizer ) { /* FIXME check if it's ok to not lock vout */ if( p_sys->p_vout != NULL && p_sys->p_vout->p_subpicture != NULL ) { subpicture_t * p_subpic; int i_subpic; for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ ) { p_subpic = &p_sys->p_vout->p_subpicture[i_subpic]; if( p_subpic != NULL && ( ( p_subpic->i_status == RESERVED_SUBPICTURE ) || ( p_subpic->i_status == READY_SUBPICTURE ) ) ) { vout_DestroySubPicture( p_sys->p_vout, p_subpic ); } } } } if( p_sys->p_block ) { block_ChainRelease( p_sys->p_block ); } free(p_sys->subtitle_data); free( p_sys );}/*****************************************************************************Initialize so the next packet will start off a new one. *****************************************************************************/void VCDSubInitSubtitleBlock( decoder_sys_t * p_sys ) { p_sys->i_spu_size = 0; p_sys->state = SUBTITLE_BLOCK_EMPTY; p_sys->i_spu = 0; p_sys->p_block = NULL; p_sys->subtitle_data_pos = 0;}void VCDSubInitSubtitleData(decoder_sys_t *p_sys){ if ( p_sys->subtitle_data ) { if ( p_sys->subtitle_data_size < p_sys->i_spu_size ) { p_sys->subtitle_data = realloc(p_sys->subtitle_data, p_sys->i_spu_size); p_sys->subtitle_data_size = p_sys->i_spu_size; } } else { p_sys->subtitle_data = malloc(p_sys->i_spu_size); p_sys->subtitle_data_size = p_sys->i_spu_size; /* FIXME: wrong place to get p_sys */ p_sys->i_image = 0; } p_sys->subtitle_data_pos = 0;}void VCDSubAppendData ( decoder_t *p_dec, uint8_t *buffer, uint32_t buf_len ){ decoder_sys_t *p_sys = p_dec->p_sys; int chunk_length = buf_len; if ( chunk_length > p_sys->i_spu_size - p_sys->subtitle_data_pos ) { msg_Warn( p_dec, "too much data (%d) expecting at most %u", chunk_length, p_sys->i_spu_size - p_sys->subtitle_data_pos ); chunk_length = p_sys->i_spu_size - p_sys->subtitle_data_pos; } if ( chunk_length > 0 ) {#if 0 int i; int8_t *b=buffer; for (i=0; i<chunk_length; i++) printf ("%02x", b[i]); printf("\n");#endif memcpy(p_sys->subtitle_data + p_sys->subtitle_data_pos, buffer, chunk_length); p_sys->subtitle_data_pos += chunk_length; dbg_print(DECODE_DBG_PACKET, "%d bytes appended, pointer now %d", chunk_length, p_sys->subtitle_data_pos); }}/***************************************************************************** * FindVout: Find a vout or wait for one to be created. *****************************************************************************/vout_thread_t *VCDSubFindVout( decoder_t *p_dec ){ vout_thread_t *p_vout = NULL; /* Find an available video output */ do { if( p_dec->b_die || p_dec->b_error ) { break; } p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout ) { break; } msleep( VOUT_OUTMEM_SLEEP ); } while( 1 ); return p_vout;}/** Remove color palette by expanding pixel entries to contain the palette values. We work from the free space at the end to the beginning so we can expand inline.*/static voidInlinePalette ( /*inout*/ uint8_t *p_dest, decoder_sys_t *p_sys ){ const unsigned int i_width = p_sys->i_width; const unsigned int i_height = p_sys->i_height; int n = (i_height * i_width) - 1; uint8_t *p_from = p_dest; ogt_yuvt_t *p_to = (ogt_yuvt_t *) p_dest; for ( ; n >= 0 ; n-- ) { p_to[n] = p_sys->p_palette[p_from[n]]; /*p_to[n] = p_sys->p_palette[p_from[3]];*/ }}/** Check to see if user has overridden subtitle aspect ratio. 0 is returned for no override which means just counteract any scaling effects.*/unsigned int VCDSubGetAROverride(vlc_object_t * p_input, vout_thread_t *p_vout){ char *psz_string = config_GetPsz( p_input, MODULE_STRING "-aspect-ratio" ); /* Check whether the user tried to override aspect ratio */ if( !psz_string ) return 0; { unsigned int i_new_aspect = 0; char *psz_parser = strchr( psz_string, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; i_new_aspect = atoi( psz_string ) * VOUT_ASPECT_FACTOR / atoi( psz_parser ); } else { i_new_aspect = p_vout->output.i_width * VOUT_ASPECT_FACTOR * atof( psz_string ) / p_vout->output.i_height; } return i_new_aspect; }}/** Scales down (reduces size) of p_dest in the x direction as determined through aspect ratio x_scale by y_scale. Scaling is done in place. p_spu->i_width, is updated to new width The aspect ratio is assumed to be between 1/2 and 1. Note: the scaling truncates the new width rather than rounds it. Perhaps something one might want to address.*/voidVCDSubScaleX( decoder_t *p_dec, subpicture_t *p_spu, unsigned int i_scale_x, unsigned int i_scale_y ){ int i_row, i_col; decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p_src1 = p_spu->p_sys->p_data; uint8_t *p_src2 = p_src1 + PIXEL_SIZE; uint8_t *p_dst = p_src1; unsigned int i_new_width = (p_spu->i_width * i_scale_x) / i_scale_y ; unsigned int i_used=0; /* Number of bytes used up in p_src1. */ dbg_print( (DECODE_DBG_CALL|DECODE_DBG_TRANSFORM) , "aspect ratio %i:%i, Old width: %d, new width: %d", i_scale_x, i_scale_y, p_spu->i_width, i_new_width); if (! (i_scale_x < i_scale_y && i_scale_y < i_scale_x+i_scale_x) ) { msg_Warn( p_dec, "Need x < y < 2x. x: %i, y: %i", i_scale_x, i_scale_y ); return; } for ( i_row=0; i_row <= p_spu->i_height - 1; i_row++ ) { if (i_used != 0) { /* Discard the remaining piece of the column of the previous line*/ i_used=0; p_src1 = p_src2; p_src2 += PIXEL_SIZE; } for ( i_col=0; i_col <= p_spu->i_width - 2; i_col++ ) { unsigned int i; unsigned int w1= i_scale_x - i_used; unsigned int w2;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?