/* write record after converting it from source into destination * format */ ssize_t write_frecord( int fd, const char* data, size_t len, upxfmt_t sfmt, upxfmt_t dfmt, FILE* log ) { ssize_t nwr = -1; int fmt_ok = 0; const char *str_from = NULL, *str_to = NULL; if( UPXDT_UDS == dfmt ) { fmt_ok = 1; nwr = write_uds_record( fd, data, len, log ); } else if( UPXDT_TS == dfmt ) { if( UPXDT_RTP_TS == sfmt ) { fmt_ok = 1; nwr = write_rtp2ts( fd, data, len, log ); } } if( !fmt_ok ) { str_from = fmt2str(sfmt); str_to = fmt2str(dfmt); (void)tmfprintf( log, "Conversion from [%s] into [%s] is not supported\n", str_from, str_to ); return -1; } return nwr; }
/* read data from source, determine underlying protocol * (if not already known); and process the packet * if needed (for RTP - register packet) * * return the number of octets read from the source * into the buffer */ static ssize_t read_packet( struct dstream_ctx* spc, int fd, char* buf, size_t len ) { ssize_t n = -1; size_t chunk_len = len; assert( spc && buf && len ); assert( fd > 0 ); /* if *RAW* data specified - read AS IS * and exit */ if( UPXDT_RAW == spc->stype ) { return read_buf( fd, buf, len, g_flog ); } /* if it is (or *could* be) RTP, read only MTU bytes */ if( (spc->stype == UPXDT_RTP_TS) || (spc->flags & F_CHECK_FMT) ) chunk_len = (len > spc->mtu) ? spc->mtu : len; #ifdef UDPXY_FILEIO if( spc->flags & F_FILE_INPUT ) { assert( !buf_overrun( buf, len, 0, chunk_len, g_flog ) ); n = read_frecord( fd, buf, chunk_len, &(spc->stype), g_flog ); if( n <= 0 ) return n; } else #endif /* UDPXY_FILEIO */ { assert( !buf_overrun(buf, len, 0, chunk_len, g_flog) ); n = read_buf( fd, buf, chunk_len, g_flog ); if( n <= 0 ) return n; } if( spc->flags & F_CHECK_FMT ) { spc->stype = get_mstream_type( buf, n, g_flog ); switch (spc->stype) { case UPXDT_RTP_TS: /* scattered: exclude RTP headers */ spc->flags |= F_SCATTERED; break; case UPXDT_TS: spc->flags &= ~F_SCATTERED; break; default: spc->stype = UPXDT_RAW; TRACE( (void)tmfputs( "Unrecognized stream type\n", g_flog ) ); break; } /* switch */ TRACE( (void)tmfprintf( g_flog, "Established stream as [%s]\n", fmt2str( spc->stype ) ) ); spc->flags &= ~F_CHECK_FMT; } if( spc->flags & F_SCATTERED ) if( -1 == register_packet( spc, buf, n ) ) return -1; return n; }
int main( int argc, char* const argv[] ) { static const char* clopt = "i:o:dtr"; char srcfile[ MAXPATHLEN ] = { '\0' }; char dstfile[ MAXPATHLEN ] = { '\0' }; upxfmt_t dst_fmt = DT_UNKNOWN; int ch, rc = 0, debug = 0; FILE* flog = NULL; while( -1 != (ch = getopt(argc, argv, clopt)) ) { switch( ch ) { case 'i': (void)strncpy( srcfile, optarg, sizeof(srcfile) - 1 ); break; case 'o': (void)strncpy( dstfile, optarg, sizeof(dstfile) - 1 ); break; case 't': dst_fmt = DT_TS; break; case 'u': dst_fmt = DT_UDS; break; case 'd': debug = 1; break; default: (void) tmfprintf( stderr, "%s: Unrecognized option [%c]\n", appname, (char)ch ); usage(); return ERR_PARAM; } /* switch */ } /* getopt loop */ if( !srcfile[0] ) { (void) tmfprintf( stderr, "%s: Missing source-file parameter\n", appname ); usage(); return ERR_PARAM; } else { if( 0 != (rc = access( srcfile, R_OK)) ) { perror( "srcfile - access" ); return ERR_PARAM; } } flog = debug ? stderr : fopen( "/dev/null", "a" ); if( NULL == flog ) { perror( "fopen" ); return ERR_INTERNAL; } TRACE( (void)tmfprintf( flog, "%s: destination format = [%s]\n", appname, fmt2str(dst_fmt)) ); if( DT_UNKNOWN == dst_fmt ) { (void)tmfprintf( flog, "%s: destination format must be specified\n", appname ); return ERR_PARAM; } rc = convert2( srcfile, dstfile, dst_fmt, flog ); if( (NULL != flog) && (stderr != flog) ) (void) fclose(flog); return (rc ? ERR_INTERNAL : 0); }