You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
7.0 KiB

/*
* import_dv.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.
*
*/
#define MOD_NAME "import_dv.so"
#define MOD_VERSION "v0.3.1 (2003-10-14)"
#define MOD_CODEC "(video) DV | (audio) PCM"
#include "transcode.h"
#include "libtc/libtc.h"
#include "libtc/xio.h"
#include "libtcvideo/tcvideo.h"
static int verbose_flag = TC_QUIET;
static int capability_flag = TC_CAP_RGB | TC_CAP_YUV | TC_CAP_DV |
TC_CAP_PCM | TC_CAP_VID | TC_CAP_YUV422;
#define MOD_PRE dv
#include "import_def.h"
char import_cmd_buf[TC_BUF_MAX];
static int frame_size=0;
static FILE *fd=NULL;
static uint8_t *tmpbuf = NULL;
static int yuv422_mode = 0, width, height;
static TCVHandle tcvhandle = 0;
/* ------------------------------------------------------------
*
* open stream
*
* ------------------------------------------------------------*/
MOD_open
{
char cat_buf[TC_BUF_MAX];
char yuv_buf[16];
long sret;
if(param->flag == TC_VIDEO) {
//directory mode?
sret = tc_file_check(vob->video_in_file);
if (sret < 0) {
return(TC_IMPORT_ERROR);
}
if(sret == 1) {
tc_snprintf(cat_buf, TC_BUF_MAX, "tccat");
} else {
if(vob->im_v_string) {
tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv %s",
vob->im_v_string);
} else {
tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv");
}
}
//yuy2 mode?
(vob->dv_yuy2_mode) ?
tc_snprintf(yuv_buf, 16, "-y yuv420p -Y") :
tc_snprintf(yuv_buf, 16, "-y yuv420p");
param->fd = NULL;
yuv422_mode = 0;
switch(vob->im_v_codec) {
case CODEC_RGB:
sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX,
"%s -i \"%s\" -d %d | tcdecode -x dv -y rgb -d %d -Q %d",
cat_buf, vob->video_in_file, vob->verbose, vob->verbose,
vob->quality);
if (sret < 0)
return(TC_IMPORT_ERROR);
// popen
if((param->fd = popen(import_cmd_buf, "r"))== NULL) {
return(TC_IMPORT_ERROR);
}
break;
case CODEC_YUV:
sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX,
"%s -i \"%s\" -d %d | tcdecode -x dv %s -d %d -Q %d",
cat_buf, vob->video_in_file, vob->verbose, yuv_buf,
vob->verbose, vob->quality);
if (sret < 0)
return(TC_IMPORT_ERROR);
// for reading
frame_size = (vob->im_v_width * vob->im_v_height * 3)/2;
param->fd = NULL;
// popen
if((fd = popen(import_cmd_buf, "r"))== NULL) {
return(TC_IMPORT_ERROR);
}
break;
case CODEC_YUV422:
sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX,
"%s -i \"%s\" -d %d |"
" tcdecode -x dv -y yuy2 -d %d -Q %d",
cat_buf, vob->video_in_file, vob->verbose,
vob->verbose, vob->quality);
if (sret < 0)
return(TC_IMPORT_ERROR);
// for reading
frame_size = vob->im_v_width * vob->im_v_height * 2;
tmpbuf = tc_malloc(frame_size);
if (!tmpbuf) {
tc_log_error(MOD_NAME, "out of memory");
return(TC_IMPORT_ERROR);
}
tcvhandle = tcv_init();
if (!tcvhandle) {
tc_log_error(MOD_NAME, "tcv_init() failed");
return(TC_IMPORT_ERROR);
}
yuv422_mode = 1;
width = vob->im_v_width;
height = vob->im_v_height;
param->fd = NULL;
// popen
if((fd = popen(import_cmd_buf, "r"))== NULL) {
return(TC_IMPORT_ERROR);
}
break;
case CODEC_RAW:
case CODEC_RAW_YUV:
sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, "%s -i \"%s\" -d %d",
cat_buf, vob->video_in_file, vob->verbose);
if (sret < 0)
return(TC_IMPORT_ERROR);
// for reading
frame_size = (vob->im_v_height==PAL_H) ?
TC_FRAME_DV_PAL : TC_FRAME_DV_NTSC;
param->fd = NULL;
// popen
if((fd = popen(import_cmd_buf, "r"))== NULL) {
return(TC_IMPORT_ERROR);
}
break;
default:
tc_log_warn(MOD_NAME, "invalid import codec request 0x%x",
vob->im_v_codec);
return(TC_IMPORT_ERROR);
}
// print out
if(verbose_flag) tc_log_info(MOD_NAME, "%s", import_cmd_buf);
return(TC_IMPORT_OK);
}
if(param->flag == TC_AUDIO) {
//directory mode?
if(tc_file_check(vob->audio_in_file)) {
tc_snprintf(cat_buf, TC_BUF_MAX, "tccat");
} else {
if(vob->im_a_string) {
tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv %s",
vob->im_a_string);
} else {
tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv");
}
}
sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX,
"%s -i \"%s\" -d %d | tcdecode -x dv -y pcm -d %d",
cat_buf, vob->audio_in_file, vob->verbose,
vob->verbose);
if (sret < 0)
return(TC_IMPORT_ERROR);
// print out
if(verbose_flag) tc_log_info(MOD_NAME, "%s", import_cmd_buf);
param->fd = NULL;
// popen
if((param->fd = popen(import_cmd_buf, "r"))== NULL) {
tc_log_perror(MOD_NAME, "popen PCM stream");
return(TC_IMPORT_ERROR);
}
return(TC_IMPORT_OK);
}
return(TC_IMPORT_ERROR);
}
/* ------------------------------------------------------------
*
* decode stream
*
* ------------------------------------------------------------*/
MOD_decode
{
if(param->flag == TC_AUDIO) return(TC_IMPORT_OK);
// video and YUV only
if(param->flag == TC_VIDEO && frame_size==0) return(TC_IMPORT_ERROR);
// return true yuv frame size as physical size of video data
param->size = frame_size;
if (yuv422_mode) {
if (fread(tmpbuf, frame_size, 1, fd) !=1)
return(TC_IMPORT_ERROR);
tcv_convert(tcvhandle, tmpbuf, param->buffer, width, height,
IMG_YUY2, IMG_YUV422P);
} else {
if (fread(param->buffer, frame_size, 1, fd) !=1)
return(TC_IMPORT_ERROR);
}
return(TC_IMPORT_OK);
}
/* ------------------------------------------------------------
*
* close stream
*
* ------------------------------------------------------------*/
MOD_close
{
if(param->fd != NULL) pclose(param->fd);
if(param->flag == TC_AUDIO) return(TC_IMPORT_OK);
if(param->flag == TC_VIDEO) {
if(fd) pclose(fd);
fd=NULL;
if (tcvhandle)
tcv_free(tcvhandle);
tcvhandle=0;
free(tmpbuf);
tmpbuf=NULL;
return(TC_IMPORT_OK);
}
return(TC_IMPORT_ERROR);
}