efl

Форк
0
299 строк · 6.8 Кб
1
#ifdef HAVE_CONFIG_H
2
# include <config.h>
3
#endif
4

5
#include <fcntl.h>
6
#include <unistd.h>
7

8
#include <gst/gst.h>
9

10
#include <Eina.h>
11

12
#include "shmfile.h"
13
#include "timeout.h"
14

15
#define DATA32  unsigned int
16

17
//#define GST_DBG
18

19
#ifdef GST_DBG
20
#define D(fmt, args...) fprintf(stderr, fmt, ## args)
21
#else
22
#define D(fmt, args...)
23
#endif
24

25
#ifdef WORDS_BIGENDIAN
26
# define CAPS "video/x-raw,format=ARGB"
27
#else
28
# define CAPS "video/x-raw,format=BGRA"
29
#endif
30

31
static GstElement *pipeline = NULL;
32
static GstElement *sink = NULL;
33
static gint64      duration = -1;
34

35
int   width = 0;
36
int   height = 0;
37
void *data = NULL;
38

39

40
static Eina_Bool
41
_gst_init(const char *filename)
42
{
43
   GstPad              *pad;
44
   GstCaps             *caps;
45
   GstStructure        *structure;
46
   gchar               *descr;
47
   gchar               *uri;
48
   GError              *error = NULL;
49
   GstFormat            format;
50
   GstStateChangeReturn ret;
51
//   int                  vidstr = 0;
52

53
   if (!filename || !*filename)
54
     return EINA_FALSE;
55

56
   if (!gst_init_check(NULL, NULL, &error))
57
     return EINA_FALSE;
58

59
   if ((*filename == '/') || (*filename == '~'))
60
     {
61
        uri = g_filename_to_uri(filename, NULL, NULL);
62
        if (!uri)
63
          {
64
             D("could not create new uri from %s", filename);
65
             goto unref_pipeline;
66
          }
67
     }
68
   else
69
     uri = strdup(filename);
70

71
   D("Setting file %s\n", uri);
72

73
   descr = g_strdup_printf("uridecodebin uri=%s ! typefind ! videoconvert ! "
74
      " appsink name=sink caps=\"" CAPS "\"", uri);
75
   pipeline = gst_parse_launch(descr, &error);
76
   free(uri);
77

78
   if (error != NULL)
79
     {
80
        D("could not construct pipeline: %s\n", error->message);
81
        g_error_free (error);
82
        goto gst_shutdown;
83
     }
84
/* needs gst 1.0+
85
 * also only works on playbin objects!!! this is a uridecodebin!
86
   g_object_get(G_OBJECT(pipeline),
87
                "n-video", &vidstr,
88
                NULL);
89
   if (vidstr <= 0)
90
     {
91
        D("no video stream\n");
92
        goto gst_shutdown;
93
     }
94
*/
95
   sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
96

97
   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
98
   switch (ret)
99
     {
100
     case GST_STATE_CHANGE_FAILURE:
101
        D("failed to play the file\n");
102
        goto unref_pipeline;
103
     case GST_STATE_CHANGE_NO_PREROLL:
104
        D("live sources not supported yet\n");
105
        goto unref_pipeline;
106
     default:
107
        break;
108
     }
109

110
   ret = gst_element_get_state((pipeline), NULL, NULL, GST_CLOCK_TIME_NONE);
111
   if (ret == GST_STATE_CHANGE_FAILURE)
112
     {
113
        D("could not complete pause\n");
114
        goto unref_pipeline;
115
     }
116

117
   format = GST_FORMAT_TIME;
118
   gst_element_query_duration (pipeline, format, &duration);
119
   if (duration == -1)
120
     {
121
        fprintf(stderr, "duration fetch err\n");
122
        D("could not retrieve the duration, set it to 1s\n");
123
        duration = 1 * GST_SECOND;
124
     }
125

126
   pad = gst_element_get_static_pad(sink, "sink");
127
   if (!pad)
128
     {
129
        D("could not retrieve the sink pad\n");
130
        goto unref_pipeline;
131
     }
132

133
   caps = gst_pad_get_current_caps(pad);
134
   if (!caps)
135
     goto unref_pad;
136

137
   structure = gst_caps_get_structure(caps, 0);
138

139
   if (!gst_structure_get_int(structure, "width", &width))
140
     goto unref_caps;
141
   if (!gst_structure_get_int(structure, "height", &height))
142
     goto unref_caps;
143

144
   gst_caps_unref(caps);
145
   gst_object_unref(pad);
146

147
   return EINA_TRUE;
148

149
 unref_caps:
150
   gst_caps_unref(caps);
151
 unref_pad:
152
   gst_object_unref(pad);
153
 unref_pipeline:
154
   gst_element_set_state (pipeline, GST_STATE_NULL);
155
   gst_object_unref(pipeline);
156
 gst_shutdown:
157
   gst_deinit();
158

159
   return EINA_FALSE;
160
}
161

162
static void
163
_gst_shutdown()
164
{
165
   gst_element_set_state (pipeline, GST_STATE_NULL);
166
   gst_object_unref(pipeline);
167
   gst_deinit();
168
}
169

170
static void
171
_gst_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED, double pos)
172
{
173
   GstBuffer *buffer;
174
   GstMapInfo info;
175
   GstSample *sample;
176

177
   D("load image\n");
178
   if (pos >= 0.0)
179
     gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
180
                             pos);
181
   else
182
     gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
183
                             duration / 2);
184
   g_signal_emit_by_name(sink, "pull-preroll", &sample, NULL);
185

186
   shm_alloc(width * height * sizeof(DATA32));
187
   if (!shm_addr) return;
188
   data = shm_addr;
189

190
   buffer = gst_sample_get_buffer (sample);
191
   gst_buffer_map (buffer, &info, GST_MAP_READ);
192
   D("load image: %p %d\n", info.data, info.size);
193

194
   memcpy(data, info.data, info.size);
195

196
   gst_buffer_unmap(buffer, &info);
197
}
198

199
int
200
main(int argc, char **argv)
201
{
202
   char *file, *p;
203
   int i, numonly;
204
   int size_w = 0, size_h = 0;
205
   int head_only = 0;
206
   long long pos = -1.0;
207

208
   if (argc < 2) return -1;
209
   // file is ALWAYS first arg, other options come after
210
   file = argv[1];
211
   for (i = 2; i < argc; i++)
212
     {
213
        if      (!strcmp(argv[i], "-head"))
214
           // asked to only load header, not body/data
215
           head_only = 1;
216
        else if (!strcmp(argv[i], "-key"))
217
          {
218
             i++;
219
             numonly = 1;
220
             for (p = argv[i]; *p; p++)
221
               {
222
                  if ((*p < '0') || (*p > '9'))
223
                    {
224
                       numonly = 0;
225
                       break;
226
                    }
227
               }
228
             if (numonly) pos = atoll(argv[i]) * 1000000;
229
             i++;
230
          }
231
        else if (!strcmp(argv[i], "-opt-scale-down-by"))
232
          { // not used by ps loader
233
             i++;
234
             // int scale_down = atoi(argv[i]);
235
          }
236
        else if (!strcmp(argv[i], "-opt-dpi"))
237
          {
238
             i++;
239
          }
240
        else if (!strcmp(argv[i], "-opt-size"))
241
          { // not used by ps loader
242
             i++;
243
             size_w = atoi(argv[i]);
244
             i++;
245
             size_h = atoi(argv[i]);
246
          }
247
     }
248

249
   timeout_init(10);
250

251
   D("_gst_init_file\n");
252

253
   if (!_gst_init(file))
254
     return -1;
255
   D("_gst_init done\n");
256

257
   if ((pos >= 0) && (pos > duration)) return -1;
258

259
   if (!head_only)
260
     {
261
        _gst_load_image(size_w, size_h, pos);
262
     }
263

264
   D("size...: %ix%i\n", width, height);
265
   D("alpha..: 0\n");
266

267
   printf("size %i %i\n", width, height);
268
   printf("alpha 0\n");
269

270
   if (!head_only)
271
     {
272
#ifdef _WIN32
273
        if (shm_fd)
274
#else
275
        if (shm_fd >= 0)
276
#endif
277
          {
278
             printf("shmfile %s\n", shmfile);
279
          }
280
        else
281
          {
282
             // could also to "tmpfile %s\n" like shmfile but just
283
             // a mmaped tmp file on the system
284
             printf("data\n");
285
             if (fwrite(data, width * height * sizeof(DATA32), 1, stdout) != 1)
286
               {
287
                  shm_free();
288
                  return -1;
289
               }
290
          }
291
        shm_free();
292
     }
293
   else
294
     printf("done\n");
295

296
   _gst_shutdown();
297
   fflush(stdout);
298
   return 0;
299
}
300

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.