1 /* 2 * export_mp2enc.c 3 * 4 * Georg Ludwig - January 2002 5 * 6 * Parts of export_wav and export_mpeg2enc used for this file 7 * 8 * This file is part of transcode, a video stream processing tool 9 * 10 * transcode is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * transcode is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with GNU Make; see the file COPYING. If not, write to 22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26 #define MOD_NAME "export_mp2enc.so" 27 #define MOD_VERSION "v1.0.11 (2006-03-16)" 28 #define MOD_CODEC "(audio) MPEG 1/2" 29 30 #include "transcode.h" 31 #include "avilib/wavlib.h" 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <sys/stat.h> 36 #include <unistd.h> 37 #include <fcntl.h> 38 39 #define CLAMP(x,l,h) x > h ? h : x < l ? l : x 40 41 static int verbose_flag = TC_QUIET; 42 static int capability_flag = TC_CAP_PCM; 43 44 #define MOD_PRE mp2enc 45 #include "export_def.h" 46 47 static FILE* pFile = NULL; 48 static WAV wav = NULL; 49 50 /* ------------------------------------------------------------ 51 * 52 * open outputfile 53 * 54 * ------------------------------------------------------------*/ 55 56 MOD_open 57 { 58 int verb; 59 60 /* check for mp2enc */ 61 if (tc_test_program("mp2enc") != 0) return (TC_EXPORT_ERROR); 62 63 if (param->flag == TC_AUDIO) 64 { 65 char buf [PATH_MAX]; 66 char mono[] = "-m"; 67 char stereo[] = "-s"; 68 int srate, brate; 69 char *chan; 70 int def_srate, def_brate; 71 char *def_chan; 72 73 verb = (verbose & TC_DEBUG) ? 2:0; 74 75 srate = (vob->mp3frequency != 0) ? vob->mp3frequency : vob->a_rate; 76 brate = vob->mp3bitrate; 77 chan = (vob->dm_chan>=2) ? stereo : mono; 78 79 def_srate = srate; 80 def_brate = brate; 81 def_chan = chan; 82 83 // default profile values, authority: videohelp and dvdfaq 84 switch(vob->mpeg_profile) { 85 case VCD_PAL: case VCD_NTSC: case VCD: 86 def_srate = 44100; 87 def_brate = 224; 88 def_chan = stereo; 89 break; 90 case SVCD_PAL: case SVCD_NTSC: case SVCD: 91 def_srate = 44100; 92 def_brate = CLAMP (brate, 64, 384); 93 def_chan = stereo; 94 break; 95 case XVCD_PAL: case XVCD_NTSC: case XVCD: 96 // check for invalid sample rate 97 if ((srate != 32000) && (srate != 44100) && (srate != 48000)) 98 def_srate = 44100; 99 // don't change if valid rate 100 def_brate = CLAMP (brate, 64, 384); 101 def_chan = stereo; 102 break; 103 case DVD_PAL: case DVD_NTSC: case DVD: 104 def_srate = 48000; 105 def_brate = CLAMP (brate, 64, 384); 106 def_chan = stereo; 107 case PROF_NONE: 108 break; 109 } 110 111 // encoding values, let commandline override profile 112 if(!(vob->export_attributes & TC_EXPORT_ATTRIBUTE_ARATE)) 113 if (srate != def_srate) { 114 tc_log_info(MOD_NAME, "export profile changed samplerate:" 115 " %d -> %d Hz.", srate, def_srate); 116 srate = def_srate; 117 } 118 if(!(vob->export_attributes & TC_EXPORT_ATTRIBUTE_ABITRATE)) 119 if (brate != def_brate) { 120 tc_log_info(MOD_NAME, "export profile changed bitrate: " 121 "%d -> %d kbps.", brate, def_brate); 122 brate = def_brate; 123 } 124 if(!(vob->export_attributes & TC_EXPORT_ATTRIBUTE_ACHANS)) 125 if (chan != def_chan) { 126 tc_log_info(MOD_NAME, "export profile changed channels: " 127 "mono -> stereo."); 128 chan = def_chan; 129 } 130 131 if(tc_snprintf(buf, PATH_MAX, "mp2enc -v %d -r %d -b %d %s -o \"%s\" %s", verb, srate, brate, chan, vob->audio_out_file, (vob->ex_a_string?vob->ex_a_string:"")) < 0) { 132 tc_log_perror(MOD_NAME, "cmd buffer overflow"); 133 return(TC_EXPORT_ERROR); 134 } 135 136 if(verbose & TC_INFO) tc_log_info(MOD_NAME, "(%d/%d) cmd=%s", 137 (int)strlen(buf), PATH_MAX, buf); 138 139 if((pFile = popen (buf, "w")) == NULL) 140 return(TC_EXPORT_ERROR); 141 142 wav = wav_fdopen(fileno(pFile), WAV_WRITE|WAV_PIPE, NULL); 143 if (wav == NULL) { 144 tc_log_perror(MOD_NAME, "open wave stream"); 145 return TC_EXPORT_ERROR; 146 } 147 148 wav_set_rate(wav, vob->a_rate); 149 wav_set_bitrate(wav, vob->dm_chan*vob->a_rate*vob->dm_bits/8); 150 wav_set_channels(wav, vob->dm_chan); 151 wav_set_bits(wav, vob->dm_bits); 152 153 return(0); 154 } 155 156 if (param->flag == TC_VIDEO) 157 return(0); 158 159 // invalid flag 160 return(TC_EXPORT_ERROR); 161 } 162 163 164 /* ------------------------------------------------------------ 165 * 166 * init codec 167 * 168 * ------------------------------------------------------------*/ 169 170 MOD_init 171 { 172 if(param->flag == TC_AUDIO) 173 { 174 return(0); 175 } 176 177 if (param->flag == TC_VIDEO) 178 return(0); 179 180 // invalid flag 181 return(TC_EXPORT_ERROR); 182 } 183 184 /* ------------------------------------------------------------ 185 * 186 * encode and export frame 187 * 188 * ------------------------------------------------------------*/ 189 190 191 MOD_encode 192 { 193 if(param->flag == TC_AUDIO) 194 { 195 if (wav_write_data(wav, param->buffer, param->size) != param->size) 196 { 197 tc_log_perror(MOD_NAME, "write audio frame"); 198 return(TC_EXPORT_ERROR); 199 } 200 return (0); 201 } 202 203 if (param->flag == TC_VIDEO) 204 return(0); 205 206 // invalid flag 207 return(TC_EXPORT_ERROR); 208 } 209 210 /* ------------------------------------------------------------ 211 * 212 * stop encoder 213 * 214 * ------------------------------------------------------------*/ 215 216 MOD_stop 217 { 218 if (param->flag == TC_VIDEO) 219 return (0); 220 221 if (param->flag == TC_AUDIO) 222 return (0); 223 224 return(TC_EXPORT_ERROR); 225 } 226 227 /* ------------------------------------------------------------ 228 * 229 * close codec 230 * 231 * ------------------------------------------------------------*/ 232 233 MOD_close 234 { 235 if (param->flag == TC_VIDEO) 236 return (0); 237 238 if (param->flag == TC_AUDIO) 239 { 240 if (wav != NULL) { 241 wav_close(wav); 242 wav = NULL; 243 } 244 if (pFile != NULL) { 245 pclose (pFile); 246 pFile = NULL; 247 } 248 249 return(0); 250 } 251 252 return (TC_EXPORT_ERROR); 253 } 254 255