diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/tools/avifix.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/tools/avifix.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/tools/avifix.c b/debian/transcode/transcode-1.1.7/tools/avifix.c new file mode 100644 index 00000000..cfd7d6ac --- /dev/null +++ b/debian/transcode/transcode-1.1.7/tools/avifix.c @@ -0,0 +1,335 @@ +/* + * avifix.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. + * + */ + +#include "transcode.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +#include "avilib/avilib.h" + +#define EXE "avifix" + +/* AVI_info is no longer in avilib */ +void AVI_info(avi_t *avifile); + +void version(void) +{ + printf("%s (%s v%s) (C) 2001-2003 Thomas Oestreich," + " 2003-2010 Transcode Team\n", + EXE, PACKAGE, VERSION); +} + +static void usage(int status) +{ + version(); + printf("\nUsage: %s [options]\n", EXE); + printf(" -i name AVI file name\n"); + printf(" -F string video codec FOURCC\n"); + printf(" -f val1,val2 video frame rate (fps=val1/val2)\n"); + printf(" -N 0xnn audio format identifier\n"); + printf(" -b bitrate audio encoder bitrate (kbps)\n"); + printf(" -e r[,b[,c]] audio stream parameter (samplerate,bits,channels)\n"); + printf(" -a num audio track number [0]\n"); + printf(" -d print debug information\n"); + printf(" -v print version\n"); + exit(status); +} + +/* read or die! */ +static void hdr_read(const char *tag, int fd, void *hdr, size_t bytes) +{ + ssize_t r = read(fd, hdr, bytes); + if (bytes != r) { + tc_log_error(EXE, "(%s) error reading AVI-file", tag); + exit(1); + } +} + +/* write or die! */ +static void hdr_write(const char *tag, int fd, const void *hdr, size_t bytes) +{ + ssize_t w = write(fd, hdr, bytes); + if (bytes != w) { + tc_log_error(EXE, "(%s) error writing AVI-file", tag); + exit(1); + } +} + + +#define VALIDATE_OPTION if (optarg[0]=='-') usage(EXIT_FAILURE) + +enum { + /* video in the lower bits */ + CHANGE_VIDEO_FOURCC = (1UL), + CHANGE_VIDEO_FPS = (1UL << 1), + /* audio in the higher bits */ + CHANGE_AUDIO_FMT = (1UL << 16), + CHANGE_AUDIO_BR = (1UL << 17), + CHANGE_AUDIO_RATE = (1UL << 18), + CHANGE_AUDIO_BITS = (1UL << 19), + CHANGE_AUDIO_CHANS = (1UL << 20) +}; +#define CHANGE_NOTHING (0UL) +#define NEED_AUDIO_CHANGE(FLAGS) (FLAGS & 0xFFFF0000) +#define NEED_VIDEO_CHANGE(FLAGS) (FLAGS & 0x0000FFFF) + + + +int main(int argc, char *argv[]) +{ + struct common_struct rtf; + struct AVIStreamHeader ash, vsh; + avi_t *avifile; + int err, fd, id = 0, track_num = 0, n, ch, debug = TC_FALSE; + int brate = 0, val1 = 0, val2 = 1, a_rate, a_chan, a_bits; + long ah_off = 0, af_off = 0, vh_off = 0, vf_off = 0; + char codec[5], *str = NULL, *filename = NULL; + uint32_t change = CHANGE_NOTHING; + + ac_init(AC_ALL); + + if (argc==1) usage(EXIT_FAILURE); + + while ((ch = getopt(argc, argv, "df:i:N:F:vb:e:a:?h")) != -1) { + switch (ch) { + case 'N': + VALIDATE_OPTION; + id = strtol(optarg, NULL, 16); + if (id < 0) { + tc_log_error(EXE, "invalid parameter set for option -N"); + } else { + change |= CHANGE_AUDIO_FMT; + } + break; + + case 'a': + VALIDATE_OPTION; + track_num = atoi(optarg); + if (track_num < 0) + usage(EXIT_FAILURE); + break; + + case 'f': + VALIDATE_OPTION; + n = sscanf(optarg,"%d,%d", &val1, &val2); + if (n != 2 || val1 < 0 || val2 < 0) { + tc_log_error(EXE, "invalid parameter set for option -f"); + } else { + change |= CHANGE_VIDEO_FPS; + } + break; + + case 'F': + VALIDATE_OPTION; + str = optarg; + if(strlen(str) > 4 || strlen(str) == 0) { + tc_log_error(EXE, "invalid parameter set for option -F"); + } else { + change |= CHANGE_VIDEO_FOURCC; + } + break; + + case 'i': + VALIDATE_OPTION; + filename = optarg; + break; + + case 'b': + VALIDATE_OPTION; + brate = atoi(optarg); + change |= CHANGE_AUDIO_BR; + break; + + case 'v': + version(); + exit(0); + + case 'e': + VALIDATE_OPTION; + n = sscanf(optarg,"%d,%d,%d", &a_rate, &a_bits, &a_chan); + switch (n) { + case 3: + change |= CHANGE_AUDIO_RATE; + case 2: + change |= CHANGE_AUDIO_BITS; + case 1: + change |= CHANGE_AUDIO_CHANS; + break; + default: + tc_log_error(EXE, "invalid parameter set for option -e"); + } + break; + + case 'd': + debug = TC_TRUE; + break; + case 'h': + usage(EXIT_SUCCESS); + default: + usage(EXIT_FAILURE); + } + } + + if (!filename) + usage(EXIT_FAILURE); + + tc_log_info(EXE, "scanning AVI-file %s for header information", filename); + + avifile = AVI_open_input_file(filename, 1); + if (!avifile) { + AVI_print_error("AVI open"); + exit(1); + } + + AVI_info(avifile); + + if (AVI_set_audio_track(avifile, track_num) < 0) { + tc_log_error(EXE, "invalid audio track"); + } + + ah_off = AVI_audio_codech_offset(avifile); + af_off = AVI_audio_codecf_offset(avifile); + vh_off = AVI_video_codech_offset(avifile); + vf_off = AVI_video_codecf_offset(avifile); + + if (debug) { + tc_log_info(EXE, + "offsets: ah=%li af=%li vh=%li vf=%li", + ah_off, af_off, vh_off, vf_off); + } + + AVI_close(avifile); + + fd = open(filename, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + lseek(fd, vh_off, SEEK_SET); + hdr_read("video codec [h]", fd, codec, 4); + codec[4] = 0; + + lseek(fd, vf_off, SEEK_SET); + hdr_read("video codec [f]", fd, codec, 4); + codec[4] = 0; + + if (change & CHANGE_VIDEO_FPS) { + lseek(fd, vh_off-4, SEEK_SET); + hdr_read("video fps", fd, &vsh, sizeof(vsh)); + + vsh.dwRate = (long)val1; + vsh.dwScale = (long)val2; + + lseek(fd, vh_off-4, SEEK_SET); + hdr_write("video fps", fd, &vsh, sizeof(vsh)); + } + + if (change & CHANGE_VIDEO_FOURCC) { + lseek(fd,vh_off,SEEK_SET); + + if (strncmp(str,"RGB",3) == 0) { + hdr_write("video 4cc", fd, codec, 4); + } else { + hdr_write("video 4cc", fd, str, 4); + } + + lseek(fd,vf_off,SEEK_SET); + + if(strncmp(str,"RGB",3)==0) { + memset(codec, 0, 4); + hdr_write("video 4cc", fd, codec, 4); + } else { + hdr_write("video 4cc", fd, str, 4); + } + } + + if (NEED_AUDIO_CHANGE(change)) { + lseek(fd, ah_off, SEEK_SET); + hdr_read("audio header [h]", fd, &ash, sizeof(ash)); + + lseek(fd, af_off, SEEK_SET); + hdr_read("audio header [f]", fd, &rtf, sizeof(rtf)); + + if (change & CHANGE_AUDIO_FMT) { + rtf.wFormatTag = (unsigned short) id; + } + if (change & CHANGE_AUDIO_BR) { + rtf.dwAvgBytesPerSec = (long) 1000*brate/8; + ash.dwRate = (long) 1000*brate/8; + ash.dwScale = 1; + } + if (change & CHANGE_AUDIO_CHANS) { + rtf.wChannels = (short) a_chan; + } + if (change & CHANGE_AUDIO_BITS) { + rtf.wBitsPerSample = (short) a_bits; + } + if (change & CHANGE_AUDIO_RATE) { + rtf.dwSamplesPerSec = (long) a_rate; + } + + lseek(fd, ah_off ,SEEK_SET); + hdr_write("audio header [h]", fd, &ash, sizeof(ash)); + lseek(fd, af_off ,SEEK_SET); + hdr_write("audio header [f]", fd, &rtf, sizeof(rtf)); + } + + err = close(fd); + if (err) { + perror("close"); + exit(1); + } + + avifile = AVI_open_input_file(filename, 1); + if (!avifile) { + AVI_print_error("AVI open"); + exit(1); + } + + tc_log_info(EXE, "updated AVI file %s", filename); + + AVI_info(avifile); + + AVI_close(avifile); + + return 0; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ |
