Noise and mirrors
[melted] / src / modules / fezzik / producer_fezzik.c
1 /*
2 * producer_fezzik.c -- a normalising filter
3 * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include "producer_fezzik.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <framework/mlt.h>
28
29 static void track_service( mlt_tractor tractor, void *service, mlt_destructor destructor )
30 {
31 mlt_properties properties = mlt_tractor_properties( tractor );
32 int registered = mlt_properties_get_int( properties, "_registered" );
33 char *key = mlt_properties_get( properties, "_registered" );
34 char *real = malloc( strlen( key ) + 2 );
35 sprintf( real, "_%s", key );
36 mlt_properties_set_data( properties, real, service, 0, destructor, NULL );
37 mlt_properties_set_int( properties, "_registered", ++ registered );
38 free( real );
39 }
40
41 static mlt_producer create_producer( char *file )
42 {
43 mlt_producer result = NULL;
44
45 // 0th Line - check for service:resource handling
46 if ( strchr( file, ':' ) )
47 {
48 char *temp = strdup( file );
49 char *service = temp;
50 char *resource = strchr( temp, ':' );
51 *resource ++ = '\0';
52 result = mlt_factory_producer( service, resource );
53 free( temp );
54 }
55
56 // 1st Line preferences
57 if ( result == NULL )
58 {
59 if ( strstr( file, ".inigo" ) )
60 result = mlt_factory_producer( "inigo_file", file );
61 else if ( strstr( file, ".mpg" ) )
62 result = mlt_factory_producer( "mcmpeg", file );
63 else if ( strstr( file, ".mpeg" ) )
64 result = mlt_factory_producer( "mcmpeg", file );
65 else if ( strstr( file, ".dv" ) )
66 result = mlt_factory_producer( "mcdv", file );
67 else if ( strstr( file, ".dif" ) )
68 result = mlt_factory_producer( "mcdv", file );
69 else if ( strstr( file, ".jpg" ) )
70 result = mlt_factory_producer( "pixbuf", file );
71 else if ( strstr( file, ".JPG" ) )
72 result = mlt_factory_producer( "pixbuf", file );
73 else if ( strstr( file, ".jpeg" ) )
74 result = mlt_factory_producer( "pixbuf", file );
75 else if ( strstr( file, ".png" ) )
76 result = mlt_factory_producer( "pixbuf", file );
77 else if ( strstr( file, ".svg" ) )
78 result = mlt_factory_producer( "pixbuf", file );
79 else if ( strstr( file, ".txt" ) )
80 result = mlt_factory_producer( "pango", file );
81 else if ( strstr( file, ".westley" ) )
82 result = mlt_factory_producer( "westley", file );
83 else if ( strstr( file, ".ogg" ) )
84 result = mlt_factory_producer( "vorbis", file );
85 }
86
87 // 2nd Line fallbacks
88 if ( result == NULL )
89 {
90 if ( strstr( file, ".dv" ) )
91 result = mlt_factory_producer( "libdv", file );
92 else if ( strstr( file, ".dif" ) )
93 result = mlt_factory_producer( "libdv", file );
94 }
95
96 // 3rd line fallbacks
97 if ( result == NULL )
98 result = mlt_factory_producer( "avformat", file );
99
100 return result;
101 }
102
103 static mlt_service create_filter( mlt_tractor tractor, mlt_service last, char *effect )
104 {
105 char *id = strdup( effect );
106 char *arg = strchr( id, ':' );
107 if ( arg != NULL )
108 *arg ++ = '\0';
109 mlt_filter filter = mlt_factory_filter( id, arg );
110 if ( filter != NULL )
111 {
112 mlt_filter_connect( filter, last, 0 );
113 track_service( tractor, filter, ( mlt_destructor )mlt_filter_close );
114 last = mlt_filter_service( filter );
115 }
116 free( id );
117 return last;
118 }
119
120 mlt_producer producer_fezzik_init( char *arg )
121 {
122 // Create the producer that the tractor will contain
123 mlt_producer producer = NULL;
124 if ( arg != NULL )
125 producer = create_producer( arg );
126
127 // Build the tractor if we have a producer and it isn't already westley'd :-)
128 if ( producer != NULL && mlt_properties_get( mlt_producer_properties( producer ), "westley" ) == NULL )
129 {
130 // Construct the tractor
131 mlt_tractor tractor = mlt_tractor_init( );
132
133 // Sanity check
134 if ( tractor != NULL )
135 {
136 // Extract the tractor properties
137 mlt_properties properties = mlt_tractor_properties( tractor );
138
139 // Our producer will be the last service
140 mlt_service last = mlt_producer_service( producer );
141
142 // Set the registered count
143 mlt_properties_set_int( properties, "_registered", 0 );
144
145 // Register our producer for seeking in the tractor
146 mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
147
148 // Now attach normalising filters
149 last = create_filter( tractor, last, "deinterlace" );
150 last = create_filter( tractor, last, "rescale" );
151 last = create_filter( tractor, last, "resize" );
152 last = create_filter( tractor, last, "resample" );
153
154 // Connect the tractor to the last
155 mlt_tractor_connect( tractor, last );
156
157 // Finally, inherit properties from producer
158 mlt_properties_inherit( properties, mlt_producer_properties( producer ) );
159
160 // Now make sure we don't lose our inherited identity
161 mlt_properties_set_int( properties, "_mlt_service_hidden", 1 );
162
163 // This is a temporary hack to ensure that westley doesn't dig too deep
164 // and fezzik doesn't overdo it with throwing rocks...
165 mlt_properties_set( properties, "westley", "was here" );
166
167 // We need to ensure that all further properties are mirrored in the producer
168 mlt_properties_mirror( properties, mlt_producer_properties( producer ) );
169
170 // Now, we return the producer of the tractor
171 producer = mlt_tractor_producer( tractor );
172 }
173 }
174
175 // Return the tractor's producer
176 return producer;
177 }