diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
| commit | 884c8093d63402a1ad0b502244b791e3c6782be3 (patch) | |
| tree | a600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/transcode/transcode-1.1.7/import/tcscan.c | |
| parent | 14e1aa2006796f147f3f4811fb908a6b01e79253 (diff) | |
| download | extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip | |
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/tcscan.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/import/tcscan.c | 719 |
1 files changed, 719 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/tcscan.c b/debian/transcode/transcode-1.1.7/import/tcscan.c new file mode 100644 index 00000000..182a06a7 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/import/tcscan.c @@ -0,0 +1,719 @@ +/* + * tcscan.c + * + * Copyright (C) Thomas Oestreich - June 2001 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#undef TCF_DEBUG + +#include "transcode.h" +#include "tcinfo.h" + +#include "libtc/xio.h" +#include "libtc/ratiocodes.h" +#include "ioaux.h" +#include "tc.h" +#include "avilib/avilib.h" +#include <math.h> + +#define EXE "tcscan" + +int verbose=TC_QUIET; + +int tc_get_mp3_header(unsigned char* hbuf, int* chans, int* srate, int *bitrate); +#define tc_decode_mp3_header(hbuf) tc_get_mp3_header(hbuf, NULL, NULL, NULL) + +void import_exit(int code) +{ + if(verbose & TC_DEBUG) + tc_log_msg(EXE, "(pid=%d) exit (code %d)", (int) getpid(), code); + exit(code); +} + +#define CHUNK_SIZE 4096 + +static int min=0, max=0; + +static void check (int v) +{ + + if (v > max) { + max = v; + } else if (v < min) { + min = v; + } + + return; +} + +/*************************************************************************/ + +/* from ac3scan.c */ + +static int get_ac3_bitrate(uint8_t *ptr) +{ + static const int bitrates[] = { + 32, 40, 48, 56, + 64, 80, 96, 112, + 128, 160, 192, 224, + 256, 320, 384, 448, + 512, 576, 640 + }; + int ratecode = (ptr[2] & 0x3E) >> 1; + if (ratecode < sizeof(bitrates)/sizeof(*bitrates)) + return bitrates[ratecode]; + return -1; +} + +static int get_ac3_samplerate(uint8_t *ptr) +{ + static const int samplerates[] = {48000, 44100, 32000, -1}; + return samplerates[ptr[2]>>6]; +} + +static int get_ac3_framesize(uint8_t *ptr) +{ + int bitrate = get_ac3_bitrate(ptr); + int samplerate = get_ac3_samplerate(ptr); + if (bitrate < 0 || samplerate < 0) + return -1; + return bitrate * 96000 / samplerate + (samplerate==44100 ? ptr[2]&1 : 0); +} + +/*************************************************************************/ + +/* enc_bitrate: Print bitrate information about the source data. + * + * Parameters: + * frames: Number of frames in the source. + * fps: Frames per second of the source. + * abitrate: Audio bitrate (bits per second). + * discsize: User-specified disc size in bytes, or 0 for none. + * Return value: + * None. + */ + +static void enc_bitrate(long frames, double fps, int abitrate, double discsize) +{ + static const int defsize[] = {650, 700, 1300, 1400}; + long time; + double audiosize, videosize, vbitrate; + + if (frames <= 0 || fps <= 0.0) + return; + time = frames / fps; + audiosize = (double)abitrate/8 * time; + + /* Print basic source information */ + printf("[%s] V: %ld frames, %ld sec @ %.3f fps\n", + EXE, frames, time, fps); + printf("[%s] A: %.2f MB @ %d kbps\n", + EXE, audiosize/(1024*1024), abitrate/1000); + + /* Print recommended bitrates for user-specified or default disc sizes */ + if (discsize) { + videosize = discsize - audiosize; + vbitrate = videosize / time * 8; + printf("USER CDSIZE: %4d MB | V: %6.1f MB @ %.1f kbps\n", + (int)floor(discsize/(1024*1024)), videosize/(1024*1024), + vbitrate/1024); + } else { + int i; + for (i = 0; i < sizeof(defsize) / sizeof(*defsize); i++) { + videosize = defsize[i]*1024*1024 - audiosize; + vbitrate = videosize / time * 8; + printf("USER CDSIZE: %4d MB | V: %6.1f MB @ %.1f kbps\n", + defsize[i], videosize/(1024*1024), + vbitrate/1024); + } + } +} + +/*************************************************************************/ + +/* ------------------------------------------------------------ + * + * print a usage/version message + * + * ------------------------------------------------------------*/ + +void version(void) +{ + /* print id string to stderr */ + fprintf(stderr, "%s (%s v%s) (C) 2001-2003 Thomas Oestreich," + " 2003-2010 Transcode Team\n", + EXE, PACKAGE, VERSION); +} + + +static void usage(int status) +{ + version(); + + fprintf(stderr,"\nUsage: %s [options]\n", EXE); + + fprintf(stderr," -i file input file name [stdin]\n"); + fprintf(stderr," -x codec source codec\n"); + fprintf(stderr," -e r[,b[,c]] PCM audio stream parameter [%d,%d,%d]\n", RATE, BITS, CHANNELS); + fprintf(stderr," -f rate,frc frame rate [%.3f][,frc]\n", PAL_FPS); + fprintf(stderr," -w num estimate bitrate for num frames\n"); + fprintf(stderr," -b bitrate audio encoder bitrate kBits/s [%d]\n", ABITRATE); + fprintf(stderr," -c cdsize user defined CD size in MB [0]\n"); + fprintf(stderr," -d mode verbosity mode\n"); + fprintf(stderr," -v print version\n"); + + exit(status); + +} + + +/* ------------------------------------------------------------ + * + * scan stream + * + * ------------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + + info_t ipipe; + + long stream_stype = TC_STYPE_UNKNOWN; + + long magic = TC_MAGIC_UNKNOWN; + + FILE *in_file; + + int n=0, ch; + char *codec=NULL, *name=NULL; + + int bytes_per_sec, bytes_read, bframes=0; + + uint64_t total=0; + + int a_rate=RATE, a_bits=BITS, chan=CHANNELS; + + int on=1; + short *s; + + char buffer[CHUNK_SIZE]; + + double fps=PAL_FPS, frames, fmin, fmax, vol=0.0; + + int frc; + + int pseudo_frame_size=0; + + int ac_bytes=0, frame_size, bitrate=ABITRATE; + + float rbytes; + + uint32_t i=0, j=0; + uint16_t sync_word = 0; + double cdsize = 0.0; + + //proper initialization + memset(&ipipe, 0, sizeof(info_t)); + + libtc_init(&argc, &argv); + + while ((ch = getopt(argc, argv, "c:b:e:i:vx:f:d:w:?h")) != -1) { + + switch (ch) { + case 'c': + if(optarg[0]=='-') usage(EXIT_FAILURE); + cdsize = atof(optarg) * (1024*1024); /* MB -> bytes */ + + break; + + case 'd': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + verbose = atoi(optarg); + + break; + + case 'e': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + + if (3 != sscanf(optarg,"%d,%d,%d", &a_rate, &a_bits, &chan)) { + tc_log_error(EXE, "invalid pcm parameter set for option -e"); + usage(EXIT_FAILURE); + } + + if(a_rate > RATE || a_rate <= 0) { + tc_log_error(EXE, "invalid pcm parameter 'rate' for option -e"); + usage(EXIT_FAILURE); + } + + if(!(a_bits == 16 || a_bits == 8)) { + tc_log_error(EXE, "invalid pcm parameter 'bits' for option -e"); + usage(EXIT_FAILURE); + } + + if(!(chan == 0 || chan == 1 || chan == 2)) { + tc_log_error(EXE, "invalid pcm parameter 'channels' for option -e"); + usage(EXIT_FAILURE); + } + + break; + + case 'i': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + name = optarg; + break; + + case 'x': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + codec = optarg; + break; + + case 'f': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + n = sscanf(optarg,"%lf,%d", &fps, &frc); + + if (n == 2 && (frc > 0 && frc <= 0x10)) + tc_frc_code_to_value(frc, &fps); + + if(fps<=0) { + tc_log_error(EXE,"invalid frame rate for option -f"); + exit(1); + } + break; + + case 'w': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + bframes = atoi(optarg); + + if(bframes <=0) { + tc_log_error(EXE,"invalid parameter for option -w"); + exit(1); + } + break; + + case 'b': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + bitrate = atoi(optarg); + + if(bitrate < 0) { + tc_log_error(EXE,"invalid bitrate for option -b"); + exit(1); + } + break; + + + case 'v': + version(); + exit(0); + break; + + case 'h': + usage(EXIT_SUCCESS); + default: + usage(EXIT_FAILURE); + } + } + + ac_init(AC_ALL); + + /* ------------------------------------------------------------ + * + * fill out defaults for info structure + * + * ------------------------------------------------------------*/ + + // simple bitrate calculator + if(bframes) { + enc_bitrate(bframes, fps, bitrate*1000, cdsize); + exit(0); + } + + // assume defaults + if(name==NULL) stream_stype=TC_STYPE_STDIN; + + // no autodetection yet + if(codec==NULL && name == NULL) { + tc_log_error(EXE, "invalid codec %s", codec); + usage(EXIT_FAILURE); + } + + if(codec==NULL) codec=""; + + // do not try to mess with the stream + if(stream_stype!=TC_STYPE_STDIN) { + + if(tc_file_check(name)) exit(1); + + if((ipipe.fd_in = xio_open(name, O_RDONLY))<0) { + tc_log_perror(EXE, "open file"); + exit(1); + } + + magic = fileinfo(ipipe.fd_in, 0); + + } else ipipe.fd_in = STDIN_FILENO; + + + /* ------------------------------------------------------------ + * + * AC3 stream + * + * ------------------------------------------------------------*/ + + if(strcmp(codec,"ac3")==0 || magic==TC_MAGIC_AC3) { + + + for(;;) { + + for(;;) { + + if (tc_pread(ipipe.fd_in, buffer, 1) !=1) { + tc_log_perror(EXE, "ac3 sync frame scan failed"); + goto ac3_summary; + } + + sync_word = (sync_word << 8) + (uint8_t) buffer[0]; + + ++i; + + if(sync_word == 0x0b77) break; + } + + i=i-2; + + if (tc_pread(ipipe.fd_in, buffer, 3) !=3) { + tc_log_perror(EXE, "ac3 header read failed"); + goto ac3_summary; + } + + if((frame_size = 2*get_ac3_framesize(buffer)) < 1) { + tc_log_warn(EXE, "ac3 framesize %d invalid - frame broken?", frame_size); + goto more; + } + + //FIXME: I assume that a single AC3 frame contains 6kB PCM bytes + + rbytes = (float) SIZE_PCM_FRAME/1024/6 * frame_size; + pseudo_frame_size = (int) rbytes; + bitrate = get_ac3_bitrate(buffer); + + printf("[%s] [%05d] offset %06d (%06d) %04d bytes, bitrate %03d kBits/s\n", EXE, n++, i, j, frame_size, bitrate); + + // read the rest + + ac_bytes = frame_size-5; + + if(ac_bytes>CHUNK_SIZE) { + tc_log_error(EXE, "Oops, no buffer space framesize %d", ac_bytes); + exit(1); + } + + if ((bytes_read=tc_pread(ipipe.fd_in, buffer, ac_bytes)) != ac_bytes) { + tc_log_warn(EXE, "error reading ac3 frame (%d/%d)", bytes_read, ac_bytes); + break; + } + + more: + + i+=frame_size; + j=i; + } + + ac3_summary: + + vol = (double) (n * 1024 * 6)/4/RATE; + + printf("[%s] valid AC3 frames=%d, estimated clip length=%.2f seconds\n", EXE, n, vol); + + return(0); + } + + /* ------------------------------------------------------------ + * + * PCM stream + * + * ------------------------------------------------------------*/ + + if(strcmp(codec,"pcm")==0) { + + while(on) { + + if( (bytes_read = tc_pread(ipipe.fd_in, buffer, CHUNK_SIZE)) != CHUNK_SIZE) on = 0; + + total += (uint64_t) bytes_read; + + s=(short *) buffer; + + for(n=0; n<bytes_read>>1; ++n) { + check((int) (*s)); + s++; + } + } + + bytes_per_sec = a_rate * (a_bits/8) * chan; + + frames = (fps*((double)total)/bytes_per_sec); + + fmin = -((double) min)/SHRT_MAX; + fmax = ((double) max)/SHRT_MAX; + + if(min==0 || max == 0) exit(0); + + vol = (fmin<fmax) ? 1./fmax : 1./fmin; + + printf("[%s] audio frames=%.2f, estimated clip length=%.2f seconds\n", EXE, frames, frames/fps); + printf("[%s] (min/max) amplitude=(%.3f/%.3f), suggested volume rescale=%.3f\n", EXE, -fmin, fmax, vol); + + enc_bitrate((long) frames, fps, bitrate*1000, cdsize); + + return(0); + } + + if(strcmp(codec,"mp3")==0 || magic == TC_MAGIC_MP3) { + + char header[4]; + int framesize = 0; + int chunks = 0; + int srate=0 , chans=0, bitrate=0; + unsigned long bitrate_add = 0; + off_t pos=0; + double ms = 0; + char bitrate_buf[TC_BUF_MIN]; + + min = 500; + max = 0; + + pos = lseek(ipipe.fd_in, 0, SEEK_CUR); + // find mp3 header + while ((total += read(ipipe.fd_in, header, 4))) { + if ( (framesize = tc_get_mp3_header (header, &chans, &srate, &bitrate)) > 0) { + break; + } + pos++; + lseek(ipipe.fd_in, pos, SEEK_SET); + } + tc_log_msg(EXE, "POS %lld", (long long)pos); + + // Example for _1_ mp3 chunk + // + // fps = 25 + // framesize = 480 bytes + // bitrate = 160 kbit/s == 20 kbytes/s == 20480 bytes/s == 819.20 bytes / frame + // + // 480 bytes = 480/20480 s/bytes = .0234 s = 23.4 ms + // + // ms = (framesize*1000*8)/(bitrate*1000); + // why 1000 and not 1024? + // correct? yes! verified with "cat file.mp3|mpg123 -w /dev/null -v -" -- tibit + + while (on) { + if ( (bytes_read = read(ipipe.fd_in, buffer, framesize-4)) != framesize-4) { + on = 0; + } else { + total += bytes_read; + while ((total += read(ipipe.fd_in, header, 4))) { + + //tc_log_msg(EXE, "%x %x %x %x", header[0]&0xff, header[1]&0xff, header[2]&0xff, header[3]&0xff); + + if ( (framesize = tc_get_mp3_header (header, &chans, &srate, &bitrate)) < 0) { + tc_log_warn(EXE, "corrupt mp3 file?"); + on = 0; + break; + } else { + + /* + tc_log_msg(EXE, "Found new header (%d) (framesize = %d) chan(%d) srate(%d) bitrate(%d)", + chunks, framesize, chans, srate, bitrate); + */ + + bitrate_add += bitrate; + check(bitrate); + ms += (framesize*8)/(bitrate); + ++chunks; + break; + } + } + + + } + } + + if (min != max) + tc_snprintf(bitrate_buf, sizeof(bitrate_buf), "(%d-%d)", min, max); + else + tc_snprintf(bitrate_buf, sizeof(bitrate_buf), "(cbr)"); + printf("[%s] MPEG-1 layer-3 stream. Info: -e %d,%d,%d\n", EXE, + srate, 16, chans); + printf("[%s] Found %d MP3 chunks. Average bitrate is %3.2f kbps %s\n", EXE, + chunks, (double)bitrate_add/chunks, bitrate_buf); + printf("[%s] AVI overhead will be max. %d*(8+16) = %d bytes (%dk)\n", EXE, + chunks, chunks*8+chunks*16, (chunks*8+chunks*16)/1024); + printf("[%s] Estimated time is %.0f ms (%02d:%02d:%02d.%02d)\n", EXE, + ms, + (int)(ms/1000.0/60.0/60.0), + (int)(ms/1000.0/60.0)%60, + (int)(ms/1000)%60, + (int)(ms)%(1000)); + return(0); + } + + /* ------------------------------------------------------------ + * + * MPEG program stream + * + * ------------------------------------------------------------*/ + + if(strcmp(codec, "mpeg2")==0 || strcmp(codec, "mpeg")==0 || strcmp(codec, "vob")==0 || magic==TC_MAGIC_VOB || magic==TC_MAGIC_M2V) { + + in_file = fdopen(ipipe.fd_in, "r"); + + scan_pes(verbose, in_file); + + return(0); + } + + /* ------------------------------------------------------------ + * + * AVI + * + * ------------------------------------------------------------*/ + + if(magic==TC_MAGIC_AVI || TC_MAGIC_WAV) { + + if(name!=NULL) AVI_scan(name); + + return(0); + } + + + tc_log_error(EXE, "unable to handle codec/filetype %s", codec); + + exit(1); + +} + + +// from mencoder +//----------------------- mp3 audio frame header parser ----------------------- + +static int tabsel_123[2][3][16] = { + { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0} }, + + { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0} } +}; +static long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; + +/* + * return frame size or -1 (bad frame) + */ +int tc_get_mp3_header(unsigned char* hbuf, int* chans, int* srate, int *bitrate){ + int stereo, ssize, crc, lsf, mpeg25, framesize; + int padding, bitrate_index, sampling_frequency; + unsigned long newhead = + hbuf[0] << 24 | + hbuf[1] << 16 | + hbuf[2] << 8 | + hbuf[3]; + + +#if 1 + // head_check: + if( (newhead & 0xffe00000) != 0xffe00000 || + (newhead & 0x0000fc00) == 0x0000fc00){ + //tc_log_warn(EXE, "head_check failed"); + return -1; + } +#endif + + if((4-((newhead>>17)&3))!=3){ + //tc_log_warn(EXE, "not layer-3"); + return -1; + } + + if( newhead & ((long)1<<20) ) { + lsf = (newhead & ((long)1<<19)) ? 0x0 : 0x1; + mpeg25 = 0; + } else { + lsf = 1; + mpeg25 = 1; + } + + if(mpeg25) + sampling_frequency = 6 + ((newhead>>10)&0x3); + else + sampling_frequency = ((newhead>>10)&0x3) + (lsf*3); + + if(sampling_frequency>8){ + tc_log_warn(EXE, "invalid sampling_frequency"); + return -1; // valid: 0..8 + } + + crc = ((newhead>>16)&0x1)^0x1; + bitrate_index = ((newhead>>12)&0xf); + padding = ((newhead>>9)&0x1); +// fr->extension = ((newhead>>8)&0x1); +// fr->mode = ((newhead>>6)&0x3); +// fr->mode_ext = ((newhead>>4)&0x3); +// fr->copyright = ((newhead>>3)&0x1); +// fr->original = ((newhead>>2)&0x1); +// fr->emphasis = newhead & 0x3; + + stereo = ( (((newhead>>6)&0x3)) == 3) ? 1 : 2; + + if(!bitrate_index){ + tc_log_warn(EXE, "Free format not supported."); + return -1; + } + + if(lsf) + ssize = (stereo == 1) ? 9 : 17; + else + ssize = (stereo == 1) ? 17 : 32; + if(crc) ssize += 2; + + framesize = tabsel_123[lsf][2][bitrate_index] * 144000; + if (bitrate) *bitrate = tabsel_123[lsf][2][bitrate_index]; + + if(!framesize){ + tc_log_warn(EXE, "invalid framesize/bitrate_index"); + return -1; // valid: 1..14 + } + + framesize /= freqs[sampling_frequency]<<lsf; + framesize += padding; + +// if(framesize<=0 || framesize>MAXFRAMESIZE) return FALSE; + if(srate) *srate = freqs[sampling_frequency]; + if(chans) *chans = stereo; + + return framesize; +} + +#include "libtc/static_xio.h" |
