📄 generic_decoder.c
字号:
/***************************************************************************** * generic_decoder.c : generic decoder thread * This decoder provides a way to parse packets which do not belong to any * known stream type, or to redirect packets to files. It can extract PES files * from a multiplexed stream, identify automatically ES in a stream missing * stream informations (i.e. a TS stream without PSI) and update ES tables in * its input thread, or just print informations about what it receives in DEBUG * mode. * A single generic decoder is able to handle several ES, therefore it can be * used as a 'default' decoder by the input thread. ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN * * Authors: * * 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 "defs.h"#include <errno.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/types.h> /* on BSD, uio.h needs types.h */#include <sys/uio.h>#include "config.h"#include "common.h"#include "mtime.h"#include "threads.h"#include "threads.h"#include "intf_msg.h"#include "debug.h"#include "input.h"#include "input_netlist.h"#include "decoder_fifo.h"#include "generic_decoder.h"/* * Local prototypes */static int CheckConfiguration ( gdec_cfg_t *p_cfg );static int InitThread ( gdec_thread_t *p_gdec );static void RunThread ( gdec_thread_t *p_gdec );static void ErrorThread ( gdec_thread_t *p_gdec );static void EndThread ( gdec_thread_t *p_gdec );static void IdentifyPES ( gdec_thread_t *p_gdec, pes_packet_t *p_pes, int i_stream_id );static void PrintPES ( pes_packet_t *p_pes, int i_stream_id );/***************************************************************************** * gdec_CreateThread: create a generic decoder thread ***************************************************************************** * This function creates a new generic decoder thread, and returns a pointer * to its description. On error, it returns NULL. * Following configuration properties are used: * GDEC_CFG_ACTIONS (required) * XXX?? *****************************************************************************/gdec_thread_t * gdec_CreateThread( gdec_cfg_t *p_cfg, input_thread_t *p_input, int *pi_status ){ gdec_thread_t * p_gdec; /* thread descriptor */ int i_status; /* thread status */ /* * Check configuration */ if( CheckConfiguration( p_cfg ) ) { return( NULL ); } /* Allocate descriptor and initialize flags */ p_gdec = (gdec_thread_t *) malloc( sizeof(gdec_thread_t) ); if( p_gdec == NULL ) /* error */ { return( NULL ); } /* Copy configuration */ p_gdec->i_actions = p_cfg->i_actions; /* XXX?? */ /* Set status */ p_gdec->pi_status = (pi_status != NULL) ? pi_status : &i_status; *p_gdec->pi_status = THREAD_CREATE; /* Initialize flags */ p_gdec->b_die = 0; p_gdec->b_error = 0; p_gdec->b_active = 1; /* Create thread */ if( vlc_thread_create( &p_gdec->thread_id, "generic decoder", (vlc_thread_func)RunThread, (void *) p_gdec) ) { intf_ErrMsg("gdec error: %s\n", strerror(ENOMEM)); intf_DbgMsg("failed\n"); free( p_gdec ); return( NULL ); } /* If status is NULL, wait until the thread is created */ if( pi_status == NULL ) { do { msleep( THREAD_SLEEP ); }while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR) && (i_status != THREAD_FATAL) ); if( i_status != THREAD_READY ) { intf_DbgMsg("failed\n"); return( NULL ); } } intf_DbgMsg("succeeded -> %p\n", p_gdec); return( p_gdec );}/***************************************************************************** * gdec_DestroyThread: destroy a generic decoder thread ***************************************************************************** * Destroy a terminated thread. This function will return 0 if the thread could * be destroyed, and non 0 else. The last case probably means that the thread * was still active, and another try may succeed. *****************************************************************************/void gdec_DestroyThread( gdec_thread_t *p_gdec, int *pi_status ){ int i_status; /* thread status */ /* Set status */ p_gdec->pi_status = (pi_status != NULL) ? pi_status : &i_status; *p_gdec->pi_status = THREAD_DESTROY; /* Request thread destruction */ p_gdec->b_die = 1; /* Make sure the decoder thread leaves the GetByte() function */ vlc_mutex_lock( &(p_gdec->fifo.data_lock) ); vlc_cond_signal( &(p_gdec->fifo.data_wait) ); vlc_mutex_unlock( &(p_gdec->fifo.data_lock) ); /* If status is NULL, wait until thread has been destroyed */ if( pi_status ) { do { msleep( THREAD_SLEEP ); }while( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR) && (i_status != THREAD_FATAL) ); } intf_DbgMsg("%p -> succeeded\n", p_gdec);}/* following functions are local *//***************************************************************************** * CheckConfiguration: check gdec_CreateThread() configuration ***************************************************************************** * Set default parameters where required. In DEBUG mode, check if configuration * is valid. *****************************************************************************/static int CheckConfiguration( gdec_cfg_t *p_cfg ){#ifdef DEBUG /* Actions (required) */ if( !(p_cfg->i_properties & GDEC_CFG_ACTIONS) ) { return( 1 ); }#endif return( 0 );}/***************************************************************************** * InitThread: initialize gdec thread ***************************************************************************** * This function is called from RunThread and performs the second step of the * initialization. It returns 0 on success. Note that the thread's flag are not * modified inside this function. *****************************************************************************/static int InitThread( gdec_thread_t *p_gdec ){ /* XXX?? */ /* Update status */ *p_gdec->pi_status = THREAD_START; /* Initialize other properties */#ifdef STATS p_gdec->c_loops = 0; p_gdec->c_idle_loops = 0; p_gdec->c_pes = 0;#endif /* Mark thread as running and return */ *p_gdec->pi_status = THREAD_READY; intf_DbgMsg("%p -> succeeded\n", p_gdec); return(0);}/***************************************************************************** * RunThread: generic decoder thread ***************************************************************************** * Generic decoder thread. This function does only returns when the thread is * terminated. *****************************************************************************/static void RunThread( gdec_thread_t *p_gdec ){ pes_packet_t * p_pes; /* current packet */ int i_stream_id; /* PES stream id */ /* * Initialize thread and free configuration */ p_gdec->b_error = InitThread( p_gdec ); if( p_gdec->b_error ) { free( p_gdec ); /* destroy descriptor */ return; } /* * Main loop - it is not executed if an error occured during * initialization */ while( (!p_gdec->b_die) && (!p_gdec->b_error) ) { /* FIXME: locks
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -