1 /* 2 * import_dv.c 3 * 4 * Copyright (C) Thomas Oestreich - June 2001 5 * 6 * This file is part of transcode, a video stream processing tool 7 * 8 * transcode is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2, or (at your option) 11 * any later version. 12 * 13 * transcode is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with GNU Make; see the file COPYING. If not, write to 20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 * 22 */ 23 24 #define MOD_NAME "import_dv.so" 25 #define MOD_VERSION "v0.3.1 (2003-10-14)" 26 #define MOD_CODEC "(video) DV | (audio) PCM" 27 28 #include "transcode.h" 29 #include "libtc/libtc.h" 30 #include "libtc/xio.h" 31 #include "libtcvideo/tcvideo.h" 32 33 static int verbose_flag = TC_QUIET; 34 static int capability_flag = TC_CAP_RGB | TC_CAP_YUV | TC_CAP_DV | 35 TC_CAP_PCM | TC_CAP_VID | TC_CAP_YUV422; 36 37 #define MOD_PRE dv 38 #include "import_def.h" 39 40 41 char import_cmd_buf[TC_BUF_MAX]; 42 43 static int frame_size=0; 44 static FILE *fd=NULL; 45 static uint8_t *tmpbuf = NULL; 46 static int yuv422_mode = 0, width, height; 47 static TCVHandle tcvhandle = 0; 48 49 /* ------------------------------------------------------------ 50 * 51 * open stream 52 * 53 * ------------------------------------------------------------*/ 54 55 MOD_open 56 { 57 58 char cat_buf[TC_BUF_MAX]; 59 char yuv_buf[16]; 60 long sret; 61 62 if(param->flag == TC_VIDEO) { 63 64 //directory mode? 65 sret = tc_file_check(vob->video_in_file); 66 if (sret < 0) { 67 return(TC_IMPORT_ERROR); 68 } 69 if(sret == 1) { 70 tc_snprintf(cat_buf, TC_BUF_MAX, "tccat"); 71 } else { 72 if(vob->im_v_string) { 73 tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv %s", 74 vob->im_v_string); 75 } else { 76 tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv"); 77 } 78 } 79 80 //yuy2 mode? 81 (vob->dv_yuy2_mode) ? 82 tc_snprintf(yuv_buf, 16, "-y yuv420p -Y") : 83 tc_snprintf(yuv_buf, 16, "-y yuv420p"); 84 85 param->fd = NULL; 86 yuv422_mode = 0; 87 88 switch(vob->im_v_codec) { 89 90 case CODEC_RGB: 91 92 sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, 93 "%s -i \"%s\" -d %d | tcdecode -x dv -y rgb -d %d -Q %d", 94 cat_buf, vob->video_in_file, vob->verbose, vob->verbose, 95 vob->quality); 96 if (sret < 0) 97 return(TC_IMPORT_ERROR); 98 99 // popen 100 if((param->fd = popen(import_cmd_buf, "r"))== NULL) { 101 return(TC_IMPORT_ERROR); 102 } 103 104 break; 105 106 case CODEC_YUV: 107 108 sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, 109 "%s -i \"%s\" -d %d | tcdecode -x dv %s -d %d -Q %d", 110 cat_buf, vob->video_in_file, vob->verbose, yuv_buf, 111 vob->verbose, vob->quality); 112 if (sret < 0) 113 return(TC_IMPORT_ERROR); 114 115 // for reading 116 frame_size = (vob->im_v_width * vob->im_v_height * 3)/2; 117 118 param->fd = NULL; 119 120 // popen 121 if((fd = popen(import_cmd_buf, "r"))== NULL) { 122 return(TC_IMPORT_ERROR); 123 } 124 125 break; 126 127 case CODEC_YUV422: 128 129 sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, 130 "%s -i \"%s\" -d %d |" 131 " tcdecode -x dv -y yuy2 -d %d -Q %d", 132 cat_buf, vob->video_in_file, vob->verbose, 133 vob->verbose, vob->quality); 134 if (sret < 0) 135 return(TC_IMPORT_ERROR); 136 137 // for reading 138 frame_size = vob->im_v_width * vob->im_v_height * 2; 139 140 tmpbuf = tc_malloc(frame_size); 141 if (!tmpbuf) { 142 tc_log_error(MOD_NAME, "out of memory"); 143 return(TC_IMPORT_ERROR); 144 } 145 146 tcvhandle = tcv_init(); 147 if (!tcvhandle) { 148 tc_log_error(MOD_NAME, "tcv_init() failed"); 149 return(TC_IMPORT_ERROR); 150 } 151 152 yuv422_mode = 1; 153 width = vob->im_v_width; 154 height = vob->im_v_height; 155 156 param->fd = NULL; 157 158 // popen 159 if((fd = popen(import_cmd_buf, "r"))== NULL) { 160 return(TC_IMPORT_ERROR); 161 } 162 163 break; 164 165 166 case CODEC_RAW: 167 case CODEC_RAW_YUV: 168 169 sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, "%s -i \"%s\" -d %d", 170 cat_buf, vob->video_in_file, vob->verbose); 171 if (sret < 0) 172 return(TC_IMPORT_ERROR); 173 174 // for reading 175 frame_size = (vob->im_v_height==PAL_H) ? 176 TC_FRAME_DV_PAL : TC_FRAME_DV_NTSC; 177 178 param->fd = NULL; 179 180 // popen 181 if((fd = popen(import_cmd_buf, "r"))== NULL) { 182 return(TC_IMPORT_ERROR); 183 } 184 185 break; 186 187 188 default: 189 tc_log_warn(MOD_NAME, "invalid import codec request 0x%x", 190 vob->im_v_codec); 191 return(TC_IMPORT_ERROR); 192 193 } 194 195 // print out 196 if(verbose_flag) tc_log_info(MOD_NAME, "%s", import_cmd_buf); 197 198 return(TC_IMPORT_OK); 199 } 200 201 if(param->flag == TC_AUDIO) { 202 203 //directory mode? 204 if(tc_file_check(vob->audio_in_file)) { 205 tc_snprintf(cat_buf, TC_BUF_MAX, "tccat"); 206 } else { 207 if(vob->im_a_string) { 208 tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv %s", 209 vob->im_a_string); 210 } else { 211 tc_snprintf(cat_buf, TC_BUF_MAX, "tcextract -x dv"); 212 } 213 } 214 215 sret = tc_snprintf(import_cmd_buf, TC_BUF_MAX, 216 "%s -i \"%s\" -d %d | tcdecode -x dv -y pcm -d %d", 217 cat_buf, vob->audio_in_file, vob->verbose, 218 vob->verbose); 219 if (sret < 0) 220 return(TC_IMPORT_ERROR); 221 222 // print out 223 if(verbose_flag) tc_log_info(MOD_NAME, "%s", import_cmd_buf); 224 225 param->fd = NULL; 226 227 // popen 228 if((param->fd = popen(import_cmd_buf, "r"))== NULL) { 229 tc_log_perror(MOD_NAME, "popen PCM stream"); 230 return(TC_IMPORT_ERROR); 231 } 232 233 return(TC_IMPORT_OK); 234 } 235 236 return(TC_IMPORT_ERROR); 237 238 } 239 240 /* ------------------------------------------------------------ 241 * 242 * decode stream 243 * 244 * ------------------------------------------------------------*/ 245 246 MOD_decode 247 { 248 249 if(param->flag == TC_AUDIO) return(TC_IMPORT_OK); 250 251 // video and YUV only 252 if(param->flag == TC_VIDEO && frame_size==0) return(TC_IMPORT_ERROR); 253 254 // return true yuv frame size as physical size of video data 255 param->size = frame_size; 256 257 if (yuv422_mode) { 258 if (fread(tmpbuf, frame_size, 1, fd) !=1) 259 return(TC_IMPORT_ERROR); 260 tcv_convert(tcvhandle, tmpbuf, param->buffer, width, height, 261 IMG_YUY2, IMG_YUV422P); 262 } else { 263 if (fread(param->buffer, frame_size, 1, fd) !=1) 264 return(TC_IMPORT_ERROR); 265 } 266 267 return(TC_IMPORT_OK); 268 } 269 270 /* ------------------------------------------------------------ 271 * 272 * close stream 273 * 274 * ------------------------------------------------------------*/ 275 276 277 MOD_close 278 { 279 if(param->fd != NULL) pclose(param->fd); 280 281 if(param->flag == TC_AUDIO) return(TC_IMPORT_OK); 282 283 if(param->flag == TC_VIDEO) { 284 285 if(fd) pclose(fd); 286 fd=NULL; 287 288 if (tcvhandle) 289 tcv_free(tcvhandle); 290 tcvhandle=0; 291 292 free(tmpbuf); 293 tmpbuf=NULL; 294 295 return(TC_IMPORT_OK); 296 297 } 298 299 return(TC_IMPORT_ERROR); 300 } 301 302