summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/import/import_mov.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/import_mov.c')
-rw-r--r--debian/transcode/transcode-1.1.7/import/import_mov.c486
1 files changed, 486 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/import_mov.c b/debian/transcode/transcode-1.1.7/import/import_mov.c
new file mode 100644
index 00000000..a330fe40
--- /dev/null
+++ b/debian/transcode/transcode-1.1.7/import/import_mov.c
@@ -0,0 +1,486 @@
+/*
+ * import_mov.c
+ *
+ * Copyright (C) Thomas Oestreich - January 2002
+ * updated by Christian Vogelgsang <Vogelgsang@informatik.uni-erlangen.de>
+ *
+ * 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.
+ *
+ */
+
+#define MOD_NAME "import_mov.so"
+#define MOD_VERSION "v0.1.3 (2005-12-04)"
+#define MOD_CODEC "(video) * | (audio) *"
+
+#include "transcode.h"
+#include "../src/filter.h"
+
+static int verbose_flag = TC_QUIET;
+static int capability_flag = TC_CAP_PCM | TC_CAP_RGB | TC_CAP_YUV |
+ TC_CAP_YUV422 | TC_CAP_VID;
+
+#define MOD_PRE mov
+#include "import_def.h"
+
+#include <quicktime.h>
+#include <colormodels.h>
+#include <lqt.h>
+#include "magic.h"
+
+#include "aclib/imgconvert.h"
+
+/* movie handles */
+static quicktime_t *qt_audio=NULL;
+static quicktime_t *qt_video=NULL;
+
+/* row pointer for decode frame */
+static unsigned char **row_ptr = NULL;
+
+/* raw or decode frame */
+static int rawVideoMode = 0;
+
+/* raw or decode audio */
+static int rawAudioMode = 0;
+
+/* frame size */
+static int w=0, h=0;
+
+/* number of audio channels */
+static int chan=0;
+
+/* number of audio bits */
+static int bits=0;
+
+/* number of frames */
+static int frames=0;
+
+/* number of audio samples */
+static int no_samples=0;
+
+/* import colormodel */
+static int qt_cm = 0;
+
+
+/* ------------------------------------------------------------
+ *
+ * open stream
+ *
+ * ------------------------------------------------------------*/
+
+MOD_open
+{
+ /* audio */
+ if(param->flag == TC_AUDIO) {
+ int numTrk;
+ long rate;
+ char *codec;
+
+ param->fd = NULL;
+
+ /* open movie for audio extraction */
+ if(qt_audio==NULL) {
+ if(NULL == (qt_audio = quicktime_open((char *)vob->audio_in_file,1,0))){
+ tc_log_warn(MOD_NAME, "can't open quicktime!");
+ return(TC_IMPORT_ERROR);
+ }
+ }
+
+ /* check for audio track */
+ numTrk = quicktime_audio_tracks(qt_audio);
+ if(numTrk==0) {
+ tc_log_warn(MOD_NAME, "AUDIO: --no audio track in quicktime found --");
+ no_samples=0;
+ return(TC_IMPORT_OK);
+ }
+
+ /* extract audio parameters */
+ rate = quicktime_sample_rate(qt_audio, 0);
+ chan = quicktime_track_channels(qt_audio, 0);
+ bits = quicktime_audio_bits(qt_audio, 0);
+ codec = quicktime_audio_compressor(qt_audio, 0);
+
+ /* The total frames */
+ no_samples=quicktime_audio_length(qt_audio, 0);
+
+ /* verbose info */
+ tc_log_info(MOD_NAME, "codec=%s, rate=%ld Hz, bits=%d,"
+ " channels=%d, samples=%d",
+ codec, rate, bits, chan, no_samples);
+
+ /* check bits */
+ if((bits!=8)&&(bits!=16)) {
+ tc_log_warn(MOD_NAME, "unsupported sample bits: %d",bits);
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* check channels */
+ if(chan>2) {
+ tc_log_warn(MOD_NAME, "too many audio channels: %d",chan);
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* check codec string */
+ if(strlen(codec)==0) {
+ tc_log_warn(MOD_NAME, "empty codec in quicktime?");
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* check if audio compressor is supported */
+ if(quicktime_supported_audio(qt_audio, 0)!=0) {
+ rawAudioMode = 0;
+ }
+#if !defined(LIBQUICKTIME_000904)
+ /* RAW PCM is directly supported */
+ else if(strcasecmp(codec,QUICKTIME_RAW)==0) {
+ rawAudioMode = 1;
+ tc_log_warn(MOD_NAME, "using RAW audio mode!");
+ }
+#endif
+ /* unsupported codec */
+ else {
+ tc_log_warn(MOD_NAME, "quicktime audio codec '%s' not supported!",
+ codec);
+ return(TC_IMPORT_ERROR);
+ }
+ return(TC_IMPORT_OK);
+ }
+
+ /* video */
+ if(param->flag == TC_VIDEO) {
+ double fps;
+ char *codec;
+ int numTrk;
+
+ param->fd = NULL;
+
+ /* open movie for video extraction */
+ if(qt_video==NULL)
+ if(NULL == (qt_video = quicktime_open((char *)vob->video_in_file,1,0))){
+ tc_log_warn(MOD_NAME,"can't open quicktime!");
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* check for audio track */
+ numTrk = quicktime_video_tracks(qt_video);
+ if(numTrk==0) {
+ tc_log_warn(MOD_NAME,"no video track in quicktime found!");
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* read all video parameter from input file */
+ w = quicktime_video_width(qt_video, 0);
+ h = quicktime_video_height(qt_video, 0);
+ fps = quicktime_frame_rate(qt_video, 0);
+ codec = quicktime_video_compressor(qt_video, 0);
+
+ //ThOe total frames
+ frames=quicktime_video_length(qt_video, 0);
+
+ /* verbose info */
+ tc_log_info(MOD_NAME, "VIDEO: codec=%s, fps=%6.3f, width=%d,"
+ " height=%d, frames=%d",
+ codec, fps, w, h, frames);
+
+ /* check codec string */
+ if(strlen(codec)==0) {
+ tc_log_warn(MOD_NAME, "empty codec in quicktime?");
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* check if a suitable compressor is available */
+ if(quicktime_supported_video(qt_video,0)==0) {
+ tc_log_warn(MOD_NAME, "quicktime codec '%s'"
+ " not supported for RGB!",
+ codec);
+ return(TC_IMPORT_ERROR);
+ }
+
+
+ /* set color model */
+ switch(vob->im_v_codec) {
+ case CODEC_RGB:
+ /* use raw mode when possible */
+ /* not working ?*/
+ /*if (strcmp(qt_codec, "raw ")) rawVideo=1; */
+ /* allocate buffer for row pointers */
+ row_ptr = tc_malloc(h*sizeof(char *));
+ if(row_ptr==0) {
+ tc_log_error(MOD_NAME,"can't alloc row pointers");
+ return(TC_IMPORT_ERROR);
+ }
+
+ quicktime_set_cmodel(qt_video, BC_RGB888); qt_cm = BC_RGB888;
+ break;
+
+ case CODEC_YUV:
+ /* use raw mode when possible */
+ /* not working ?*/
+ /* if (strcmp(qt_codec, "yv12")) rawVideo=1; */
+
+ /* allocate buffer for row pointers */
+ row_ptr = tc_malloc(3*sizeof(char *));
+ if(row_ptr==0) {
+ tc_log_error(MOD_NAME,"can't alloc row pointers");
+ return(TC_IMPORT_ERROR);
+ }
+
+ if (!quicktime_reads_cmodel(qt_video, BC_YUV420P, 0)) {
+ if (quicktime_reads_cmodel(qt_video, BC_YUVJ420P, 0)) {
+ /* stolen from import_ffmpeg */
+ /* load levels filter */
+ if (!tc_filter_add("levels", "output=16-240:pre=1")) {
+ tc_log_warn(MOD_NAME, "cannot load levels filter. Try -V rgb24.");
+ }
+ quicktime_set_cmodel(qt_video, BC_YUVJ420P);
+
+ } else {
+ tc_log_error(MOD_NAME,"unable to handle colormodel. Try -V rgb24.");
+ return(TC_IMPORT_ERROR);
+ }
+ } else {
+ quicktime_set_cmodel(qt_video, BC_YUV420P);
+ }
+
+ qt_cm = BC_YUV420P;
+ break;
+
+ case CODEC_YUV422:
+ /* allocate buffer for row pointers */
+ row_ptr = tc_malloc(3*sizeof(char *));
+ if(row_ptr==0) {
+ tc_log_error(MOD_NAME,"can't alloc row pointers");
+ return(TC_IMPORT_ERROR);
+ }
+
+ if (!quicktime_reads_cmodel(qt_video, BC_YUV422P, 0)) {
+ tc_log_error(MOD_NAME,"unable to handle colormodel. Try -V rgb24.");
+ return(TC_IMPORT_ERROR);
+ }
+
+ quicktime_set_cmodel(qt_video, BC_YUV422P); qt_cm = BC_YUV422P;
+ break;
+
+ case CODEC_YUY2:
+ quicktime_set_cmodel(qt_video, BC_YUV422); qt_cm = BC_YUV422;
+ break;
+
+ /* passthrough */
+ case CODEC_RAW_RGB:
+ case CODEC_RAW_YUV:
+ case CODEC_RAW:
+ rawVideoMode = 1;
+ break;
+
+ default:
+ /* unsupported internal format */
+ tc_log_warn(MOD_NAME,"unsupported internal video format %x",
+ vob->ex_v_codec);
+ return(TC_EXPORT_ERROR);
+ break;
+ }
+
+ return(TC_IMPORT_OK);
+ }
+
+ return(TC_IMPORT_ERROR);
+}
+
+
+/* ------------------------------------------------------------
+ *
+ * decode stream
+ *
+ * ------------------------------------------------------------*/
+
+MOD_decode
+{
+ /* video */
+ if(param->flag == TC_VIDEO) {
+ if(rawVideoMode) {
+ /* read frame raw */
+ param->size = quicktime_read_frame(qt_video, param->buffer, 0);
+ if(param->size<=0) {
+ if(verbose & TC_DEBUG)
+ tc_log_warn(MOD_NAME,"quicktime read video frame");
+ return(TC_IMPORT_ERROR);
+ }
+ } else {
+ /* decode frame */
+ unsigned char *mem = param->buffer;
+
+ int iy,sl;
+
+ switch(qt_cm) {
+ case BC_RGB888:
+ /* setup row pointers for RGB: inverse! */
+ sl = w*3;
+ for(iy=0;iy<h;iy++){
+ row_ptr[iy] = mem;
+ mem += sl;
+ }
+
+ param->size = (h*w) * 3;
+ break;
+
+ case BC_YUV420P: {
+ /* setup row pointers for YUV420P */
+ YUV_INIT_PLANES(row_ptr, mem, IMG_YUV420P, h, w);
+ param->size = (h*w*3)/2;
+ break;
+ }
+
+ case BC_YUV422P: {
+ /* setup row pointers for YUV422P */
+ YUV_INIT_PLANES(row_ptr, mem, IMG_YUV422P, h, w);
+ param->size = (h*w)*2;
+ break;
+ }
+ }
+
+ /* decode the next frame */
+ if(lqt_decode_video(qt_video,row_ptr,0)<0) {
+ if(verbose & TC_DEBUG)
+ tc_log_warn(MOD_NAME,"can't decode frame");
+ return(TC_IMPORT_ERROR);
+ }
+ }
+
+ //ThOe trust file header and terminate after all frames have been processed.
+ if(frames--==0) return(TC_IMPORT_ERROR);
+ return(TC_IMPORT_OK);
+ }
+
+ /* audio */
+ if(param->flag == TC_AUDIO) {
+
+ int bytes_read;
+
+ /* Leave if audio track is empty */
+ if (no_samples==0){
+ param->size=0;
+ return(TC_IMPORT_OK);
+ }
+
+ /* raw read mode */
+#if !defined(LIBQUICKTIME_000904)
+ if(rawAudioMode) {
+ bytes_read = quicktime_read_audio(qt_audio,
+ param->buffer, param->size, 0);
+ } else
+#endif
+ {
+ /* decode audio mode */
+ long pos = quicktime_audio_position(qt_audio,0);
+ long samples = param->size;
+ if(bits==16)
+ samples >>= 1;
+
+ /* mono */
+ if(chan==1) {
+ /* direct copy */
+ bytes_read = quicktime_decode_audio(qt_audio,
+ (int16_t *)param->buffer,NULL,
+ samples,0);
+
+ /* check result */
+ if(bytes_read<0) {
+ if(verbose & TC_DEBUG)
+ tc_log_warn(MOD_NAME,"reading quicktime audio frame!");
+ return(TC_IMPORT_ERROR);
+ }
+ }
+ /* stereo */
+ else {
+ int16_t *tgt;
+ int16_t *tmp;
+ int s,t;
+
+ samples >>= 1;
+ tgt = (int16_t *)param->buffer;
+ tmp = tc_malloc(samples*sizeof(int16_t));
+
+ /* read first channel into target buffer */
+ bytes_read = quicktime_decode_audio(qt_audio,tgt,NULL,samples,0);
+ if(bytes_read<0) {
+ if(verbose & TC_DEBUG)
+ tc_log_warn(MOD_NAME,"reading quicktime audio frame!");
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* read second channel in temp buffer */
+ quicktime_set_audio_position(qt_audio,pos,0);
+ bytes_read = quicktime_decode_audio(qt_audio,tmp,NULL,samples,1);
+ if(bytes_read<0) {
+ if(verbose & TC_DEBUG)
+ tc_log_warn(MOD_NAME,"reading quicktime audio frame!");
+ return(TC_IMPORT_ERROR);
+ }
+
+ /* spread first channel */
+ for(s=samples-1;s>=0;s--)
+ tgt[s<<1] = tgt[s];
+
+ /* fill in second channel from temp buffer */
+ t = 1;
+ for(s=0;s<samples;s++) {
+ tgt[t] = tmp[s];
+ t += 2;
+ }
+
+ free(tmp);
+ }
+ quicktime_set_audio_position(qt_audio,pos+samples,0);
+ }
+
+ return(TC_IMPORT_OK);
+ }
+
+ return(TC_IMPORT_ERROR);
+}
+
+/* ------------------------------------------------------------
+ *
+ * close stream
+ *
+ * ------------------------------------------------------------*/
+
+MOD_close
+{
+ /* free up audio */
+ if(param->flag == TC_AUDIO) {
+ if(qt_audio!=NULL) {
+ quicktime_close(qt_audio);
+ qt_audio=NULL;
+ }
+ return(TC_IMPORT_OK);
+ }
+
+ /* free up video */
+ if(param->flag == TC_VIDEO) {
+ if(qt_video!=NULL) {
+ quicktime_close(qt_video);
+ qt_video=NULL;
+ }
+ /* free row pointer */
+ if(row_ptr!=0)
+ free(row_ptr);
+
+ return(TC_IMPORT_OK);
+ }
+
+ return(TC_IMPORT_ERROR);
+}