1 /*
2  *  export_ogg.c
3  *
4  *  Copyright (C) Tilmann Bitterberg, July 2002
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    "export_ogg.so"
25 #define MOD_VERSION "v0.0.5 (2003-08-31)"
26 #define MOD_CODEC   "(video) null | (audio) ogg"
27 
28 #include "transcode.h"
29 
30 #include <stdio.h>
31 #include <unistd.h>
32 
33 static int   verbose_flag=TC_QUIET;
34 static int   capability_flag=TC_CAP_PCM;
35 
36 #define MOD_PRE ogg
37 #include "export_def.h"
38 static FILE *pFile = NULL;
39 
p_write(char * buf,size_t len)40 static inline int p_write (char *buf, size_t len)
41 {
42     size_t n  = 0;
43     size_t r  = 0;
44     int    fd = fileno (pFile);
45 
46     while (r < len)
47     {
48         if ((n = write (fd, buf + r, len - r)) < 0)
49 	    return n;
50 
51         r += n;
52     }
53 
54     return r;
55 }
56 
57 /* ------------------------------------------------------------
58  *
59  * open codec
60  *
61  * ------------------------------------------------------------*/
62 
63 MOD_open
64 {
65     int result;
66     int ifreq,ofreq;
67 
68     /* check for oggenc */
69     if (tc_test_program("oggenc") != 0) return (TC_EXPORT_ERROR);
70 
71     ofreq = vob->mp3frequency;
72     ifreq = vob->a_rate;
73 
74     /* default out freq */
75     if(ofreq==0)
76         ofreq = ifreq;
77 
78     if (param->flag == TC_AUDIO) {
79 	char buf [PATH_MAX];
80 	char resample [PATH_MAX];
81 
82 	if (ofreq != ifreq) {
83 	    result = tc_snprintf(resample, PATH_MAX, "--resample %d -R %d", vob->mp3frequency, vob->a_rate);
84 	} else {
85 	    result = tc_snprintf(resample, PATH_MAX, "-R %d", vob->a_rate);
86         }
87 	if (result < 0) {
88 	    tc_log_perror(MOD_NAME, "command buffer overflow");
89 	    return(TC_EXPORT_ERROR);
90 	}
91 
92 	if (!strcmp(vob->video_out_file, vob->audio_out_file)) {
93 	    tc_log_info(MOD_NAME, "Writing audio to \"/dev/null\" (no -m option)");
94 	}
95 	if (vob->mp3bitrate == 0)
96 	    result = tc_snprintf (buf, PATH_MAX, "oggenc -r -B %d -C %d -q %.2f %s -Q -o \"%s\" %s -",
97 		vob->dm_bits,
98 		vob->dm_chan,
99 		vob->mp3quality,
100 		resample,
101 		vob->audio_out_file?vob->audio_out_file:"/dev/null",
102 		(vob->ex_a_string?vob->ex_a_string:""));
103 	else
104 	    result = tc_snprintf (buf, PATH_MAX, "oggenc -r -B %d -C %d -b %d %s -Q -o \"%s\" %s -",
105 		vob->dm_bits,
106 		vob->dm_chan,
107 		vob->mp3bitrate,
108 		resample,
109 		vob->audio_out_file?vob->audio_out_file:"/dev/null",
110 		(vob->ex_a_string?vob->ex_a_string:""));
111 	if (result < 0) {
112 	    tc_log_perror(MOD_NAME, "command buffer overflow");
113 	    return(TC_EXPORT_ERROR);
114 	}
115 	if ((pFile = popen (buf, "w")) == NULL)
116 	    return(TC_EXPORT_ERROR);
117 
118 	if (verbose > 0)
119 	    tc_log_info (MOD_NAME, "%s", buf);
120 
121 	return(0);
122 
123     }
124     if (param->flag == TC_VIDEO)
125 	return(0);
126 
127     // invalid flag
128     return(TC_EXPORT_ERROR);
129 }
130 
131 /* ------------------------------------------------------------
132  *
133  * init codec
134  *
135  * ------------------------------------------------------------*/
136 
137 MOD_init
138 {
139     if(param->flag == TC_AUDIO)
140     {
141         return(0);
142     }
143 
144     if (param->flag == TC_VIDEO)
145 	return(0);
146 
147     // invalid flag
148     return(TC_EXPORT_ERROR);
149 }
150 
151 
152 /* ------------------------------------------------------------
153  *
154  * encode and export
155  *
156  * ------------------------------------------------------------*/
157 
158 MOD_encode
159 {
160     if(param->flag == TC_AUDIO)
161     {
162         if (p_write (param->buffer, param->size) != param->size)
163         {
164             tc_log_perror(MOD_NAME, "write audio frame");
165             return(TC_EXPORT_ERROR);
166         }
167         return (0);
168     }
169 
170     if (param->flag == TC_VIDEO)
171         return(0);
172 
173     // invalid flag
174     return(TC_EXPORT_ERROR);
175 }
176 
177 
178 /* ------------------------------------------------------------
179  *
180  * stop codec
181  *
182  * ------------------------------------------------------------*/
183 
184 MOD_stop
185 {
186     if (param->flag == TC_VIDEO)
187         return (0);
188 
189     if (param->flag == TC_AUDIO)
190 	return (0);
191 
192     return(TC_EXPORT_ERROR);
193 }
194 
195 
196 /* ------------------------------------------------------------
197  *
198  * close codec
199  *
200  * ------------------------------------------------------------*/
201 
202 MOD_close
203 {
204     vob_t *vob = tc_get_vob();
205 
206     if (param->flag == TC_VIDEO)
207 	return (0);
208 
209     if (param->flag == TC_AUDIO)
210     {
211         if (pFile)
212 	  pclose (pFile);
213 
214 	pFile = NULL;
215 
216 	if (verbose > 0 && strcmp (vob->audio_out_file, "/dev/null") &&
217 		strcmp (vob->video_out_file, "/dev/null")!=0) {
218 	    tc_log_info (MOD_NAME, "Hint: Now merge the files with");
219 	    tc_log_info (MOD_NAME, "Hint: ogmmerge -o complete.ogg %s %s",
220 			 vob->video_out_file, vob->audio_out_file );
221 	}
222 
223         return(0);
224     }
225 
226     return (TC_EXPORT_ERROR);
227 }
228 
229 /* vim: sw=4
230  */
231