140 141 #ifdef GSTREAMER_LITE 142 #define LIBGSTREAMER_LIB_NAME "gstreamer-lite" 143 #endif // GSTREAMER_LITE 144 145 146 #ifdef G_OS_WIN32 147 #include <windows.h> 148 extern HMODULE _priv_gst_dll_handle; 149 #endif 150 151 #if defined(GSTREAMER_LITE) && defined(HAVE_OSX) 152 #include <mach-o/dyld.h> 153 #include <mach-o/ldsyms.h> //defines _mh_dylib_header see man page for ld 154 #endif // GSTREAMER_LITE 155 156 #if defined (GSTREAMER_LITE) && defined(LINUX) 157 #include <link.h> 158 #include <dlfcn.h> 159 160 static const int AVCODEC_EXPLICIT_VERSIONS[] = { 53, 54, 55, 56 }; 161 static const int AVCODEC_FFMPEG_EXPLICIT_VERSIONS[] = { 56 }; 162 163 typedef unsigned (*avcodec_version_proto)(); 164 165 /* 166 * Callback passed to dl_iterate_phdr(): finds the path of 167 * LIBGSTREAMER_LIB_NAME and returns it in data which is actually 168 * a char**. 169 */ 170 static int dl_callback (struct dl_phdr_info *info, size_t size, void *data) 171 { 172 int result = 0; 173 174 if (NULL != info) 175 { 176 if (NULL != strstr (info->dlpi_name, LIBGSTREAMER_LIB_NAME)) 177 { 178 if (NULL != data) 179 { 180 char** name = (char**)data; 181 *name = (char*)info->dlpi_name; 182 } 183 1351 } 1352 if (!(file_status.st_mode & S_IFREG)) { 1353 GST_TRACE_OBJECT (context->registry, "%s is not a regular file, ignoring", 1354 filename); 1355 g_free (filename); 1356 continue; 1357 } 1358 if (!g_str_has_suffix (dirent, G_MODULE_SUFFIX) 1359 #ifdef GST_EXTRA_MODULE_SUFFIX 1360 && !g_str_has_suffix (dirent, GST_EXTRA_MODULE_SUFFIX) 1361 #endif 1362 ) { 1363 GST_TRACE_OBJECT (context->registry, 1364 "extension is not recognized as module file, ignoring file %s", 1365 filename); 1366 g_free (filename); 1367 continue; 1368 } 1369 #else // GSTREAMER_LITE 1370 1371 for (gstlite_plugins_list_index = 0; gstlite_plugins_list[gstlite_plugins_list_index] != NULL; gstlite_plugins_list_index++) 1372 { 1373 filename_partial = g_build_filename (path, gstlite_plugins_list[gstlite_plugins_list_index], NULL); 1374 #ifdef LINUX 1375 if (g_str_has_suffix(filename_partial, "libavplugin")) // Check libav version and load correspondent module. 1376 { 1377 int vi = (sizeof(AVCODEC_EXPLICIT_VERSIONS)/sizeof(AVCODEC_EXPLICIT_VERSIONS[0])); 1378 1379 while(!avcHandle && --vi >= 0) 1380 { 1381 int version = AVCODEC_EXPLICIT_VERSIONS[vi]; 1382 gchar* libname = g_strdup_printf("libavcodec.so.%d", version); 1383 avcHandle = dlopen(libname, RTLD_NOW); 1384 g_free(libname); 1385 } 1386 1387 // Look for libavcodec-ffmpeg if libavcodec is not available 1388 if (avcHandle == NULL) 1389 { 1390 vi = (sizeof(AVCODEC_FFMPEG_EXPLICIT_VERSIONS)/sizeof(AVCODEC_FFMPEG_EXPLICIT_VERSIONS[0])); 1391 while(!avcHandle && --vi >= 0) 1392 { 1393 int version = AVCODEC_FFMPEG_EXPLICIT_VERSIONS[vi]; 1394 gchar* libname = g_strdup_printf("libavcodec-ffmpeg.so.%d", version); 1395 avcHandle = dlopen(libname, RTLD_NOW); 1396 g_free(libname); 1397 } 1398 1399 if (avcHandle) 1400 isAVCFFMPEG = TRUE; 1401 } 1402 1403 if (avcHandle) 1404 { 1405 dlclose(avcHandle); 1406 avcHandle = NULL; 1407 1408 // Try simple name first. OpenJDK build may contain the latest bits. 1409 filename = g_strdup_printf("%s%s", filename_partial, GST_EXTRA_MODULE_SUFFIX); 1410 if (g_stat (filename, &file_status) < 0) // Not available, create a versioned filename 1411 { 1412 g_free(filename); 1413 if (isAVCFFMPEG) 1414 filename = g_strdup_printf("%s-ffmpeg-%d%s", filename_partial, AVCODEC_FFMPEG_EXPLICIT_VERSIONS[vi], GST_EXTRA_MODULE_SUFFIX); 1415 else 1416 filename = g_strdup_printf("%s-%d%s", filename_partial, AVCODEC_EXPLICIT_VERSIONS[vi], GST_EXTRA_MODULE_SUFFIX); 1417 } 1418 } 1419 else 1420 { 1421 g_free(filename_partial); 1422 continue; // No libavcodec.so installed. 1423 } 1424 } 1425 else 1426 filename = g_strconcat(filename_partial, GST_EXTRA_MODULE_SUFFIX, NULL); 1427 #else 1428 filename = g_strconcat(filename_partial, GST_EXTRA_MODULE_SUFFIX, NULL); 1429 #endif 1430 g_free(filename_partial); 1431 1432 if (g_stat (filename, &file_status) < 0) { 1433 /* Plugin will be removed from cache after the scan completes if it 1434 * is still marked 'cached' */ 1435 g_free (filename); 1436 continue; 1437 } 1438 #endif // GSTREAMER_LITE 1439 1440 GST_LOG_OBJECT (context->registry, "file %s looks like a possible module", 1441 filename); 1442 1443 #ifndef GSTREAMER_LITE 1444 /* try to avoid unnecessary plugin-move pain */ 1445 if (g_str_has_prefix (dirent, "libgstvalve") || 1446 g_str_has_prefix (dirent, "libgstselector")) { | 140 141 #ifdef GSTREAMER_LITE 142 #define LIBGSTREAMER_LIB_NAME "gstreamer-lite" 143 #endif // GSTREAMER_LITE 144 145 146 #ifdef G_OS_WIN32 147 #include <windows.h> 148 extern HMODULE _priv_gst_dll_handle; 149 #endif 150 151 #if defined(GSTREAMER_LITE) && defined(HAVE_OSX) 152 #include <mach-o/dyld.h> 153 #include <mach-o/ldsyms.h> //defines _mh_dylib_header see man page for ld 154 #endif // GSTREAMER_LITE 155 156 #if defined (GSTREAMER_LITE) && defined(LINUX) 157 #include <link.h> 158 #include <dlfcn.h> 159 160 // For libav (libavcodec.so) 161 static const int AVCODEC_LIBAV_EXPLICIT_VERSIONS[] = { 53, 54, 55, 56 }; 162 // For ffmpeg (libavcodec-ffmpeg.so) 163 static const int AVCODEC_FFMPEG_EXPLICIT_VERSIONS[] = { 56 }; 164 // For libav or ffmpeg (libavcodec.so) 165 static const int AVCODEC_EXPLICIT_VERSIONS[] = { 57 }; 166 167 /* 168 * Callback passed to dl_iterate_phdr(): finds the path of 169 * LIBGSTREAMER_LIB_NAME and returns it in data which is actually 170 * a char**. 171 */ 172 static int dl_callback (struct dl_phdr_info *info, size_t size, void *data) 173 { 174 int result = 0; 175 176 if (NULL != info) 177 { 178 if (NULL != strstr (info->dlpi_name, LIBGSTREAMER_LIB_NAME)) 179 { 180 if (NULL != data) 181 { 182 char** name = (char**)data; 183 *name = (char*)info->dlpi_name; 184 } 185 1353 } 1354 if (!(file_status.st_mode & S_IFREG)) { 1355 GST_TRACE_OBJECT (context->registry, "%s is not a regular file, ignoring", 1356 filename); 1357 g_free (filename); 1358 continue; 1359 } 1360 if (!g_str_has_suffix (dirent, G_MODULE_SUFFIX) 1361 #ifdef GST_EXTRA_MODULE_SUFFIX 1362 && !g_str_has_suffix (dirent, GST_EXTRA_MODULE_SUFFIX) 1363 #endif 1364 ) { 1365 GST_TRACE_OBJECT (context->registry, 1366 "extension is not recognized as module file, ignoring file %s", 1367 filename); 1368 g_free (filename); 1369 continue; 1370 } 1371 #else // GSTREAMER_LITE 1372 1373 for (gstlite_plugins_list_index = 0; gstlite_plugins_list[gstlite_plugins_list_index] != NULL; gstlite_plugins_list_index++) { 1374 filename_partial = g_build_filename (path, gstlite_plugins_list[gstlite_plugins_list_index], NULL); 1375 #ifdef LINUX 1376 if (g_str_has_suffix(filename_partial, "libavplugin")) { // Check libav version and load correspondent module. 1377 int plugin_version = 0; 1378 // Look for libavcodec and check its version to figure out if it is 1379 // libav or ffmpeg. Starting from 57 and up 1380 int vi = (sizeof(AVCODEC_EXPLICIT_VERSIONS)/sizeof(AVCODEC_EXPLICIT_VERSIONS[0])); 1381 while(!avcHandle && --vi >= 0) { 1382 int version = AVCODEC_EXPLICIT_VERSIONS[vi]; 1383 gchar* libname = g_strdup_printf("libavcodec.so.%d", version); 1384 avcHandle = dlopen(libname, RTLD_NOW); 1385 g_free(libname); 1386 } 1387 1388 // Check if it is libav or ffmpeg 1389 if (avcHandle) { 1390 unsigned int (*av_version)(void); 1391 av_version = dlsym(avcHandle, "avcodec_version"); 1392 if (av_version != NULL) { 1393 unsigned int version = (*av_version)(); 1394 unsigned int micro = version & 0xFF; 1395 if (micro >= 100) 1396 isAVCFFMPEG = TRUE; 1397 plugin_version = AVCODEC_EXPLICIT_VERSIONS[vi]; 1398 } else { // Something wrong 1399 dlclose(avcHandle); 1400 avcHandle = NULL; 1401 } 1402 } 1403 1404 // Look for libavcodec-ffmpeg. For 56 only 1405 if (avcHandle == NULL) { 1406 vi = (sizeof(AVCODEC_FFMPEG_EXPLICIT_VERSIONS)/sizeof(AVCODEC_FFMPEG_EXPLICIT_VERSIONS[0])); 1407 while(!avcHandle && --vi >= 0) { 1408 int version = AVCODEC_FFMPEG_EXPLICIT_VERSIONS[vi]; 1409 gchar* libname = g_strdup_printf("libavcodec-ffmpeg.so.%d", version); 1410 avcHandle = dlopen(libname, RTLD_NOW); 1411 g_free(libname); 1412 } 1413 1414 if (avcHandle) { 1415 plugin_version = AVCODEC_FFMPEG_EXPLICIT_VERSIONS[vi]; 1416 isAVCFFMPEG = TRUE; 1417 } 1418 } 1419 1420 // Looks for libav 56 and below 1421 if (avcHandle == NULL) { 1422 vi = (sizeof(AVCODEC_LIBAV_EXPLICIT_VERSIONS)/sizeof(AVCODEC_LIBAV_EXPLICIT_VERSIONS[0])); 1423 while(!avcHandle && --vi >= 0) { 1424 int version = AVCODEC_LIBAV_EXPLICIT_VERSIONS[vi]; 1425 gchar* libname = g_strdup_printf("libavcodec.so.%d", version); 1426 avcHandle = dlopen(libname, RTLD_NOW); 1427 g_free(libname); 1428 } 1429 1430 if (avcHandle) { 1431 plugin_version = AVCODEC_LIBAV_EXPLICIT_VERSIONS[vi]; 1432 } 1433 } 1434 1435 if (avcHandle) { 1436 dlclose(avcHandle); 1437 avcHandle = NULL; 1438 1439 // Try simple name first. OpenJDK build may contain the latest bits. 1440 filename = g_strdup_printf("%s%s", filename_partial, GST_EXTRA_MODULE_SUFFIX); 1441 if (g_stat (filename, &file_status) < 0) { // Not available, create a versioned filename 1442 g_free(filename); 1443 if (isAVCFFMPEG) 1444 filename = g_strdup_printf("%s-ffmpeg-%d%s", filename_partial, plugin_version, GST_EXTRA_MODULE_SUFFIX); 1445 else 1446 filename = g_strdup_printf("%s-%d%s", filename_partial, plugin_version, GST_EXTRA_MODULE_SUFFIX); 1447 } 1448 } else { 1449 g_free(filename_partial); 1450 continue; // No libavcodec.so installed. 1451 } 1452 } else { 1453 filename = g_strconcat(filename_partial, GST_EXTRA_MODULE_SUFFIX, NULL); 1454 } 1455 #else 1456 filename = g_strconcat(filename_partial, GST_EXTRA_MODULE_SUFFIX, NULL); 1457 #endif 1458 g_free(filename_partial); 1459 1460 if (g_stat (filename, &file_status) < 0) { 1461 /* Plugin will be removed from cache after the scan completes if it 1462 * is still marked 'cached' */ 1463 g_free (filename); 1464 continue; 1465 } 1466 #endif // GSTREAMER_LITE 1467 1468 GST_LOG_OBJECT (context->registry, "file %s looks like a possible module", 1469 filename); 1470 1471 #ifndef GSTREAMER_LITE 1472 /* try to avoid unnecessary plugin-move pain */ 1473 if (g_str_has_prefix (dirent, "libgstvalve") || 1474 g_str_has_prefix (dirent, "libgstselector")) { |